diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequest.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequest.java index 6a633699668..0ace844a8b6 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequest.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequest.java @@ -68,6 +68,7 @@ public class DefaultHttpJsonRequest implements HttpJsonRequest { private String method; private Object body; private List> queryParams; + private List> headers; private String authorizationHeaderValue; protected DefaultHttpJsonRequest(String url, String method) { @@ -118,6 +119,16 @@ public HttpJsonRequest addQueryParam(@NotNull String name, @NotNull Object value return this; } + public HttpJsonRequest addHeader(@NotNull String name, @NotNull String value) { + requireNonNull(name, "Required non-null header name"); + requireNonNull(value, "Required non-null header value"); + if (headers == null) { + headers = new ArrayList<>(); + } + headers.add(Pair.of(name, value)); + return this; + } + @Override public HttpJsonRequest setAuthorizationHeader(@NotNull String value) { requireNonNull(value, "Required non-null header value"); @@ -149,7 +160,7 @@ public HttpJsonResponse request() if (method == null) { throw new IllegalStateException("Could not perform request, request method wasn't set"); } - return doRequest(timeout, url, method, body, queryParams, authorizationHeaderValue); + return doRequest(timeout, url, method, body, queryParams, authorizationHeaderValue, headers); } /** @@ -182,7 +193,8 @@ protected DefaultHttpJsonResponse doRequest( String method, Object body, List> parameters, - String authorizationHeaderValue) + String authorizationHeaderValue, + List> headers) throws IOException, ServerException, ForbiddenException, NotFoundException, UnauthorizedException, ConflictException, BadRequestException { final String authToken = EnvironmentContext.getCurrent().getSubject().getToken(); @@ -202,6 +214,15 @@ protected DefaultHttpJsonResponse doRequest( final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); conn.setConnectTimeout(timeout > 0 ? timeout : 60000); conn.setReadTimeout(timeout > 0 ? timeout : 60000); + + final boolean hasHeaders = headers != null && !headers.isEmpty(); + + if (hasHeaders) { + for (Pair header : headers) { + conn.setRequestProperty(header.first, header.second); + } + } + try { conn.setRequestMethod(method); // drop a hint for server side that we want to receive application/json @@ -225,7 +246,6 @@ protected DefaultHttpJsonResponse doRequest( output.write(DtoFactory.getInstance().toJson(body).getBytes()); } } - final int responseCode = conn.getResponseCode(); if ((responseCode / 100) != 2) { InputStream in = conn.getErrorStream(); diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/HttpJsonRequest.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/HttpJsonRequest.java index 34af8b26628..ec8d3194d59 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/HttpJsonRequest.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/HttpJsonRequest.java @@ -110,6 +110,16 @@ public interface HttpJsonRequest { */ HttpJsonRequest addQueryParam(@NotNull String name, @NotNull Object value); + /** + * Adds header to the request. + * + * @param name header name + * @param value header value + * @return this request instance + * @throws NullPointerException when either header name or value is null + */ + HttpJsonRequest addHeader(@NotNull String name, @NotNull String value); + /** * Adds authorization header to the request. * @@ -206,4 +216,16 @@ default HttpJsonRequest addQueryParams(@NotNull Map params) { params.forEach(this::addQueryParam); return this; } + + /** + * Adds set of headers to this request. + * + * @param headers map with headers + * @return this request instance + */ + default HttpJsonRequest addHeaders(@NotNull Map headers) { + Objects.requireNonNull(headers, "Required non-null headers"); + headers.forEach(this::addHeader); + return this; + } } diff --git a/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequestTest.java b/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequestTest.java index ca877bfd54f..cac0f46ac31 100644 --- a/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequestTest.java +++ b/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequestTest.java @@ -103,10 +103,11 @@ public void shouldUseUrlAndMethodFromTheLinks() throws Exception { anyString(), nullable(Object.class), nullable(List.class), - nullable(String.class)); + nullable(String.class), + nullable(List.class)); request.request(); - verify(request).doRequest(0, DEFAULT_URL, "POST", null, null, null); + verify(request).doRequest(0, DEFAULT_URL, "POST", null, null, null, null); } @Test @@ -119,6 +120,7 @@ public void shouldBeAbleToMakeRequest() throws Exception { .setTimeout(10_000_000) .addQueryParam("name", "value") .addQueryParam("name2", "value2") + .addHeader("Connection", "close") .request(); verify(request) @@ -128,7 +130,8 @@ public void shouldBeAbleToMakeRequest() throws Exception { "PUT", body, asList(Pair.of("name", "value"), Pair.of("name2", "value2")), - null); + null, + asList(Pair.of("Connection", "close"))); } @Test @@ -146,6 +149,7 @@ public void shouldBeAbleToUseStringMapAsRequestBody() throws Exception { eq("POST"), mapCaptor.capture(), eq(null), + eq(null), eq(null)); assertTrue(mapCaptor.getValue() instanceof JsonStringMap); assertEquals(mapCaptor.getValue(), body); @@ -164,6 +168,7 @@ public void shouldBeAbleToUseListOfJsonSerializableElementsAsRequestBody() throw eq("POST"), listCaptor.capture(), eq(null), + eq(null), eq(null)); assertTrue(listCaptor.getValue() instanceof JsonArray); assertEquals(listCaptor.getValue(), body); @@ -172,7 +177,7 @@ public void shouldBeAbleToUseListOfJsonSerializableElementsAsRequestBody() throw @Test public void defaultMethodIsGet() throws Exception { request.request(); - verify(request).doRequest(0, DEFAULT_URL, HttpMethod.GET, null, null, null); + verify(request).doRequest(0, DEFAULT_URL, HttpMethod.GET, null, null, null, null); } @Test(expectedExceptions = NullPointerException.class) @@ -216,6 +221,21 @@ public void shouldThrowNullPointerExceptionWhenQueryParamsAreNull() throws Excep new DefaultHttpJsonRequest("http://localhost:8080").addQueryParams(null); } + @Test(expectedExceptions = NullPointerException.class) + public void shouldThrowNullPointerExceptionWhenHeaderNameIsNull() throws Exception { + new DefaultHttpJsonRequest("http://localhost:8080").addHeader(null, "close"); + } + + @Test(expectedExceptions = NullPointerException.class) + public void shouldThrowNullPointerExceptionWhenHeaderValueIsNull() throws Exception { + new DefaultHttpJsonRequest("http://localhost:8080").addHeader("Connection", null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void shouldThrowNullPointerExceptionWhenHeadersAreNull() throws Exception { + new DefaultHttpJsonRequest("http://localhost:8080").addHeaders(null); + } + @Test(expectedExceptions = NullPointerException.class) public void shouldThrowNullPointerExceptionWhenLinkHrefIsNull() throws Exception { new DefaultHttpJsonRequest(createLink("GET", null, null)); @@ -375,6 +395,7 @@ private void prepareResponse(String response) throws Exception { anyString(), nullable(Object.class), nullable(List.class), - nullable(String.class)); + nullable(String.class), + nullable(List.class)); } } diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactory.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactory.java index 6032f1a66fb..afdec7e0f02 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactory.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactory.java @@ -39,6 +39,8 @@ public class WsAgentPingRequestFactory { "Workspace agent server not found in dev machine."; private static final String WS_AGENT_URL_IS_NULL_OR_EMPTY_ERROR = "URL of Workspace Agent is null or empty."; + private static final String CONNECTION_HEADER = "Connection"; + private static final String CONNECTION_CLOSE = "close"; private final HttpJsonRequestFactory httpJsonRequestFactory; private final int wsAgentPingConnectionTimeoutMs; @@ -80,9 +82,11 @@ public HttpJsonRequest createRequest(Machine machine) throws ServerException { if (!wsAgentPingUrl.endsWith("/")) { wsAgentPingUrl = wsAgentPingUrl.concat("/"); } + return httpJsonRequestFactory .fromUrl(wsAgentPingUrl) .setMethod(HttpMethod.GET) - .setTimeout(wsAgentPingConnectionTimeoutMs); + .setTimeout(wsAgentPingConnectionTimeoutMs) + .addHeader(CONNECTION_HEADER, CONNECTION_CLOSE); } } diff --git a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactoryTest.java b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactoryTest.java index 61ec61e3bb1..df403da4f0a 100644 --- a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactoryTest.java +++ b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactoryTest.java @@ -40,6 +40,8 @@ public class WsAgentPingRequestFactoryTest { private static final String WS_AGENT_SERVER_NOT_FOUND_ERROR = "Workspace agent server not found in dev machine."; private static final String WS_AGENT_SERVER_URL = "ws_agent"; + private static final String CONNECTION_HEADER = "Connection"; + private static final String CONNECTION_CLOSE = "close"; @Mock private HttpJsonRequestFactory httpJsonRequestFactory; @Mock private HttpJsonRequest httpJsonRequest; @@ -62,6 +64,10 @@ public void setUp() throws Exception { when(httpJsonRequestFactory.fromUrl(anyString())).thenReturn(httpJsonRequest); when(httpJsonRequest.setMethod(HttpMethod.GET)).thenReturn(httpJsonRequest); + when(httpJsonRequest.setTimeout(WS_AGENT_PING_CONNECTION_TIMEOUT_MS)) + .thenReturn(httpJsonRequest); + when(httpJsonRequest.addHeader(CONNECTION_HEADER, CONNECTION_CLOSE)) + .thenReturn(httpJsonRequest); when(server.getProperties()).thenReturn(serverProperties); when(serverProperties.getInternalUrl()).thenReturn(WS_AGENT_SERVER_URL); when(devMachine.getRuntime()).thenReturn(machineRuntimeInfo); @@ -105,5 +111,6 @@ public void pingRequestShouldBeCreated() throws Exception { verify(httpJsonRequestFactory).fromUrl(WS_AGENT_SERVER_URL + '/'); verify(httpJsonRequest).setMethod(javax.ws.rs.HttpMethod.GET); verify(httpJsonRequest).setTimeout(WS_AGENT_PING_CONNECTION_TIMEOUT_MS); + verify(httpJsonRequest).addHeader(CONNECTION_HEADER, CONNECTION_CLOSE); } }