Oracle MCS Custom API call from MAF Application - oracle

I have created a custom API in Oracle MCS to get the user information and trying to call it from MAF application... As a response i am getting 200 as success code... but when i try to parse the response it shows a HTML page instead of actual responce....
Custom API
https://mobileportalsetrial1304dev-mcsdem0001.mobileenv.us2.oraclecloud.com:443/mobile/custom/rvs_ekkfetchuserinfo/fetchcontent
and userid=101 as parameter
Calling Method to get User information
#Override
public Response getUserInformation(int userId) {
System.out.println("In loginService");
String restURI = "https://mobileportalsetrial1304dev-mcsdem0001.mobileenv.us2.oraclecloud.com:443/mobile/custom/rvs_ekkfetchuserinfo/fetchcontent?userid=" + userId;
String jsonRequest = "";
Response response = new Response();
response = RestUtil.callGet(restURI, jsonRequest);
return response;
}
callGet Method
public static Response callGet(String restURI, String jsonRequest) {
String responseJson = "";
Response response = new Response();
System.out.println("restURI:" + restURI);
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
restServiceAdapter.clearRequestProperties();
restServiceAdapter.setConnectionName("MiddlewareAPI");
restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_GET);
restServiceAdapter.addRequestProperty("Content-Type", "application/json");
restServiceAdapter.addRequestProperty("Accept", "application/json; charset=UTF-8");
restServiceAdapter.addRequestProperty("Oracle-Mobile-Backend-Id", "da5c7d86-29c0-43e8-b613-53de55a7ae6c");
restServiceAdapter.addRequestProperty("Authorization", "Basic TUNTREVNMDAwMV9NT0JJTEVQT1JUQUxTRVRSSUFMMTMwNERFVl9NT0JJTEVfQU5PTllNT1VTX0FQUElEOmR5Nm91NW5wX3RnbE5r");//+new String(encodedBytes));
restServiceAdapter.setRequestURI(restURI);
restServiceAdapter.setRetryLimit(0);
try {
responseJson = restServiceAdapter.send(jsonRequest);
System.out.println("response" + responseJson);
int responseCode = restServiceAdapter.getResponseStatus();
System.out.println("responseCode" + responseCode);
response.setResponseCode(responseCode);
response.setResponseMessage(responseJson);
response.setHeader(restServiceAdapter.getResponseHeaders());
} catch (Exception e) {
System.out.println("Error in calling API" + e.getStackTrace());
int responseCode = restServiceAdapter.getResponseStatus();
response.setResponseCode(responseCode);
response.setResponseMessage(responseJson);
}
return response;
}
Json Parsing
JSONObject obj = new JSONObject(response);
JSONArray arr = obj.getJSONArray("posts");
for (int i = 0; i < arr.length(); i++)
{
String user_id = arr.getJSONObject(i).getString("UserId");
}
Here what i am getting is JSONObject["items"] is not found... when i print the responce message it gives a HTML Script file
Expected Output
{
"items": [
{
"UserId": "101",
"AgentId": null,
"Category": "Rental",
"Division": "KDR",
"Status": null,
"LocationId": null,
"Operation": "CheckOut",
"Admin": "N",
"createdBy": "mcs-demo_user09#oracleads.com",
"createdOn": "2015-09-25T11:29:10.215564+00:00",
"modifiedBy": "mcs-demo_user09#oracleads.com",
"modifiedOn": "2015-09-25T11:29:10.215564+00:00"
}
]
}

what is the content of the HTML page (it will have some JavaScript I assume but should have a HTML title as well). Anyway, a user Id in MCS is not 101 but an internal ID, so I don't know if you've chosen 101 for simplification in this question.
In MAF, the REST connection is defined through a REST connection with the root URL and the relative URI. In your example, the REST connection is referenced as "MiddlewareAPI". Unless the value of this connection is null, the restURI you provide needs to be reduced to not contain the root URL.
The HTTP 200 you get because the request is answered by the server. However, it appears to be missing either an authorized user (in case of a failed basic authorization for accessing the API) or the authenticated user is not allowed to request the user platform API (by default you can only request information about the user you re authenticated as).
Frank

Hi I got the solution...
I was trying to call customAPI through Oracle-MCS. I replaced RestServiceAdapter with HttpsURLConnection. Then it Works perfectly fine.

Related

Displaying file in web page using AJAX and Spring Boot

I am building a REST API in Spring Boot for uploading and fetching file from the server, I want to upload various types of file that can either be text,image,audio,video,etc..
While uploading there is no problem, but when I want to display the file on my web page, on content is appearing, but I am getting the data from the server as a raw data.
I want to put that data into URL.createObjectURL() and then redirect to the URL which is generated.
There are some screenshots which I am uploading.
This is the data when I do console.log(response);
The code which I am using for AJAX
var form = new FormData();
form.append("qualifiedFilePath", "E://files/test.png");
var settings = {
"async": true,
"crossDomain": true,
"url": "http://localhost:8081/callTransaction/file",
"method": "POST",
"timeout": 0,
"processData": false,
"mimeType": "multipart/form-data",
"contentType": false,
"Accept": "image/png",
"data": form
};
$.ajax(settings).done(function(response) {
console.log(response);
const objectURL = URL.createObjectURL(new Blob([response], {
"type": "image/png"
}));
console.log(objectURL);
});
I get the URL:
blob:http://localhost:8080/81c9fbde-5e84-400e-8d92-5da6fc02c7ef
Output:
The Source Code in Spring Boot:
Controller:
#PostMapping(path="/file")
#CrossOrigin(origins = "http://localhost:8080")
public ResponseEntity<Resource> loadFile(#RequestPart("qualifiedFilePath") String qualifiedFilePath, HttpServletRequest request)
{
return ctbl.loadFile(qualifiedFilePath,request);
}
BusinessLogic:
public ResponseEntity<Resource> loadFile(String qualifiedFilePath, HttpServletRequest request)
{
Resource file=null;
if(qualifiedFilePath==null)
{
return new ResponseEntity<Resource>(file,HttpStatus.BAD_REQUEST);
}
try {
file=ctdi.loadFile(qualifiedFilePath);
} catch (MalformedURLException e) {
return new ResponseEntity<Resource>(file,HttpStatus.INTERNAL_SERVER_ERROR);
}
if(file==null)
{
return new ResponseEntity<Resource>(file,HttpStatus.NO_CONTENT);
}
String contentType = null;
try {
contentType = request.getServletContext().getMimeType(file.getFile().getAbsolutePath());
} catch (IOException ex) {
return new ResponseEntity<Resource>(file,HttpStatus.INTERNAL_SERVER_ERROR);
}
if(contentType == null) {
contentType = "application/octet-stream";
}
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"")
.body(file);
}
DAO:
#Override
public Resource loadFile(String qualifiedFilePath) throws MalformedURLException {
Path filePath = Paths.get(qualifiedFilePath);
Resource resource = new UrlResource(filePath.toUri());
return resource;
}
It has been a long time to answer since the question was posted, but the solution to it has been discovered.
It has a very simple solution.
I used the program logic from the CalliCoder webiste[the link is attached below], by using this I was able to store files, view files and download them too, they have given a very nice explanation of the program and how to do it.
By using this we can make a URL(endpoint) by which we can access the file we are approaching for, they too have given an example for accessing the file.
They have made a web-based front-end in which they are trying to upload files, but the module for displaying the file/downloading the file in front-end is missing.
Yes, We can just copy the URL(endpoint) in the browser and it starts displaying/playing the file.
If we want to use URL.createObjectURL() for making a temporary and local URL for the same source, then we can do like this:
URL.createObjectURL(await fetch("URL(endpoint)").then(r => r.blob()));
This example is taken from Stackoverflow[The link is attached bellow]
References:
CalliCoder
StackOverflow

spring boot DeferredResult onError how to invoke the callback?

Need to perform some asynchronous processing in a Rest service without holding up the server's Http threads .
I think DeferredResult would be a good option.
However when I am trying to ensure my callback on error gets called - am not able to do so .
Here is a naive attempt on my part:
#GetMapping("/getErrorResults")
public DeferredResult<ResponseEntity<?>> getDeferredResultsError(){
final String METHOD_NAME = "getDeferredResultsError";
logger.info("START : {}",METHOD_NAME);
DeferredResult<ResponseEntity<?>> deferredOutput = new DeferredResult<>();
ForkJoinPool.commonPool().submit(() -> {
logger.info("processing in separate thread");
int age = 0;
try {
age = age / 0;
}catch(Exception e) {
logger.error("we got some error");
logger.error(e);
throw e;
}
logger.info("after try catch block");
});
deferredOutput.onError((Throwable t) -> {
logger.error("<<< HERE !!! >>>");
deferredOutput.setErrorResult(
ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(t.getMessage()));
});
logger.info("done");
return deferredOutput;
}
When I call this Rest endpoint from Postman - I can see in server logs the arithmetic exception by zero but dont see the 'onError' getting invoked.
After some time get a response in Postman as follows:
{
"timestamp": "2019-07-30T09:57:16.854+0000",
"status": 503,
"error": "Service Unavailable",
"message": "No message available",
"path": "/dfr/getErrorResults"
}
So my question is how does the 'onError' get invoked ?
You need to pass the DeferredResult object to the asynchronous operation so you could update it in case of success or failure:
#GetMapping(value = "/getErrorResults")
public DeferredResult<ResponseEntity<String>> getDeferredResultsError() {
DeferredResult<ResponseEntity<String>> deferredResult = new DeferredResult<>();
ForkJoinPool.commonPool().submit(() -> {
System.out.println("Processing...");
int age = 0;
try {
age = age / 0;
deferredResult.setResult(ResponseEntity.ok("completed"));
}catch(Exception e) {
System.out.println("Failed to process: " + e.getMessage());
deferredResult.setErrorResult(
ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(e.getMessage()));
}
});
return deferredResult;
}
In the code you posted, you returned the DeferredResult object without passing it to the asynchronous operation. So after your return it, SpringMVC holds the client connection and wait until the DeferredResult object will be assigned with some kind of result. But in your case, the DeferredResult is not held by the asynchronous operation and will never updated so you get "Service Unavailable".
Here you can find working (light) project example.

Secure Web API Post Method with Username and Password

I have a Web API service hosted in Microsoft Azure. I need a certain POST method to be only accessible with one unique username and password.
I understand the [Authorize] method does a token based authentication but its not tied to a single username and password. In my app, the web api also does the login authentication, so anyone who registers can access this post method if im not mistaken. (Please correct me if im wrong)
I am new to this could you guide me the right way please.
This is my WebAPI Post method i want to secure access to with specific unique username&pass:
[AllowAnonymous]
[HttpPost, Route("send")]
public async Task<NotificationOutcome> Post([FromBody]string message)
{
string hubName = "myHub";
string hubNameDefaultShared = "myHubNameDefaultShared";
NotificationHubClient hub = NotificationHubClient
.CreateClientFromConnectionString(hubNameDefaultShared, hubName, enableTestSend: true);
string installationId = string.Empty;
var templateParams = new Dictionary<string, string>
{
["messageParam"] = message
};
NotificationOutcome result = null;
if (string.IsNullOrWhiteSpace(installationId))
{
result = await hub.SendTemplateNotificationAsync(templateParams).ConfigureAwait(false);
}
else
{
result = await hub.SendTemplateNotificationAsync(templateParams, "$InstallationId:{" + installationId + "}").ConfigureAwait(false);
}
return result;
}
And this is how I currently access the POST Method:
var client = new RestClient("myWebApiRouteName");
var request = new RestRequest(Method.POST);
request.AddHeader("Postman-Token", "46c23eba-8ca6-4ede-b4fe-161473dc063a");
request.AddHeader("cache-control", "no-cache");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("undefined", messageBody, ParameterType.RequestBody);
try
{
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}

Customizing the criteria for triggering Fallback in Hystrix Circuit Breaker

I would like to trigger a fallback from a #HystrixCommand Method based on my own criteria (checking for a specific response status).
My method basically acts as a client which calls a service in another URL (marked here as URL).
Here is my code:
#HystrixCommand(fallbackMethod="fallbackPerformOperation")
public Future<Object> performOperation(String requestString) throws InterruptedException {
return new AsyncResult<Object>() {
#Override
public Object invoke() {
Client client = null;
WebResource webResource = null;
ClientResponse response =null;
String results = null;
try{
client = Client.create();
webResource = client.resource(URL);
client.setConnectTimeout(10000);
client.setReadTimeout(10000);
response = webResource.type("application/xml")
.post(ClientResponse.class, requestString);
logger.info("RESPONSE STATUS: " + response.getStatus());
if (response.getStatus() != 200) {
webResource = null;
logger.error(" request failed with the HTTP Status: " + response.getStatus());
throw new RuntimeException(" request failed with the HTTP Status: "
+ response.getStatus());
}
results = response.getEntity(String.class);
} finally {
client.destroy();
webResource = null;
}
return results;
}
};
}
This triggers the fallback Method fallbackPerformOperation() when the response status code is not 200 i.e. response.getStatus()!=200.
The fallback method returns a string which tells the user that the Request did not return a status of 200 and so it is falling back.
I want to know if I can trigger the fallback without having to explicitly throw an exception inside my performOperation() Method.
Could I use #HystrixProperty? I know people mostly use it for timeouts and volume thresholds but could I write a custom #HystrixProperty that checks if the response status is 200 or not within my Method?

How do I return ajax response from unirest in nodejs?

I am using unirest from unirest.io to make ajax calls in node.
I want to return attendance so I can use it in another place.
function studentAttendance(req, res) {
unirest
.post('http://coer.ac.in/atten.php')
.field('coerid', req.params['id'])
.end(function (response) {
if (response.error) {
return response.error;
} else {
var attendance = {
"name": null,
"attendance": null,
"attenLastUpdated": null
}
if (response.raw_body.indexOf('Invalid COER ID') === -1) {
attendance = {
"name": response.raw_body.split("<h3>")[1].split("</h3>")[0].split("Mr/Ms ")[1].split(" have")[0],
"attendance": response.raw_body.split("<h3>")[1].split("</h3>")[0].split("%")[0].substr(String.length - 6),
"attenLastUpdated": response.raw_body.split("<p>")[1].split("</p>")[0].split(" Update ")[1]
}
console.log("\n\t\t Found ID in Database\n" + JSON.stringify(attendance));
res.send(attendance);
} else {
attendance = {
"name": null,
"attendance": "Invalid ID",
"attenLastUpdated": "Invalid ID"
}
console.error("\nError: Invalid COER ID. No match in Database.");
res.send(attendance);
}
}
});
}
I have tried return audience; and then return unirest and then print it's output but it prints a lot of objects and other data that can be used in a ajax call.
I want to use the result from this POST call to an attendance server and use this result in another place. To do this I need to return attendance but I have no idea how to do it.
I am trying to build a system so you just have to enter your ID and it'll fetch your name and attendance and pass it along as response to the API consumer and also save the unirest response saved to a database.
I can open and save data inside unirest's end method but this function or route is public and anyone can access this without providing a secret key in header. I am trying to avoid that because I guess it is risky?
Just one motive, Fetch the data, pass it to whoever requested it and save a copy to database.
No mongo inside unirest, because it might(?) dangerous.
Final option left(atleast the one that I can think of) is, returning the response and use it some where else.
Unirest uses a lot of things that I don't about and I think that I can not return the respone like you can do in other functions.
This problem was solved by putting the function in an object and than create another object data that'll hold the data.
Now, When you recieve the response update the data object and then pass a callback in unirest that'll return the data object.
This worked for me.
Whole Code:
var studentAttendance = {
"studentAttendance": function (req, res) {
var _id = req.params['id'];
unirest
.post('http://coer.ac.in/atten.php')
.field('coerid', _id)
.end(function getData(response) {
if (response.error) {
throw response.error;
} else {
if (response.raw_body.indexOf('Invalid COER ID') === -1) {
studentAttendance.data._id = _id;
studentAttendance.data.name = response.raw_body.split("<h3>")[1].split("</h3>")[0].split("Mr/Ms ")[1].split(" have")[0];
studentAttendance.data.attendance = parseFloat(response.raw_body.split("have ")[1].split("%")[0]);
studentAttendance.data.attenLastUpdated = response.raw_body.split("<p>")[1].split("</p>")[0].split(" Update ")[1]
console.log("\n\t\t Found ID in Database\n" + JSON.stringify(studentAttendance.data) + "\n Updating Record in Database");
res.send(studentAttendance.data);
} else {
studentAttendance.data._id = _id;
studentAttendance.data.name = null;
studentAttendance.data.attendance = "Invalid ID",
studentAttendance.data.attenLastUpdated = "Invalid ID"
console.error("\nError: Invalid COER ID. No match in Database.");
res.send(studentAttendance.data);
}
}
}
, attendanceCallback)
},
"data": {
"_id": null,
"name": null,
"attendance": null,
"attenLastUpdated": null
}
}
function attendanceCallback() {
return studentAttendance.data;
}

Resources