Mercurial > hg > thermostat-ng > agent
view agent/core/src/test/java/com/redhat/thermostat/agent/internal/http/HttpRequestServiceImplTest.java @ 2751:f31a81430347
Split HttpRequestService and KeycloakAccessTokenService
Reviewed-by: jkang
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-September/024882.html
author | Severin Gehwolf <sgehwolf@redhat.com> |
---|---|
date | Wed, 06 Sep 2017 19:47:49 +0200 |
parents | agent/core/src/test/java/com/redhat/thermostat/agent/http/HttpRequestServiceTest.java@915993144f20 |
children |
line wrap: on
line source
/* * Copyright 2012-2017 Red Hat, Inc. * * This file is part of Thermostat. * * Thermostat is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2, or (at your * option) any later version. * * Thermostat is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Thermostat; see the file COPYING. If not see * <http://www.gnu.org/licenses/>. * * Linking this code with other modules is making a combined work * based on this code. Thus, the terms and conditions of the GNU * General Public License cover the whole combination. * * As a special exception, the copyright holders of this code give * you permission to link this code with independent modules to * produce an executable, regardless of the license terms of these * independent modules, and to copy and distribute the resulting * executable under terms of your choice, provided that you also * meet, for each linked independent module, the terms and conditions * of the license of that module. An independent module is a module * which is not derived from or based on this code. If you modify * this code, you may extend this exception to your version of the * library, but you are not obligated to do so. If you do not wish * to do so, delete this exception statement from your version. */ package com.redhat.thermostat.agent.internal.http; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.IOException; import java.net.URI; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.util.StringContentProvider; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import com.redhat.thermostat.agent.config.AgentStartupConfiguration; import com.redhat.thermostat.agent.http.HttpRequestService; import com.redhat.thermostat.agent.http.RequestFailedException; import com.redhat.thermostat.agent.internal.http.BasicHttpService.ConfigCreator; import com.redhat.thermostat.agent.internal.http.BasicHttpService.CredentialsCreator; import com.redhat.thermostat.agent.internal.http.BasicHttpService.HttpClientCreator; import com.redhat.thermostat.agent.keycloak.KeycloakAccessToken; import com.redhat.thermostat.agent.keycloak.KeycloakAccessTokenService; import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.config.SSLConfiguration; import com.redhat.thermostat.storage.core.StorageCredentials; public class HttpRequestServiceImplTest { private static final URI GATEWAY_URI = URI.create("http://127.0.0.1:30000/test/"); private static final URI GET_URI = GATEWAY_URI.resolve("?q=foo&l=3"); private static final String payload = "{}"; private static final char[] PASSWORD = new char[] { 'p', 'a', 's', 's' }; private static final String USERNAME = "testing"; private static final String KEYCLOAK_ACCESS_TOKEN_STRING = "keycloak-bearer-token-value"; private HttpClientCreator clientCreator; private ConfigCreator configCreator; private CredentialsCreator credsCreator; private HttpClientFacade client; private Request httpRequest; private KeycloakAccessTokenService tokenService; @Before public void setup() throws InterruptedException, ExecutionException, TimeoutException, RequestFailedException { client = mock(HttpClientFacade.class); httpRequest = mock(Request.class); when(client.newRequest(eq(GATEWAY_URI))).thenReturn(httpRequest); ContentResponse response = mock(ContentResponse.class); when(response.getStatus()).thenReturn(HttpStatus.OK_200); when(httpRequest.send()).thenReturn(response); clientCreator = mock(HttpClientCreator.class); when(clientCreator.create(any(SSLConfiguration.class))).thenReturn(client); configCreator = mock(ConfigCreator.class); credsCreator = mock(CredentialsCreator.class); StorageCredentials creds = mock(StorageCredentials.class); when(creds.getPassword()).thenReturn(PASSWORD); when(creds.getUsername()).thenReturn(USERNAME); when(credsCreator.create(any(CommonPaths.class))).thenReturn(creds); tokenService = mock(KeycloakAccessTokenService.class); KeycloakAccessToken keycloakAccessToken = mock(KeycloakAccessToken.class); when(keycloakAccessToken.getAccessToken()).thenReturn(KEYCLOAK_ACCESS_TOKEN_STRING); when(tokenService.getAccessToken()).thenReturn(keycloakAccessToken); } @Test public void testRequestWithBasicAuth() throws Exception { AgentStartupConfiguration configuration = createBasicAuthConfig(); HttpRequestService service = createAndActivateRequestService(configuration); service.sendHttpRequest(payload, GATEWAY_URI, com.redhat.thermostat.agent.http.HttpRequestService.Method.POST); verify(configuration).isKeycloakEnabled(); verifyHttpPostRequest(httpRequest); verify(tokenService, times(0)).getAccessToken(); } @Test public void testRequestWithKeycloakAuth() throws Exception { AgentStartupConfiguration configuration = mock(AgentStartupConfiguration.class); when(configuration.isKeycloakEnabled()).thenReturn(true); HttpRequestService service = createAndActivateRequestService(configuration); service.sendHttpRequest(payload, GATEWAY_URI, com.redhat.thermostat.agent.http.HttpRequestService.Method.POST); verify(configuration).isKeycloakEnabled(); verifyHttpPostRequest(httpRequest); verify(httpRequest).header(eq("Authorization"), eq("Bearer " + KEYCLOAK_ACCESS_TOKEN_STRING)); verify(tokenService).getAccessToken(); } @Test public void testRequestWithNullPayload() throws Exception { AgentStartupConfiguration configuration = createBasicAuthConfig(); HttpRequestService service = createAndActivateRequestService(configuration); String response = service.sendHttpRequest(null, GATEWAY_URI, com.redhat.thermostat.agent.http.HttpRequestService.Method.POST); assertNull(response); verify(client).newRequest(GATEWAY_URI); verify(configuration).isKeycloakEnabled(); verify(httpRequest, times(0)).content(any(StringContentProvider.class), anyString()); verify(httpRequest).method(eq(HttpMethod.POST)); verify(httpRequest).send(); } @Test public void verifyBasicAuthConfig() throws Exception { AgentStartupConfiguration configuration = createBasicAuthConfig(); HttpRequestService service = createAndActivateRequestService(configuration); service.sendHttpRequest(null, GATEWAY_URI, com.redhat.thermostat.agent.http.HttpRequestService.Method.GET); verify(client).newRequest(GATEWAY_URI); verify(configuration).isKeycloakEnabled(); ArgumentCaptor<String> authValueCaptor = ArgumentCaptor.forClass(String.class); verify(httpRequest).header(eq(HttpHeader.AUTHORIZATION.asString()), authValueCaptor.capture()); String authValueEncoded = authValueCaptor.getValue(); assertTrue(authValueEncoded.startsWith("Basic ")); String userPassEncoded = authValueEncoded.substring("Basic ".length()); String decodedUserPass = getDecodedUserPass(userPassEncoded); String expectedCreds = USERNAME + ":" + new String(PASSWORD); assertEquals(expectedCreds, decodedUserPass); verify(httpRequest).method(eq(HttpMethod.GET)); verify(httpRequest).send(); } /** * If no authentication settings are done, no authorization headers should * get added. * * @throws Exception */ @Test public void verifyNoAuthConfig() throws Exception { AgentStartupConfiguration configuration = createNoAuthConfig(); HttpRequestService service = createAndActivateRequestService(configuration); service.sendHttpRequest(null, GATEWAY_URI, com.redhat.thermostat.agent.http.HttpRequestService.Method.GET); verify(client).newRequest(GATEWAY_URI); verify(configuration).isKeycloakEnabled(); verify(configuration).isBasicAuthEnabled(); verify(httpRequest, times(0)).header(eq(HttpHeader.AUTHORIZATION.asString()), anyString()); verify(httpRequest).method(eq(HttpMethod.GET)); verify(httpRequest).send(); } private String getDecodedUserPass(String userPassEncoded) throws IOException { @SuppressWarnings("restriction") byte[] decodedBytes = new sun.misc.BASE64Decoder().decodeBuffer(userPassEncoded); return new String(decodedBytes); } private HttpRequestService createAndActivateRequestService(AgentStartupConfiguration configuration) throws Exception { when(configCreator.create(any(CommonPaths.class))).thenReturn(configuration); HttpRequestServiceImpl service = new HttpRequestServiceImpl(clientCreator, configCreator, credsCreator); service.bindTokenService(tokenService); service.activate(); verify(client).start(); return service; } @Test public void testGetRequestWithResponse() throws Exception { String getContent = "foo bar"; HttpClientCreator creator = mock(HttpClientCreator.class); HttpClientFacade getClient = setupHttpClient(creator, getContent); AgentStartupConfiguration configuration = createBasicAuthConfig(); ConfigCreator configCreator = mock(ConfigCreator.class); when(configCreator.create(any(CommonPaths.class))).thenReturn(configuration); HttpRequestServiceImpl service = new HttpRequestServiceImpl(creator, configCreator, credsCreator); service.activate(); String content = service.sendHttpRequest(null, GET_URI, com.redhat.thermostat.agent.http.HttpRequestService.Method.GET); verify(getClient).newRequest(GET_URI); assertEquals(getContent, content); } @Test public void testGetRequestNormalizesURI() throws Exception { String getContent = "foo bar"; HttpClientCreator creator = mock(HttpClientCreator.class); HttpClientFacade getClient = setupHttpClient(creator, getContent); AgentStartupConfiguration configuration = createBasicAuthConfig(); ConfigCreator configCreator = mock(ConfigCreator.class); when(configCreator.create(any(CommonPaths.class))).thenReturn(configuration); HttpRequestServiceImpl service = new HttpRequestServiceImpl(creator, configCreator, credsCreator); service.activate(); // Add extra slashes to URI URI uri = URI.create("http://127.0.0.1:30000//test//?q=bar&l=5"); URI normalized = URI.create("http://127.0.0.1:30000/test/?q=bar&l=5"); String content = service.sendHttpRequest(null, uri, com.redhat.thermostat.agent.http.HttpRequestService.Method.GET); verify(getClient).newRequest(normalized); assertEquals(getContent, content); } private HttpClientFacade setupHttpClient(HttpClientCreator creator, String getContent) throws Exception { Request request = mock(Request.class); ContentResponse contentResponse = mock(ContentResponse.class); when(contentResponse.getStatus()).thenReturn(HttpStatus.OK_200); when(contentResponse.getContentAsString()).thenReturn(getContent); when(request.send()).thenReturn(contentResponse); HttpClientFacade getClient = mock(HttpClientFacade.class); when(getClient.newRequest(any(URI.class))).thenReturn(request); when(creator.create(any(SSLConfiguration.class))).thenReturn(getClient); return getClient; } @Test(expected = RequestFailedException.class) public void failureThrowsRequestFailedException() throws Exception { Request request = mock(Request.class); when(client.newRequest(any(URI.class))).thenReturn(request); AgentStartupConfiguration configuration = createBasicAuthConfig(); doThrow(RequestFailedException.class).when(request).send(); HttpRequestService service = createAndActivateRequestService(configuration); service.sendHttpRequest("foo", GATEWAY_URI, com.redhat.thermostat.agent.http.HttpRequestService.Method.DELETE /*any valid method*/); } private AgentStartupConfiguration createBasicAuthConfig() { return createAuthConfig(true, false); } private AgentStartupConfiguration createNoAuthConfig() { return createAuthConfig(false, false); } private AgentStartupConfiguration createAuthConfig(boolean isBasicAuthEnabled, boolean isKeycloakEnabled) { AgentStartupConfiguration configuration = mock(AgentStartupConfiguration.class); when(configuration.isKeycloakEnabled()).thenReturn(isKeycloakEnabled); when(configuration.isBasicAuthEnabled()).thenReturn(isBasicAuthEnabled); return configuration; } private void verifyHttpPostRequest(Request httpRequest) throws InterruptedException, ExecutionException, TimeoutException { verify(client).newRequest(GATEWAY_URI); verify(httpRequest).content(any(StringContentProvider.class), eq("application/json")); verify(httpRequest).method(eq(HttpMethod.POST)); verify(httpRequest).send(); } }