0
votes

I have two microservices and a gateway. one microservice is developed with JHipster and spring boot(Service1), and the other has the spring integration framework(IntegrationService). Now I need to call the service1 API from the IntegrationService. I am using HTTPS for communication in both microservice. But when called the API I got the following error log.

2021-05-05 11:05:45.503 INFO 22105 --- [ XNIO-1 task-4] c.m.a.s.IntegrationService : exception in IntegrationService org.springframework.messaging.MessageHandlingException: HTTP request execution failed for URI [https://<server_ip>/gateway/services/service1/api/viewrecords?id=100100100100157] in the [bean 'outboundGateway'; defined in: 'class path resource [com/esi/app/service/IntegrationService.class]'; from source: 'org.springframework.core.type.classreading.SimpleMethodMetadata@3fa2213']; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on GET request for "https://<server_ip>/gateway/services/service1/api/viewrecords": PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target, failedMessage=GenericMessage [payload={custId=100100100100157}, headers={http_requestMethod=GET, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@703c6baf, Connection=Keep-Alive, Host=<server_ip>:port, accept=/, authorization=Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImF1dGgiOiJST0xFX0FETUlOLFJPTEVfVVNFUiIsImV4cCI6MTYyMDI3ODk4NH0.-4ByR7OQY-G_dZh7XUHYOSo3FRS2Ug6JxVOkq6XOmhUV05LnQj10puEGotcJk1EUlYDvt4n2dAJFSuR3evnvHA, replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@703c6baf, http_requestUrl=http://<server_ip>:/api/getrecordsfromservice1?transactionId=1111111111&id=100100100100157, id=1eec8d00-4040-c9b2-cdb1-4f2d8743d007, Content-Length=0, http_userPrincipal=org.springframework.security.authentication.UsernamePasswordAuthenticationToken@143b9e60: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_ADMIN, ROLE_USER, accept-encoding=gzip, deflate, br, user-agent=PostmanRuntime/7.28.0, timestamp=1620192945487}]

The API end point I used to invoke the IntegrationService is,

https://<server_ip>/gateway/services/integration/api/getrecordsfromservice1?transactionId=1111111111&id=100100100100157

integration is the service name registered in the gateway for IntegrationService. similarly, service1 is for Service1.

The things I am not able able to understand are:

  1. how did the "http_requestUrl" changed to the one in the log, rather than the endpoint that I am hitting?
  2. Why did the "SunCertPathBuilderException" occurred even though I am using HTTPS in both microservice?
  3. To get the "Host" message header, is the spring framework look for the IP and port on the config files, application.yml, rather than checking the URL?

Can anyone please help? @artem

My inbound and outbound gateways are given below:

@ServiceActivator(inputChannel = "channelOutbound")
    @Bean
    public HttpRequestExecutingMessageHandler outboundGateway() {
        final HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler(
                viewrecordsEndpoint + "{id}");
        handler.setExpectedResponseType(String.class);
        handler.setHttpMethod(HttpMethod.GET);
        handler.setOutputChannelName("channelOutboundResponse");

        final ExpressionParser parser = new SpelExpressionParser();
        final Expression exp = parser.parseExpression("payload[id]");
        final Map<String, Expression> uriExp = new HashMap<>();
        uriExp.put(Constants.ID, exp);
        handler.setUriVariableExpressions(uriExp);
        return handler;
    }

@Bean
    public HttpRequestHandlingMessagingGateway inboundGateway() {
        final HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway();
        gateway.setRequestMapping(requestMapping());
        gateway.setRequestChannelName("channelInbound");
        gateway.setReplyChannelName("channelInboundReply");
        gateway.setErrorChannelName("channelInboundError");
        return gateway;
    }

private RequestMapping getGoldLoansForUcicInboundRequestMapping() {
        final RequestMapping mapping = new requestMapping();
        mapping.setPathPatterns("/api/getrecordsfromservice1");
        mapping.setMethods(HttpMethod.GET);
        return mapping;
    }
1

1 Answers

1
votes

Spring Integration has nothing to do with HTTPS. It is standard SSL Java configuration which has to be supplied properly on both side. It is just not enough to change HTTP schema to HTTPS.

See some possible solutions in the Internet: https://docs.oracle.com/cd/E19906-01/820-4916/6ngbm6hre/index.html

Re. problem with your url. That's probably how API Gateway works. So, it just strips its own context when an external request has reached its endpoint.