From 1424a8e6afe0dfa1664b694dd22afeeb4fba7f4c Mon Sep 17 00:00:00 2001 From: "Singal, Kapil (ks220y)" Date: Wed, 24 Mar 2021 14:54:47 -0400 Subject: Moving chef-adaptor from APPC Issue-ID: CCSDK-3198 Signed-off-by: Singal, Kapil (ks220y) Change-Id: I416450c0de9951fe4d5c62cd7cea201c25feb562 --- .../chefclient/impl/ChefApiClientImplTest.java | 231 +++++++++++ .../chefclient/impl/ChefApiHeaderFactoryTest.java | 85 ++++ .../chefclient/impl/FormattedTimestampTest.java | 42 ++ .../impl/ChefAdaptorImplDataRetrieverTest.java | 83 ++++ .../chef/impl/ChefAdaptorImplHttpMethodTest.java | 185 +++++++++ .../chef/impl/ChefAdaptorImplJobPusherTest.java | 269 ++++++++++++ .../adaptors/chef/impl/ChefAdaptorImplTest.java | 197 +++++++++ .../impl/ChefAdaptorImplVNFCOperationsTest.java | 452 +++++++++++++++++++++ .../adaptors/chef/impl/PrivateKeyCheckerTest.java | 41 ++ .../java/org/onap/ccsdk/test/ExecutorHarness.java | 170 ++++++++ .../java/org/onap/ccsdk/test/InterceptLogger.java | 447 ++++++++++++++++++++ .../properties/chef-adaptor-test.properties | 101 +++++ .../src/test/resources/testclient.pem | 27 ++ 13 files changed, 2330 insertions(+) create mode 100644 adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/chefclient/impl/ChefApiClientImplTest.java create mode 100644 adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/chefclient/impl/ChefApiHeaderFactoryTest.java create mode 100644 adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/chefclient/impl/FormattedTimestampTest.java create mode 100644 adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplDataRetrieverTest.java create mode 100644 adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplHttpMethodTest.java create mode 100644 adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplJobPusherTest.java create mode 100644 adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplTest.java create mode 100644 adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplVNFCOperationsTest.java create mode 100644 adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/PrivateKeyCheckerTest.java create mode 100644 adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/test/ExecutorHarness.java create mode 100644 adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/test/InterceptLogger.java create mode 100644 adaptors/chef-adaptor/chef-adaptor-bundle/src/test/resources/properties/chef-adaptor-test.properties create mode 100644 adaptors/chef-adaptor/chef-adaptor-bundle/src/test/resources/testclient.pem (limited to 'adaptors/chef-adaptor/chef-adaptor-bundle/src/test') diff --git a/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/chefclient/impl/ChefApiClientImplTest.java b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/chefclient/impl/ChefApiClientImplTest.java new file mode 100644 index 000000000..6f9601c7d --- /dev/null +++ b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/chefclient/impl/ChefApiClientImplTest.java @@ -0,0 +1,231 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2018 Nokia. All rights reserved. + * Copyright (C) 2018 AT&T 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.ccsdk.sli.adaptors.chef.chefclient.impl; + +import com.google.common.collect.ImmutableMap; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.function.Supplier; +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.StatusLine; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.entity.StringEntity; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatcher; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.onap.ccsdk.sli.adaptors.chef.chefclient.ChefApiClientFactory; +import org.onap.ccsdk.sli.adaptors.chef.chefclient.api.ChefApiClient; +import org.onap.ccsdk.sli.adaptors.chef.chefclient.api.ChefResponse; + +import static junit.framework.TestCase.assertEquals; +import static org.mockito.BDDMockito.given; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.mock; + +@RunWith(MockitoJUnitRunner.class) +public class ChefApiClientImplTest { + + private static final String END_POINT = "https://chefServer"; + private static final String ORGANIZATIONS_PATH = "onap"; + private static final String USER_ID = "testUser"; + private static final String REQUEST_PATH = "/test/path"; + private static final String BODY = "SOME BODY STRING"; + private static final String PEM_FILEPATH = "path/to/pemFile"; + private static final ImmutableMap HEADERS = ImmutableMap.builder() + .put("Content-type", "application/json") + .put("Accept", "application/json") + .put("X-Ops-Timestamp", "1970-01-15T06:56:07Z") + .put("X-Ops-UserId", USER_ID) + .put("X-Chef-Version", "12.4.1") + .put("X-Ops-Content-Hash", BODY) + .put("X-Ops-Sign", "version=1.0").build(); + + @Mock + private HttpClient httpClient; + @Mock + private org.onap.ccsdk.sli.adaptors.chef.chefclient.impl.ChefApiHeaderFactory chefHttpHeaderFactory; + + @InjectMocks + private ChefApiClientFactory chefApiClientFactory; + private ChefApiClient chefApiClient; + + @Before + public void setUp() { + chefApiClient = chefApiClientFactory.create( + END_POINT, + ORGANIZATIONS_PATH, + USER_ID, + PEM_FILEPATH); + } + + @Test + public void execute_HttpGet_shouldReturnResponseObject_whenRequestIsSuccessful() throws IOException { + // GIVEN + String methodName = "GET"; + String body = ""; + Supplier chefClientApiCall = () -> chefApiClient.get(REQUEST_PATH); + + // WHEN //THEN + assertChefApiClientCall(methodName, body, chefClientApiCall); + } + + @Test + public void execute_HttpDelete_shouldReturnResponseObject_whenRequestIsSuccessful() throws IOException { + // GIVEN + String methodName = "DELETE"; + String body = ""; + Supplier chefClientApiCall = () -> chefApiClient.delete(REQUEST_PATH); + + // WHEN //THEN + assertChefApiClientCall(methodName, body, chefClientApiCall); + } + + @Test + public void execute_HttpPost_shouldReturnResponseObject_whenRequestIsSuccessful() throws IOException { + // GIVEN + String methodName = "POST"; + Supplier chefClientApiCall = () -> chefApiClient.post(REQUEST_PATH, BODY); + + // WHEN //THEN + assertChefApiClientCall(methodName, BODY, chefClientApiCall); + } + + @Test + public void execute_HttpPut_shouldReturnResponseObject_whenRequestIsSuccessful() throws IOException { + // GIVEN + String methodName = "PUT"; + Supplier chefClientApiCall = () -> chefApiClient.put(REQUEST_PATH, BODY); + + // WHEN //THEN + assertChefApiClientCall(methodName, BODY, chefClientApiCall); + } + + private void assertChefApiClientCall(String methodName, String body, Supplier httpMethod) + throws IOException { + // GIVEN + given(chefHttpHeaderFactory.create(methodName, REQUEST_PATH, body, USER_ID, ORGANIZATIONS_PATH, PEM_FILEPATH)) + .willReturn(HEADERS); + + StatusLine statusLine = mock(StatusLine.class); + given(statusLine.getStatusCode()).willReturn(HttpStatus.SC_OK); + HttpResponse httpResponse = mock(HttpResponse.class); + given(httpResponse.getStatusLine()).willReturn(statusLine); + given(httpResponse.getEntity()).willReturn(new StringEntity("Successful Response String")); + given(httpClient.execute(argThat(new HttpRequestBaseMatcher(methodName)))) + .willReturn(httpResponse); + + // WHEN + ChefResponse chefResponse = httpMethod.get(); + + // THEN + assertEquals("Successful Response String", chefResponse.getBody()); + assertEquals(HttpStatus.SC_OK, chefResponse.getStatusCode()); + } + + @Test + public void execute_shouldHandleException_whenHttpClientExecutionFails() throws IOException { + + // GIVEN + given(chefHttpHeaderFactory.create("GET", REQUEST_PATH, "", USER_ID, ORGANIZATIONS_PATH, PEM_FILEPATH)) + .willReturn(HEADERS); + + String expectedErrorMsg = "HttpClient call failed"; + given(httpClient.execute(argThat(new HttpRequestBaseMatcher("GET")))) + .willThrow(new IOException(expectedErrorMsg)); + + // WHEN + ChefResponse chefResponse = chefApiClient.get(REQUEST_PATH); + + // THEN + assertEquals(expectedErrorMsg, chefResponse.getBody()); + assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, chefResponse.getStatusCode()); + } + + @Test + public void execute_shouldHandleException_whenEndpointURIisMalformed() { + // GIVEN + String expectedErrorMsg = "Malformed escape pair at index 1: /%#@/"; + + // WHEN + ChefApiClient chefApiClient = chefApiClientFactory.create( + "/%#@/", + ORGANIZATIONS_PATH, + USER_ID, + PEM_FILEPATH); + ChefResponse chefResponse = chefApiClient.get(REQUEST_PATH); + + // THEN + assertEquals(expectedErrorMsg, chefResponse.getBody()); + assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, chefResponse.getStatusCode()); + } + + private class HttpRequestBaseMatcher extends ArgumentMatcher { + + private final String methodName; + + public HttpRequestBaseMatcher(String methodName) { + this.methodName = methodName; + } + + @Override + public boolean matches(Object arguments) { + HttpRequestBase httpRequestBase = (HttpRequestBase) arguments; + try { + return methodName.equals(httpRequestBase.getMethod()) + && new URI(END_POINT + "/organizations/" + ORGANIZATIONS_PATH + REQUEST_PATH).equals(httpRequestBase.getURI()) + && checkIfBodyMatches(httpRequestBase) + && checkIfHeadersMatch(httpRequestBase); + } catch (URISyntaxException e) { + e.printStackTrace(); + return false; + } + } + + public boolean checkIfBodyMatches(HttpRequestBase httpRequestBase) { + if (httpRequestBase instanceof HttpEntityEnclosingRequestBase) { + HttpEntityEnclosingRequestBase requestBaseWithBody = (HttpEntityEnclosingRequestBase) httpRequestBase; + StringEntity stringEntity = new StringEntity(BODY, "UTF-8"); + stringEntity.setContentType("application/json"); + return stringEntity.toString().equals(requestBaseWithBody.getEntity().toString()); + } + return true; + } + + private boolean checkIfHeadersMatch(HttpRequestBase httpRequestBase) { + Header[] generatedHeaders = httpRequestBase.getAllHeaders(); + return generatedHeaders.length > 0 + && generatedHeaders.length == HEADERS.size() + && HEADERS.entrySet().stream().allMatch(p -> httpRequestBase.getFirstHeader(p.getKey()).getValue().equals(p.getValue())); + } + + } + +} diff --git a/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/chefclient/impl/ChefApiHeaderFactoryTest.java b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/chefclient/impl/ChefApiHeaderFactoryTest.java new file mode 100644 index 000000000..f890d9249 --- /dev/null +++ b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/chefclient/impl/ChefApiHeaderFactoryTest.java @@ -0,0 +1,85 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2018 Nokia. 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.ccsdk.sli.adaptors.chef.chefclient.impl; + +import com.google.common.collect.ImmutableMap; +import java.util.Date; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import static junit.framework.TestCase.assertEquals; +import static org.mockito.BDDMockito.given; +import static org.mockito.Matchers.any; + +@RunWith(MockitoJUnitRunner.class) +public class ChefApiHeaderFactoryTest { + + private static final String ORGANIZATIONS_PATH = "onap"; + private static final String USER_ID = "testUser"; + private static final String REQUEST_PATH = "/test/path"; + private static final String EXPECTED_TIMESTAMP = "1970-01-15T06:56:07Z"; + private static final String EMPTY_BODY = ""; + + @Mock + private org.onap.ccsdk.sli.adaptors.chef.chefclient.impl.FormattedTimestamp formattedTimestamp; + + @InjectMocks + private org.onap.ccsdk.sli.adaptors.chef.chefclient.impl.ChefApiHeaderFactory chefApiHeaderFactory; + + @Test + public void create_shouldCreateProperChefHeaders_withHashedAuthorizationString() { + // GIVEN + given(formattedTimestamp.format(any(Date.class))).willReturn(EXPECTED_TIMESTAMP); + String pemFilePath = getClass().getResource("/testclient.pem").getPath(); + + // WHEN + ImmutableMap headers = chefApiHeaderFactory + .create("GET", REQUEST_PATH, "", USER_ID, ORGANIZATIONS_PATH, pemFilePath); + + // THEN + assertEquals(headers, createExpectedHeaders()); + } + + private ImmutableMap createExpectedHeaders() { + String hashedBody = org.onap.ccsdk.sli.adaptors.chef.chefclient.impl.Utils.sha1AndBase64(EMPTY_BODY); + ImmutableMap.Builder builder = ImmutableMap.builder(); + builder + .put("Content-type", "application/json") + .put("Accept", "application/json") + .put("X-Ops-Timestamp", EXPECTED_TIMESTAMP) + .put("X-Ops-UserId", USER_ID) + .put("X-Chef-Version", "12.4.1") + .put("X-Ops-Content-Hash", hashedBody) + .put("X-Ops-Sign", "version=1.0") + .put("X-Ops-Authorization-1", "i+HGCso703727yd2ZQWMZIIpGKgTzm41fA31LIExNxEf9mOUMcpesIHjH/Wr") + .put("X-Ops-Authorization-2", "QEvsX/Gy1ay9KsUtqhy9GA6PB8UfDeMNoVUisqR4HQW+S6IOfvqBjW+2afzE") + .put("X-Ops-Authorization-3", "RdRReB/TJIF3s6ZC8vNpbEdY9kHmwiDglhxmS8X2FS+ArSh/DK/i7MqBbjux") + .put("X-Ops-Authorization-4", "49iiOlRVG7aTr/FA115hlBYP9CYCIQWKIBUOK3JyV9fXNdVqc9R0r1XdjxUl") + .put("X-Ops-Authorization-5", "EDGw6tuE8YW8mH5wkgHCjKpXG3WjmWt2X6kUrdIu44qCBK2N3sZziSub2fJA") + .put("X-Ops-Authorization-6", "hPBuOhjiYDZuFUqC99lCryM0Hf5RMw1uTlkYsBEZmA=="); + + return builder.build(); + } + +} \ No newline at end of file diff --git a/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/chefclient/impl/FormattedTimestampTest.java b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/chefclient/impl/FormattedTimestampTest.java new file mode 100644 index 000000000..8d5f10f19 --- /dev/null +++ b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/chefclient/impl/FormattedTimestampTest.java @@ -0,0 +1,42 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2018 Nokia. 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.ccsdk.sli.adaptors.chef.chefclient.impl; + +import java.util.Date; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class FormattedTimestampTest { + + @Test + public void format_shouldFormatGivenDate_withCorrectTimezoneSet() { + // GIVEN + String expectedFormattedDate = "1970-01-15T06:56:07Z"; + + // WHEN + String formattedDateWithTimezone = new org.onap.ccsdk.sli.adaptors.chef.chefclient.impl.FormattedTimestamp().format(new Date(1234567890)); + + // THEN + assertEquals(expectedFormattedDate, formattedDateWithTimezone); + } + +} \ No newline at end of file diff --git a/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplDataRetrieverTest.java b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplDataRetrieverTest.java new file mode 100644 index 000000000..16f0e0174 --- /dev/null +++ b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplDataRetrieverTest.java @@ -0,0 +1,83 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2018 Nokia. 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.ccsdk.sli.adaptors.chef.impl; + +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import org.assertj.core.api.Assertions; +import org.junit.Test; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; + +public class ChefAdaptorImplDataRetrieverTest { + + private static final String KEY_PARAM = "key"; + private static final String DG_CONTEXT_PARAM = "dgContext"; + private static final String ALL_CONFIG_PARAM = "allConfig"; + private static final String KEY_VALUE = "keyValue"; + private static final String DG_CONTEXT_VALUE = "contextValue"; + + @Test + public void retrieveData_shouldSetContextData_withExtractedJsonString() { + // GIVEN + Map params = givenParamMapWithJson("{" + KEY_VALUE + ":testValue}"); + SvcLogicContext svcLogicContext = new SvcLogicContext(); + + // WHEN + new org.onap.ccsdk.sli.adaptors.chef.impl.ChefAdaptorFactory().create().retrieveData(params, svcLogicContext); + + // THEN + Assertions.assertThat(svcLogicContext.getAttribute(DG_CONTEXT_VALUE)).isEqualTo("testValue"); + } + + @Test + public void retrieveData_shouldSetContextData_withExtractedJsonObject() { + // GIVEN + Map params = givenParamMapWithJson("{" + KEY_VALUE + ": {param : testValue} }"); + SvcLogicContext svcLogicContext = new SvcLogicContext(); + + // WHEN + new org.onap.ccsdk.sli.adaptors.chef.impl.ChefAdaptorFactory().create().retrieveData(params, svcLogicContext); + + // THEN + Assertions.assertThat(svcLogicContext.getAttribute(DG_CONTEXT_VALUE)).isEqualTo("{\"param\":\"testValue\"}"); + } + + @Test + public void retrieveData_shouldSetContextData_withExtractedJsonArray() { + // GIVEN + Map params = givenParamMapWithJson("{" + KEY_VALUE + ": [val1, val2, val3] }"); + SvcLogicContext svcLogicContext = new SvcLogicContext(); + + // WHEN + new org.onap.ccsdk.sli.adaptors.chef.impl.ChefAdaptorFactory().create().retrieveData(params, svcLogicContext); + + // THEN + Assertions.assertThat(svcLogicContext.getAttribute(DG_CONTEXT_VALUE)).isEqualTo("[\"val1\",\"val2\",\"val3\"]"); + } + + private Map givenParamMapWithJson(String json) { + return ImmutableMap + .of(KEY_PARAM, KEY_VALUE, + DG_CONTEXT_PARAM, DG_CONTEXT_VALUE, + ALL_CONFIG_PARAM, json); + } + +} \ No newline at end of file diff --git a/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplHttpMethodTest.java b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplHttpMethodTest.java new file mode 100644 index 000000000..283b51ebb --- /dev/null +++ b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplHttpMethodTest.java @@ -0,0 +1,185 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2018 Nokia. 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.ccsdk.sli.adaptors.chef.impl; + +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Supplier; +import org.apache.http.HttpStatus; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.onap.ccsdk.sli.adaptors.chef.ChefAdaptor; +import org.onap.ccsdk.sli.adaptors.chef.chefclient.ChefApiClientFactory; +import org.onap.ccsdk.sli.adaptors.chef.chefclient.api.ChefApiClient; +import org.onap.ccsdk.sli.adaptors.chef.chefclient.api.ChefResponse; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.verifyZeroInteractions; + +@RunWith(MockitoJUnitRunner.class) +public class ChefAdaptorImplHttpMethodTest { + + private static final String CLIENT_PRIVATE_KEY_PATH = "/opt/onap/appc/chef/localhost/onap/testclient.pem"; + private static final String RESULT_CODE_ATTR_KEY = "chefServerResult.code"; + private static final String RESULT_MESSAGE_ATTR_KEY = "chefServerResult.message"; + private static final String EXPECTED_RESPONSE_MSG = "chefResponseMessage"; + private static final String ACTION_PARAM = "action"; + private static final String REQUEST_BODY_DATA = "requestBodyData"; + private static final Map PARAMS = ImmutableMap + .of("username", "testclient", + "serverAddress", "localhost", + "organizations", "onap", + "chefAction", ACTION_PARAM, + "chefRequestBody", REQUEST_BODY_DATA); + @Mock + private org.onap.ccsdk.sli.adaptors.chef.impl.PrivateKeyChecker privateKeyChecker; + @Mock + private ChefApiClientFactory chefApiClientFactory; + @Mock + private ChefApiClient chefApiClient; + + @InjectMocks + private org.onap.ccsdk.sli.adaptors.chef.impl.ChefAdaptorFactory chefAdaptorFactory; + private SvcLogicContext svcLogicContext; + + @Before + public void setUp() { + svcLogicContext = new SvcLogicContext(); + } + + @Test + public void chefGet_shouldExecuteHttpClient_andSetChefResponseInContext_whenPrivateKeyFileExists() { + assertSuccessfulChefHttpCallFor(() -> chefApiClient.get(ACTION_PARAM), this :: chefGet); + } + + @Test + public void chefGet_shouldNotExecuteHttpClient_andSetErrorResponseInContext_whenPrivateKeyFileDoesNotExist() { + assertNoChefCallOccurFor(this :: chefGet); + } + + @Test + public void chefDelete_shouldExecuteHttpClient_andSetChefResponseInContext_whenPrivateKeyFileExists() { + assertSuccessfulChefHttpCallFor(() -> chefApiClient.delete(ACTION_PARAM), this :: chefDelete); + } + + @Test + public void chefDelete_shouldNotExecuteHttpClient_andSetErrorResponseInContext_whenPrivateKeyFileDoesNotExist() { + assertNoChefCallOccurFor(this :: chefDelete); + } + + @Test + public void chefPut_shouldExecuteHttpClient_andSetChefResponseInContext_whenPrivateKeyFileExists() { + assertSuccessfulChefHttpCallFor(() -> chefApiClient.put(ACTION_PARAM, REQUEST_BODY_DATA), this :: chefPut); + } + + @Test + public void chefPut_shouldNotExecuteHttpClient_andSetErrorResponseInContext_whenPrivateKeyFileDoesNotExist() { + assertNoChefCallOccurFor(this :: chefPut); + } + + @Test + public void chefPost_shouldExecuteHttpClient_andSetChefResponseInContext_whenPrivateKeyFileExists() { + assertSuccessfulChefHttpCallFor(() -> chefApiClient.post(ACTION_PARAM, REQUEST_BODY_DATA), this :: chefPost); + } + + @Test + public void chefPost_shouldNotExecuteHttpClient_andSetErrorResponseInContext_whenPrivateKeyFileDoesNotExist() { + assertNoChefCallOccurFor(this :: chefPost); + } + + public void assertSuccessfulChefHttpCallFor(Supplier responseSupplier, + Consumer chefAdaptorCall) { + // GIVEN + given(privateKeyChecker.doesExist(CLIENT_PRIVATE_KEY_PATH)).willReturn(true); + given(chefApiClientFactory.create("https://localhost/organizations/onap", + "onap", + "testclient", + CLIENT_PRIVATE_KEY_PATH)).willReturn(chefApiClient); + given(responseSupplier.get()).willReturn(ChefResponse.create(HttpStatus.SC_OK, EXPECTED_RESPONSE_MSG)); + + // WHEN + chefAdaptorCall.accept(chefAdaptorFactory.create()); + + // THEN + assertTrue(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_OK)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(EXPECTED_RESPONSE_MSG); + } + + public void assertNoChefCallOccurFor(Consumer chefAdaptorCall) { + // GIVEN + given(privateKeyChecker.doesExist(CLIENT_PRIVATE_KEY_PATH)).willReturn(false); + + // WHEN + chefAdaptorCall.accept(chefAdaptorFactory.create()); + + // THEN + verifyZeroInteractions(chefApiClient); + assertTrue(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)) + .isEqualTo(Integer.toString(HttpStatus.SC_INTERNAL_SERVER_ERROR)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo( + "Cannot find the private key in the APPC file system, please load the private key to " + + CLIENT_PRIVATE_KEY_PATH); + } + + public void chefGet(ChefAdaptor chefAdaptor) { + try { + chefAdaptor.chefGet(PARAMS, svcLogicContext); + } catch (SvcLogicException e) { + e.printStackTrace(); + } + } + + public void chefDelete(ChefAdaptor chefAdaptor) { + try { + chefAdaptor.chefDelete(PARAMS, svcLogicContext); + } catch (SvcLogicException e) { + e.printStackTrace(); + } + } + + public void chefPost(ChefAdaptor chefAdaptor) { + try { + chefAdaptor.chefPost(PARAMS, svcLogicContext); + } catch (SvcLogicException e) { + e.printStackTrace(); + } + } + + public void chefPut(ChefAdaptor chefAdaptor) { + try { + chefAdaptor.chefPut(PARAMS, svcLogicContext); + } catch (SvcLogicException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplJobPusherTest.java b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplJobPusherTest.java new file mode 100644 index 000000000..4bf5a2280 --- /dev/null +++ b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplJobPusherTest.java @@ -0,0 +1,269 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2018 Nokia. All rights reserved. + * Copyright (C) 2018 AT&T 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.ccsdk.sli.adaptors.chef.impl; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; +import java.util.Map; +import java.util.Map.Entry; +import org.apache.http.HttpStatus; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.onap.ccsdk.sli.adaptors.chef.chefclient.ChefApiClientFactory; +import org.onap.ccsdk.sli.adaptors.chef.chefclient.api.ChefApiClient; +import org.onap.ccsdk.sli.adaptors.chef.chefclient.api.ChefResponse; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; + +import static com.google.common.collect.Maps.immutableEntry; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.BDDMockito.given; + +@RunWith(MockitoJUnitRunner.class) +public class ChefAdaptorImplJobPusherTest { + + private static final String CLIENT_PRIVATE_KEY_PATH = "/opt/onap/appc/chef/localhost/onap/testclient.pem"; + private static final String RESULT_CODE_ATTR_KEY = "chefServerResult.code"; + private static final String RESULT_MESSAGE_ATTR_KEY = "chefServerResult.message"; + private static final String EXPECTED_RESPONSE_MSG = "jobs/{666}/"; + + private static final String USERNAME = "testclient"; + private static final String SERVER_ADDRESS = "localhost"; + private static final String ORGANIZATIONS = "onap"; + private static final String ACTION_PARAM = "/pushy/jobs"; + private static final String REQUEST_BODY_DATA = "requestBodyData"; + private static final String JOB_ID = "jobID"; + + @Mock + private org.onap.ccsdk.sli.adaptors.chef.impl.PrivateKeyChecker privateKeyChecker; + + @Mock + private ChefApiClientFactory chefApiClientFactory; + + @Mock + private ChefApiClient chefApiClient; + + @InjectMocks + private org.onap.ccsdk.sli.adaptors.chef.impl.ChefAdaptorFactory chefAdaptorFactory; + private SvcLogicContext svcLogicContext; + + @Before + public void setUp() { + svcLogicContext = new SvcLogicContext(); + } + + @Test + public void pushJob_shouldSuccessfullyMakePostCall_andUpdateSvcLogicContext_whenReturnedStatusIsDifferentThan_201() + throws SvcLogicException { + assertSuccessfulPostCallForStatus(HttpStatus.SC_OK); + assertThat(svcLogicContext.getAttribute(JOB_ID)).isBlank(); + } + + @Test + public void pushJob_shouldSuccessfullyMakePostCall_andUpdateSvcLogicContext_withReturnedStatusIs_201() + throws SvcLogicException { + assertSuccessfulPostCallForStatus(HttpStatus.SC_CREATED); + assertThat(svcLogicContext.getAttribute(JOB_ID)).isEqualTo("666"); + } + + @SuppressWarnings("unchecked") + public void assertSuccessfulPostCallForStatus(int expectedHttpStatus) throws SvcLogicException { + // GIVEN + Map params = givenInputParams( + immutableEntry("chefAction", ACTION_PARAM), + immutableEntry("pushRequest", REQUEST_BODY_DATA)); + given(chefApiClientFactory.create("https://localhost/organizations/onap", ORGANIZATIONS, USERNAME, + CLIENT_PRIVATE_KEY_PATH)).willReturn(chefApiClient); + given(chefApiClient.post(ACTION_PARAM, REQUEST_BODY_DATA)) + .willReturn(ChefResponse.create(expectedHttpStatus, EXPECTED_RESPONSE_MSG)); + + // WHEN + chefAdaptorFactory.create().pushJob(params, svcLogicContext); + + // THEN + assertTrue(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(expectedHttpStatus)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(EXPECTED_RESPONSE_MSG); + } + + @SuppressWarnings("unchecked") + @Test + public void pushJob_shouldHandleAllOccurringExceptions_duringMethodExecution() { + // GIVEN + Map params = givenInputParams(); + String expectedErrorMessage = "Something went wrong"; + given(chefApiClientFactory.create("https://localhost/organizations/onap", ORGANIZATIONS, USERNAME, + CLIENT_PRIVATE_KEY_PATH)).willThrow(new NullPointerException(expectedErrorMessage)); + + // WHEN // THEN + assertThatExceptionOfType(SvcLogicException.class) + .isThrownBy(() -> chefAdaptorFactory.create().pushJob(params, svcLogicContext)) + .withMessage("Chef Adaptor error:" + expectedErrorMessage); + + assertFalse(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_UNAUTHORIZED)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(expectedErrorMessage); + assertThat(svcLogicContext.getAttribute(JOB_ID)).isBlank(); + } + + @SuppressWarnings("unchecked") + @Test + public void checkPushJob_shouldSetFailStatusAndMsgInContext_andThrowException_whenRetryTimesParamIsMissing() { + // GIVEN + Map params = givenInputParams( + immutableEntry("retryInterval", "1"), + immutableEntry("jobid", "666")); + + // WHEN // THEN + assertIfInputParamsAreValidated(params); + } + + @SuppressWarnings("unchecked") + @Test + public void checkPushJob_shouldSetFailStatusAndMsgInContext_andThrowException_whenRetryIntervalParamIsMissing() { + // GIVEN + Map params = givenInputParams( + immutableEntry("retryTimes", "4"), + immutableEntry("jobid", "666")); + + // WHEN // THEN + assertIfInputParamsAreValidated(params); + } + + @SuppressWarnings("unchecked") + @Test + public void checkPushJob_shouldSetFailStatusAndMsgInContext_andThrowException_whenJobIdParamIsMissing() { + // GIVEN + Map params = givenInputParams( + immutableEntry("retryTimes", "4"), + immutableEntry("retryInterval", "1")); + assertIfInputParamsAreValidated(params); + } + + public void assertIfInputParamsAreValidated(Map params) { + // WHEN // THEN + assertThatExceptionOfType(SvcLogicException.class) + .isThrownBy(() -> chefAdaptorFactory.create().checkPushJob(params, svcLogicContext)) + .withMessage("Chef Adaptor error:" + "Missing Mandatory param(s) retryTimes , retryInterval "); + + assertFalse(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_UNAUTHORIZED)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo("Missing Mandatory param(s) retryTimes , retryInterval "); + } + + @Test + public void checkPushJob_shouldCheckJobStatusOnlyOnce_withoutAdditionalRetries_whenFirstReturnedJobStatusIs_Complete() + throws SvcLogicException { + String expectedHttpStatus = Integer.toString(HttpStatus.SC_OK); + //String expectedMessage = "{status:complete}"; + String expectedMessage = "{\"nodes\":{\"succeeded\":[\"NODE1.atttest.com\"]},\"id\":\"26d\",\"command\":\"chef-client\",\"status\":\"complete\"} "; + assertCheckJobStatusFor( + expectedHttpStatus, + expectedMessage, + ChefResponse.create(HttpStatus.SC_OK, expectedMessage), + ChefResponse.create(HttpStatus.SC_OK, "{status:running}")); + } + + @Test + public void checkPushJob_withFailedNode_whenFirstReturnedJobStatusIs_Complete() + throws SvcLogicException { + String expectedHttpStatus = "401"; + String message = "{\"nodes\":{\"failed\":[\"NODE1.atttest.com\"]},\"id\":\"26d\",\"command\":\"chef-client\",\"status\":\"complete\"} "; + String expectedMessage = "PushJob Status Complete but check failed nodes in the message :" + message; + + assertCheckJobStatusFor( + expectedHttpStatus, + expectedMessage, + ChefResponse.create(HttpStatus.SC_OK, message)); + } + + @Test + public void checkPushJob_shouldCheckJobStatusExpectedNumberOf_ThreeRetryTimes_whenEachReturnedStatusIs_Running() + throws SvcLogicException { + String expectedHttpStatus = Integer.toString(HttpStatus.SC_ACCEPTED); + String expectedMessage = "chef client runtime out"; + + assertCheckJobStatusFor( + expectedHttpStatus, + expectedMessage, + ChefResponse.create(HttpStatus.SC_OK, "{status:running}"), + ChefResponse.create(HttpStatus.SC_OK, "{status:running}"), + ChefResponse.create(HttpStatus.SC_OK, "{status:running}")); + } + + @Test + public void checkPushJob_shouldCheckJobStatusOnlyOnce_withoutAdditionalRetries_whenFirstReturnedJobStatusIsNot_Running() + throws SvcLogicException { + + String expectedHttpStatus = Integer.toString(HttpStatus.SC_INTERNAL_SERVER_ERROR); + String expectedMessage = "{status:unexpectedStatus}"; + + assertCheckJobStatusFor( + expectedHttpStatus, + expectedMessage, + ChefResponse.create(HttpStatus.SC_OK, "{status:unexpectedStatus}"), + ChefResponse.create(HttpStatus.SC_OK, "{status:running}")); + } + + @SuppressWarnings("unchecked") + public void assertCheckJobStatusFor(String expectedHttpStatus, String expectedMessage, ChefResponse firstResponse, + ChefResponse... nextResponses) throws SvcLogicException { + + // GIVEN + Map params = givenInputParams( + immutableEntry("jobid", "666"), + immutableEntry("retryTimes", "3"), + immutableEntry("retryInterval", "1")); + given(chefApiClientFactory.create("https://localhost/organizations/onap", ORGANIZATIONS, USERNAME, + CLIENT_PRIVATE_KEY_PATH)).willReturn(chefApiClient); + given(chefApiClient.get(ACTION_PARAM + "/" + params.get("jobid"))) + .willReturn(firstResponse, nextResponses); + + // WHEN + chefAdaptorFactory.create().checkPushJob(params, svcLogicContext); + + // THEN + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(expectedHttpStatus); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(expectedMessage); + } + + @SuppressWarnings("unchecked") + private Map givenInputParams(Entry... entries) { + Builder paramsBuilder = ImmutableMap.builder(); + paramsBuilder.put("username", USERNAME) + .put("serverAddress", SERVER_ADDRESS) + .put("organizations", ORGANIZATIONS); + + for (Entry entry : entries) { + paramsBuilder.put(entry); + } + return paramsBuilder.build(); + } + +} diff --git a/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplTest.java b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplTest.java new file mode 100644 index 000000000..1fa6bc168 --- /dev/null +++ b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplTest.java @@ -0,0 +1,197 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2018 Nokia. All rights reserved. + * Copyright (C) 2018 AT&T 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.ccsdk.sli.adaptors.chef.impl; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import java.util.Collections; +import java.util.Map; +import org.apache.http.HttpStatus; +import org.json.JSONObject; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.onap.ccsdk.sli.adaptors.chef.chefclient.ChefApiClientFactory; +import org.onap.ccsdk.sli.adaptors.chef.chefclient.api.ChefResponse; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.Answers.RETURNS_DEEP_STUBS; +import static org.mockito.BDDMockito.given; + +@RunWith(MockitoJUnitRunner.class) +public class ChefAdaptorImplTest { + + private static final String EXPECTED_NODE_OBJECT_ATTR_NAME = "chef.nodeObject"; + private static final String RESULT_CODE_ATTR_KEY = "chefClientResult.code"; + private static final String RESULT_MESSAGE_ATTR_KEY = "chefClientResult.message"; + private static final String EXPECTED_RESPONSE_MSG = "chefResponseMessage"; + private static final String IP_PARAM = "ip"; + private static final String ENDPOINT_IP = "http://127.0.0.1"; + private static final String CHEF_AGENT_CODE_KEY = "chefAgent.code"; + private static final String CHEF_AGENT_MESSAGE_KEY = "chefAgent.message"; + + @Mock(answer = RETURNS_DEEP_STUBS) + private ChefApiClientFactory chefApiClientFactory; + @Mock + private org.onap.ccsdk.sli.adaptors.chef.impl.PrivateKeyChecker privateKeyChecker; + + @InjectMocks + private org.onap.ccsdk.sli.adaptors.chef.impl.ChefAdaptorFactory chefAdaptorFactory; + + @Test + public void nodeObjectBuilder_shouldBuildJsonNodeObject_forPassedParams_andAddToSvcLogicContext() { + // GIVEN + Map params = givenInputParams(); + SvcLogicContext svcLogicContext = new SvcLogicContext(); + + // WHEN + chefAdaptorFactory.create().nodeObejctBuilder(params, svcLogicContext); + + // THEN + assertThat(resultJson(svcLogicContext)).isEqualTo(expectedJson()); + } + + private String resultJson(SvcLogicContext svcLogicContext) { + String resultJsonString = svcLogicContext.getAttribute(EXPECTED_NODE_OBJECT_ATTR_NAME); + return new JSONObject(resultJsonString).toString(); + } + + private Map givenInputParams() { + return ImmutableMap.builder() + .put("nodeobject.name", "testNodeName") + .put("nodeobject.normal", "val:normal") + .put("nodeobject.overrides", "val:override") + .put("nodeobject.defaults", "val:default") + .put("nodeobject.run_list", "val1,val2,val3") + .put("nodeobject.chef_environment", "testChefEnvVal") + .build(); + } + + private String expectedJson() { + JSONObject expectedJson = new JSONObject(); + expectedJson.put("json_class", "Chef::Node"); + expectedJson.put("chef_type", "node"); + expectedJson.put("automatic", Collections.emptyMap()); + expectedJson.put("name", "testNodeName"); + expectedJson.put("normal", ImmutableMap.of("val", "normal")); + expectedJson.put("override", ImmutableMap.of("val", "override")); + expectedJson.put("default", ImmutableMap.of("val", "default")); + expectedJson.put("run_list", ImmutableList.of("val1", "val2", "val3")); + expectedJson.put("chef_environment", "testChefEnvVal"); + return expectedJson.toString(); + } + + @Test + public void combineStrings_shouldConcatenateTwoParamStrings_andSetThemInSvcContext() { + // GIVEN + Map params = ImmutableMap + .of("dgContext", "contextValue", "String1", "paramString1", "String2", "paramString2"); + SvcLogicContext svcLogicContext = new SvcLogicContext(); + + // WHEN + chefAdaptorFactory.create().combineStrings(params, svcLogicContext); + + // THEN + assertThat(svcLogicContext.getAttribute("contextValue")).isEqualTo("paramString1paramString2"); + } + + @Test + public void trigger_shouldTriggerTargetEndpoint_andUpdateSvclogicContext() { + // GIVEN + Map params = ImmutableMap.of(IP_PARAM, ENDPOINT_IP); + SvcLogicContext svcLogicContext = new SvcLogicContext(); + given(chefApiClientFactory.create(ENDPOINT_IP, "").get("")) + .willReturn(ChefResponse.create(HttpStatus.SC_OK, EXPECTED_RESPONSE_MSG)); + + // WHEN + chefAdaptorFactory.create().trigger(params, svcLogicContext); + + // THEN + assertTrue(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(CHEF_AGENT_CODE_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_OK)); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_OK)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(EXPECTED_RESPONSE_MSG); + } + + @Test + public void trigger_shouldUpdateSvcLogicContext_withFailStatusAndMsg_whenExceptionOccurs() { + // GIVEN + Map params = ImmutableMap.of(IP_PARAM, ENDPOINT_IP); + SvcLogicContext svcLogicContext = new SvcLogicContext(); + given(chefApiClientFactory.create(ENDPOINT_IP, "")).willThrow(new RuntimeException()); + + // WHEN + chefAdaptorFactory.create().trigger(params, svcLogicContext); + + // THEN + assertThat(svcLogicContext.getAttribute(CHEF_AGENT_CODE_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_INTERNAL_SERVER_ERROR)); + assertThat(svcLogicContext.getAttribute(CHEF_AGENT_MESSAGE_KEY)).isEqualTo(new RuntimeException().toString()); + } + + @Test + public void chefInfo_shouldUpdateSvcLogicContext_withFailStatusAndMsg_andThrowException_whenUsernameParamIsMissing() { + Map params = ImmutableMap.of( + "serverAddress", "http://chefAddress", + "organizations", "onap"); + checkIfInputParamsAreValidated(params); + } + + @Test + public void chefInfo_shouldUpdateSvcLogicContext_withFailStatusAndMsg_andThrowException_whenServerAddressParamIsMissing() { + Map params = ImmutableMap.of( + "username", "TestUsername", + "organizations", "onap"); + checkIfInputParamsAreValidated(params); + } + + @Test + public void chefInfo_shouldUpdateSvcLogicContext_withFailStatusAndMsg_andThrowException_whenOrganizationsParamIsMissing() { + Map params = ImmutableMap.of( + "username", "TestUsername", + "serverAddress", "http://chefAddress"); + checkIfInputParamsAreValidated(params); + } + + private void checkIfInputParamsAreValidated(Map params) { + // GIVEN + String expectedErrorMsg = "Missing mandatory param(s) such as username, serverAddress, organizations"; + SvcLogicContext svcLogicContext = new SvcLogicContext(); + + // WHEN// THEN + assertThatExceptionOfType(SvcLogicException.class) + .isThrownBy(() -> chefAdaptorFactory.create().chefGet(params, svcLogicContext)) + .withMessage("Chef Adaptor error:" + + expectedErrorMsg); + + assertFalse(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute("chefServerResult.code")).isEqualTo(Integer.toString(HttpStatus.SC_UNAUTHORIZED)); + assertThat(svcLogicContext.getAttribute("chefServerResult.message")).isEqualTo(expectedErrorMsg); + } + +} diff --git a/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplVNFCOperationsTest.java b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplVNFCOperationsTest.java new file mode 100644 index 000000000..253cfcc9f --- /dev/null +++ b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/ChefAdaptorImplVNFCOperationsTest.java @@ -0,0 +1,452 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2018 Nokia. All rights reserved. + * Copyright (C) 2018 AT&T 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.ccsdk.sli.adaptors.chef.impl; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; +import java.util.Map; +import java.util.Map.Entry; +import org.apache.http.HttpStatus; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.onap.ccsdk.sli.adaptors.chef.chefclient.ChefApiClientFactory; +import org.onap.ccsdk.sli.adaptors.chef.chefclient.api.ChefApiClient; +import org.onap.ccsdk.sli.adaptors.chef.chefclient.api.ChefResponse; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; + +import static com.google.common.collect.Maps.immutableEntry; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.mockito.BDDMockito.given; + +@RunWith(MockitoJUnitRunner.class) +public class ChefAdaptorImplVNFCOperationsTest { + + private static final String CHEF_END_POINT = "https://localhost/organizations/onap"; + private static final String USERNAME = "testclient"; + private static final String ORGANIZATIONS = "onap"; + private static final String SERVER_ADDRESS = "localhost"; + private static final String CLIENT_PRIVATE_KEY_PATH = "/opt/onap/appc/chef/localhost/onap/testclient.pem"; + private static final String RESULT_CODE_ATTR_KEY = "chefServerResult.code"; + private static final String RESULT_MESSAGE_ATTR_KEY = "chefServerResult.message"; + private static final String FAILURE_STATUS = "failure"; + private static final String SUCCESS_STATUS = "success"; + private static final String CHEF_ADAPTOR_ERROR_PREFIX = "Chef Adaptor error:"; + private static final String ENV_PARAM_KEY = "Environment"; + private static final String ENV_JSON_VALUE = "{name:envName}"; + + @Mock + private org.onap.ccsdk.sli.adaptors.chef.impl.PrivateKeyChecker privateKeyChecker; + + @Mock + private ChefApiClientFactory chefApiClientFactory; + + @Mock + private ChefApiClient chefApiClient; + + @InjectMocks + private org.onap.ccsdk.sli.adaptors.chef.impl.ChefAdaptorFactory chefAdaptorFactory; + private SvcLogicContext svcLogicContext; + + @Before + public void setUp() { + svcLogicContext = new SvcLogicContext(); + } + + @SuppressWarnings("unchecked") + @Test + public void vnfcEnvironment_shouldSkipEnvironmentCreation_whenEnvParamIsEmpty() throws SvcLogicException { + // GIVEN + Map params = givenInputParams(immutableEntry(ENV_PARAM_KEY, "")); + + // WHEN + chefAdaptorFactory.create().vnfcEnvironment(params, svcLogicContext); + + // THEN + assertTrue(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_OK)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo("Skip Environment block "); + } + + @SuppressWarnings("unchecked") + @Test + public void vnfcEnvironment_shouldCreateNewEnvironment_forEnvParam_whenRequestedEnvDoesNotExist() + throws SvcLogicException { + // GIVEN + String expectedErrorMessage = "New Environment Created"; + Map params = givenInputParams(immutableEntry(ENV_PARAM_KEY, ENV_JSON_VALUE)); + given(privateKeyChecker.doesExist(CLIENT_PRIVATE_KEY_PATH)).willReturn(true); + given(chefApiClientFactory.create(CHEF_END_POINT, ORGANIZATIONS, USERNAME, + CLIENT_PRIVATE_KEY_PATH)).willReturn(chefApiClient); + given(chefApiClient.put("/environments/" + "envName", ENV_JSON_VALUE)) + .willReturn(ChefResponse.create(HttpStatus.SC_NOT_FOUND, "")); + given(chefApiClient.post("/environments", ENV_JSON_VALUE)) + .willReturn(ChefResponse.create(HttpStatus.SC_CREATED, expectedErrorMessage)); + + // WHEN + chefAdaptorFactory.create().vnfcEnvironment(params, svcLogicContext); + + // THEN + assertTrue(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_CREATED)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(expectedErrorMessage); + } + + @SuppressWarnings("unchecked") + @Test + public void vnfcEnvironment_shouldNotAttemptEnvCreation_andThrowException_whenPrivateKeyCheckFails() { + // GIVEN + String expectedErrorMsg = "Cannot find the private key in the APPC file system, please load the private key to "; + Map params = givenInputParams(immutableEntry(ENV_PARAM_KEY, ENV_JSON_VALUE)); + given(privateKeyChecker.doesExist(CLIENT_PRIVATE_KEY_PATH)).willReturn(false); + + // WHEN // THEN + assertThatExceptionOfType(SvcLogicException.class) + .isThrownBy(() -> chefAdaptorFactory.create().vnfcEnvironment(params, svcLogicContext)) + .withMessage(CHEF_ADAPTOR_ERROR_PREFIX + expectedErrorMsg + CLIENT_PRIVATE_KEY_PATH); + + assertFalse(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_INTERNAL_SERVER_ERROR)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(expectedErrorMsg + CLIENT_PRIVATE_KEY_PATH); + } + + @SuppressWarnings("unchecked") + @Test + public void vnfcEnvironment_shouldNotAttemptEnvCreation_andHandleJSONException_whenJSONParamsAreMalformed() { + // GIVEN + String expectedErrorMessage = "Error posting request due to invalid JSON block: "; + Map params = givenInputParams(immutableEntry(ENV_PARAM_KEY, "MALFORMED_JSON")); + given(privateKeyChecker.doesExist(CLIENT_PRIVATE_KEY_PATH)).willReturn(true); + + // WHEN // THEN + assertThatExceptionOfType(SvcLogicException.class) + .isThrownBy(() -> chefAdaptorFactory.create().vnfcEnvironment(params, svcLogicContext)) + .withMessageStartingWith(CHEF_ADAPTOR_ERROR_PREFIX + expectedErrorMessage); + + assertFalse(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_UNAUTHORIZED)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).startsWith(expectedErrorMessage); + } + + @SuppressWarnings("unchecked") + @Test + public void vnfcEnvironment_shouldNotAttemptEnvCreation_andHandleException_whenExceptionOccursDuringExecution() { + // GIVEN + String expectedErrorMessage = "Error posting request: "; + Map params = givenInputParams(immutableEntry(ENV_PARAM_KEY, ENV_JSON_VALUE)); + given(privateKeyChecker.doesExist(CLIENT_PRIVATE_KEY_PATH)).willReturn(true); + given(chefApiClientFactory.create(CHEF_END_POINT, ORGANIZATIONS, USERNAME, + CLIENT_PRIVATE_KEY_PATH)).willThrow(new NullPointerException("Null value encountered")); + + // WHEN // THEN + assertThatExceptionOfType(SvcLogicException.class) + .isThrownBy(() -> chefAdaptorFactory.create().vnfcEnvironment(params, svcLogicContext)) + .withMessage(CHEF_ADAPTOR_ERROR_PREFIX + expectedErrorMessage + "vnfcEnvironmentNull value encountered"); + + assertFalse(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_UNAUTHORIZED)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).startsWith(expectedErrorMessage); + } + + @Test + public void vnfcNodeObjects_shouldUpdateNodeObjects_andSetCodeAndMessageFromLastSuccessfulResponseInSvcLogicContext() + throws SvcLogicException { + // GIVEN + ChefResponse firstNodeResponse = ChefResponse.create(HttpStatus.SC_OK, "firstMessage"); + ChefResponse secondNodeResponse = ChefResponse.create(HttpStatus.SC_OK, "secondMessage"); + int expectedHttpStatus = HttpStatus.SC_OK; + String expectedMessage = "secondMessage"; + + assertNodeObjectsAreUpdatedFor(firstNodeResponse, secondNodeResponse, expectedHttpStatus, expectedMessage); + } + + @Test + public void vnfcNodeObjects_shouldStopProcessingNodeObjectUpdates_whenFirstReturnedResponseIsOtherThan_200() + throws SvcLogicException { + ChefResponse firstNodeResponse = ChefResponse.create(HttpStatus.SC_ACCEPTED, "firstMessage"); + ChefResponse secondNodeResponse = ChefResponse.create(HttpStatus.SC_OK, "secondMessage"); + int expectedHttpStatus = HttpStatus.SC_ACCEPTED; + String expectedMessage = "firstMessage"; + + assertNodeObjectsAreUpdatedFor(firstNodeResponse, secondNodeResponse, expectedHttpStatus, expectedMessage); + } + + @SuppressWarnings("unchecked") + public void assertNodeObjectsAreUpdatedFor(ChefResponse firstNodeResponse, ChefResponse secondNodeResponse, + int expectedHttpStatus, String expectedMessage) throws SvcLogicException { + // GIVEN + Map params = givenInputParams( + immutableEntry("NodeList", "[\"test1.vnf_b.onap.com\", \"test2.vnf_b.onap.com\"]"), + immutableEntry("Node", "{name:nodeName}")); + + given(privateKeyChecker.doesExist(CLIENT_PRIVATE_KEY_PATH)).willReturn(true); + given(chefApiClientFactory.create(CHEF_END_POINT, ORGANIZATIONS, USERNAME, + CLIENT_PRIVATE_KEY_PATH)).willReturn(chefApiClient); + given(chefApiClient.put("/nodes/" + "test1.vnf_b.onap.com", "{\"name\":\"test1.vnf_b.onap.com\"}")) + .willReturn(firstNodeResponse); + given(chefApiClient.put("/nodes/" + "test2.vnf_b.onap.com", "{\"name\":\"test2.vnf_b.onap.com\"}")) + .willReturn(secondNodeResponse); + + // WHEN + chefAdaptorFactory.create().vnfcNodeobjects(params, svcLogicContext); + + // THEN + assertTrue(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(expectedHttpStatus)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(expectedMessage); + } + + @SuppressWarnings("unchecked") + @Test + public void vnfcNodeObjects_shouldThrowSvcLogicException_whenNodeListParamIsEmpty() { + Map params = givenInputParams( + immutableEntry("NodeList", ""), + immutableEntry("Node", "{name:nodeName}")); + checkMissingParamsAreValidated(params); + } + + @SuppressWarnings("unchecked") + @Test + public void vnfcNodeObjects_shouldThrowSvcLogicException_whenNodeParamIsEmpty() { + Map params = givenInputParams( + immutableEntry("NodeList", "[\"test1.vnf_b.onap.com\", \"test2.vnf_b.onap.com\"]"), + immutableEntry("Node", "")); + checkMissingParamsAreValidated(params); + } + + public void checkMissingParamsAreValidated(Map params) { + // GIVEN + String expectedErrorMsg = "vnfcNodeobjectsMissing Mandatory param(s) Node , NodeList "; + + // WHEN // THEN + assertThatExceptionOfType(SvcLogicException.class) + .isThrownBy(() -> chefAdaptorFactory.create().vnfcNodeobjects(params, svcLogicContext)) + .withMessage(CHEF_ADAPTOR_ERROR_PREFIX + "Error posting request: " + expectedErrorMsg); + + assertFalse(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_UNAUTHORIZED)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo("Error posting request: " + expectedErrorMsg); + } + + @SuppressWarnings("unchecked") + @Test + public void vnfcNodeObjects_shouldNotUpdateNodes_andHandleJSONException_whenJSONParamsAreMalformed() { + // GIVEN + Map params = givenInputParams( + immutableEntry("NodeList", "[\"test1.vnf_b.onap.com\", \"test2.vnf_b.onap.com\"]"), + immutableEntry("Node", "MALFORMED_JSON")); + String expectedErrorMessage = "Error posting request due to invalid JSON block: "; + given(privateKeyChecker.doesExist(CLIENT_PRIVATE_KEY_PATH)).willReturn(true); + + // WHEN // THEN + assertThatExceptionOfType(SvcLogicException.class) + .isThrownBy(() -> chefAdaptorFactory.create().vnfcNodeobjects(params, svcLogicContext)) + .withMessageStartingWith(CHEF_ADAPTOR_ERROR_PREFIX + expectedErrorMessage); + + assertFalse(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_UNAUTHORIZED)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).startsWith(expectedErrorMessage); + } + + @SuppressWarnings("unchecked") + @Test + public void vnfcPushJob_shouldUpdateSvcContextWithJobId_whenPushJobWasSuccessfullyCreatedWithCallbackUrl() + throws SvcLogicException { + Map params = givenInputParams( + immutableEntry("NodeList", "[\"test1.vnf_b.onap.com\", \"test2.vnf_b.onap.com\"]"), + immutableEntry("CallbackCapable", "true"), + immutableEntry("RequestId", "666"), + immutableEntry("CallbackUrl", "someURLForCallback")); + int expectedResponseStatus = HttpStatus.SC_CREATED; + String expectedResponseMessage = "jobs:666-9"; + + assertVnfcPushJobExecutionFor(params, buildJsonRequestWithCallback(), expectedResponseStatus, expectedResponseMessage); + assertThat(svcLogicContext.getAttribute("jobID")).isEqualTo("666"); + } + + private String buildJsonRequestWithCallback() { + return "{" + "\"command\": \"chef-client\"," + "\"run_timeout\": 300," + "\"nodes\":" + + "[\"test1.vnf_b.onap.com\", \"test2.vnf_b.onap.com\"]" + "," + "\"env\": {\"RequestId\": \"" + "666" + + "\", \"CallbackUrl\": \"" + + "someURLForCallback" + "\"}," + "\"capture_output\": true" + "}"; + } + + @SuppressWarnings("unchecked") + @Test + public void vnfcPushJob_shouldUpdateSvcContextWithJobId_whenPushJobWasSuccessfullyCreatedWithoutCallbackUrl() + throws SvcLogicException { + Map params = givenInputParams( + immutableEntry("NodeList", "[\"test1.vnf_b.onap.com\", \"test2.vnf_b.onap.com\"]"), + immutableEntry("RequestId", "666")); + int expectedResponseStatus = HttpStatus.SC_OK; + String expectedResponseMessage = "jobs:666-9"; + + assertVnfcPushJobExecutionFor(params, buildJsonRequestWithoutCallback(), expectedResponseStatus, expectedResponseMessage); + assertThat(svcLogicContext.getAttribute("jobID")).isBlank(); + } + + private String buildJsonRequestWithoutCallback() { + return "{" + "\"command\": \"chef-client\"," + "\"run_timeout\": 300," + "\"nodes\":" + + "[\"test1.vnf_b.onap.com\", \"test2.vnf_b.onap.com\"]" + "," + "\"env\": {}," + "\"capture_output\": true" + + "}"; + } + + public void assertVnfcPushJobExecutionFor(Map params, String pushRequestWithCallback, + int expectedResponseStatus, String expectedResponseMessage) throws SvcLogicException { + // GIVEN + given(chefApiClientFactory.create(CHEF_END_POINT, ORGANIZATIONS, USERNAME, + CLIENT_PRIVATE_KEY_PATH)).willReturn(chefApiClient); + given(chefApiClient.post("/pushy/jobs", pushRequestWithCallback)) + .willReturn(ChefResponse.create(expectedResponseStatus, expectedResponseMessage)); + + // WHEN + chefAdaptorFactory.create().vnfcPushJob(params, svcLogicContext); + + // THEN + assertTrue(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(expectedResponseStatus)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(expectedResponseMessage); + } + + @SuppressWarnings("unchecked") + @Test + public void vnfcPushJob_shouldNotPushJob_andThrowException_whenNodeListParamIsEmpty() { + // GIVEN + String expectedErrorMessage = "Error posting request: vnfcPushJobMissing Mandatory param(s) NodeList "; + Map params = givenInputParams(); + // WHEN // THEN + assertThatExceptionOfType(SvcLogicException.class) + .isThrownBy(() -> chefAdaptorFactory.create().vnfcPushJob(params, svcLogicContext)) + .withMessageStartingWith(CHEF_ADAPTOR_ERROR_PREFIX + expectedErrorMessage); + + assertFalse(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_UNAUTHORIZED)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(expectedErrorMessage); + } + + @SuppressWarnings("unchecked") + @Test + public void fetchResults_shouldNotFetchResults_andThrowException_whenNodeListParamIsEmpty() { + // GIVEN + String expectedErrorMessage = "Error posting request: fetchResultsMissing Mandatory param(s) NodeList "; + Map params = givenInputParams(); + // WHEN // THEN + assertThatExceptionOfType(SvcLogicException.class) + .isThrownBy(() -> chefAdaptorFactory.create().fetchResults(params, svcLogicContext)) + .withMessageStartingWith(CHEF_ADAPTOR_ERROR_PREFIX + expectedErrorMessage); + + assertFalse(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_UNAUTHORIZED)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(expectedErrorMessage); + } + + @SuppressWarnings("unchecked") + @Test + public void fetchResults_shouldNotFetchResults_andThrowException_whenPrivateKeyCheckFails() { + // GIVEN + Map params = givenInputParams( + immutableEntry("NodeList", "[\"test1.vnf_b.onap.com\", \"test2.vnf_b.onap.com\"]")); + String expectedErrorMessage = + "Error posting request: fetchResults" + + CHEF_ADAPTOR_ERROR_PREFIX + + "Cannot find the private key in the APPC file system, please load the private key to " + + CLIENT_PRIVATE_KEY_PATH; + given(privateKeyChecker.doesExist(CLIENT_PRIVATE_KEY_PATH)).willReturn(false); + + // WHEN // THEN + assertThatExceptionOfType(SvcLogicException.class) + .isThrownBy(() -> chefAdaptorFactory.create().fetchResults(params, svcLogicContext)) + .withMessage(CHEF_ADAPTOR_ERROR_PREFIX + expectedErrorMessage); + + assertFalse(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_UNAUTHORIZED)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo(expectedErrorMessage); + } + + @SuppressWarnings("unchecked") + @Test + public void fetchResults_shouldUpdateSvcLogicContextWithJsonResponse_fromSuccessfulChefServerCall() + throws SvcLogicException { + // GIVEN + String json = "{normal:{PushJobOutput : \"ssh start/running, process 1090\"}}"; + Map params = givenInputParams( + immutableEntry("NodeList", "[\"test1.vnf_b.onap.com\"]")); + given(privateKeyChecker.doesExist(CLIENT_PRIVATE_KEY_PATH)).willReturn(true); + given(chefApiClientFactory.create(CHEF_END_POINT, ORGANIZATIONS, USERNAME, + CLIENT_PRIVATE_KEY_PATH)).willReturn(chefApiClient); + given(chefApiClient.get("/nodes/" + "test1.vnf_b.onap.com")) + .willReturn(ChefResponse.create(HttpStatus.SC_OK, json)); + + // WHEN + chefAdaptorFactory.create().fetchResults(params, svcLogicContext); + + // THEN + assertTrue(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_OK)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)) + .isEqualTo("{\"test1.vnf_b.onap.com\":{\"PushJobOutput\":\"ssh start/running, process 1090\"}}"); + } + + @SuppressWarnings("unchecked") + @Test + public void fetchResults_shouldUpdateSvcLogicContextWithFailedMessage_whenReturnedJSONMessageIsMissingAttribute() + throws SvcLogicException { + // GIVEN + String json = "{normal:{invalidKey : \"ssh start/running, process 1090\"}}"; + Map params = givenInputParams( + immutableEntry("NodeList", "[\"test1.vnf_b.onap.com\"]")); + given(privateKeyChecker.doesExist(CLIENT_PRIVATE_KEY_PATH)).willReturn(true); + given(chefApiClientFactory.create(CHEF_END_POINT, ORGANIZATIONS, USERNAME, + CLIENT_PRIVATE_KEY_PATH)).willReturn(chefApiClient); + given(chefApiClient.get("/nodes/" + "test1.vnf_b.onap.com")) + .willReturn(ChefResponse.create(HttpStatus.SC_OK, json)); + + // WHEN + chefAdaptorFactory.create().fetchResults(params, svcLogicContext); + + // THEN + assertTrue(svcLogicContext.isSuccess()); + assertThat(svcLogicContext.getAttribute(RESULT_CODE_ATTR_KEY)).isEqualTo(Integer.toString(HttpStatus.SC_INTERNAL_SERVER_ERROR)); + assertThat(svcLogicContext.getAttribute(RESULT_MESSAGE_ATTR_KEY)).isEqualTo("Cannot find PushJobOutput"); + } + + @SuppressWarnings("unchecked") + private Map givenInputParams(Entry... entries) { + Builder paramsBuilder = ImmutableMap.builder(); + paramsBuilder.put("username", USERNAME) + .put("serverAddress", SERVER_ADDRESS) + .put("organizations", ORGANIZATIONS); + + for (Entry entry : entries) { + paramsBuilder.put(entry); + } + return paramsBuilder.build(); + } + +} diff --git a/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/PrivateKeyCheckerTest.java b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/PrivateKeyCheckerTest.java new file mode 100644 index 000000000..e8d383ab1 --- /dev/null +++ b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/chef/impl/PrivateKeyCheckerTest.java @@ -0,0 +1,41 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2018 Nokia. 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.ccsdk.sli.adaptors.chef.impl; + +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class PrivateKeyCheckerTest { + + @Test + public void doesExist_shouldReturnTrue_whenFileExists() { + String pemFilePath = getClass().getResource("/testclient.pem").getPath(); + assertTrue(new org.onap.ccsdk.sli.adaptors.chef.impl.PrivateKeyChecker().doesExist(pemFilePath)); + } + + @Test + public void doesExist_shouldReturnFalse_whenFileDoesNotExist() { + assertFalse(new org.onap.ccsdk.sli.adaptors.chef.impl.PrivateKeyChecker().doesExist("dummyPemFile")); + } + +} \ No newline at end of file diff --git a/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/test/ExecutorHarness.java b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/test/ExecutorHarness.java new file mode 100644 index 000000000..f3878148e --- /dev/null +++ b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/test/ExecutorHarness.java @@ -0,0 +1,170 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * 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.ccsdk.test; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; + +/** + * This class is used as a test harness to wrap the call to an executor node. + */ + +public class ExecutorHarness { + + /** + * The executor to be tested + */ + private SvcLogicJavaPlugin executor; + + /** + * The collection of all exec methods found on the class + */ + private Map methods; + + /** + * The field of the class being tested that contains the reference to the logger to be used. This is modified to + * point to our interception logger for the test. + */ + private Field contextLogger; + + /** + * The interception logger that buffers all messages logged and allows us to look at them as part of the test case. + */ + private org.onap.ccsdk.test.InterceptLogger logger; + + /** + * Create the harness and initialize it + * + * @throws SecurityException If a security manager, s, is present and any of the following conditions is met: + *
    + *
  • invocation of s.checkMemberAccess(this, Member.DECLARED) denies access to the declared field
  • + *
  • the caller's class loader is not the same as or an ancestor of the class loader for the current + * class and invocation of s.checkPackageAccess() denies access to the package of this class
  • + *
+ * @throws NoSuchFieldException if a field with the specified name is not found. + * @throws IllegalAccessException if this Field object is enforcing Java language access control and the underlying field is either + * inaccessible or final. + * @throws IllegalArgumentException if the specified object is not an instance of the class or interface declaring the underlying field + * (or a subclass or implementor thereof), or if an unwrapping conversion fails. + */ + @SuppressWarnings("nls") + public ExecutorHarness() throws NoSuchFieldException, SecurityException, IllegalArgumentException, + IllegalAccessException { + methods = new HashMap<>(); + new SvcLogicContext(); + + Class contextClass = SvcLogicContext.class; + contextLogger = contextClass.getDeclaredField("LOG"); + contextLogger.setAccessible(true); + logger = new org.onap.ccsdk.test.InterceptLogger(); + contextLogger.set(null, logger); + } + + /** + * Convenience constructor + * + * @param executor The executor to be tested by the harness + * + * @throws SecurityException If a security manager, s, is present and any of the following conditions is met: + *
    + *
  • invocation of s.checkMemberAccess(this, Member.DECLARED) denies access to the declared field
  • + *
  • the caller's class loader is not the same as or an ancestor of the class loader for the current + * class and invocation of s.checkPackageAccess() denies access to the package of this class
  • + *
+ * @throws NoSuchFieldException if a field with the specified name is not found. + * @throws IllegalAccessException if this Field object is enforcing Java language access control and the underlying field is either + * inaccessible or final. + * @throws IllegalArgumentException if the specified object is not an instance of the class or interface declaring the underlying field + * (or a subclass or implementor thereof), or if an unwrapping conversion fails. + */ + public ExecutorHarness(SvcLogicJavaPlugin executor) throws NoSuchFieldException, SecurityException, + IllegalArgumentException, IllegalAccessException { + this(); + setExecutor(executor); + } + + /** + * @return The java plugin class to be executed + */ + public SvcLogicJavaPlugin getExecutor() { + return executor; + } + + /** + * @param executor The java plugin class to be executed + */ + public void setExecutor(SvcLogicJavaPlugin executor) { + this.executor = executor; + scanExecutor(); + } + + /** + * @return The set of all methods that meet the signature requirements + */ + public List getExecMethodNames() { + List names = new ArrayList<>(); + names.addAll(methods.keySet()); + return names; + } + + /** + * Returns an indication if the named method is a valid executor method that could be called from a DG execute node + * + * @param methodName The method name to be validated + * + * @return True if the method name meets the signature requirements, false if the method either does not exist or + * does not meet the requirements. + */ + public boolean isExecMethod(String methodName) { + return methods.containsKey(methodName); + } + + /** + * This method scans the executor class hierarchy to locate all methods that match the required signature of the + * executor and records these methods in a map. + */ + private void scanExecutor() { + methods.clear(); + Class executorClass = executor.getClass(); + Method[] publicMethods = executorClass.getMethods(); + for (Method method : publicMethods) { + if (method.getReturnType().equals(Void.class)) { + Class[] paramTypes = method.getParameterTypes(); + if (paramTypes.length == 2) { + if (Map.class.isAssignableFrom(paramTypes[0]) + && SvcLogicContext.class.isAssignableFrom(paramTypes[1])) { + methods.put(method.getName(), method); + } + } + } + } + } + +} diff --git a/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/test/InterceptLogger.java b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/test/InterceptLogger.java new file mode 100644 index 000000000..9f80f6880 --- /dev/null +++ b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/java/org/onap/ccsdk/test/InterceptLogger.java @@ -0,0 +1,447 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * 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.ccsdk.test; + +import ch.qos.logback.classic.Level; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; +import org.slf4j.Marker; + +/** + * This class is used as an intercept logger that can be used in testing to intercept and record all messages that are + * logged, thus allowing a junit test case to examine the log output and make assertions. + */ +public class InterceptLogger implements org.slf4j.Logger { + + /** + * The list of all intercepted log events + */ + private List events; + + /** + * Create the intercept logger + */ + public InterceptLogger() { + events = new ArrayList(1000); + } + + /** + * @return Returns all intercepted log events + */ + public List getLogRecords() { + return events; + } + + /** + * Clears all log events + */ + public void clear() { + events.clear(); + } + + @Override + public void debug(Marker marker, String msg) { + debug(msg); + } + + @Override + public void debug(Marker marker, String format, Object arg) { + debug(MessageFormat.format(format, arg)); + } + + @Override + public void debug(Marker marker, String format, Object... arguments) { + debug(MessageFormat.format(format, arguments)); + } + + @Override + public void debug(Marker marker, String format, Object arg1, Object arg2) { + debug(MessageFormat.format(format, arg1, arg2)); + } + + @Override + public void debug(Marker marker, String msg, Throwable t) { + debug(msg, t); + } + + @Override + public void debug(String msg) { + events.add(new LogRecord(Level.DEBUG, msg)); + } + + @Override + public void debug(String format, Object arg) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arg))); + } + + @Override + public void debug(String format, Object... arguments) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arguments))); + } + + @Override + public void debug(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void debug(String msg, Throwable t) { + events.add(new LogRecord(Level.DEBUG, msg, t)); + } + + @Override + public void error(Marker marker, String msg) { + error(msg); + } + + @Override + public void error(Marker marker, String format, Object arg) { + error(format, arg); + } + + @Override + public void error(Marker marker, String format, Object... arguments) { + error(format, arguments); + } + + @Override + public void error(Marker marker, String format, Object arg1, Object arg2) { + error(format, arg1, arg2); + } + + @Override + public void error(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.ERROR, msg, t)); + } + + @Override + public void error(String msg) { + events.add(new LogRecord(Level.ERROR, msg)); + } + + @Override + public void error(String format, Object arg) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arg))); + } + + @Override + public void error(String format, Object... arguments) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arguments))); + } + + @Override + public void error(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void error(String msg, Throwable t) { + events.add(new LogRecord(Level.ERROR, msg, t)); + } + + @Override + public String getName() { + return null; + } + + @Override + public void info(Marker marker, String msg) { + info(msg); + } + + @Override + public void info(Marker marker, String format, Object arg) { + info(format, arg); + } + + @Override + public void info(Marker marker, String format, Object... arguments) { + info(format, arguments); + } + + @Override + public void info(Marker marker, String format, Object arg1, Object arg2) { + info(format, arg1, arg2); + } + + @Override + public void info(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.INFO, msg, t)); + } + + @Override + public void info(String msg) { + events.add(new LogRecord(Level.INFO, msg)); + } + + @Override + public void info(String format, Object arg) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arg))); + } + + @Override + public void info(String format, Object... arguments) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arguments))); + } + + @Override + public void info(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void info(String msg, Throwable t) { + events.add(new LogRecord(Level.INFO, msg, t)); + } + + @Override + public boolean isDebugEnabled() { + return true; + } + + @Override + public boolean isDebugEnabled(Marker marker) { + return true; + } + + @Override + public boolean isErrorEnabled() { + return true; + } + + @Override + public boolean isErrorEnabled(Marker marker) { + return true; + } + + @Override + public boolean isInfoEnabled() { + return true; + } + + @Override + public boolean isInfoEnabled(Marker marker) { + return true; + } + + @Override + public boolean isTraceEnabled() { + return true; + } + + @Override + public boolean isTraceEnabled(Marker marker) { + return true; + } + + @Override + public boolean isWarnEnabled() { + return true; + } + + @Override + public boolean isWarnEnabled(Marker marker) { + return true; + } + + @Override + public void trace(Marker marker, String msg) { + trace(msg); + } + + @Override + public void trace(Marker marker, String format, Object arg) { + trace(format, arg); + } + + @Override + public void trace(Marker marker, String format, Object... argArray) { + trace(format, argArray); + } + + @Override + public void trace(Marker marker, String format, Object arg1, Object arg2) { + trace(format, arg1, arg2); + } + + @Override + public void trace(Marker marker, String msg, Throwable t) { + trace(msg, t); + } + + @Override + public void trace(String msg) { + events.add(new LogRecord(Level.TRACE, msg)); + } + + @Override + public void trace(String format, Object arg) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arg))); + } + + @Override + public void trace(String format, Object... arguments) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arguments))); + } + + @Override + public void trace(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void trace(String msg, Throwable t) { + events.add(new LogRecord(Level.TRACE, msg, t)); + } + + @Override + public void warn(Marker marker, String msg) { + warn(msg); + } + + @Override + public void warn(Marker marker, String format, Object arg) { + warn(format, arg); + } + + @Override + public void warn(Marker marker, String format, Object... arguments) { + warn(format, arguments); + } + + @Override + public void warn(Marker marker, String format, Object arg1, Object arg2) { + warn(format, arg1, arg2); + } + + @Override + public void warn(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.WARN, msg, t)); + } + + @Override + public void warn(String msg) { + events.add(new LogRecord(Level.WARN, msg)); + } + + @Override + public void warn(String format, Object arg) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arg))); + } + + @Override + public void warn(String format, Object... arguments) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arguments))); + } + + @Override + public void warn(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void warn(String msg, Throwable t) { + events.add(new LogRecord(Level.WARN, msg, t)); + } + + /** + * This inner class represents an intercepted log event + */ + public class LogRecord { + private Level level; + private String message; + private long timestamp; + private Throwable t; + + public LogRecord(Level level, String message) { + setLevel(level); + setTimestamp(System.currentTimeMillis()); + setMessage(message); + } + + public LogRecord(Level level, String message, Throwable t) { + this(level, message); + setThrowable(t); + } + + /** + * @return the value of level + */ + public Level getLevel() { + return level; + } + + /** + * @param level the value for level + */ + public void setLevel(Level level) { + this.level = level; + } + + /** + * @return the value of message + */ + public String getMessage() { + return message; + } + + /** + * @param message the value for message + */ + public void setMessage(String message) { + this.message = message; + } + + /** + * @return the value of timestamp + */ + public long getTimestamp() { + return timestamp; + } + + /** + * @param timestamp the value for timestamp + */ + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + /** + * @return the value of t + */ + public Throwable getThrowable() { + return t; + } + + /** + * @param t the value for t + */ + public void setThrowable(Throwable t) { + this.t = t; + } + + } + +} diff --git a/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/resources/properties/chef-adaptor-test.properties b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/resources/properties/chef-adaptor-test.properties new file mode 100644 index 000000000..4ccbf654c --- /dev/null +++ b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/resources/properties/chef-adaptor-test.properties @@ -0,0 +1,101 @@ +### +# ============LICENSE_START======================================================= +# ONAP : APPC +# ================================================================================ +# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# Copyright (C) 2017 Amdocs +# ============================================================================= +# 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========================================================= +### +# +# Default properties for the APP-C Provider Adaptor +# +# ------------------------------------------------------------------------------------------------- +# +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.onap.appc.bootstrap.file=appc.properties +org.onap.appc.bootstrap.path=/opt/onap/appc/data/properties,${user.home},. +appc.application.name=APPC +# +# Define the message resource bundle name to be loaded +org.onap.appc.resources=org/onap/appc/i18n/MessageResources +# +# The name of the adaptor. +org.onap.appc.provider.adaptor.name=org.onap.appc.appc_provider_adaptor +# +# Set up the logging environment +# +org.onap.appc.logging.file=org/onap/appc/logback.xml +org.onap.appc.logging.path=${user.home};etc;../etc +org.onap.appc.logger=org.onap.appc +org.onap.appc.security.logger=org.onap.appc.security +# +# The minimum and maximum provider/tenant context pool sizes. Min=1 means that as soon +# as the provider/tenant is referenced a Context is opened and added to the pool. Max=0 +# means that the upper bound on the pool is unbounded. +org.onap.appc.provider.min.pool=1 +org.onap.appc.provider.max.pool=0 +# +# The following properties are used to configure the retry logic for connection to the +# IaaS provider(s). The retry delay property is the amount of time, in seconds, the +# application waits between retry attempts. The retry limit is the number of retries +# that are allowed before the request is failed. +org.onap.appc.provider.retry.delay=30 +org.onap.appc.provider.retry.limit=10 +# +# The trusted hosts list for SSL access when a certificate is not provided. +# +provider.trusted.hosts=* +# +# The amount of time, in seconds, to wait for a server state change (start->stop, stop->start, etc). +# If the server does not change state to a valid state within the alloted time, the operation +# fails. +org.onap.appc.server.state.change.timeout=300 +# +# The amount of time to wait, in seconds, between subsequent polls to the OpenStack provider +# to refresh the status of a resource we are waiting on. +# +org.onap.appc.openstack.poll.interval=20 +# +# The connection information to connect to the provider we are using. These properties +# are "structured" properties, in that the name is a compound name, where the nodes +# of the name can be ordered (1, 2, 3, ...). All of the properties with the same ordinal +# position are defining the same entity. For example, provider1.type and provider1.name +# are defining the same provider, whereas provider2.name and provider2.type are defining +# the values for a different provider. Any number of providers can be defined in this +# way. +# +# Don't change these 2 right now since they are hard coded in the DG +#provider1.type=appc +#provider1.name=appc +#These you can change +#provider1.identity=appc +#provider1.tenant1.name=appc +#provider1.tenant1.userid=appc +#provider1.tenant1.password=appc +# After a change to the provider make sure to recheck these values with an api call to provider1.identity/tokens +test.expected-regions=1 +test.expected-endpoints=1 +#Your OpenStack IP +#test.ip=192.168.1.2 +# Your OpenStack Platform's Keystone Port (default is 5000) +#test.port=5000 +#test.tenantid=abcde12345fghijk6789lmnopq123rst +#test.vmid=abc12345-1234-5678-890a-abcdefg12345 +# Port 8774 below is default port for OpenStack's Nova API Service +#test.url=http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345 + diff --git a/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/resources/testclient.pem b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/resources/testclient.pem new file mode 100644 index 000000000..a12f38118 --- /dev/null +++ b/adaptors/chef-adaptor/chef-adaptor-bundle/src/test/resources/testclient.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAqDFyi0Tp4CQN2Q1kp2NXLPl5P4CVqjdXTUgxugupRC9aqJa5 +l7NOOkQWadSaU/CCtdsikp6ymyxEqR0Y3TtxmY3ongFBtLDaU/UnWXZY0pcaJBN/ +ZZKV9++lZF8+USKlZTQo+EqD7XlEjiDKjfwylaMTSwQPKGa0bDZZ6U44K63uuClw +mkvhtlaeS+t4Ah/YMU2nSxrWH3CpPxO4qD2KducrNRs01+hRxoVEaEX7HGXi8zdz +BHSp8mcA8mGl9uJFXN8Gtgphrlknq7DPjVb0iZ9Lw2u6WNhZizFHghEwHRSJYn26 +DNzmOjyD0IaQf5lf1L1sO5DcPkWC2I21MNaE4QIDAQABAoIBAEa/Xe4lE7d7kvOd +BZy/VZkOaykB/nJ2CtvwJTKb2xxaSuklVXXxL1Ok9kSX8D6kqWazgYxpArnw2gTE +v4O3kGZF4fYskyXdSkkMkvu3o08Zzh4ksW7ZRQngnRJmWcEpMKcsVJt0RKAsZWDf +fDRTRDfbO69PSsz0vqnSBunzQ/9i4LbFDOKYnWFDOiGKzM8SXMvVUVpGAzvc773M +lthBAo9KpbNrbO0b3OGUM8pU2o9GRbBAEzIq8j/i2h/vHtswgM9g3IsHNqYbvJPD +uAY8hsYEPZh/RasIBLN1J9HD+Ex1q2OA+Yi3jBtT4s545MJIHpdmo57/B2SHQbug +KuWTsb0CgYEA0ZKIig/jeZEOokvWxDrN6Ok2Hb9TFZcNi/qBLcQ25A1C2fDkvsHc +S6UDxknT2cyQ77R9xK25vrFKKrv5FUwgg7h0ps19w8xSZRG9Wvg0nus69oavXIDi +MOCBfb6pn2+Glhdt84Ku0oSTPtfcTHerACOunGATpk1NW2dlmDbvmTcCgYEAzXQs +9lS31+2Oh64g4gH/6Jfx+Mh5JY+2bUhSMy53tulzFwfI1zLyyu9SLLfVbAnxhmS8 +rSg7Q2mN492ZhnoVScYN3RTpudBJIinqlFoarqu+6E83k+83wGv3m2pP6XPbpHCy +QE6IQm5U+ZSbMRD+8SjG3pbPRYcwww5xRsIj/qcCgYA2kEc6Yu6fzROZT9OH3aOU +u3tafWC9Y0mko0EU0FxWPdmk8qIrxD999mWoL7qXnzoxHrYMCgstSe18eNpeICbr +BJBiiWfwHXdqVxcM40iYA7ijTOfFVs0NWrZ8LbLuDtRkqY738pNfviK0HvF9ez6r +V57zmdQj3UaBwMbjvZHeOwKBgQCA0gsvGMd8+FKZ+DBeBWrz5/GsT+bGCmoT83i2 +5rfhVFb5ZcQkSqm5XH1l1I5ZA5MQ9TDoUYV3K0PwUA3nJ70ZWLlwmaBDBboVVbrj +8esxAjbdam4qr5+BYzEJnYslkaNyY8cgUx1UqeFV7DuydDml9C9deanUqoOEihW0 +jB4NmQKBgD4nwTUcQIbzeWnFoPxbDMQIIheZ3EK+rEbmXiU3blPhmCoye9q58Qet +YaeQKiJEF2mWnBE6VtSg84OiENSAMxUn2VlwopFoTbfLKD4qfGoGWm9tjUdBblHe +3U3ZdQLYKTiSNr+LXrAI0w4MukmL8vzxzo80tcB4+tePyWN/lqoq +-----END RSA PRIVATE KEY----- -- cgit 1.2.3-korg