Google-HttpClient: Post request successful but no data added to database - integration-testing

I'm using Google Http Client to code a Post request. Our underlying call is an AJAX post request and the request is successful which return 200 but there is no data added to database. I don't know what wrong with the HTTP Call as the code is design as one HTTP URL call with many function(Add contact, Add organization). How to debug this? Please help me. Thanks.
public void addContact() {
try {
String requestBody = "{'Source': 'Contact', 'MethodName': 'AddContact', 'UserID': '1', 'SalutationID': '1', 'FirstName': 'Peter', "
+ "'LastName': 'Wong', 'JobTitle': 'Software QA', 'PrimaryEmail': 'peterapiit#gmail.com', "
+ "'BusinessPhone': '60163963326', 'CountryID': '104', 'OrganizationID': '1', 'AOIIDs': '2'}";
GenericUrl url = new GenericUrl("https://extranet-uat.who.int/epqs/Main/ServiceProxy");
HttpRequestFactory rf = new NetHttpTransport().createRequestFactory();
HttpRequest request = rf.buildPostRequest(url, ByteArrayContent.fromString("application/json",
requestBody));
request.getHeaders().setContentType("application/json");
HttpResponse response = request.execute();
SoftAssert sAssert = new SoftAssert();
sAssert.assertEquals(response.getStatusCode(), 200);
System.out.println("HTTP Status Code : " + response.getStatusCode());
} catch (IOException ex) {
LogManager.logger.log(Level.INFO, "Exception: " + ex.getMessage());
}
}
The underlying javascript code is available to download from here.

Related

Using RestSharp to aend files between to API's on Kubernetes

So I have to API's running on Kubernetes. One has a controller function as such:
string filePath = "/blobs/data/runsession/" + folderName;
if (!Directory.Exists(filePath))
return null;
var tempFile = Path.Combine(Path.GetTempPath(), guid.ToString());
logger.Info("GetTempPath()" + Path.GetTempPath());
logger.Info("Temp path is: " + tempFile);
ZipFile.CreateFromDirectory(filePath, (tempFile + ".zip"));
byte[] fileBytes = File.ReadAllBytes(tempFile + ".zip");
HelpMethods.GetNetworkTimeStamp("Stop", 2);
return fileBytes;
This controller method works fine and when I call it from postman it returns a file.
Now in the other API I want to call this function from one of my service classes as such:
public async Task<byte[]> DownloadRunSession(string foldername)
{
try
{
var request = new RestRequest($"blob/{foldername}")
{
Timeout = -1,
};
var response = await client.ExecuteGetAsync(request);
if (!response.IsSuccessful)
{
Console.WriteLine("File download failed");
Console.WriteLine(response.Content.ToString());
return null;
}
return response.RawBytes;
}catch(Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
return null;
}
Now the server logs on the API that sends the file Give me a status 200 but says "the application aborted the connection", and the API that is supposed to receive the file gets no response and the response variable is always "null".
Any one that has had a similar dilemma and knows how to solve it?

How to send success and error messages to jQuery AJAX call from a webmethod

I am calling an asp.net webform's webmethod using jQuery AJAX, from an aspx page. When the webmethod experiences an exception I am throwing an HttpResponseException exception. I am not sure what's the best way to return a success message. In a Web API, I would have returned a ApiController.Created(HttpStatusCode) or Ok(200). But I don't see such an option available on a webmethod. In the AJAX call I have to handle success and error accordingly. The following is my code:
[WebMethod()]
public async Task<IHttpActionResult> ProcessData(CustomerData customerData)
{
try
{
HttpClient client = new HttpClient();
HttpResponseMessage resp = await client.PostAsync(<data>);
if (resp.IsSuccessStatusCode)
{
string result = await resp.Content.ReadAsStringAsync();
return ???;//how to send success message?
}
else
{
string reasonAndStatusCode = resp.StatusCode + "; " + resp.ReasonPhrase;
string errorMessage = "Method Name: ProcessData." +
"Did not process customer data." +
"Status Code and Reason: " +
reasonAndStatusCode;
HttpResponseMessage error = GenerateError(resp.StatusCode, errorMessage.ToString());
throw new HttpResponseException(error);
}
}
catch (Exception ex)
{
HttpResponseMessage error = GenerateError(HttpStatusCode.InternalServerError,
errorMessage.ToString());
throw new HttpResponseException(error);
}
}
You can change the response status code using HttpContext Current static object.
For example, if you want to send a 404 status code, see the code below.
HttpContext.Current.Response.StatusCode = (int)HttpStatusCode.NotFound;

POST from Java or JS to GCM

I know there are many different situations that resemble mine across stackoverflow, but I just couldn't make the connection.
What I am trying to do, is to send a simple push notification to the GCM. I found two links for which I try to POST too. Note both these links work in this PHP script i found.
https://gcm-http.googleapis.com/gcm/send
https://android.googleapis.com/gcm/send
I tried to send push notifications from JS to the GCM, but many people have stated that this can not because of security issues. As of now, when I execute my code in Angular JS, I am getting a 405 error from https://gcm-http.googleapis.com/gcm/send. Status 405 means method not accepted (link for reference http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html).
Here is the code for JS. I have two method that I tried.
Method 1:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
//ite
}
};
var jsonCall = {
registration_id: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx-AEQtUUWnCVH566xcwib4HinI16W3_g"
};
xmlhttp.open("POST", "https://gcm-http.googleapis.com/gcm/send", true);
xmlhttp.setRequestHeader("Content-type", "application/json");
xmlhttp.setRequestHeader("Authorization", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
xmlhttp.send(jsonCall);
Method 2
var jsonCall = {
registration_id: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx-AEQtUUWnCVH566xcwib4HinI16W3_g"
};
$http({
method:'POST',
url: 'https://gcm-http.googleapis.com/gcm/send',
data: jsonCall,
headers: {
'Authorization': 'A1nxxxxxxxxxxxxxxxxxx',
'Content-type': 'application/json' }
})
This is what I have tried in Java. Note that my project was not created as an Android project, but just as a normal Java project. I get a 411 error here, so I think the string I use as JSON is incorrect. Note that I get a 200 if I use GET.
Method 3:
HttpURLConnection connection = null;
try {
//Create connection
String json ="{\"registration_ids\":[\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxx\"]}";
URL url = new URL("https://gcm-http.googleapis.com/gcm/send");
connection = (HttpURLConnection)url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setRequestProperty("Content-Length", "0");
connection.setRequestProperty("Authorization", "key="+"xxxxxxxxxxxxxxxxxxxxxxxxxx");
System.out.println(connection.getResponseCode());
InputStream stream = (InputStream) connection.getInputStream();
InputStreamReader isReader = new InputStreamReader(stream);
//put output stream into a string
BufferedReader br = new BufferedReader(isReader);
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}
OutputStream os = connection.getOutputStream();
os.write(json.getBytes("UTF-8"));
os.flush();
os.close();
} catch(Exception e){
System.out.println(e);
}
If someone can take a look at this, and set me in the correct direction, I would really appreciate it.
UPDATE:
I have gotten rid of that 411 error. I think it was because I never connected in the first place. Now I am getting the correct 200 code, but the push notification does not send. Is my JSON the correct format?
HttpURLConnection connection = null;
try {
//Create connection
String json ="{\"registration_ids\":[\"APA91bGxHWapgmxgyvPceu85ArDMLaFekbTt5RGzy3gv1xtSO09tJbvnaeVLefBqNl_iBrctoZQ2AltSMfrXykq8-AEQtUUWnCVH566xcwib4HinI16W3_g\"]}";
URL url = new URL("https://gcm-http.googleapis.com/gcm/send");
connection = (HttpURLConnection)url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Authorization", "key=xxxxxxxxxxxxxxxxxxxxxxx");
connection.connect();
OutputStream os = connection.getOutputStream();
os.write(json.getBytes("UTF-8"));
System.out.println(connection.getResponseCode());
InputStream stream = (InputStream) connection.getInputStream();
InputStreamReader isReader = new InputStreamReader(stream);
//put output stream into a string
BufferedReader br = new BufferedReader(isReader);
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}
os.flush();
os.close();
} catch(Exception e){
System.out.println(e);
}
This has been solved using the Java method. JS keeps on returning those status codes of 400, 401, 411 etc. It turns out the reason Java returned a 200 but my phone did not receive anything was because my JSON was incorrect. Here is the correct JSON value:
String postData = "{ \"registration_ids\": [ \"" + CLIENT_REG_ID + "\" ], " +
"\"delay_while_idle\": true, " +
"\"data\": {\"tickerText\":\"My Ticket\", " +
"\"contentTitle\":\"My Title\", " +
"\"message\": \"Test GCM message from GCMServer-Android\"}}";
This was obtained from another question I posted, where a fellow SO member provided this solution.

HttpUrlConnection response code always returns -1

I have created my server in amazon ec2 instance. Through my android app i am connecting to the server with HttpUrlConnection. But i get response code as -1. Does anyone has any idea ?? Here is my code.
private String getHttpResponse(final String srcUrl) {
HttpURLConnection urlConnection = null;
FileOutputStream fos = null;
try {
URL url = new URL(srcUrl);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setRequestProperty("Content-Type", "application/json");
mETag = readETagFromPrefForCategory();
urlConnection.setRequestProperty("If-None-Match", mETag);
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("xyz", "abc".toCharArray());
}
});
urlConnection.connect();
mETag = urlConnection.getHeaderField("ETag");
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
Log.v("http","not modifed");
return readLocalJson();
}
if (urlConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
Log.w(TAG, "Bad response [" + urlConnection.getResponseCode() + "] from (" + srcUrl + ")");
return null;
}}//end of try block
An answer in this post seemed to solve it for a few people:
Android Https Status code -1
Hope that helps.
The problem might be that your headers HTTP version is not properly formatted. Check this SO link where I have answered a similar question which worked for me.
Java Http~URLConnection response code -1
Why are you setting "Content-Type" on a GET request?

User authentication through REST web service on a different domain - asp.net

I am looking to connect to a web service on a different domain in order to authenticate users. The Web Service itself is a RESTful service, written in Java. Data is passed to and from it in JSON.
I initially tried to connect using jQuery (see below)
function Login()
{
$.ajax({
url: "http://www.externaldomain.com/login/authenticate",
type: "POST",
dataType: "json",
contentType: "application/json",
data: "{'emailAddress':'bob#bob.com', 'password':'Password1'}",
success: LoadUsersSuccess,
error: LoadUsersError
});
}
function LoadUsersSuccess(){
alert(1);
}
function LoadUsersError(){
alert(2);
}
However, when checking on Firebug, this brought up a 405 Method Not Allowed error.
At this stage, as this is the first time I've really worked with web services, I really just wondered whether this was the best way to do things? Is it worth persevering with this method in order to find a solution, or am I best to maybe try and find a server-side answer to this issue? If so, does anyone have any examples they could post up?
Many thanks
Doing cross-domain web service calls in a browser is very tricky. Because it's a potential security vulnerability, browsers block these types of requests. However, there is a workaround called JSONP. If you use JSONP instead of plain JSON, you should be able to make the cross-domain request.
Right ok, to update where I am, I checked in firebug and on the external server and the reason why I'm getting a 405 error is because I'm doing a Get rather than a Post.
What I need to do is send the username and password, then receive a GUID back which will then be used for any future requests. I thought by having 'type:post' in the code would be enough but apparently not. Anyone know where I might be going wrong here? As I said, a novice to web services and nothing I have tried from looking online has had any effect. Many thanks
Ok, I got the problem solved, and I did it by going back to C# and doing it there instead of using jQuery or JSONP and I used Json.Net for handling the data received. Here is the code:
protected void uxLogin_Click(object sender, EventArgs e)
{
StringBuilder data = new StringBuilder();
data.Append("{");
data.Append("'emailAddress': '" + uxEmail.Text + "', ");
data.Append("'password': '" + uxPassword.Text + "'");
data.Append("}");
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data.ToString());
string url = System.Configuration.ConfigurationManager.AppSettings["AuthenticationURL"].ToString();
string JSONCallback = string.Empty;
Uri address = new Uri(url);
// Create the web request
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
// Set type to POST
request.Method = "POST";
request.ContentType = "application/json";
// Create a byte array of the data we want to send
// Set the content length in the request headers
request.ContentLength = byteData.Length;
// Write data
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
// Console application output
JSONCallback = reader.ReadToEnd().ToString();
}
if (!String.IsNullOrEmpty(JSONCallback))
{
JObject jObject = JObject.Parse(JSONCallback);
if ((bool)jObject["loginResult"] == false)
{
string errorMessage = jObject["errorMessage"].ToString();
int errorCode = (int)jObject["errorCode"];
}
else
{
string idToken = jObject["idToken"].ToString();
Session["Userid"] = idToken;
Response.Redirect("~/MyDetails.aspx");
}
}
else
{
uxReturnData.Text = "The web service request was not successful - no data was returned";
}
}
Thanks anyway :)

Resources