Oracle MAF-MCS API call - oracle

I have created a custom POST api for getting login information in MCS. when i check in SOAPUI it works perfectly fine. the parameters passed are
1. header
Oracle-Mobile-Backend-Id: ********************
2. Authentocation
Username:****************
password: **************
and basic login info username and password as "User1" and "user1" respectively.
Step2:
when i call the API from MAF i am getting an error 400
the post method used is
public static Response callPost(String restURI, String jsonRequest) {
String responseJson = "";
Response response = new Response();
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
restServiceAdapter.clearRequestProperties();
//restServiceAdapter.setConnectionName("MiddlewareAPI");
// restServiceAdapter.setConnectionName("");
restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_POST);
restServiceAdapter.addRequestProperty("Content-Type", "application/json");
restServiceAdapter.addRequestProperty("Accept", "application/json; charset=UTF-8");
restServiceAdapter.addRequestProperty("Oracle-Mobile-Backend-Id", "**********");
restServiceAdapter.addRequestProperty("Domain", "mcsdem0001");
restServiceAdapter.addRequestProperty("Username", "******");
restServiceAdapter.addRequestProperty("Password", "*****");
//restServiceAdapter.addRequestProperty("Authorization", "Basic "+new String(encodedBytes));
System.out.println("**** Authorization String ****=>"+new String(encodedBytes));
System.out.println("**** RestURI ******=>"+restURI);
System.out.println("**** jsonRequest ******=>"+jsonRequest);
restServiceAdapter.setRequestURI(restURI);
restServiceAdapter.setRetryLimit(0);
try {
responseJson = restServiceAdapter.send(jsonRequest);
int responseCode = restServiceAdapter.getResponseStatus();
response.setResponseCode(responseCode);
response.setResponseMessage(responseJson);
response.setHeader(restServiceAdapter.getResponseHeaders());
} catch (Exception e) {
int responseCode = restServiceAdapter.getResponseStatus();
response.setResponseCode(responseCode);
response.setResponseMessage(responseJson);
}
System.out.println("Response:" + responseJson);
return response;
}
Could anyone please tell me is there any error in the post method??

This can be due to the version conflict. Try to use HttpUrlConnection instead of RestServiceAdapter and let me know if it works.

actually this bit
restServiceAdapter.addRequestProperty("Username", "******");
restServiceAdapter.addRequestProperty("Password", "*****");
doesn't work because you attempt to pass username and password as a HTTP header. Instead it should be passed as you were trying here
restServiceAdapter.addRequestProperty("Authorization", "Basic "+new String(encodedBytes));
However, these should not be encoded bytes but a base64 encoded string in the form
Basis (without the < abd >)
Note that user identity domains only need to be provided in multi-tenant environments. In MCS, the user domain is defined through the mobile backend you connect to.
Frank

Use the MAF MCS Utility library to make it allot easier.
The developer guide can be found here: http://download.oracle.com/otn_hosted_doc/maf/mafmcsutility-api-doc-082015.pdf
Example code:
MBEConfiguration mbeConfiguration =
new MBEConfiguration(
<mbe rest connection>,<mobileBackendId>,
<anonymous key string>,<application key string>,
MBEConfiguration.AuthenticationType.BASIC_AUTH);
mbeConfiguration.setEnableAnalytics(true);
mbeConfiguration.setLoggingEnabled(false)
mbeConfiguration.setMobileDeviceId(
DeviceManagerFactory.getDeviceManager().getName());
MBE mobileBackend = MBEManager.getManager().
createOrRenewMobileBackend(<mobile backend Id>, mbeConfiguration);
CustomAPI customApiProxy = mbe.getServiceProxyCustomApi();
MCSRequest request = new MCSRequest(mobileBackend.getMbeConfiguration());
request.setConnectionName(<Rest connection name>);
request.setRequestURI("/moile/custom/mockup/employees");
request.setHttpMethod(MCSRequest.HttpMethod.POST);
request.setPayload("{\"id\":\"1\"\"name\":\"nimphius\",\"firstName\":\"frank\"}");
request.setRetryLimit(0);
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type","application/json");
request.setHttpHeaders(headers);
MCSResponse response = customApiProxy .sendForStringResponse(request);
String jsonResponse = (String) response.getMessage();

Related

How to make jira attachments download work using jira rest api

I am trying to download attachments from Jira. I use /rest/api/2/attachment/{id} to get json response of the attachment. It has field "content" that is the attachment url. I use this url and construct HttpGet and execute to get response that always gives me html content asking for login. I am sending Basic Authorization in the httpGet header. Apparently this works for downloading .png files but not any other file types. I am using java spring rest to connect to Jira horizon.
Closeable httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(jira attachmenturl);
httpGet.setHeader("Authorization", "Basic <base64Credentials>);
CloseableHttpResponse response = httpclient.execute(httpGet)
The response for .txt, .jpeg, Microsoft documents is different from response that I get for .png files.
This works:
#GetMapping(value = "/getAttachment")
public String getAttachment(#RequestParam("id") String attachmentID) throws Exception {
Client client = Client.create();
WebResource webResource = client.resource(jiraBaseURLRest + "attachment/" +
attachmentID);
ClientResponse response = webResource.header("Authorization", "Basic " +
base64Creds).type("application/json")
.accept("application/json").get(ClientResponse.class);
String result = response.getEntity(String.class);
JSONObject jsonObj = new JSONObject(result);
System.out.println("JSON Object = "+jsonObj);
URL url = new URL(jsonObj.getString("content"));
Closeable httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url.toURI());
httpGet.setHeader("Authorization", "Basic " + base64Creds);
CloseableHttpResponse response1 = ((CloseableHttpClient) httpclient).execute(httpGet);
if(response1.getStatusLine().getStatusCode() == 200)
{
HttpEntity entity = response1.getEntity();
if (entity.isStreaming())
{
System.out.println("Streaming...");
byte data[] = EntityUtils.toByteArray(entity);
FileOutputStream fout = new FileOutputStream(new File("D://pdf1.pdf"));
fout.write(data);
fout.close();
System.out.println("Done!!");
}
}
return "Success";
}

Invalid mimetype exception in Spring boot rest call

I am new to both Spring boot and rest calls.
I am trying to consume a rest service and I do not have any information about that rest API except URL. When I hit that URL from a browser I am getting a response as {key:value}. So, I assumed that it is a JSON response.
I am consuming it in spring boot as follows
restTemplate.getForObject(url, String.class) .
This is giving Invalid mime type "content-type: text/plain; charset=ISO-8859-1": Invalid token character ':' in token "content-type: text"
I assume that this error is because response content type is set to text/plain but it is returning JSON format.
EDIT:
Tried this way but did not work.
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>("parameters",headers);
ResponseEntity<String> result = restTemplate.exchange(url,HttpMethod.GET,
entity, String.class);
How to handle and solve it?
You might want to read about the request headers your REST API needs. Content-Type header specifies the media type of the request you're sending to the server. Because you're just getting data from the server you should set the Accept header to the kind of response you want i.e., Accept: application/json.
Unfortunately, you can't set headers using getForObject(). You could try this:
URL url = new URL("Enter the URL of the REST endpoint");
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Accept", "application/json");
if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuffer content = new StringBuffer();
String inputLine;
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
}

the passed param by resttemplate.exchange was not decoded in service side automatically

Below is my REST API code:
#RequestMapping(value = "/get", method = RequestMethod.POST, produces = { "application/json" })
#ApiOperation(value = "get data by key.", notes = "return json string value.")
public JsonObjectResponse<String> get(
#ApiParam(required = true, name = "regionName", value = "region name") #RequestParam("regionName") String regionName,
#ApiParam(required = true, name = "key", value = "region key,Default is uuid") #RequestParam("key") String key) throws UnsupportedEncodingException
{
JsonObjectResponse<String> jr = new JsonObjectResponse<String>();
//key = decodeJsonString(key); // added for junit
String val = adfService.onPath(regionName).get(key);
jr.setState(StateCode.SUCCESS);
jr.setData(JsonObject.create().append(key,val).toJson());
return jr;
}
I'm trying to pass parameters:
regionName=/fusion/table1&key={"fusionTbl1DetailNo":"fusionNo001","pk":"PK0001"}
If I call it via swagger-ui, it calls like this:
http://localhost:8080/service/basic/get?regionName=%2Ffusion%2Ftable1&key=%7B%22fusionTbl1DetailNo%22%3A%22fusionNo001%22%2C%22pk%22%3A%22PK0001%22%7D&token=8652493a-4147-43f4-af3a-bcb117fb7d42`
It encoded the parameters and these parameters also can be decoded automatically in server side correctly.
When I want to add testcase for this API, I use restTemplate.exchange method, code as below:
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
for (Entry<String, String> entry : queryParamMap.entrySet()) {
builder.queryParam(entry.getKey(), entry.getValue());
}
if (uriParamMap != null) {
url = builder.buildAndExpand(uriParamMap).toUriString();
} else {
url = builder.toUriString();
}
if (StringUtils.isEmpty(requestBody)) {
if (bodyParamMap != null) {
requestBody = parseMapToParams(bodyParamMap);
} else {
requestBody = "";
}
}
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = new MediaType("application", "json", Charset.forName("UTF-8"));
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
// headers.add(HttpHeaders.CONTENT_TYPE, "application/json");
// headers.add("Accept", "application/json");
// headers.set(HttpHeaders.ACCEPT, "application/json");
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
// headers.add("Accept-Encoding", "gzip, deflate, br");
headers.set("Accept-Charset", "utf-8");
headers.set("Accept-Encoding", "gzip");
headers.add("Accept-Language", "zh-CN,zh;q=0.8,en;q=0.6");
headers.add("User-Agent",
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
headers.add(TestBase.TOKEN_HEADER, TestBase.getTokenId());
HttpEntity<String> request = new HttpEntity<>(body, headers);
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
ResponseEntity<String> response = restTemplate.exchange(url, httpMethod, request, String.class);
localresponse.set(response);
System.out.println("response:" + response);
return response;
I used UriComponentsBuilder to append the parameters, it will format the url to
http://localhost:8080/service/basic/get?regionName=/fusion/table1&key=%7B%22fusionTbl1DetailNo%22:%22fusionNo001%22,%22pk%22:%22PK0001%22%7D
for method exchange. However, when the server side received the call, it did not decode the param key, it's value still was:
%7B%22fusionTbl1DetailNo%22:%22fusionNo001%22,%22pk%22:%22PK0001%22%7D
Why is that? I compared the header settings from the swagger calling, added additional settings, no effect :(.
Instead of toUriString() use, UriComponentsBuilder.fromUriString(url).queryParam("name","John Doe").build().toString();
Try like the following:
ResponseEntity<String> res = restTemplate.exchange("http://localhost:8080/service/basic/get?regionName={arg1}&key={arg2}", HttpMethod.POST, null, String.class,"/fusion/table1", "{\"fusionTbl1DetailNo\":\"fusionNo001\",\"pk\":\"PK0001\"}");
arg1 and arg2 will be replaced by
"/fusion/table1" and "{\"fusionTbl1DetailNo\":\"fusionNo001\",\"pk\":\"PK0001\"}"
I send null in requestEntity as no request body and request parameters is in uriVariables.
The Spring Documentation on RestTemplate reads:
For each HTTP method there are three variants: two accept a URI
template string and URI variables (array or map) while a third accepts
a URI. Note that for URI templates it is assumed encoding is
necessary, e.g. restTemplate.getForObject("http://example.com/hotel
list") becomes "http://example.com/hotel%20list". This also means if
the URI template or URI variables are already encoded, double encoding
will occur,
It looks like you are using a RestTemplate exchange method that takes a URI template string and you should therefore NOT encode the url-string.
The url-string is first encoded on
builder.toUriString()
And then again on the exchange-call. So the problem seems to be double encoding on the client side, not lack of decoding on the server side

ALM 12 REST using SpringFramework RestTemplate: "401 QCSession cookie missing"

In ALM 12 we have to explicity call "qcbin/rest/site-session" to get session.
When I GET call "/qcbin/rest/site-session" I receive the following:
"Set-Cookie=[BIGipServerALMAST330P-QC=rd100o00000000000000000000ffff0fe0dd74o8080; path=/, ]""
I extract the cookie as described here:
HP ALM 12 REST not returning QCSession cookie.
Instead of this RestConnector, our project is using RestTemplate from SpringFramework, so I did:
private HashMap getQCSession() throws Exception {
URL url = new URL("https://almxxxx.saas.hp.com/qcbin/rest/site-session?login-form-required=y");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/xml");
conn.setRequestProperty("Accept", "application/xml");
conn.connect();
HashMap cookies = updateCookies(conn);
return cookies;
}
public HashMap updateCookies(HttpURLConnection conn) {
String cookie2 = conn.getHeaderField("Set-Cookie");
int equalIndex = cookie2.indexOf('=');
int semicolonIndex = cookie2.indexOf(';');
String cookieKey = cookie2.substring(0, equalIndex);
String cookieValue = cookie2.substring(equalIndex + 1, semicolonIndex);
HashMap cookies = new HashMap();
cookies.put(cookieKey, cookieValue);
System.out.println(cookies.toString());
return cookies;
}
To send the cookie in the GET call using the RestTemplate I followed the instructions from http://springinpractice.com/2012/04/08/sending-cookies-with-resttemplate/, so I did:
public <U extends Object> ResponseEntity<U> getFromURL(URI url, Class<U> responseBodyClass) throws Exception {
logger.info("GET na URL: {} esperando classe: {} no response", url, responseBodyClass);
HashMap cookie = this.getQCSession();
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("Cookie", this.getQCSession().toString());
this.httpEntity = new HttpEntity(null, requestHeaders);
return super.exchange(url, HttpMethod.GET, this.httpEntity, responseBodyClass);
}
The requestHeaders content added to the HttpEntity (SpringFramework) is:
{Cookie=[{BIGipServerALMAST330P-QC=rd100o00000000000000000000ffff0fe0dd74o8080}]}
However I'm still getting "401 QCSession cookie missing".
I already tried to send in the GET call the JSESSIONID, with no success as well.
I appreciate any help.
Any clue?
I ran into this. As of ALM12 you need to create a session also.
I POST some XML or JSON to here "/authentication-point/alm-authenticate" to authenticate
Then collect the Set-Cookie header
I then POST to "/rest/site-session" with the cookie from the previous response.
I collect the session cookies from that response to use in my subsequent requests.
Hope that helps
I don't know, if it can help you but you are sending it with query param for UI authentication.
"POST .../rest/site-session?login-form-required=y"
I would suggest to POST it without query param
"POST .../rest/site-session"
Also the order of actions you should do before asking for QCSession token is:
1.Check whether you are authenticated
"GET .../rest/is-authenticated"
2.If not you'll get reference where to authenticate: WWW-Authenticate: LWSSO realm=".../authentication-point"
3.Send basic auth header to authentication point with added alm-authenticate at the end. Which returns you LWSSO_COOKIE_KEY.
"POST .../authentication-point/alm-authenticate"
Authentication: Basic BASE64{username:password}
4.Then you'll need to POST that LWSSO_COOKIE_KEY to site-session and ALM will return you QCSession key.
"POST .../rest/site-session"
"Cookie: LWSSO_COOKIE_KEY={cookie}; Path=/"
Hopefully I was able to help you.
If you still have problems, feel free to contact me.

401 error with urbanairship using httpsurlconnection class

I am getting a 401 error when i try to hit the push URL. I am using HTTP BASIC authentication with "Application Key" as username and "Application Master Secret"as password. I am using JAVA HttpsUrlConnection class. I dont know whats wrong with my code.
` URL url = new URL("https://go.urbanairship.com/api/push");
HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Content-Type","application/json");
connection.setRequestProperty("Content-Length", Integer.toString(data.length()));
String authString = "xxxxxxxxxxxxxxxxxx:yyyyyyyyyyyyyyyyy";
authString = Base64Coder.encodeString(authString);
connection.setRequestProperty("Authorization","Basic "+ authString);
OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
wr.write(data);
wr.flush();
int responseCode = connection.getResponseCode();
//Get the response
String responseLine = new BufferedReader(new InputStreamReader(connection.getInputStream())).readLine();`
Your authString should be composed of <application-key>:<application-master-secret>. Also your authstring may not be getting encoded properly. Try using Apache Commons Codec or ostermiller library to encode the authstring

Resources