ConfigConvergenceChecker extends AbstractComponent { public ServiceResponse checkService(Application application, String hostAndPortToCheck, URI requestUrl, Duration timeout) { Long wantedGeneration = application.getApplicationGeneration(); try { if (! hostInApplication(application, hostAndPortToCheck)) return ServiceResponse.createHostNotFoundInAppResponse(requestUrl, hostAndPortToCheck, wantedGeneration); long currentGeneration = getServiceGeneration(URI.create("http: boolean converged = currentGeneration >= wantedGeneration; return ServiceResponse.createOkResponse(requestUrl, hostAndPortToCheck, wantedGeneration, currentGeneration, converged); } catch (ProcessingException e) { return ServiceResponse.createNotFoundResponse(requestUrl, hostAndPortToCheck, wantedGeneration, e.getMessage()); } catch (Exception e) { return ServiceResponse.createErrorResponse(requestUrl, hostAndPortToCheck, wantedGeneration, e.getMessage()); } } @Inject  ConfigConvergenceChecker();  ConfigConvergenceChecker(StateApiFactory stateApiFactory); ServiceListResponse servicesToCheck(Application application, URI requestUrl, Duration timeoutPerService); ServiceResponse checkService(Application application, String hostAndPortToCheck, URI requestUrl, Duration timeout); @Override void deconstruct();  }
@Test public void service_convergence() { { String serviceName = hostAndPort(this.service); URI requestUrl = testServer().resolve("/serviceconverge/" + serviceName); wireMock.stubFor(get(urlEqualTo("/state/v1/config")).willReturn(okJson("{\"config\":{\"generation\":3}}"))); HttpResponse serviceResponse = checker.checkService(application, hostAndPort(this.service), requestUrl, clientTimeout); assertResponse("{\n" + " \"url\": \"" + requestUrl.toString() + "\",\n" + " \"host\": \"" + hostAndPort(this.service) + "\",\n" + " \"wantedGeneration\": 3,\n" + " \"converged\": true,\n" + " \"currentGeneration\": 3\n" + "}", 200, serviceResponse); } { String serviceName = "notPresent:1337"; URI requestUrl = testServer().resolve("/serviceconverge/" + serviceName); HttpResponse response = checker.checkService(application, "notPresent:1337", requestUrl,clientTimeout); assertResponse("{\n" + " \"url\": \"" + requestUrl.toString() + "\",\n" + " \"host\": \"" + serviceName + "\",\n" + " \"wantedGeneration\": 3,\n" + " \"problem\": \"Host:port (service) no longer part of application, refetch list of services.\"\n" + "}", 410, response); } }
@Test public void service_convergence_timeout() { URI requestUrl = testServer().resolve("/serviceconverge"); wireMock.stubFor(get(urlEqualTo("/state/v1/config")).willReturn(aResponse() .withFixedDelay((int) clientTimeout.plus(Duration.ofSeconds(1)).toMillis()) .withBody("response too slow"))); HttpResponse response = checker.checkService(application, hostAndPort(service), requestUrl, Duration.ofMillis(1)); assertResponse((responseBody) -> assertTrue("Response matches", responseBody.startsWith( "{\"url\":\"" + requestUrl.toString() + "\",\"host\":\"" + hostAndPort(requestUrl) + "\",\"wantedGeneration\":3,\"error\":\"java.net.SocketTimeoutException") && responseBody.endsWith("\"}")), 404, response); }