VID-266 added stub server for testing 23/61323/6
authorkoblosz <sandra.koblosz@nokia.com>
Mon, 20 Aug 2018 14:42:57 +0000 (16:42 +0200)
committerkoblosz <sandra.koblosz@nokia.com>
Tue, 21 Aug 2018 07:28:10 +0000 (09:28 +0200)
Change-Id: I39b8fca2df4c45123e2308142dfbb43c737f7707
Issue-ID: VID-266
Signed-off-by: Koblosz, Sandra <sandra.koblosz@nokia.com>
vid-app-common/pom.xml
vid-app-common/src/main/java/org/onap/vid/scheduler/SchedulerRestInterface.java
vid-app-common/src/test/java/org/onap/vid/scheduler/SchedulerRestInterfaceTest.java [new file with mode: 0644]
vid-app-common/src/test/java/org/onap/vid/testUtils/StubServerUtil.java [new file with mode: 0644]

index 6ae5056..b8fbd85 100755 (executable)
                    <artifactId>opencsv</artifactId>\r
                    <version>4.1</version>\r
                </dependency>\r
-                       \r
+\r
+               <!-- HTTP client -->\r
+               <dependency>\r
+                       <groupId>com.xebialabs.restito</groupId>\r
+                       <artifactId>restito</artifactId>\r
+                       <version>0.9.3</version>\r
+                       <scope>test</scope>\r
+               </dependency>\r
                        \r
                <!-- SDK overlay war -->\r
 \r
                    <artifactId>togglz-spring-core</artifactId>\r
                    <version>2.5.0.Final</version>\r
                </dependency>\r
+                       <dependency>\r
+                               <groupId>org.assertj</groupId>\r
+                               <artifactId>assertj-core</artifactId>\r
+                               <version>3.10.0</version>\r
+                               <scope>compile</scope>\r
+                       </dependency>\r
                </dependencies>\r
 </project>\r
index abd03f3..9a7522b 100644 (file)
@@ -18,123 +18,134 @@ import javax.ws.rs.client.Client;
 import javax.ws.rs.core.MultivaluedHashMap;
 import javax.ws.rs.core.Response;
 import java.util.Collections;
+import java.util.function.Function;
 
 import static org.onap.vid.utils.Logging.REQUEST_ID_HEADER_KEY;
 
 @Service
 public class SchedulerRestInterface implements SchedulerRestInterfaceIfc {
 
-       private Client client = null;
-
-       @Autowired
-       HttpsAuthClient httpsAuthClient;
-
-       private MultivaluedHashMap<String, Object> commonHeaders;
-       
-       /** The logger. */
-       private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SchedulerRestInterface.class);
-       final private static EELFLogger outgoingRequestsLogger = Logging.getRequestsLogger("scheduler");
-       
-       public void initRestClient() {
-               logger.info("Starting to initialize rest client ");
-               
-               final String username;
-               final String password;
-               
+    private Client client = null;
+    private Function<String, String> propertyGetter;
+
+    @Autowired
+    HttpsAuthClient httpsAuthClient;
+
+    private MultivaluedHashMap<String, Object> commonHeaders;
+
+    /** The logger. */
+    private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SchedulerRestInterface.class);
+    final private static EELFLogger outgoingRequestsLogger = Logging.getRequestsLogger("scheduler");
+
+    @Autowired
+    public SchedulerRestInterface(){
+        this.propertyGetter = SystemProperties::getProperty;
+    }
+
+    public SchedulerRestInterface(Function<String, String> propertyGetter){
+        this.propertyGetter = propertyGetter;
+    }
+
+    public void initRestClient() {
+        logger.info("Starting to initialize rest client ");
+
+        final String username;
+        final String password;
+
                /*Setting user name based on properties*/
-               String retrievedUsername = SystemProperties.getProperty(SchedulerProperties.SCHEDULER_USER_NAME_VAL);
-               if(retrievedUsername.isEmpty()) {
-                       username = "";
-               } else {
-                       username = retrievedUsername;
-               }
-               
+        String retrievedUsername = propertyGetter.apply(SchedulerProperties.SCHEDULER_USER_NAME_VAL);
+        if(retrievedUsername.isEmpty()) {
+            username = "";
+        } else {
+            username = retrievedUsername;
+        }
+
                /*Setting password based on properties*/
-               String retrievedPassword = SystemProperties.getProperty(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 = new MultivaluedHashMap<String, Object> ();
-               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);
-               }
-
-               logger.info("\t<== Client Initialized \n");
-       }
-               
-       public <T> void Get (T t, String sourceId, String path, org.onap.vid.scheduler.RestObject<T> restObject ) {
-               
-               String methodName = "Get";
-               String url = SystemProperties.getProperty(SchedulerProperties.SCHEDULER_SERVER_URL_VAL) + path;
-               initRestClient();
-               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);
-               
-               if (status == 200) {
-                        t = (T) cres.readEntity(t.getClass());
-                        restObject.set(t);
-                       
-                } else {
-                    throw new GenericUncheckedException(methodName + " with status="+ status + ", url= " + url );
-                }
-
-       }
-
-       public <T> void Delete(T t, String sourceID, String path, org.onap.vid.scheduler.RestObject<T> restObject) {
-
-               initRestClient();
-
-               String url = SystemProperties.getProperty(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();
-               restObject.setStatusCode(status);
-
-               t = (T) cres.readEntity(t.getClass());
-               restObject.set(t);
-
-       }
-
-       public <T> T getInstance(Class<T> clazz) throws IllegalAccessException, InstantiationException
-       {
-               return clazz.newInstance();
-       }
+        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 = 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);
+        }
+
+        logger.info("\t<== Client Initialized \n");
+    }
+
+    public <T> void Get (T t, String sourceId, String path, org.onap.vid.scheduler.RestObject<T> restObject ) {
+
+        String methodName = "Get";
+        String url = String.format("%s%s",propertyGetter.apply(SchedulerProperties.SCHEDULER_SERVER_URL_VAL), path);
+        initRestClient();
+        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);
+
+        if (status == 200) {
+            t = (T) cres.readEntity(t.getClass());
+            restObject.set(t);
+
+        } else {
+            throw new GenericUncheckedException(String.format("%s with status=%d, url=%s", methodName, status,url));
+        }
+
+    }
+
+    public <T> void Delete(T t, String sourceID, String path, org.onap.vid.scheduler.RestObject<T> restObject) {
+
+        initRestClient();
+
+        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();
+        restObject.setStatusCode(status);
+
+        t = (T) cres.readEntity(t.getClass());
+        restObject.set(t);
+
+    }
+
+    public <T> T getInstance(Class<T> clazz) throws IllegalAccessException, InstantiationException
+    {
+        return clazz.newInstance();
+    }
 
 }
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
new file mode 100644 (file)
index 0000000..7becf8b
--- /dev/null
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2018 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+
+package org.onap.vid.scheduler;
+
+import com.xebialabs.restito.semantics.Action;
+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.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 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<String, Object> commonHeaders = new MultivaluedHashMap<>();
+    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<String, String> propertyGetter;
+
+    @InjectMocks
+    private SchedulerRestInterface schedulerInterface = new SchedulerRestInterface();
+
+    @BeforeClass
+    public static void setUpClass() {
+        serverUtil = new StubServerUtil();
+        serverUtil.runServer();
+        commonHeaders.put("Authorization", Collections.singletonList("Basic " + USR_PWD_AUTH_STRING));
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        serverUtil.stopServer();
+    }
+
+    @BeforeMethod
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        sampleBaseUrl = serverUtil.constructTargetUrl("http", "");
+    }
+
+    @Test
+    public void testShouldGetOKWhenStringIsExpected() throws IOException, GeneralSecurityException {
+        String sampleSourceId = "AAI";
+        RestObject<String> 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);
+    }
+
+
+    @Test
+    public void testShouldDeleteSuccessfully() throws IOException, GeneralSecurityException {
+        String sampleTargetUrl = serverUtil.constructTargetUrl("http", "");
+        String sampleSourceId = "AAI";
+        RestObject<String> 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);
+    }
+
+
+    private void assertResponseData(RestObject<String> sampleRestObj, String expectedResponse, int expectedStatusCode) {
+
+        assertThat(sampleRestObj.getStatusCode()).isEqualTo(expectedStatusCode);
+        assertThat(sampleRestObj.get()).isInstanceOf(String.class).isEqualTo(expectedResponse);
+        assertThat(sampleRestObj.getUUID()).isNull();
+
+    }
+
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/testUtils/StubServerUtil.java b/vid-app-common/src/test/java/org/onap/vid/testUtils/StubServerUtil.java
new file mode 100644 (file)
index 0000000..e84655f
--- /dev/null
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2018 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.testUtils;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.xebialabs.restito.semantics.Action;
+import com.xebialabs.restito.semantics.Condition;
+import com.xebialabs.restito.server.StubServer;
+
+import static com.xebialabs.restito.builder.stub.StubHttp.whenHttp;
+import static com.xebialabs.restito.semantics.Action.contentType;
+import static com.xebialabs.restito.semantics.Action.stringContent;
+
+public class StubServerUtil {
+
+    private static final String APPLICATION_JSON = "application/json";
+    private ObjectMapper objectMapper;
+
+
+    private StubServer stubServer;
+
+    public StubServerUtil() {
+        this.objectMapper = new ObjectMapper();
+        this.stubServer = new StubServer();
+    }
+
+
+    public void runServer() {
+        stubServer.run();
+    }
+
+    public void stopServer() {
+        stubServer.stop();
+    }
+
+
+    public String constructTargetUrl(String protocol, String relativePath) {
+        return String.format("%s://localhost:%s/%s", protocol, stubServer.getPort(), relativePath);
+    }
+
+    public void prepareGetCall(String path, Object returnObj, Action expectedAction) throws JsonProcessingException {
+        whenHttp(stubServer)
+                .match(Condition.get(path))
+                .then(expectedAction, jsonContent(returnObj), contentType(APPLICATION_JSON));
+    }
+
+    public void prepareDeleteCall(String path, Object returnObj, Action expectedAction) throws JsonProcessingException {
+        whenHttp(stubServer)
+                .match(Condition.delete(path))
+                .then(expectedAction, jsonContent(returnObj), contentType(APPLICATION_JSON));
+    }
+
+    public void preparePostCall(String path, Object returnObj, Action expectedAction) throws JsonProcessingException {
+        whenHttp(stubServer)
+                .match(Condition.post(path),
+                        Condition.withPostBodyContaining(objectMapper.writeValueAsString(returnObj)))
+                .then(expectedAction, jsonContent(returnObj), contentType(APPLICATION_JSON));
+    }
+
+    public void preparePutCall(String path, Object returnObj, Action expectedStatus) throws JsonProcessingException {
+        whenHttp(stubServer)
+                .match(Condition.put(path),
+                        Condition.withPostBodyContaining(objectMapper.writeValueAsString(returnObj)))
+                .then(expectedStatus, jsonContent(returnObj), contentType(APPLICATION_JSON));
+    }
+
+    private Action jsonContent(Object returnObj) throws JsonProcessingException {
+        return stringContent(objectMapper.writeValueAsString(returnObj));
+    }
+
+}