From 296599aa5977fb047d9d0619ec3e463c031b0b49 Mon Sep 17 00:00:00 2001 From: koblosz Date: Thu, 23 Aug 2018 15:39:19 +0200 Subject: Using Generic client in SchedulerRestInterface Change-Id: I69603792016a091037d8767bec0f3d25641af86e Issue-ID: VID-270 Signed-off-by: koblosz --- .../onap/vid/scheduler/SchedulerRestInterface.java | 151 ++++++++------------ .../src/main/java/org/onap/vid/utils/Logging.java | 10 ++ .../org/onap/vid/mso/MsoBusinessLogicTest.java | 11 +- .../vid/scheduler/SchedulerRestInterfaceTest.java | 154 +++++++++------------ .../test/resources/WEB-INF/conf/system.properties | 2 + 5 files changed, 137 insertions(+), 191 deletions(-) diff --git a/vid-app-common/src/main/java/org/onap/vid/scheduler/SchedulerRestInterface.java b/vid-app-common/src/main/java/org/onap/vid/scheduler/SchedulerRestInterface.java index d66ed4947..a4c5b00a8 100644 --- a/vid-app-common/src/main/java/org/onap/vid/scheduler/SchedulerRestInterface.java +++ b/vid-app-common/src/main/java/org/onap/vid/scheduler/SchedulerRestInterface.java @@ -1,23 +1,22 @@ package org.onap.vid.scheduler; import com.att.eelf.configuration.EELFLogger; -import org.apache.commons.codec.binary.Base64; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import io.joshworks.restclient.http.HttpResponse; import org.eclipse.jetty.util.security.Password; -import org.onap.vid.aai.util.HttpClientMode; -import org.onap.vid.aai.util.HttpsAuthClient; -import org.onap.vid.client.HttpBasicClient; -import org.onap.vid.exceptions.GenericUncheckedException; -import org.onap.vid.utils.Logging; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.util.SystemProperties; -import org.springframework.beans.factory.annotation.Autowired; +import org.onap.vid.client.SyncRestClient; +import org.onap.vid.client.SyncRestClientInterface; +import org.onap.vid.exceptions.GenericUncheckedException; +import org.onap.vid.utils.Logging; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; -import javax.ws.rs.client.Client; -import javax.ws.rs.core.MultivaluedHashMap; -import javax.ws.rs.core.Response; +import java.util.Base64; import java.util.Collections; +import java.util.Map; import java.util.function.Function; import static org.onap.vid.utils.Logging.REQUEST_ID_HEADER_KEY; @@ -25,126 +24,88 @@ import static org.onap.vid.utils.Logging.REQUEST_ID_HEADER_KEY; @Service public class SchedulerRestInterface implements SchedulerRestInterfaceIfc { - private Client client = null; - private Function propertyGetter; - - @Autowired - HttpsAuthClient httpsAuthClient; - - private MultivaluedHashMap commonHeaders; - - /** The logger. */ - private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SchedulerRestInterface.class); final private static EELFLogger outgoingRequestsLogger = Logging.getRequestsLogger("scheduler"); + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SchedulerRestInterface.class); + private SyncRestClientInterface syncRestClient; + private Function propertyGetter; + private Map commonHeaders; - public SchedulerRestInterface(){ + public SchedulerRestInterface() { this.propertyGetter = SystemProperties::getProperty; } - public SchedulerRestInterface(Function propertyGetter){ + public SchedulerRestInterface(Function propertyGetter) { this.propertyGetter = propertyGetter; } public void initRestClient() { logger.info("Starting to initialize rest client "); + String authStringEnc = calcEncodedAuthString(); - final String username; - final String password; - - /*Setting user name based on properties*/ - String retrievedUsername = propertyGetter.apply(SchedulerProperties.SCHEDULER_USER_NAME_VAL); - if(retrievedUsername.isEmpty()) { - username = ""; - } else { - username = retrievedUsername; - } - - /*Setting password based on properties*/ - String retrievedPassword = propertyGetter.apply(SchedulerProperties.SCHEDULER_PASSWORD_VAL); - if(retrievedPassword.isEmpty()) { - password = ""; - } else { - if (retrievedPassword.contains("OBF:")) { - password = Password.deobfuscate(retrievedPassword); - } else { - password = retrievedPassword; - } - } - - String authString = username + ":" + password; - - byte[] authEncBytes = Base64.encodeBase64(authString.getBytes()); - String authStringEnc = new String(authEncBytes); + commonHeaders = Maps.newHashMap(); + commonHeaders.put("Authorization", "Basic " + authStringEnc); - commonHeaders = new MultivaluedHashMap<> (); - commonHeaders.put("Authorization", Collections.singletonList("Basic " + authStringEnc)); - - try { - if ( !username.isEmpty() ) { - client = httpsAuthClient.getClient(HttpClientMode.WITHOUT_KEYSTORE); - } - else { - - client = HttpBasicClient.getClient(); - } - } catch (Exception e) { - logger.error(" <== Unable to initialize rest client ", e); - } + syncRestClient = new SyncRestClient(); logger.info("\t<== Client Initialized \n"); } - public void Get (T t, String sourceId, String path, org.onap.vid.scheduler.RestObject restObject ) { - - String methodName = "Get"; - String url = String.format("%s%s",propertyGetter.apply(SchedulerProperties.SCHEDULER_SERVER_URL_VAL), path); + public void Get(T t, String sourceId, String path, org.onap.vid.scheduler.RestObject restObject) { initRestClient(); + String methodName = "Get"; + String url = String.format("%s%s", propertyGetter.apply(SchedulerProperties.SCHEDULER_SERVER_URL_VAL), path); Logging.logRequest(outgoingRequestsLogger, HttpMethod.GET, url); - final Response cres = client.target(url) - .request() - .accept("application/json") - .headers(commonHeaders) - .header(REQUEST_ID_HEADER_KEY, Logging.extractOrGenerateRequestId()) - .get(); - Logging.logResponse(outgoingRequestsLogger, HttpMethod.GET, url, cres); - int status = cres.getStatus(); - restObject.setStatusCode (status); + Map requestHeaders = ImmutableMap.builder() + .putAll(commonHeaders) + .put(REQUEST_ID_HEADER_KEY, Logging.extractOrGenerateRequestId()).build(); + final HttpResponse response = ((HttpResponse) syncRestClient.get(url, requestHeaders, + Collections.emptyMap(), t.getClass())); + Logging.logResponse(outgoingRequestsLogger, HttpMethod.GET, url, response); + int status = response.getStatus(); + restObject.setStatusCode(status); if (status == 200) { - t = (T) cres.readEntity(t.getClass()); + t = response.getBody(); restObject.set(t); } else { - throw new GenericUncheckedException(String.format("%s with status=%d, url=%s", methodName, status,url)); + throw new GenericUncheckedException(String.format("%s with status=%d, url=%s", methodName, status, url)); } - } public void Delete(T t, String sourceID, String path, org.onap.vid.scheduler.RestObject restObject) { - initRestClient(); - - String url = String.format( "%s%s",propertyGetter.apply(SchedulerProperties.SCHEDULER_SERVER_URL_VAL), path); + String url = String.format("%s%s", propertyGetter.apply(SchedulerProperties.SCHEDULER_SERVER_URL_VAL), path); Logging.logRequest(outgoingRequestsLogger, HttpMethod.DELETE, url); - Response cres = client.target(url) - .request() - .accept("application/json") - .headers(commonHeaders) - .header(REQUEST_ID_HEADER_KEY, Logging.extractOrGenerateRequestId()) - .delete(); - Logging.logResponse(outgoingRequestsLogger, HttpMethod.DELETE, url, cres); - - int status = cres.getStatus(); + Map requestHeaders = ImmutableMap.builder() + .putAll(commonHeaders) + .put(REQUEST_ID_HEADER_KEY, Logging.extractOrGenerateRequestId()).build(); + final HttpResponse response = (HttpResponse) syncRestClient.delete(url, requestHeaders, t.getClass()); + + Logging.logResponse(outgoingRequestsLogger, HttpMethod.DELETE, url, response); + + int status = response.getStatus(); restObject.setStatusCode(status); - t = (T) cres.readEntity(t.getClass()); + t = response.getBody(); restObject.set(t); - } - public T getInstance(Class clazz) throws IllegalAccessException, InstantiationException - { + public T getInstance(Class clazz) throws IllegalAccessException, InstantiationException { return clazz.newInstance(); } + private String calcEncodedAuthString() { + String retrievedUsername = propertyGetter.apply(SchedulerProperties.SCHEDULER_USER_NAME_VAL); + final String username = retrievedUsername.isEmpty() ? "" : retrievedUsername; + + String retrievedPassword = propertyGetter.apply(SchedulerProperties.SCHEDULER_PASSWORD_VAL); + final String password = retrievedPassword.isEmpty() ? "" : getDeobfuscatedPassword(retrievedPassword); + + return Base64.getEncoder().encodeToString((username + ":" + password).getBytes()); + } + + private static String getDeobfuscatedPassword(String password) { + return password.contains("OBF:") ? Password.deobfuscate(password) : password; + } } diff --git a/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java b/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java index e0ee6fbf0..3ac905884 100644 --- a/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java +++ b/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.google.common.collect.ImmutableList; +import io.joshworks.restclient.http.HttpResponse; import org.apache.commons.lang3.StringUtils; import org.onap.vid.exceptions.GenericUncheckedException; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; @@ -101,6 +102,15 @@ public class Logging { } } + public static void logResponse(final EELFLogger logger, final HttpMethod method, final String url, final HttpResponse response) { + try { + logger.debug("Received {} {} Status: {} . Body: {}", method.name(), url, response.getStatus(), response.getBody()); + } + catch (ProcessingException | IllegalStateException e) { + logger.debug("Received {} {} Status: {} . Failed to read response", method.name(), url, response.getStatus()); + } + } + public static void logResponse(final EELFLogger logger, final HttpMethod method, final String url, final Response response) { logResponse(logger, method, url, response, String.class); } diff --git a/vid-app-common/src/test/java/org/onap/vid/mso/MsoBusinessLogicTest.java b/vid-app-common/src/test/java/org/onap/vid/mso/MsoBusinessLogicTest.java index 738e8df03..af7f74b3d 100644 --- a/vid-app-common/src/test/java/org/onap/vid/mso/MsoBusinessLogicTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/mso/MsoBusinessLogicTest.java @@ -1,16 +1,16 @@ package org.onap.vid.mso; import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; +import org.mockito.runners.MockitoJUnitRunner; import org.onap.vid.mso.MsoBusinessLogicImpl; import org.onap.vid.mso.MsoInterface; import org.onap.vid.mso.MsoResponseWrapper; import org.onap.vid.mso.rest.RequestDetails; import org.onap.vid.mso.rest.RequestDetailsWrapper; -import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.net.URL; @@ -18,7 +18,7 @@ import java.net.URL; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; -@Test +@RunWith(MockitoJUnitRunner.class) public class MsoBusinessLogicTest { @InjectMocks @@ -27,11 +27,6 @@ public class MsoBusinessLogicTest { @Mock private MsoInterface msoClient; - @BeforeMethod - public void initMocks(){ - MockitoAnnotations.initMocks(this); - } - @Test public void testCreateInstance() throws Exception { String instanceId = "3f93c7cb-2fd0-4557-9514-e189b7b04f9d"; diff --git a/vid-app-common/src/test/java/org/onap/vid/scheduler/SchedulerRestInterfaceTest.java b/vid-app-common/src/test/java/org/onap/vid/scheduler/SchedulerRestInterfaceTest.java index 7becf8b7e..6390f5800 100644 --- a/vid-app-common/src/test/java/org/onap/vid/scheduler/SchedulerRestInterfaceTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/scheduler/SchedulerRestInterfaceTest.java @@ -21,27 +21,22 @@ package org.onap.vid.scheduler; +import com.fasterxml.jackson.core.JsonProcessingException; import com.xebialabs.restito.semantics.Action; +import org.glassfish.grizzly.http.util.HttpStatus; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.*; import org.mockito.runners.MockitoJUnitRunner; -import org.onap.vid.aai.util.HttpClientMode; -import org.onap.vid.aai.util.HttpsAuthClient; +import org.onap.vid.exceptions.GenericUncheckedException; import org.onap.vid.testUtils.StubServerUtil; -import org.testng.annotations.BeforeMethod; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MultivaluedHashMap; -import javax.ws.rs.core.Response; -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.util.Collections; -import java.util.function.Function; +import org.testng.annotations.AfterMethod; + +import java.util.HashMap; +import java.util.Map; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; @@ -49,33 +44,25 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; @RunWith(MockitoJUnitRunner.class) public class SchedulerRestInterfaceTest { - private static final String USR_PWD_AUTH_STRING = "c2FtcGxlOnBhUyR3MFJk"; - private static final String APPLICATION_JSON = "application/json"; - private static MultivaluedHashMap commonHeaders = new MultivaluedHashMap<>(); + private static final String SAMPLE_USERNAME = "sample"; + private static final String SAMPLE_PASSWORD = "paS$w0Rd"; + private static final String SAMPLE_SCHEDULER_SERVER_URL = "http://localhost"; + private static final String SAMPLE_SOURCE_ID = "AAI"; + private static final JSONParser JSON_PARSER = new JSONParser(); + private static final String RESPONSE_CONTENT = "\"schedules\": \"SAMPLE STRING\""; + private static final String ERROR_RESPONSE = "\"error\": \"Internal server error!\""; + private static Map DUMMY_SYSTEM_PROPERTIES = new HashMap() {{ + put(SchedulerProperties.SCHEDULER_USER_NAME_VAL, SAMPLE_USERNAME); + put(SchedulerProperties.SCHEDULER_PASSWORD_VAL, SAMPLE_PASSWORD); + put(SchedulerProperties.SCHEDULER_SERVER_URL_VAL, SAMPLE_SCHEDULER_SERVER_URL); + }}; private static StubServerUtil serverUtil; - private String sampleBaseUrl; - @Mock - private HttpsAuthClient mockedHttpsAuthClient; - @Mock - private Client mockedClient; - @Mock - private Invocation.Builder mockedBuilder; - @Mock - private Response mockedResponse; - @Mock - private WebTarget mockedWebTarget; - - @Mock - private Function propertyGetter; - - @InjectMocks - private SchedulerRestInterface schedulerInterface = new SchedulerRestInterface(); + private static SchedulerRestInterface schedulerInterface = new SchedulerRestInterface((key) -> DUMMY_SYSTEM_PROPERTIES.get(key)); @BeforeClass public static void setUpClass() { serverUtil = new StubServerUtil(); serverUtil.runServer(); - commonHeaders.put("Authorization", Collections.singletonList("Basic " + USR_PWD_AUTH_STRING)); } @AfterClass @@ -83,76 +70,67 @@ public class SchedulerRestInterfaceTest { serverUtil.stopServer(); } - @BeforeMethod - public void setUp() { - MockitoAnnotations.initMocks(this); - sampleBaseUrl = serverUtil.constructTargetUrl("http", ""); + @AfterMethod + public void tearDown() { + serverUtil.stopServer(); } @Test - public void testShouldGetOKWhenStringIsExpected() throws IOException, GeneralSecurityException { - String sampleSourceId = "AAI"; + public void testShouldGetOKWhenStringIsExpected() throws JsonProcessingException, ParseException { + prepareEnvForTest(); RestObject sampleRestObj = new RestObject<>(); - String resultHolder = ""; - - String responseContent = "sample : SAMPLE RESULT STRING"; - Mockito.doReturn(mockedClient).when(mockedHttpsAuthClient).getClient(HttpClientMode.WITHOUT_KEYSTORE); - Mockito.doReturn("sample").when(propertyGetter).apply(SchedulerProperties.SCHEDULER_USER_NAME_VAL); - Mockito.doReturn("paS$w0Rd").when(propertyGetter).apply(SchedulerProperties.SCHEDULER_PASSWORD_VAL); - Mockito.doReturn(sampleBaseUrl).when(propertyGetter).apply(SchedulerProperties.SCHEDULER_SERVER_URL_VAL); - Mockito.doReturn(200).when(mockedResponse).getStatus(); - Mockito.doReturn(responseContent).when(mockedResponse).readEntity(String.class); - Mockito.doReturn(mockedResponse).when(mockedBuilder).get(); - Mockito.when(mockedBuilder.header(Matchers.any(), Matchers.any())).thenReturn(mockedBuilder); - Mockito.doReturn(mockedBuilder).when(mockedBuilder).headers(commonHeaders); - Mockito.doReturn(mockedBuilder).when(mockedBuilder).accept(APPLICATION_JSON); - Mockito.doReturn(mockedBuilder).when(mockedWebTarget).request(); - Mockito.doReturn(mockedWebTarget).when(mockedClient).target(sampleBaseUrl + "test"); - - serverUtil.prepareGetCall("/test", responseContent, Action.ok()); - - schedulerInterface.Get(resultHolder, sampleSourceId, "test", sampleRestObj); - - assertResponseData(sampleRestObj, responseContent, 200); + serverUtil.prepareGetCall("/test", RESPONSE_CONTENT, Action.ok()); + + schedulerInterface.Get("", SAMPLE_SOURCE_ID, "", sampleRestObj); + + assertResponseHasExpectedBodyAndStatus(sampleRestObj, RESPONSE_CONTENT, 200); } + @Test(expected = GenericUncheckedException.class) + public void shouldRaiseExceptionWhenErrorOccursDuringGet() throws JsonProcessingException { + prepareEnvForTest(); + RestObject sampleRestObj = new RestObject<>(); + + serverUtil.prepareGetCall("/test", ERROR_RESPONSE, Action.status(HttpStatus.INTERNAL_SERVER_ERROR_500)); + + schedulerInterface.Get("", SAMPLE_SOURCE_ID, "", sampleRestObj); + } @Test - public void testShouldDeleteSuccessfully() throws IOException, GeneralSecurityException { - String sampleTargetUrl = serverUtil.constructTargetUrl("http", ""); - String sampleSourceId = "AAI"; + public void shouldDeleteResourceSuccessfully() throws JsonProcessingException, ParseException { + prepareEnvForTest(); RestObject sampleRestObj = new RestObject<>(); - String resultHolder = ""; - - String responseContent = "sample : SAMPLE RESULT STRING"; - Mockito.doReturn(mockedClient).when(mockedHttpsAuthClient).getClient(HttpClientMode.WITHOUT_KEYSTORE); - Mockito.doReturn("sample").when(propertyGetter).apply(SchedulerProperties.SCHEDULER_USER_NAME_VAL); - Mockito.doReturn("paS$w0Rd").when(propertyGetter).apply(SchedulerProperties.SCHEDULER_PASSWORD_VAL); - Mockito.doReturn(sampleTargetUrl).when(propertyGetter).apply(SchedulerProperties.SCHEDULER_SERVER_URL_VAL); - Mockito.doReturn(200).when(mockedResponse).getStatus(); - Mockito.doReturn(responseContent).when(mockedResponse).readEntity(String.class); - Mockito.doReturn(mockedResponse).when(mockedBuilder).delete(); - Mockito.when(mockedBuilder.header(Matchers.any(), Matchers.any())).thenReturn(mockedBuilder); - Mockito.doReturn(mockedBuilder).when(mockedBuilder).headers(commonHeaders); - Mockito.doReturn(mockedBuilder).when(mockedBuilder).accept(APPLICATION_JSON); - Mockito.doReturn(mockedBuilder).when(mockedWebTarget).request(); - Mockito.doReturn(mockedWebTarget).when(mockedClient).target(sampleTargetUrl + "test"); - - serverUtil.prepareDeleteCall("/test", responseContent, Action.ok()); - - schedulerInterface.Delete(resultHolder, sampleSourceId, "test", sampleRestObj); - - assertResponseData(sampleRestObj, responseContent, 200); + serverUtil.prepareDeleteCall("/test", RESPONSE_CONTENT, Action.ok()); + + schedulerInterface.Delete("", SAMPLE_SOURCE_ID, "", sampleRestObj); + + assertResponseHasExpectedBodyAndStatus(sampleRestObj, RESPONSE_CONTENT, 200); + } + + @Test + public void shouldRaiseExceptionWhenErrorOccursDuringDelete() throws JsonProcessingException, ParseException { + prepareEnvForTest(); + RestObject sampleRestObj = new RestObject<>(); + serverUtil.prepareDeleteCall("/test", ERROR_RESPONSE, Action.status(HttpStatus.INTERNAL_SERVER_ERROR_500)); + + schedulerInterface.Delete("", SAMPLE_SOURCE_ID, "", sampleRestObj); + + assertResponseHasExpectedBodyAndStatus(sampleRestObj, ERROR_RESPONSE, 500); } - private void assertResponseData(RestObject sampleRestObj, String expectedResponse, int expectedStatusCode) { + private void assertResponseHasExpectedBodyAndStatus(RestObject sampleRestObj, String expectedResponse, int expectedStatusCode) throws ParseException { + Object parsedResult = JSON_PARSER.parse(sampleRestObj.get()); assertThat(sampleRestObj.getStatusCode()).isEqualTo(expectedStatusCode); - assertThat(sampleRestObj.get()).isInstanceOf(String.class).isEqualTo(expectedResponse); + assertThat(parsedResult).isInstanceOf(String.class).isEqualTo(expectedResponse); assertThat(sampleRestObj.getUUID()).isNull(); } + private void prepareEnvForTest() { + String targetUrl = serverUtil.constructTargetUrl("http", "test"); + DUMMY_SYSTEM_PROPERTIES.put(SchedulerProperties.SCHEDULER_SERVER_URL_VAL, targetUrl); + } } diff --git a/vid-app-common/src/test/resources/WEB-INF/conf/system.properties b/vid-app-common/src/test/resources/WEB-INF/conf/system.properties index a67f57897..f86a09ace 100644 --- a/vid-app-common/src/test/resources/WEB-INF/conf/system.properties +++ b/vid-app-common/src/test/resources/WEB-INF/conf/system.properties @@ -83,6 +83,8 @@ aai.server.url.base=https://aai-ext1.test.att.com:8443/aai/ aai.server.url=http://localhost:8080/vidSimulator/aai/v12/ #aai.server.url=http://localhost:1080/aai #aai.server.url=https://aai-int2.test.att.com:8443/aai/v12/ +aai.vid.username=VID +aai.vid.passwd.x=OBF:1jm91i0v1jl9 -- cgit 1.2.3-korg