Spring Boot Feign and Restemplate verify purchase order with Apple return error 21004 - feign

I have a Object Dto to verify purchase order with Apple.
String payload = "MIIT3w.....";
String password = "****";
AppleVerifyReceiptRequestCli requestCli= new AppleVerifyReceiptRequestCli();
receiptRequestCli.setReceiptData(payload);
receiptRequestCli.setPassword(password);
receiptRequestCli.setExcludeOldTransaction(false);
Using Restemplate :
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
// Call api to Apple Store to verify
String url = "https://buy.itunes.apple.com/verifyReceipt";
HttpEntity<AppleVerifyReceiptRequestCli> reqUpContentDTO = new HttpEntity<>(requestCli, headers);
HttpEntity<AppleVerifyReceiptResponseCli> responseCliHttpEntity = restTemplate.exchange(url, HttpMethod.POST,reqUpContentDTO, AppleVerifyReceiptResponseCli.class);
Receiver a right resposne {"environment":"Production","receipt":{"adam_id":"159579***" .....}
Using Feign :
#FeignClient(value = "IAppleFeign", url = "https://buy.itunes.apple.com")
public interface IAppleFeign {
#PostMapping(path = "/verifyReceipt",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<AppleVerifyReceiptResponseCli> verifyReceipt(
#RequestBody AppleVerifyReceiptRequestCli request);
}
Receive response error : {"environment":"Production","receipt":null,"status":21004}
I don't know, why Apple return 21004 with feign ?
Tell me why? please.

Related

RestTemplate GET with parameteres with Spring Boot Controller

I'm creating a microservice that recieves data from Rest Template requests to API. I run microservice at localhost:8080 and API at localhost:13001 and test it with Postman. Test method returns String. And there is an issue when request has parameteres. With code below I always get "404 Not Found". But when API controller don't have any parameteres - method works. Can't solve this problem.
Sequence:
1) Postman (GET http://localhost:8080/test)
2) Microservice Controller (Rest Template exchange) --> code below
#RequestMapping(
method = [RequestMethod.GET],
produces = [MediaType.APPLICATION_JSON_VALUE],
path = ["/test"],
params = ["workspace_id"]
)
#ResponseBody
fun test(
authentication : OAuth2Authentication,
#RequestParam(value = "workspace_id")
workspaceId : UUID
) : String
{
return serviceDashboard.get(authentication, workspaceId)
}
3) Rest Template (GET http://localhost:13001/test?workspace_id=......) --> code below
#Autowired
lateinit var restTemplate : RestTemplate
override fun get(
authentication : OAuth2Authentication,
workspaceId : UUID
) : String
{
//Header
val token = (authentication.details as OAuth2AuthenticationDetails).tokenValue
val headers = HttpHeaders()
headers.setBearerAuth(token)
val entity = HttpEntity<Any>(headers)
//Parameters
val params = HashMap<String, UUID>()
params["workspace_id"] = workspaceId
//URI
val endpoint = URI.create("http://localhost:13001/test")
return restTemplate.exchange(endpoint.toString(), HttpMethod.GET, entity, String::class.java, params).body!!
}
4) API Controller (return data) --> code below
----------- Non-working version ----------------
#GetMapping(
produces = [MediaType.APPLICATION_JSON_VALUE],
params = ["workspace_id"],
path = ["/test"])
#ResponseBody
fun test(
#RequestParam(value = "workspace_id")
workspaceId : UUID
) : String
{
if ( workspaceId.toString() == "650a539a-0356-467e-a0d0-71d472c41aae") return "It works"
else return "It doesn't work"
}
----------- Working version ----------------
#GetMapping(
produces = [MediaType.APPLICATION_JSON_VALUE]
path = ["/test"])
#ResponseBody
fun test() : String
{
return "It works"
}
What is the annotation you are using at Class level.
You need to use #RestController.

How to create a SOAP request in EWS?

I've got such kind of class with required login, password, url and domain:
class Service
{
public ExchangeService service;
public void Connect()
{
const string exchangeUser = "login";
const string exchangePassword = "password";
const string exchangeUri = "url";
service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
service.UseDefaultCredentials = true;
service.Credentials = new WebCredentials(exchangeUser, exchangePassword, "domain");
service.Url = new Uri(exchangeUri);
}
}
And I need to add such method as CreateAppointment()
public void CreateAppointment()
{
Appointment appointment = new Appointment(service);
appointment.Subject = "Team building exercise";
appointment.Body = "Let's learn to really work as a team and then have lunch!";
appointment.Start = DateTime.Now.AddHours(2);
appointment.End = appointment.Start.AddHours(4);
appointment.Location = "Some city";
appointment.RequiredAttendees.Add("somebody#something.com");
appointment.ReminderMinutesBeforeStart = 30;
appointment.Save(SendInvitationsMode.SendToNone);
}
Save() method doesn't work because of some reasons for creating service and appointment objects. So I need to rewrite this method using xml request. And I've got an example of SOAP request from msdn https://msdn.microsoft.com/en-us/library/office/dd633661(v=exchg.80).aspx
How could I insert the SOAP request instead of CreateAppointment() method? I've got no idea what to do with xml code to make it work as CreateAppointment() method.

How to send the authentication cookie WebRequest and receive the response in JIRA through REST api?

all
I am working on JIRA, i am sending the authentication request from saparate code and i am getting the response, later i need to fetch all issues from the JIRA than i am sending the request that time i am getting the 401 (Unauthorized) while i am sending the same username and password with gZip compression.
my first request code is following where from i am getting the proper response as authenticated.
string urll = ConfigurationManager.AppSettings["globalUrlForLP"];
HttpWebRequest request;
WebResponse response;
String uri;
LpResponse lp_response;
uri = urll + url;
request = WebRequest.Create(uri) as HttpWebRequest;
request.Credentials = CredentialCache.DefaultCredentials;
request.Method = verb;
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
request.Headers.Set("Authorization", Convert.ToBase64String(Encoding.ASCII.GetBytes(this.Username + ":" + this._password)));
if (null != data)
{
request.ContentType = "application/json";
String jsonPayload = JsonConvert.SerializeObject(data);
byte[] jsonPayloadByteArray = Encoding.ASCII.GetBytes(jsonPayload.ToCharArray());
request.GetRequestStream().Write(jsonPayloadByteArray, 0, jsonPayloadByteArray.Length);
}
lp_response = new LpResponse();
try
{
response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
lp_response.response = reader.ReadToEnd();
}
catch (Exception e)
{
lp_response.error = e;
}
return lp_response;
}
from it i am getting response as following.
{
"session": {
"name": "JSESSIONID",
"value": "12345678901234567890"
},
"loginInfo": {
"failedLoginCount": 10,
"loginCount": 127,
"lastFailedLoginTime": "2014-10-28T06:52:52.211+0000",
"previousLoginTime": "2014-10-28T06:52:52.211+0000"
}
}
Now come to the point, I want to get all projects from the JIRA for that i written following code and i am getting here 401 Unathorized. After getting this i read the JIRA REST Api documentation and there i found following.
"Returns information about the caller's session if the caller is authenticated.
Note that the response contains the Set-Cookie HTTP headers that must be honoured by the caller. If you are using a cookie-aware
HTTP client then it will handle all Set-Cookie headers automatically. This is important because setting the JSESSIONID cookie alone may
not be sufficient for the authentication to work."
so please suggest me what i need to do more with following code ?
my Failure code is following.
string url = ConfigurationManager.AppSettings["urlAllJiraProject"];
LpResponse res = new LpResponse();
HttpWebRequest request;
WebResponse response;
List<AllJiraProject> jiraproject = new List<AllJiraProject>();
request = WebRequest.Create(url) as HttpWebRequest;
request.Credentials = CredentialCache.DefaultCredentials;
request.Method = "GET";
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
request.Headers.Set("Authorization", Convert.ToBase64String(Encoding.ASCII.GetBytes(userNamejira + ":" + passwordjira)));
LpResponse lp_response = new LpResponse();
try
{
response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
lp_response.response = reader.ReadToEnd();
jiraproject = (List<AllJiraProject>)JsonConvert.DeserializeObject<List<AllJiraProject>>(lp_response.response.ToString());
}
catch (Exception e)
{
lp_response.error = e;
}
return jiraproject;
The accepted answer uses basic authentication and not a cookie. When requesting the cookie you don't need add any authorization to the headers. This method will accept a json string with the user name and password and the URL. It will return the cookie values.
public async Task<JiraCookie> GetCookieAsync(string myJsonPass, string JiraCookieEndpointUrl)
{
using (var client = new HttpClient())
{
var response = await client.PostAsync(
JiraCookieEndpointUrl,
new StringContent(myJsonPass, Encoding.UTF8, "application/json"));
var json = response.Content.ReadAsStringAsync().Result;
var jiraCookie= JsonConvert.DeserializeObject<JiraCookie>(json);
return jArr;
}
}
public class JiraCookie
{
public Session session { get; set; }
}
public class Session
{
public string name { get; set; }
public string value { get; set; }
}
When I call it using url: http://[baseJiraUrl]/rest/auth/1/session it returns the following JSON response:
{
"session" : -{
"name" : JSESSIONID,
"value" : cookieValue
}
Keep in mind the URL above is valid in the version of JIRA I'm using and may vary depending on which version you're using.
Read the JIRA API documentation for the correct URL for the version you are using.
Check out this answer on how add cookies to your HttpClient request.
How do I set a cookie on HttpClient's HttpRequestMessage
I got it, my code does not have Basic authentication into the header, while API demands the Basic authentication, so i replaced my one line with following two lines.
Replaced line
request.Headers.Set("Authorization", Convert.ToBase64String(Encoding.ASCII.GetBytes(userNamejira + ":" + passwordjira)));
Replaced By
byte[] authBytes = Encoding.UTF8.GetBytes("user:password".ToCharArray());
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(authBytes);
Jira has three type of authentications, this one from Basic authentication, it is easy to implement, but i had no idea how to implement authentication from cookie.

Jersey client. MultivaluedMap goes empty

My RESTful client has this method:
public void testGetCateogrywiseData() {
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
client.addFilter(new LoggingFilter(System.out));
WebResource service = client
.resource("http://localhost:8080/MyApp/rest/publicdata");
#SuppressWarnings("rawtypes")
MultivaluedMap queryParams = new MultivaluedMapImpl();
queryParams.add("latitude", "18.522387");
queryParams.add("longitude", "73.878437");
queryParams.add("categoryID", "2");
service.queryParams(queryParams);
ClientResponse response = service.get(ClientResponse.class);
System.out.println(response.getStatus());
System.out.println("Form response " + response.getEntity(String.class));
}
On the server side the method looks like this:
#Path("publicdata")
#GET
#Produces(MediaType.TEXT_HTML)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String getPublicData() throws JSONException {
MultivaluedMap<String, String> valueMap = uriInfo.getQueryParameters();
Long latString = Long.parseLong(valueMap.getFirst("latitude"));
Long lonString = Long.parseLong(valueMap.getFirst("longitude"));
Long categoryId = Long.parseLong(valueMap.getFirst("categoryID"));
// Do necessary stuff and return json string
return null;
}
My problem is the valueMap at the server end is always empty. It never gets the three parameters that I have sent from the client code. What am I missing?
The problem happens on this line:
service.queryParams(queryParams);
It successfully adds the query params, but it does not change the original service, it returns a new one to you. To make it work you need to change to this:
service = service.queryParams(queryParams);

HTTP Status 500 - org.springframework.web.client.HttpClientErrorException: 404 /

I am using RestTemplate, but when i call postFor function i get following exception, Below are the code for showing detail:
Controller
#Controller
#RequestMapping("/data")
public class DataController {
#RequestMapping(value = "/{id}", method = RequestMethod.POST)
public ResponseEntity<ManagementResource> postData(#PathVariable("id") String id,#RequestBody Data1 data) {
RSResponse<Data1> response = new RSResponse<Data1>();
response.setStatus(RSResponse.Status.SUCCESS);
response.setData(data);
return new ResponseEntity<ManagementResource>(HttpStatus.CREATED);
}
}
client code:
RestTemplate rt = new RestTemplate();
Data1 d = new Data1();
d.setEmp_id(1);
d.setEmp_name("abc");
d.setEmp_salary(10000);
Map<String, String> vars = new HashMap<String, String>();
vars.put("id", "JS01");
String url = "http://localhost:8090/JSFFaceletsTutorial/data/{id}";
ResponseEntity<Data1> response = rt.postForEntity(url,d,Data1.class,vars);
Data1 data = response.getBody();
please tell if anyone knows it.
Thanks
Does your service need headers? If so, you can pass like this,
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("Accept", "application/json");
HttpEntity<Data1> request = new HttpEntity<Data1>(d, headers);
ResponseEntity<Data1> response = rt.postForEntity(url,request,Data1.class,vars);
Data1 data = response.getBody();