0

I have code snippet below where I am trying to call HTTP POST from my service class. I am getting below error

javax.net.ssl.SSLException: Connection reset

I am using Java 11 and Spring boot 2.1.6

  public void processURL(UserInput userInput, String userId, String emailId) {
    String requestJson = helper.marshallObjectToJson(userInput);
    StringEntity entity = new StringEntity(requestJson, "UTF8");
    entity.setContentType(new BasicHeader("Content-Type", "application/json"));
    httpPost.setEntity(entity);
    HttpClient httpClient = getAPIBasicAuthDefaultHttpClient();
    try {
        HttpPost httpPost = buildPostWithHeaders(userId, emailId);
        HttpResponse response = httpClient.execute(httpPost);
        respStatus = response.getStatusLine().getStatusCode();

        if (HttpStatus.SC_CREATED == respStatus) {
            logger.info("success");
        } else {
            logger.error("Failure");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

 public HttpPost buildPostWithHeaders(String userId, String emailId) {
    HttpPost httpPost = new HttpPost("https://apphost.com/APIService/user/");
    httpPost.addHeader("userId", userId);
    httpPost.addHeader("email", emailId);
    httpPost.addHeader("roleType", admin);
    return httpPost;
 }

 public HttpClient getAPIBasicAuthDefaultHttpClient() {
    CredentialsProvider provider = new BasicCredentialsProvider();
    UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(user, password);
    provider.setCredentials(AuthScope.ANY, credentials);
    HttpClient client = 
    HttpClientBuilder.create().setDefaultCredentialsProvider(provider).build();
    return client;
 }

I have the below dependency in gradle too

implementation('org.apache.httpcomponents:httpclient:4.5')

Not sure what I am missing here. Please note - this has worked when I tried to connect through my rest client tool, but could not succeed through service API call

Below is a stack trace of this error

javax.net.ssl.SSLException: Connection reset
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:127)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:352)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:295)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:290)
    at java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1521)
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:114)
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:104)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)
    Suppressed: java.net.SocketException: Connection reset by peer: socket write error
        at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)

Thanks in advance.

user3919727
  • 283
  • 2
  • 7
  • 25
  • 1
    It looks like the error is from a filter that's trying to send metrics to some monitoring infrastructure, nothing to do with the actual request. Are you making the post while servicing an incoming request? – erickson Aug 25 '21 at 16:55
  • @erickson: yes, I am trying to call external service from my service. Thinking this has to do something with n/w related issues – user3919727 Aug 25 '21 at 17:57
  • 1
    Okay, so look more closely at the filter that tries to report metrics on that incoming request, not the outbound post. I'm guessing it "worked when [you] tried to connect through [your] rest client tool" because it doesn't attempt to collect metrics. For example, if your metrics reporter tries to maintain a persistent connection to a time series database that might be idle for long periods, keep alive settings might need attention. – erickson Aug 25 '21 at 18:06
  • @erickson: Will look into it. Thanks for your inputs, really appreciated – user3919727 Aug 25 '21 at 18:33

1 Answers1

0

I added Base64 encoded Authorization header in the POST request and it worked for me

String plainCred = user+":"+ password;
String base64Cred = new String(Base64.getEncoder().encode(plainCred.getBytes()));

HttpPost httpPost = new HttpPost("https://apphost.com/APIService/user/");
httpPost.addHeader("Authorization", "Basic " + base64Cred);
user3919727
  • 283
  • 2
  • 7
  • 25