http client failing to call service with jearsey multipart as an argument - rest

Trying to hit Jersey multipart service with httpclient, and seeing some issues. Could you please share your insights to resolve this issue. Below I posted client code, service, stack trace.
Thanks for your support.
It works good when I use below client and register classes. Not finding any facility to register these classes for http client.
javax.ws.rs.client.Client
client.register(JacksonJsonProvider.class);
client.register(MultiPartFeature.class);
CLIENT CODE:
final String CONTENT_TYPE_MULTIPART = "multipart/related";
final String CONTENT_TYPE = "application/octet-stream";
final String BOUNDARY = "--upload_boundary--";
String responseStr = "";
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntityBuilder.addBinaryBody("file_upload", inputStream, ContentType.create(CONTENT_TYPE), "filename");
HttpPost httpPost = new HttpPost(finalURL);
httpPost.setHeader(HttpHeaders.CONTENT_TYPE, CONTENT_TYPE_MULTIPART);//+";type="+CONTENT_TYPE+";boundary="+BOUNDARY);
httpPost.setEntity(multipartEntityBuilder.build());
CloseableHttpResponse response = null;
try {
response = httpclient.execute(httpPost);
HttpEntity entity = response.getEntity();
responseStr = entity.toString();
RestHelper.verifyResponse(response, responseStr);
} catch (ClientProtocolException e) {
LOGGER.error("ClientProtocolException during upload",e);
} catch (IOException e) {
LOGGER.error("IOException during upload",e);
} finally {
response.close();
httpclient.close();
}
REST SERVICE:
#Consumes(MULTIPART_RELATED)
public String addDocument(MultiPart multipart)
STACKTRACE:
httpResponse :::::::::::::::::::: HttpResponseProxy{HTTP/1.1 400 Bad Request [Content-Type: text/html;charset=ISO-8859-1, $WSEP: , Content-Language: en-US, Transfer-Encoding: chunked, X-Cnection: Close, Date: Mon, 10 May 2021 11:50:32 GMT, Set-Cookie: dev-issapps.us=2036276652.6195.0000; path=/; Httponly] ResponseEntityProxy{[Content-Type: text/html;charset=ISO-8859-1,Chunked: true]}}
17:20:32.220 [main] ERROR us.dc.httpproxy.RestHelper - Response Error: RestException{us.dc.httpproxy.RestException
: HTTP/1.1 400 Bad Request', statusCode=400, detail='ResponseEntityProxy{[Content-Type: text/html;charset=ISO-8859-1,Chunked: true]}'}
17:20:32.221 [main] ERROR us.dc.httpproxy.RestClient - Exception in executeMultiPartRequest http://XXXXXXXXXXXXXXXX/XXXXXXXXXXXXXXXX/api/applications/GWEW/documents
RestException{ us.dc.httpproxy.RestException: HTTP/1.1 400 Bad Request', statusCode=400, detail='ResponseEntityProxy{[Content-Type: text/html;charset=ISO-8859-1,Chunked: true]}'}

Here is the solution, hope it helps somebody:
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.13'
compile group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.5.3'
try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
File file = new File("src/main/resources/48-1.jpg");
MultipartEntityBuilder entitybuilder = MultipartEntityBuilder.create();
entitybuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
entitybuilder.addBinaryBody("image", new FileInputStream(file), ContentType.APPLICATION_OCTET_STREAM, file.getName());
entitybuilder.setContentType(ContentType.create("multipart/related"));
HttpEntity mutiPartHttpEntity = entitybuilder.build();
RequestBuilder reqbuilder = RequestBuilder.post(url);
reqbuilder.setEntity(mutiPartHttpEntity);
HttpUriRequest multipartRequest = reqbuilder.build();
HttpResponse httpresponse = httpclient.execute(multipartRequest);
System.out.println("response status = " + httpresponse.getStatusLine().getStatusCode());
System.out.println("filenet id = " + EntityUtils.toString(httpresponse.getEntity()));
}catch(Exception e) {
e.printStackTrace();
}

Related

Getting Invalid Response from API . - Groovy Scripting

I am trying a POST method in groovy which basically creates a Issue in Jira . I am getting invalid response from the API . However in postman I could able to get the response . I have searched few questions in stackoverflow where they are recommending to set the Accept-Encoding to "" . I tried out different methods but it didnt work .
Code :
import javax.net.ssl.*;
import java.security.cert.*;
import groovy.json.JsonBuilder;
import groovy.json.JsonOutput;
import groovy.json.JsonSlurperClassic;
import groovy.json.StreamingJsonBuilder;
def jiraurl = "xxxxx";
def netProxyAddr = "xxxx";
def netProxyPort = 80;
try {
// NOTE: Adjust the following as needed
def uri = jiraurl + "/issue";
def jiraTicketMap = [:];
jiraTicketMap["fields"] = [:];
jiraTicketMap["fields"]["project"]= [:];
jiraTicketMap["fields"]["project"]["id"] = "12412"
jiraTicketMap["fields"]["summary"] = "Test ticket for API";
jiraTicketMap["fields"]["assignee"] = [:];
jiraTicketMap["fields"]["assignee"]["name"] = "*********";
jiraTicketMap["fields"]["customfield_10700"] = [:];
jiraTicketMap["fields"]["customfield_10700"]["value"] = "Normal";
jiraTicketMap["fields"]["customfield_16901"] = "nothing impacted";
jiraTicketMap["fields"]["customfield_16900"] = "testing ";
jiraTicketMap["fields"]["customfield_10710"] = "removing the URL" ;
jiraTicketMap["fields"]["customfield_10711"] = "********";
jiraTicketMap["fields"]["customfield_16902"] = "descriptiong";
jiraTicketMap["fields"]["customfield_10702"] = [:];
jiraTicketMap["fields"]["customfield_10702"]["value"] ="Low";
jiraTicketMap["fields"]["customfield_10900"] = [:];
jiraTicketMap["fields"]["customfield_10900"]["value"] = "Yes";
jiraTicketMap["fields"]["customfield_10703"] = [:];
jiraTicketMap["fields"]["customfield_10703"]["value"] = "Low";
jiraTicketMap["fields"]["customfield_10705"] = "2022-03-19T10:29:29.908+1100";
jiraTicketMap["fields"]["customfield_10706"] = "2022-03-20T10:29:29.908+1100";
jiraTicketMap["fields"]["customfield_10707"] = "testing done";
jiraTicketMap["fields"]["customfield_10708"] = "Implemtation test done for zscaler";
jiraTicketMap["fields"]["customfield_10709"] = "post implention done";
jiraTicketMap["fields"]["issuetype"] = [:];
jiraTicketMap["fields"]["issuetype"]["id"]= "10200";
jiraTicketMap["fields"]["labels"] = ["test"];
jiraTicketMap["fields"]["customfield_21400"] = "Test Environment is required.";
jiraTicketMap["fields"]["customfield_21500"] = "Back-Out Test Details is required";
DEBUG.println("DEBUG: jiraTicketMap is: ${jiraTicketMap}");
def payloadData = StringUtils.mapToJson(jiraTicketMap);
DEBUG.println("DEBUG: Payload is: ${payloadData}");
DEBUG.println("DEBUG: PayloadData is: ${payloadData}");
DEBUG.println("DEBUG: PayloadData type is:"+payloadData.getClass());
netProxyPort = netProxyPort.toInteger();
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(netProxyAddr, netProxyPort));
def authString = "*********".getBytes().encodeBase64().toString()
def url = new URL(uri);
// NOTE: The following removes all checks against SSL certificates
disableSSL();
def conn = url.openConnection(proxy);
conn.doOutput = true;
// Build the Credentials and HTTP headers
conn.setRequestProperty("Authorization", "Basic ***********");
conn.setRequestProperty("Content-type", "application/JSON;charset=UTF-8");
conn.setRequestProperty("Accept","*/*");
conn.setRequestMethod("POST");
conn.setDoOutput(true);
//BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF8"));
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(),"UTF-8")
writer?.write(payloadData);
writer?.flush();
writer?.close();
if(conn.getResponseCode() == 201 || conn.getResponseCode() == 200 ) {
InputStream responseStream = conn.getInputStream();
result = responseStream.getText("UTF-8");
DEBUG.println("DEBUG:>>>>>>>>>>>>> SUccessfully Posted Data to Jira");
// NOTE: If you need to get the response header, use below
//INPUTS.HEADERS = conn.getHeaderFields();
responseStream.close();
}
else {
INPUTS.RSEXCEPTION = "Response code was " + conn.getResponseCode();
// Attempt to parse error stream.
InputStream responseStream = conn.getErrorStream();
result = responseStream?.getText("UTF-8");
responseStream?.close();
}
}
catch (Exception e) {
//INPUTS.RSEXCEPTION = e.getMessage();
result = e.getMessage();
result += "\n" + e.getClass() + ": " + e.getMessage();
for (trace in e.getStackTrace())
{
result += "\n\t" + trace;
}
}
return result;
Response :
Response from Postman and local code editor
{
"id": "12212",
"key": "WCM-2211",
"self": "https://********/rest/api/2/issue/2496228"
}
Response from Vendor Tool:
�4̱#0��w��^BV��\z(M��J"��u1���?`4tPȶ.���S���7��0�%���q7A M�X����xv…qD�h�O��~��NCe
Response Headers
[X-AREQUESTID:[533x1208409x1], null:[HTTP/1.1 201 Created], Server:[Web Server], X-Content-Type-Options:[nosniff], Connection:[close], X-ANODEID:[node1], Date:[Thu, 12 May 2022 07:53:25 GMT], X-Frame-Options:[SAMEORIGIN], Referrer-Policy:[no-referrer-when-downgrade], Strict-Transport-Security:[max-age=15768000], Cache-Control:[no-cache, no-store, no-transform], Content-Security-Policy:[frame-ancestors 'self'], X-AUSERNAME:[SVC], Content-Encoding:[gzip], X-ASESSIONID:[1l2vszx], Set-Cookie:[akaalb_jira_dev_alb=~op=jira_dev_lb:jira-dev-ld6|~rv=95~m=jia-dev-ld6:0|~os=287df636055edb4e278283~id=de0d2567c76bf80374af7c583f; path=/; HttpOnly; Secure; SameSite=None, JESSIONID=2920944044.37151.0000; path=/; Httponly; Secure, atlassian.xsrf.token=BZXB-Z179-LJQD-6WAV_9b298f0387a7c68a8652e963b69e4_lin; Path=/; Secure, JSESSIONID=27C93900AA8B780AA44C2861F73; Path=/; Secure; HttpOnly], Feature-Policy:[midi 'none'], Vary:[Accept-Encoding, User-Agent], X-XSS-Protection:[1; mode=block], X-Seraph-LoginReason:[OK], X-Powered-By:[Web Server], Content-Type:[application/json;charset=UTF-8]]
Solution from #dagget :
// use the below code when reading it from input stream
accept-encoding : identity
responseStream = new java.util.zip.GZIPInputStream(responseStream)

Karate ApacheHttpClient Response is failing with error com.intuit.karate - Runtimejava.io.IOException: Attempted read from closed stream

Reference: java.io.IOException: Attempted read from closed stream
Reference: https://github.com/karatelabs/karate/blob/master/karate-core/src/main/java/com/intuit/karate/http/ApacheHttpClient.java
KarateCore - class file: ApacheHttpClient.java is unable to process the Response its failing at the code line
CloseableHttpClient client = clientBuilder.build();
CloseableHttpResponse httpResponse;
byte [] bytes;
try {
httpResponse = client.execute(requestBuilder.build());
HttpEntity responseEntity = httpResponse.getEntity();
if (responseEntity == null || responseEntity.getContent() == null) {
bytes = Constants.ZERO_BYTES;
} else {
**InputStream is = responseEntity.getContent();**
bytes = FileUtils.toBytes(is);
}
request.setEndTimeMillis(System.currentTimeMillis());
} catch (Exception e) {
if (e instanceof ClientProtocolException && e.getCause() != null) { // better error message
throw new RuntimeException(e.getCause());
} else {
throw new RuntimeException(e);
}
}
The Code is failing at line InputStream is = responseEntity.getContent(); when trying to read from a closed stream. The exception message displayed
Error com.intuit.karate - Runtimejava.io.IOException: Attempted read from closed stream.
May be the InputStream need to updated.
I am able read the Http Response content using below code
BufferedReader br = new BufferedReader(
new InputStreamReader((httpResponse.getEntity().getContent())));
String output;
while ((output = br.readLine()) != null){
output = br,readLine();
System.out.println(output);
}
Also the able to read the response using EntityUtils as a string content
String content = EntityUtils.toString(responseEntity);
System.out.println(content);
Not sure if i am missing something in the feature:scenario file response or the ApacheHttpClient.java file need to updated to read InputStream and then convert to bytes.
Feature: Hello
Scenario: Rest API Post
Given url 'some url path'
And header Content-Type = 'application/json'
And request { username: 'abc', password: 'pwd' }
When method POST
Then status 200
And print 'Response is:', response
The expected Response is a JSON format as:
{
"accessToken": "akjdoioikf",
"expires":"2020-01-29T01:09:48Z"
}
Any suggestions, appreciated!

DataFlowTemplate response does not return body

Considering the test07 stream is already created the following code snippet won't get response body in the exception stack trace.
try {
URI dataFlowUri = URI.create("http://localhost:9393");
DataFlowOperations dataFlowOperations = new DataFlowTemplate(dataFlowUri);
StreamDefinition streamDefinition = Stream.builder(dataFlowOperations)
.name("test07")
.definition("time|log")
.create();
}
catch (Exception ex){
ex.printStackTrace();
}
org.springframework.web.client.HttpClientErrorException$Conflict: 409 : [no body]
at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:125)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:184)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:125)
at org.springframework.cloud.dataflow.rest.client.VndErrorResponseErrorHandler.handleError(VndErrorResponseErrorHandler.java:62)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:782)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:740)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:674)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:418)
at org.springframework.cloud.dataflow.rest.client.StreamTemplate.createStream(StreamTemplate.java:121)
at org.springframework.cloud.dataflow.rest.client.dsl.StreamDefinition.(StreamDefinition.java:60)
at org.springframework.cloud.dataflow.rest.client.dsl.Stream$StreamDefinitionBuilder.create(Stream.java:400)
on other hand when Post request this directly
http://localhost:9393/streams/definitions?name=test07&definition=time%20%7C%20log&description=test07
the response as follow with status code 409
[
{
"logref": "DuplicateStreamDefinitionException",
"message": "Cannot create stream test07 because another one has already been created with the same name"
}
]
I want to get response body when exception occur
so anyone can help if I'm missing something here?
I had to override the default rest template to get the response body as desired.
ClientHttpRequestFactory factory = new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory());
RestTemplate restTemplate = new RestTemplate(factory);
URI dataFlowUri = URI.create("http://localhost:9393");
DataFlowOperations dataFlowOperations = new DataFlowTemplate(dataFlowUri, restTemplate);
StreamDefinition streamDefinition = Stream.builder(dataFlowOperations)
.name("test07")
.definition("time|log")
.create();
thanks

Resteasy client not working from office, but working from home

I am using RestEasy client api, to make call to some internal api, but when I run the code from my home I am able to get the response without any timeout exception. But when I run from office getting timeout execution, am I missing any configurations?
I/O exception (java.net.ConnectException) caught when processing request: Operation timed out
Below the code am using:
ClientRequest request = new ClientRequest(
"https://example.com/v2");
request.queryParameter("name", "jhon");
request.accept("application/json");
ClientResponse<String> response = request.get(String.class);
if(response.getStatus() == 404){
System.out.println(response.getEntity());
System.out.println(response.getStatus());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
new ByteArrayInputStream(response.getEntity().getBytes())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
JSONObject d = new JSONObject(output);
JSONObject sd = d.getJSONObject("Error");
System.out.println(sd.get("Detail"));
}

How to bypass SSL certificates issue in JBOSS REST ClientRequest

I'm new in Jboss, and using rest easy client for connection in my jboss code. Below is the code -
---
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
---
public String login() throws Exception {
---
String URL = "https://IP//service/perform.do?operationId=XXXXX";
ClientRequest restClient = new ClientRequest(URL);
restClient.accept(MediaType.APPLICATION_JSON);
restClient.body(MediaType.APPLICATION_JSON, hmap);
ClientResponse < String > resp = restClient.post(String.class);
if (resp.getStatus() != 201) {
throw new RuntimeException("Failed : HTTPS error code : " + resp.getStatus());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
new ByteArrayInputStream(resp.getEntity().getBytes())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
return output;
}
While connecting with SSL enabled server, getting certificate error "HTTP Status 500 - org.jboss.resteasy.spi.UnhandledException: javax.net.ssl.SSLException: hostname in certificate didn't match".
We can't change certificate at this moment, but is there any way to trust any certificate? I googled many posts, but nothing helped.
Anyone can tell me what is the solution of this issue.