Java heap memory issue while calling the API - spring-boot

I am calling an Autodesk API GET {urn}/metadata/{guid}/properties
this API returns {"result":"success"} as JSON String for the first time.
If I call the same API repeatedly using a while loop it returns the properties of a flat list of objects from an object tree of 64MB of data.
To verify the data I received from API, below code is what I have written
boolean hasResult = false;
boolean hasData = false;
String result
do {
result = api call
JSONObject jo = new JSONObject(result);
hasResult = jo.has("result");
hasData = jo.has("data");
if (hasData) {
break;
}
} while (hasResult);
This process leads to running out of memory java heap space issue.

Related

is returning stream considered anti pattern in web api?

I am from the old world that think webapi should return a strong typed object and let json serialization return data.
However, recently we got this requirement:
We have a sql table which has more than 500 columns.
The customer always want to return all the columns.
Our c# code does nothing other than reading the SqlDatareader, convert the reader to a c# object and return result.
In this case, wouldn't better to do this (example copied from another stackoverflow post). Basically just return a stream? Does returning a stream still considered to be anti-pattern?
public HttpResponseMessage SomeMethod(List<string> someIds)
{
HttpResponseMessage resp = new HttpResponseMessage();
resp.Content = new PushStreamContent(async (responseStream, content, context) =>
{
await CopyBinaryValueToResponseStream(responseStream, someIds);
});
return resp;
}
private static async Task CopyBinaryValueToResponseStream(Stream responseStream, int imageId)
{
// PushStreamContent requires the responseStream to be closed
// for signaling it that you have finished writing the response.
using (responseStream)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
await connection.OpenAsync();
using (SqlCommand command = new SqlCommand("SELECT 500 columns FROM [StupidWideTable] WHERE ....", connection))
{
.....
using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess))
{
if (await reader.ReadAsync())
{
if (!(await reader.IsDBNullAsync(0)))
{
using (Stream data = reader.GetStream(0))
{
// Asynchronously copy the stream from the server to the response stream
await data.CopyToAsync(responseStream);
}
}
}
}
}
}
}// close response stream
}
Does returning a stream still considered to be anti-pattern?
Well, that depends on what you want to do. For example, if you want to return a 500 if the SQL server fails partway through, then you shouldn't return a stream.
Streaming results works fine on ASP.NET, but it's important to note that all headers (including the response status code) are sent before the stream begins. So you'll send an immediate 200 when you start streaming the result, and if there's an error later on there's no way to go back in time and change that to a 500. Or add some kind of Continue header.
In other words, yes it's supported; but you lose all the benefits of model binding, content negotiation, exception handlers, etc., because you're bypassing that whole pipeline.

Looking for PendingResult await() equivalent in New Places SDK Client

Background: I have a List of strings which contains the different place IDs. Once a user has selected his location, I have a loop that executes and determines if each place in the list (I obtain the location from the place ID) is near his selected location. I was able to implement this with the old Places SDK but could not migrate it to the new SDK because it seems that the new SDK has no await() equivalent.
Here is my old code:
// contains a list of Offices. Has method getId() which contains the Place ID from Google.
List<Office> results = obtained from the database...
// go thru each Location and find those near the user's location
for (int i = 0; i < results.size(); i++) {
// Get the place from the placeID
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi.
getPlaceById(mGoogleApiClient, results.get(i).getId());
// wait for the result to come out (NEED EQUIVALENT IN NEW PLACES SDK)
PlaceBuffer places = placeResult.await();
// Get the latitude and longitude for the specific Location
LatLng latLng = places.get(0).getLatLng();
// Set the location object for the specific business
Location A = new Location("Business");
A.setLatitude(latLng.latitude);
A.setLongitude(latLng.longitude);
// get the distance of the business from the user's selected location
float distance = A.distanceTo(mSelectedLocation);
// if the distance is less than 50m away
if (distance < 50) { ... do something in code}
As you can see in the code above, the old PLACES SDK API has a PendingResult class with await() as one of the methods. This await() as per documentation Blocks until the task is completed.. IN SUMMARY, the code will not proceed till a result is obtained from getPlaceById.
I migrated to the new Places SDK as per documentation and I have issues. Here is my new migrated code based on the Google documentation: https://developers.google.com/places/android-sdk/client-migration#fetch_a_place_by_id
for (int i = 0; i < results.size(); i++) {
// Get the place Id
String placeId = results.get(position).getId();
// Specify the fields to return.
List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.NAME,
Place.Field.LAT_LNG, Place.Field.ADDRESS);
// Construct a request object, passing the place ID and fields array.
FetchPlaceRequest request = FetchPlaceRequest.builder(placeId, placeFields)
.build();
// Add a listener to handle the response.
placesClient.fetchPlace(request).addOnSuccessListener((response) -> {
Place place = response.getPlace();
// Get the latitude and longitude for the specific location
LatLng latLng = place.getLatLng();
// Set the location object for the specific business
Location A = new Location("Business");
A.setLatitude(latLng.latitude);
A.setLongitude(latLng.longitude);
// get the distance of the business from the selected location
float distance = A.distanceTo(mSelectedLocation);
// if the distance is less than 50m away
if (distance < 50) { ... do something in code}
It seems that key issue here is that in the old code await() blocks the code till its successful hence the for loop does not process. However this is not the case with OnSuccessListener. As a result, with the new migrated code, the for loop proceeds and completes the loop even when fetchPlace is not yet complete getting its results for each iteration. Thus, the code is broken and is unable to get the results needed.
Is there a way to block the code to move till fetchPlace is completed?!
Any Google API task can be waited on by Google's Task API as far as I'm aware.
For example, findAutocompletePredictions returns a Task<> object. Instead of adding an onCompleteListener, you can pass that task to Tasks.await.
Instead of this non-blocking way:
OnCompleteListener<T> onCompleteListener=
new OnCompleteListener<T> {...}
placesClient.findAutocompletePredictions(f)
.addOnCompleteListener(onCompleteListener);
You could pass it on to Tasks.await() and make the API call blocking:
T results = null;
try {
// No timeout
results = Tasks.await(placesClient.findAutocompletePredictions(f));
// Optionally, with a 30 second timeout:
results = Tasks.await(
placesClient.findAutocompletePredictions(f), 30, TimeUnit.SECONDS);
} catch (ExecutionException e) {
// Catch me
} catch (TimeoutException e) {
// Catch me, only needed when a timeout is set
} catch (InterruptedException e) {
// Catch me
}
if (results != null) {
// Do something
} else {
// Do another thing
}
Basically, instead of getting a PendingResult by default, you're now given a Task<T> that you can use however.
I solved the issue by using the Task Class. See below:
for (int position = 0; position < results.size(); position++) {
// Get the placeID
String placeId = results.get(position).getAddress();
// Specify the fields to return.
List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.NAME,
Place.Field.LAT_LNG, Place.Field.ADDRESS);
// Construct a request object, passing the place ID and fields array.
FetchPlaceRequest request = FetchPlaceRequest.builder(placeId, placeFields)
.build();
// create a FetchPlaceResponse task
Task<FetchPlaceResponse> task = placesClient.fetchPlace(request);
try {
FetchPlaceResponse response = Tasks.await(task);
Place place = response.getPlace();
// Get the latitude and longitude for the specific place
LatLng latLng = place.getLatLng();
// Set the location object for the specific business
Location A = new Location("Business");
A.setLatitude(latLng.latitude);
A.setLongitude(latLng.longitude);
// get the distance of the business from the selected location
float distance = A.distanceTo(mSelectedLocation);
These two codes will ask the system to wait for the response..
Task task = placesClient.fetchPlace(request);
FetchPlaceResponse response = Tasks.await(task);

Globally formatting .net Web Api response

I have a Web Api service that retrieves data from another service, which returns Json. I don't want to do anything to the response, I just want to return it directly to the client.
Since the response is a string, if I simply return the response, it contains escape characters and messy formatting. If I convert the response in to an object, the WebApi will use Json.Net to automatically format the response correctly.
public IHttpActionResult GetServices()
{
var data = _dataService.Get(); //retrieves data from a service
var result = JsonConvert.DeserializeObject(data); //convert to object
return Ok(result);
}
What I would like is to either A: Be able to return the exact string response from the service, without any of the escape characters and with the proper formatting, or B: Set a global settings that will automatically Deserialize the response so that the Web Api can handle it the way I am doing it already.
On Startup I am setting some values that describe how formatting should be handled, but apparently these aren't correct for what im trying to do.
HttpConfiguration configuration = new HttpConfiguration();
var settings = configuration.Formatters.JsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new DefaultContractResolver();
Do I need to create a custom ContractResolver or something? Is there one that already handles this for me?
Thanks
If you want to just pass through the json (Option A), you can do this
public IHttpActionResult GetServices() {
var json = _dataService.Get(); //retrieves data from a service
HttpContent content = new System.Net.Http.StringContent(json, Encoding.UTF8, "application/json");
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = content;
return ResponseMessage(response);
}

Issue while integrating PayU in windows universal apps

I am new to Windows universal apps development. Now I am developing an app in which I have to integrate PayU. I tried a lot but everytime the transaction error is thrown from the server.
string temp1 = "key=xxxxxx&txnid=xxxxxx&hash=hashValue&amount=xxx&firstname=abc" +
"&email=a#a.com&phone=80xxxxxxxx&productinfo=xxxxxxxxxxxx" +
"&surl=https://www.google.com&furl=https://www.twitter.com" +
"&udf1=a&udf2=b&udf3=c&udf4=d&udf5=e&pg=CC&bankcode=CC" +
"&ccardtype=CC&ccnum=1234xxxxxxxxx&ccname=xxx&ccvv=xxx" +
"&ccexpmon=xx&ccexpyr=xxxx";
var httpClient = new Windows.Web.Http.HttpClient();
Windows.Web.Http.HttpRequestMessage httpRequestMessage = new Windows.Web.Http.HttpRequestMessage(Windows.Web.Http.HttpMethod.Post, theUri);
Windows.Web.Http.IHttpContent content = new Windows.Web.Http.HttpStringContent(temp1, Windows.Storage.Streams.UnicodeEncoding.Utf8);
httpRequestMessage.Content = content;
try
{
webView.NavigateWithHttpRequestMessage(httpRequestMessage);
}
catch(Exception f)
{
new MessageDialog(f.ToString()).ShowAsync();
}
And I am creating the hashValue by using method :
public String SampleHashMsg(String strMsg)
{
// Convert the message string to binary data.
string strAlgName = HashAlgorithmNames.Sha512;
IBuffer buffUtf8Msg = CryptographicBuffer.ConvertStringToBinary(strMsg, BinaryStringEncoding.Utf8);
// Create a HashAlgorithmProvider object.
HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(strAlgName);
// Demonstrate how to retrieve the name of the hashing algorithm.
String strAlgNameUsed = objAlgProv.AlgorithmName;
// Hash the message.
IBuffer buffHash = objAlgProv.HashData(buffUtf8Msg);
// Verify that the hash length equals the length specified for the algorithm.
if (buffHash.Length != objAlgProv.HashLength)
{
throw new Exception("There was an error creating the hash");
}
// Convert the hash to a string (for display).
//String strHashBase64 = CryptographicBuffer.EncodeToBase64String(buffHash);
String strHashBase64 = CryptographicBuffer.EncodeToHexString(buffHash);
// Return the encoded string
return strHashBase64;
}
I should load the request to the webview. But I am getting an error "Transaction Error" in that.
I am getting transaction error, txnid is not provided. Well at PayU side the sent hash key will be used for verify a transaction. May be my txnid and the txnid contained by hash does not match and payu server denies the transaction saying that provide txnid.
I am using Microsoft Visual Studio 2013 Universal apps for the app development.
But still I am not getting correct result. Please if anyone can help me out, then please reply immediately. Thanks in advance.

WebService ASP.NET MVC 3 Send and Receive

I've been racking my brain for a couple of days now on how to approach a new requirement.
I have two websites. The first one lets the user fill out an application. The second website is an internal website use to manage the users applications. I need to develop a "web service" that sends the application data from website 1 to website 2 and return a response to website 2 of success or failure. I have never done a web service before and I'm a bit confused on where to start. I've been reading various examples online but they all seem to be just a starting point for building a webservice... no specific examples.
So for posting the data website 1, what would my controller method look like? Do I use Json to post the data to website 2? What would and example of that look like? Is there some form of redirect in the method that points to website 2?
So for posting the response back to website 2 what would that controller method look like? I assume I would use Json again to send the response back to website 1? Is there some form of redirect in the method that points back to website 1?
I would use JSON and POST the application to the web service.
First I am assuming the application data is contained in some type of object. Use JSON.Net to serialize the object into JSON. It will look something like the following code.
var application = new Application();
string serializedApplication = JsonConvert.Serialize(application);
Second is to POST the code your endpoint(webservice, mvc action). To this you'll need to make a HTTPRequest to the endpoint. The following code is what I use to make to POST the code.
public bool Post(string url, string body)
{
//Make the post
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
var bytes = Encoding.Default.GetBytes(body);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
Stream stream = null;
try
{
request.KeepAlive = false;
request.ContentLength = bytes.Length;
request.ContentType = "application/x-www-form-urlencoded";
request.Timeout = -1;
request.Method = "POST";
stream = request.GetRequestStream();
stream.Write(bytes, 0, bytes.Length);
}
finally
{
if (stream != null)
{
stream.Flush();
stream.Close();
}
}
bool success = GetResponse(request);
return success;
}
public bool GetResponse(HttpWebRequest request)
{
bool success;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.Created)
{
throw new HttpException((int)response.StatusCode, response.StatusDescription);
}
var end = string.Empty;
using (StreamReader reader = new StreamReader(responseStream))
{
end = reader.ReadToEnd();
reader.Close();
success = JsonConvert.DeserializeObject<bool>(end);
}
response.Close();
}
}
return success;
}
So now you have can POST JSON to an endpoint and receive a response the next step is to create the endpoint. The following code will get you started on an endpoint in mvc that will receive an application and process it.
[HttpPost]
public ActionResult SubmitApplication()
{
//Retrieve the POSTed payload
string body;
using (StreamReader reader = new StreamReader(Request.InputStream))
{
body = reader.ReadToEnd();
reader.Close();
}
var application = JsonConvert.Deserialize<Application>(body);
//Save the application
bool success = SaveApplication(application);
//Send the server a response of success or failure.
return Json(success);
}
The above code is a good start. Please note, I have not tested this code.
You have obviously more than one client for the data & operations. so a service is what you are looking for.
ASP.NET MVC is a good candidate for developing RESTful services. If you (and your Manager) are ready to use beta version, Then Checkout ASP.NET-Web API.
If you want to stay with a stable product, Go for MVC3. you may need to write some custom code to return the data in XML as well as JSON to server different kind of clients. There are some tutorials out there.
So create a Service (ASP.NET MVC / WCF Service) .You may then create 2 client apps, one for the external clients and another for the Internal users. Both of this apps can call methods in the Service to Create/ Read the user accounts / or whatever operation you want to do.
To make the apps more interactive and lively , you may conside including a wonderful thing called SiganalR, which helps you to get some real time data without continuosly polling the data base/ middle tier very in every n seconds !

Resources