HTTP connection to JIRA XRAY Rest API not working - java

Need help
I am trying to connect to XRAY JIRA using Rest API and want to execute a case but getting 400 error response at step inputStream=new InputStreamReader(con.getInputStream(),"UTF-8")
java.io.IOException: Server returned HTTP response code: 400 for URL:
My Code is below:
*HttpURLConnection con=null;
InputStreamReader inputStream=null;
URL jira_API_URL=new URL("https://jira.abc.com/rest/raven/latest/import/execution");
String encodeCredentials=Base64.getEncoder().encodeToString(
"kkris:testjira#234".getBytes("UTF-8"));
con=(HttpURLConnection)jira_API_URL.openConnection();
con.setRequestMethod("POST"); con.setDoOutput(true);
con.setRequestProperty("Autherization", "Basic "+encodeCredentials);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("X-Atlassian-Token", "nocheck");
try(OutputStream os=con.getOutputStream()){
byte[] input=json.toString().getBytes("UTF-8");
os.write(input,0,input.length);
}
inputStream=new InputStreamReader(con.getInputStream(),"UTF-8");*
Note :Would like to add that I am able to hit this RestAPI using postman and Restassured & able to execute testcase in XRAYJIRA successfully

Well, first of all we need to clarify if you have Xray on Jira server/datacenter or Xray on Jira cloud, as they are different products and the APIs are also slightly different.
From your example, it seems that you're targetting Xray on Jira server/datacenter, and that you aim to import results using the Xray JSON format and respective endpoint as detailed here.
The endpoint URL in that case should either be
<jira_base_url>/rest/raven/1.0/import/execution or <jira_base_url>/rest/raven/2.0/import/execution
Also, please make sure the Xray JSON content you submit follows this syntax.
Note: you may want to have a look at this repo which contains some sample code for submiting results in Java and other languages, including a proof-of-concept client api.
The response body content may show you clues about what's wrong. You can start by using curl utility first as shown here and then implement the java code.
curl -H "Content-Type: application/json" -X POST -u admin:admin --data #data.json http://yourserver/rest/raven/1.0/import/execution

Related

Unable to get Dataflow steps information using Java API

I am trying to get the steps & jobMetrics information of an active streaming job using the following code:
val jobMetrics = dataflowClient.projects().jobs().getMetrics(projectId, jobId).execute().getMetrics
val steps = dataflowClient.projects().jobs().get(projectId, jobId).execute().getSteps
But, even though I am able to get the jobMetrics information, the steps is always returning null.
Any pointers on what I am doing wrong?
Apologies I'm Java illiterate but with regards to the details that you need I can point you to which endpoint in Dataflow API to get them. My examples are done by sending HTTP requests to the Dataflow API using curl.
To retrieve steps using Dataflow API use projects.jobs.get endpoint and specify what JobView you want. JOB_VIEW_ALL is required to return job.steps.
Sample curl command used:
curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) https://dataflow.googleapis.com/v1b3/projects/my-project/locations/us-central1/jobs/2022-01-13_19_11_56-999999999999?view=JOB_VIEW_ALL
Response snippet with steps:
But if following Dataflow Java API. You need to build your GetJobRequest to include setView() with Enum JobView as the parameter. Using code snippet from getJob() documentation:
try (JobsV1Beta3Client jobsV1Beta3Client = JobsV1Beta3Client.create()) {
GetJobRequest request =
GetJobRequest.newBuilder()
.setProjectId("your-project")
.setJobId("jobId101296568")
.setView(JobView.forNumber(2)) // try 2 as value for JOB_VIEW_ALL as per Enum JobView documentation provided above
.setLocation("us-central1")
.build();
Job response = jobsV1Beta3Client.getJob(request);
}
Code snippet above should return Job object where you can try doing getSteps() and see if it will return something.

IoT module GET request in Java

I'm trying to read a JSON response from a RESTful webserver running on an IoT module (Advantech WISE-4012). According to the documentation, any GET request should be made in this form
GET /ai_value/slot_0/ch_0
Any Java implementation of GET requests (Java libraries, Apache etc.), anyway, append to the end of the request the protocol signature HTTP/1.1. E.g:
GET http://192.168.0.14/ai_value/slot_0/ch_0 HTTP/1.1
Because of this (probably) i'm getting Error 400 (Bad request) on every client i tried so far. The only working method i've discovered was sending a simple request through the address bar on Google Chrome browser (sometimes i get a response, sometimes a get a bad request error either). How can i write a java implementation of a GET request plain and simple as described by the documentation? How can i test a custom GET request without HTTP/1.1 at the end? Every chrome extension i tried (Advanced REST Client, Postman) add the protocol version at the end, so i haven't had the chance to verify if that's why i'm getting a bad request error.
EDIT:
This is the response header from Advanced REST client
Connection: close
Content-Type: application/json
Server: WISE-4000/8.1.0020
While the source message is the following one:
GET /ai_value/slot_0/ch_0 HTTP/1.1
HOST: 192.168.0.14
The only mismatch between the documentation is the HTTP/1.1 signature as mentioned before. Adding the "accept: application/json" makes no difference either
After a bit of digging into the documentation, it looks like the default timeout (i.e. 720 seconds) is the one causing an issue. There doesn't seem to be any way to work it around (ideally, the system should reset the time after a successful request and we should only get 400 - or 403 ideally after 720 seconds of inactivity).
A couple of points I would like to recommend to the API developers for WISE-4012 (if they are in touch with you):
Add brief documentation for authentication and timeout (probably, more response codes and error messages with each error response)
Enable OAuth for API Access
As far as current implentation is conerned, I guess you need to do a basic auth and pass username/password with every request, Or add Authentication header with every API request to get successful response without any 400s.
Check if this helps.
HttpClient httpClient = HttpClients.createDefault();
URI reqUri = new URI(<uri>);
RequestBuilder requestBuilder = RequestBuilder.create("GET");
requestBuilder.setUri(reqUri);
requestBuilder.setHeader(<headerKey>, <headerValue>);
requestBuilder.setEntity(<entity_data>);
HttpUriRequest httpRequest = requestBuilder.build();
httpResponse = httpClient.execute(httpRequest);

cURL DELETE in Java [duplicate]

This question already has answers here:
How to send PUT, DELETE HTTP request in HttpURLConnection in JAVA
(3 answers)
Closed 8 years ago.
Like the title says, I'm trying to write the following curl DELETE command in Java.
curl -X DELETE -H "Content-Type: application/json; charset=UTF-8" http://10.84.14.2:8082/virtual-network/47a91732-629b-4cbe-9aa5-45ba4d7b0e99
My understanding is that you have to format the DELETE request inside of a POST. Below is my working code for a GET call.
URL dc0ContrailUrl2 = new URL("http://10.10.10.120:8082/network-policy/363bf699-6417-486e-9791-d5aaf873d9bb");
URLConnection dcConn2 = dc0ContrailUrl2.openConnection();
dcConn2.setRequestProperty("Content-Type", "application/json");
BufferedReader in2 = newBufferedReader(newInputStreamReader(dcConn2.getInputStream()));
String inputLine2;
while ((inputLine2 = in2.readLine()) != null){ //while response is not null, assign response to inputLine and print inputLine
System.out.println(inputLine2);
}
in2.close();
When I looked around for how to approach a DELETE request, I ended up with the following:
URL url3 = new URL("http://10.10.10.120:8082/network-policy/363bf699-6417-486e-9791-d5aaf873d9bb");
HttpURLConnection httpConnection3 = (HttpURLConnection) url3.openConnection();
httpConnection3.setDoOutput(true);
httpConnection3.setRequestProperty("Content-Type", "application/json" );
httpConnection3.setRequestMethod("DELETE");
At this point I've gone so far down the google rabbit hole that I'm certain the solution is very simple and is just a matter of changing some syntax/method calls. Any help is greatly appreciated.
Note: I am able to get the DELETE call to work using Postman(chrome app) by simply entering the URL http://10.10.10.120:8082/network-policy/363bf699-6417-486e-9791-d5aaf873d9bb, and switching the drop down menu to DELETE, so I know my URL isn't the issue.
Instead of using HttpURLConnection directly, try with a library like the HttpClient from the Apache HttpComponents, an example of how you can use it with your delete command:
void sendDelete() throws IOException {
CloseableHttpClient httpclient = HttpClients.createDefault();
// create DELETE REQUEST
HttpDelete httpDelete = new HttpDelete(
"http://10.84.14.2:8082/virtual-network/47a91732-629b-4cbe-9aa5-45ba4d7b0e99");
// add header "content-type"
httpDelete.addHeader(new BasicHeader("Content-Type", "application/json; charset=UTF-8"));
// send request
CloseableHttpResponse response1 = httpclient.execute(httpDelete);
// close response (ideally inside a finally clause in a try/catch)
response1.close();
}
My understanding is that you have to format the DELETE request inside of a POST.
That is incorrect. The Curl command you posted performs a 'DELETE' request, and in this sense POST and DELETE (and GET) are alternative HTTP request "methods". There might be web services that accept some kind of delete command in the form of a POST and/or GET request, but that's not what Curl is doing. (It's also not what Postman is doing when you select the 'DELETE' request method.)
Your code is actually pretty much right. It's not useful to specify that you're going to do output (because you're not), nor, therefore, to specify a Content-type (because the request will have no content), but it's probably not harmful to do so. You could even setDoInput(false) on the connection, since you wouldn't normally expect the server to send any content in its response, but leaving that out should be ok, too.
The main thing you're missing is a call to the connection's connect() method. You don't need that in your "GET" example because reading the connection's input stream causes it to connect automatically.

Suddenly getting 405 Method Not Allowed during POST to create folder in box-api

I'm suddenly seeing a problem with code (java) that was working about a week ago using the Box API. I'm getting a 405 Method Not Allowed while doing a POST to create a folder. I have tried to trouble shoot the problem assuming it may have something to do with recent v2 api going live. However, going back to trying the examples in the docs I am also seeing problems. For example, the docs give the following example ...
curl https://api.box.com/2.0/folders -H "Authorization: Bearer MY_V1_AUTH_TOKEN_HERE" -d '{"name":"API Test Create", "parent": {"id": "ID_OF_PARENT_FOLDER_HERE"}}' -X POST
Which does nothing when I test it. No new folder and no output at all. I have tried with different folder IDs (including zero) and and I have tried generating new V1 auth tokens. Still nothing.
From what I understand, the V1 auth tokens should continue to work for a little longer. Is that not correct? Is anyone else seeing this issue?
Here is the existing java code that suddenly now has started giving a 405. It uses apache fluent lib ...
String response = Request.Post(new
StringBuilder(API_BASE_URL).append("/folders/").append(parent_folder_id).toString())
.addHeader("Authorization", API_REQUEST_HEADER)
.bodyString(new StringBuilder("{\"name\":\"")
.append(name).append("\"}").toString(), ContentType.DEFAULT_TEXT)
.execute()
.handleResponse(myResponseHandler);
where API_BASE_URL="https://www.box.com/api/2.0" and API_REQUEST_HEADER="BoxAuth api_key=MY_APP_API_KEY&auth_token=MY_V1_AUTH_TOKEN"
It would be great if there is a quick, even temporary, solution to this issue. Any clues are appreciated.
The Bearer header i.e.
Authorization: Bearer {a bearer token acquired through oauth2}
will only work with bearer tokens retrieved through the OAuth 2 process. This header will not work with auth tokens retrieved through the V1 Auth process. You'll need to use the old header style with V1 auth tokens i.e.
Authorization: BoxAuth api_key={your api key}&auth_token={your v1 auth token}
The Create a New Folder method has changed just a bit; this is indicated in the cURL example you've included. Now you must not include the parent folder ID at the end of the request URL, and you must include the parent folder ID in the request body:
String response = Request.Post(newStringBuilder(API_BASE_URL)
.append("/folders").toString()
.addHeader("Authorization", API_REQUEST_HEADER)
.bodyString(new StringBuilder("{\"name\":\"").append(name)
.append("\", \"parent\": {\"id\": \"").append(parent_folder_id).append("\"}}")
.toString(), ContentType.DEFAULT_TEXT)
.execute().handleResponse(myResponseHandler);
EDIT: While I think the method signature change will address your immediate problem, seanrose is spot on in pointing out that you'll need to transition to OAuth2 for long-term stability.

Sending JSON in GET Rest resource - curl and code have separate behavior

I will start with: I am doing something terribly wrong. And here is what I am doing wrong.
I created a REST resource for searching something and I am expecting a JSON data in request parameters:
#GET
#Path("/device")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response searchContent(String searchJSONString) {
String message = new SearchServices().search(searchJSONString);
return getResponse(message); //Checks the message for any error and sends back the response.
}//end of searchContent()
I should not have written:
#Consumes
since it is a GET resource and it does not consumes anything. But my problem is how to send JSON data in a java code for this (GET resource). I tried curl command which is able to send JSON data to this resource but not a java code by any means.
I tried following curl command to send JSON data to it:
curl -X GET -H "Content-Type: application/json" -d '{"keyword":"hello"}' http://localhost:8080/search-test/rest/search
And its working fine and giving me back a proper JSON response.
But if I am using a curl command without specifying any method (which should be a default http get), I am getting a 405 (Method not allowed) response from tomcat:
curl -d '{"keyword":"hello"}' http://localhost:8080/search-test/rest/search
or through Java code:
HttpURLConnection urlConnection = (HttpURLConnection) new URL(urlString).openConnection();
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestMethod("GET"); //This is not working.
getting the same 405 (Method not allowed) response from tomcat.
If I am sending a GET request using java code, I am not able to send the JSON data as in a post method, and I am forced to use a name=value thing and for that I need to change my REST resource to accept it as a name/value pair.
It means something like this:
http://localhost:8080/search-test/rest/search?param={"keyword":"permission"}
If I am doing something similar in POST:
#POST
#Path("/device")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response searchContent(String searchJSONString) {
String message = new SearchServices().search(searchJSONString);
return getResponse(message); //Checks the message for any error and sends back the response.
}//end of searchContent()
I am able to send the JSON data both from Java code and curl command as well:
curl -X POST -H "Content-Type: application/json" -d '{"keyword":"hello"}' http://localhost:8080/search-test/rest/search
or through Java code:
HttpURLConnection urlConnection = (HttpURLConnection) new URL(urlString).openConnection();
urlConnection.setRequestMethod("POST"); //Works fine.
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setDoOutput(true);
Where is the problem? Why am I not able to send it from code but from curl? Is there any other way to send JSON data to the GET resource other than a name=value pair?
HttpURLConnection does not allow GET requests with entity and will strip the entity from the request before it is sent to the server. So, I'd strongly recommend avoiding it as even if you use a different Java HTTP client library that allows you to do it, your users will likely run into similar issues (plus web caches and proxies may add more problems).

Categories