TL;DR Am using org.mortbay.jetty:jetty:6.1.26 in my JUnits to Stub a server. I was hoping to get predetermined content in output. However am getting exception java.net.ConnectException: Connection refused: no further information. When I hit the endpoint from web browser, I do not get response immediately but after all JUnits are completed and Jetty shut the server (I get expected response in browser as well as Socket closed exception in app logs). I searched few stackoverflow posts but couldn't progress much and hence need help
Details: Application code we have is (successfully) getting required information from external clients by reading that data, parsing it and finally saving that data. Below is how code looks like
HTTPUtilities.performGet(uri)
.thenApply(HTTPUtilities::httpResponseToReader)
.thenApply(reader -> parseContent(reader, id))
.thenAccept(idDetailsList -> idRepository.saveAll(idDetailsList))
.whenComplete((resp, err) -> {
if (err == null) {
log.info("Data for {} is successfully saved", id);
} else {
log.error("Exception encountered for URI {} / id : {}. Message: -> {} ", uri, id, err.getMessage());
}
});
My intent is to Stub first method of above CompletableFuture which is HTTPUtilities.performGet(uri). It's a static method and its code looks like below
HttpUriRequest request = RequestBuilder.get()
.setUri(uri)
.setHeader(HttpHeaders.ACCEPT, HEADER_ACCEPT_CONSTANT)
.setHeader(HttpHeaders.USER_AGENT, HEADER_USER_AGENT_CONSTANT)
.build();
CompletableFuture<HttpResponse> resp = new CompletableFuture<>();
executorService.execute(() -> {
try (CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(config).build();
CloseableHttpResponse response = httpclient.execute(request)) {
resp.complete(response);
log.info("Successfully returning response for URL: {}", uri);
} catch (NullPointerException ex) {
log.error("NullPointerException encountered when performing GET against URL {} with message {}", uri, ex.getCause());
resp.completeExceptionally(ex);
} catch (IOException ex) {
log.error("IOException encountered when performing GET against URL {} with message {}", uri, ex.getCause());
resp.completeExceptionally(ex);
}
});
return resp;
This code works fine for actual calls. However, it fails with below stack trace when run from JUnits where HTTP calls are stubbed using Jetty. Below stacktrace is generated when code reaches CloseableHttpResponse response = httpclient.execute(request) line in above call.
java.net.ConnectException: Connection refused: no further information
at java.base/sun.nio.ch.Net.pollConnect(Native Method)
at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672)
at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:633)
at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:75)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376)
Below is code from JUnit Test class
@ExtendWith(MockitoExtension.class)
public class IdRetreieveAndSaveTest {
@InjectMocks
UpdateIdData updateIdData;
@BeforeAll
static void initial() throws Exception {
//Stub to replace actual call
Server server = new Server(stubbedPort);
Context contentOkContext = new Context(server, stubbedContext);
contentOkContext.setHandler(new HttpCustomHandler());
server.setStopAtShutdown(true);
server.start();
}
@Test
void updateIdDataTest() {
List<IdData> resp = new ArrayList<>();
updateIdData.invokeHttpAndSave(id);
assertEquals(100, resp.size());
}
}
and finally helper class for JUnit
public class HttpCustomHandler extends AbstractHandler {
@Override
public void handle(String s, HttpServletRequest httpServletRequest, HttpServletResponse response, int i) throws IOException {
OutputStream out = response.getOutputStream();
try (ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer()) {
writer.write(codeThatReturnsSampleDataFromExternalClient());
writer.flush();
response.setIntHeader(HttpHeaders.CONTENT_LENGTH, writer.size());
writer.writeTo(out);
out.flush();
};
}
}
I verified that port is up and listening during Junit execution. Below is response when at breakpoint during JUnit execution in debug mode and these lines disappear for same command once JUnit test execution completes
netstat -ano | Select-String -pattern "65500"
TCP 0.0.0.0:65500 0.0.0.0:0 LISTENING 27448
TCP [::]:65500 [::]:0 LISTENING 27448
Thank you in advance