2  * ========================LICENSE_START=================================
 
   4  * ======================================================================
 
   5  * Copyright (C) 2020 Nordix Foundation. All rights reserved.
 
   6  * ======================================================================
 
   7  * Licensed under the Apache License, Version 2.0 (the "License");
 
   8  * you may not use this file except in compliance with the License.
 
   9  * You may obtain a copy of the License at
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  13  * Unless required by applicable law or agreed to in writing, software
 
  14  * distributed under the License is distributed on an "AS IS" BASIS,
 
  15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  16  * See the License for the specific language governing permissions and
 
  17  * limitations under the License.
 
  18  * ========================LICENSE_END===================================
 
  21 package org.onap.ccsdk.oran.a1policymanagementservice.clients;
 
  23 import static org.junit.jupiter.api.Assertions.assertEquals;
 
  24 import static org.junit.jupiter.api.Assertions.assertThrows;
 
  25 import static org.mockito.ArgumentMatchers.anyString;
 
  26 import static org.mockito.Mockito.verify;
 
  27 import static org.mockito.Mockito.when;
 
  29 import com.google.gson.Gson;
 
  30 import com.google.gson.JsonElement;
 
  33 import java.io.IOException;
 
  35 import java.nio.file.Files;
 
  36 import java.util.Arrays;
 
  37 import java.util.List;
 
  38 import java.util.Optional;
 
  40 import org.junit.jupiter.api.Test;
 
  41 import org.junit.jupiter.api.extension.ExtendWith;
 
  42 import org.mockito.Mock;
 
  43 import org.mockito.junit.jupiter.MockitoExtension;
 
  44 import org.mockito.stubbing.OngoingStubbing;
 
  45 import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client.A1ProtocolType;
 
  46 import org.onap.ccsdk.oran.a1policymanagementservice.clients.CcsdkA1AdapterClient.AdapterOutput;
 
  47 import org.onap.ccsdk.oran.a1policymanagementservice.clients.CcsdkA1AdapterClient.AdapterRequest;
 
  48 import org.onap.ccsdk.oran.a1policymanagementservice.clients.ImmutableAdapterOutput.Builder;
 
  49 import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ControllerConfig;
 
  50 import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ImmutableControllerConfig;
 
  51 import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policy;
 
  52 import org.springframework.http.HttpStatus;
 
  53 import org.springframework.web.reactive.function.client.WebClientResponseException;
 
  55 import reactor.core.publisher.Mono;
 
  56 import reactor.test.StepVerifier;
 
  58 @ExtendWith(MockitoExtension.class)
 
  59 class CcsdkA1AdapterClientTest {
 
  60     private static final String CONTROLLER_USERNAME = "username";
 
  61     private static final String CONTROLLER_PASSWORD = "password";
 
  62     private static final String RIC_1_URL = "RicUrl";
 
  63     private static final String GET_A1_POLICY_URL = "/A1-ADAPTER-API:getA1Policy";
 
  64     private static final String PUT_A1_URL = "/A1-ADAPTER-API:putA1Policy";
 
  65     private static final String DELETE_A1_URL = "/A1-ADAPTER-API:deleteA1Policy";
 
  66     private static final String GET_A1_POLICY_STATUS_URL = "/A1-ADAPTER-API:getA1PolicyStatus";
 
  67     private static final String POLICY_TYPE_1_ID = "type1";
 
  68     private static final String POLICY_1_ID = "policy1";
 
  69     private static final String POLICY_JSON_VALID = "{\"scope\":{\"ueId\":\"ue1\"}}";
 
  71     CcsdkA1AdapterClient clientUnderTest;
 
  74     AsyncRestClient asyncRestClientMock;
 
  76     private ControllerConfig controllerConfig() {
 
  77         return ImmutableControllerConfig.builder() //
 
  79                 .baseUrl("baseUrl") //
 
  80                 .password(CONTROLLER_PASSWORD) //
 
  81                 .userName(CONTROLLER_USERNAME) //
 
  86     void createClientWithWrongProtocol_thenErrorIsThrown() {
 
  87         assertThrows(IllegalArgumentException.class, () -> {
 
  88             new CcsdkA1AdapterClient(A1ProtocolType.STD_V1_1, null, null, new AsyncRestClient("", null, null));
 
  93     void getPolicyTypeIdentities_STD_V1() {
 
  94         clientUnderTest = new CcsdkA1AdapterClient(A1ProtocolType.CCSDK_A1_ADAPTER_STD_V1_1, //
 
  95                 A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
 
  96                 controllerConfig(), asyncRestClientMock);
 
  97         List<String> policyTypeIds = clientUnderTest.getPolicyTypeIdentities().block();
 
  98         assertEquals(1, policyTypeIds.size(), "should hardcoded to one");
 
  99         assertEquals("", policyTypeIds.get(0), "should hardcoded to empty");
 
 102     private void testGetPolicyTypeIdentities(A1ProtocolType protocolType, String expUrl) {
 
 103         clientUnderTest = new CcsdkA1AdapterClient(protocolType, //
 
 104                 A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
 
 105                 controllerConfig(), asyncRestClientMock);
 
 107         String response = createOkResponseWithBody(Arrays.asList(POLICY_TYPE_1_ID));
 
 108         whenAsyncPostThenReturn(Mono.just(response));
 
 110         List<String> policyTypeIds = clientUnderTest.getPolicyTypeIdentities().block();
 
 112         assertEquals(1, policyTypeIds.size());
 
 113         assertEquals(POLICY_TYPE_1_ID, policyTypeIds.get(0));
 
 115         ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() //
 
 116                 .nearRtRicUrl(expUrl) //
 
 118         String expInput = A1AdapterJsonHelper.createInputJsonString(expectedParams);
 
 119         verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME,
 
 120                 CONTROLLER_PASSWORD);
 
 124     void getPolicyTypeIdentities_OSC() {
 
 125         testGetPolicyTypeIdentities(A1ProtocolType.CCSDK_A1_ADAPTER_OSC_V1, RIC_1_URL + "/a1-p/policytypes");
 
 129     void getPolicyTypeIdentities_STD_V2() {
 
 130         testGetPolicyTypeIdentities(A1ProtocolType.CCSDK_A1_ADAPTER_STD_V2_0_0, RIC_1_URL + "/A1-P/v2/policytypes");
 
 134     void getTypeSchema_STD_V1() {
 
 136         clientUnderTest = new CcsdkA1AdapterClient(A1ProtocolType.CCSDK_A1_ADAPTER_STD_V1_1, //
 
 137                 A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
 
 138                 controllerConfig(), asyncRestClientMock);
 
 140         String policyType = clientUnderTest.getPolicyTypeSchema("").block();
 
 142         assertEquals("{}", policyType);
 
 145     private void testGetTypeSchema(A1ProtocolType protocolType, String expUrl, String policyTypeId,
 
 146             String getSchemaResponseFile) throws IOException {
 
 147         clientUnderTest = new CcsdkA1AdapterClient(protocolType, //
 
 148                 A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
 
 149                 controllerConfig(), asyncRestClientMock);
 
 151         String ricResponse = loadFile(getSchemaResponseFile);
 
 152         JsonElement elem = gson().fromJson(ricResponse, JsonElement.class);
 
 153         String responseFromController = createOkResponseWithBody(elem);
 
 154         whenAsyncPostThenReturn(Mono.just(responseFromController));
 
 156         String response = clientUnderTest.getPolicyTypeSchema(policyTypeId).block();
 
 158         JsonElement respJson = gson().fromJson(response, JsonElement.class);
 
 159         assertEquals(policyTypeId, respJson.getAsJsonObject().get("title").getAsString(),
 
 160                 "title should be updated to contain policyType ID");
 
 162         ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() //
 
 163                 .nearRtRicUrl(expUrl) //
 
 165         String expInput = A1AdapterJsonHelper.createInputJsonString(expectedParams);
 
 167         verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME,
 
 168                 CONTROLLER_PASSWORD);
 
 172     void getTypeSchema_OSC() throws IOException {
 
 173         String expUrl = RIC_1_URL + "/a1-p/policytypes/policyTypeId";
 
 174         testGetTypeSchema(A1ProtocolType.CCSDK_A1_ADAPTER_OSC_V1, expUrl, "policyTypeId",
 
 175                 "test_osc_get_schema_response.json");
 
 179     void getTypeSchema_STD_V2() throws IOException {
 
 180         String expUrl = RIC_1_URL + "/A1-P/v2/policytypes/policyTypeId";
 
 181         testGetTypeSchema(A1ProtocolType.CCSDK_A1_ADAPTER_STD_V2_0_0, expUrl, "policyTypeId",
 
 182                 "test_oran_get_schema_response.json");
 
 186     void parseJsonArrayOfString() {
 
 187         // One integer and one string
 
 188         String inputString = "[1, \"1\" ]";
 
 190         List<String> result = A1AdapterJsonHelper.parseJsonArrayOfString(inputString).collectList().block();
 
 191         assertEquals(2, result.size());
 
 192         assertEquals("1", result.get(0));
 
 193         assertEquals("1", result.get(1));
 
 196     private void getPolicyIdentities(A1ProtocolType protocolType, String... expUrls) {
 
 197         clientUnderTest = new CcsdkA1AdapterClient(protocolType, //
 
 198                 A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
 
 199                 controllerConfig(), asyncRestClientMock);
 
 200         String resp = createOkResponseWithBody(Arrays.asList("xxx"));
 
 201         whenAsyncPostThenReturn(Mono.just(resp));
 
 203         List<String> returned = clientUnderTest.getPolicyIdentities().block();
 
 205         assertEquals(1, returned.size());
 
 206         for (String expUrl : expUrls) {
 
 207             ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() //
 
 208                     .nearRtRicUrl(expUrl) //
 
 210             String expInput = A1AdapterJsonHelper.createInputJsonString(expectedParams);
 
 211             verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME,
 
 212                     CONTROLLER_PASSWORD);
 
 217     void getPolicyIdentities_STD_V1() {
 
 218         String expUrl = RIC_1_URL + "/A1-P/v1/policies";
 
 219         getPolicyIdentities(A1ProtocolType.CCSDK_A1_ADAPTER_STD_V1_1, expUrl);
 
 223     void getPolicyIdentities_STD_V2() {
 
 224         String expUrlPolicies = RIC_1_URL + "/A1-P/v2/policytypes";
 
 225         String expUrlInstances = RIC_1_URL + "/A1-P/v2/policytypes/xxx/policies";
 
 226         getPolicyIdentities(A1ProtocolType.CCSDK_A1_ADAPTER_STD_V2_0_0, expUrlPolicies, expUrlInstances);
 
 230     void getPolicyIdentities_OSC() {
 
 231         String expUrlTypes = RIC_1_URL + "/a1-p/policytypes";
 
 232         String expUrlInstances = RIC_1_URL + "/a1-p/policytypes/xxx/policies";
 
 233         getPolicyIdentities(A1ProtocolType.CCSDK_A1_ADAPTER_OSC_V1, expUrlTypes, expUrlInstances);
 
 236     private void putPolicy(A1ProtocolType protocolType, String expUrl) {
 
 237         clientUnderTest = new CcsdkA1AdapterClient(protocolType, //
 
 238                 A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
 
 239                 controllerConfig(), asyncRestClientMock);
 
 241         whenPostReturnOkResponse();
 
 243         String returned = clientUnderTest
 
 244                 .putPolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID))
 
 247         assertEquals("OK", returned);
 
 248         AdapterRequest expectedInputParams = ImmutableAdapterRequest.builder() //
 
 249                 .nearRtRicUrl(expUrl) //
 
 250                 .body(POLICY_JSON_VALID) //
 
 252         String expInput = A1AdapterJsonHelper.createInputJsonString(expectedInputParams);
 
 254         verify(asyncRestClientMock).postWithAuthHeader(PUT_A1_URL, expInput, CONTROLLER_USERNAME, CONTROLLER_PASSWORD);
 
 259     void putPolicy_OSC() {
 
 260         String expUrl = RIC_1_URL + "/a1-p/policytypes/type1/policies/policy1";
 
 261         putPolicy(A1ProtocolType.CCSDK_A1_ADAPTER_OSC_V1, expUrl);
 
 265     void putPolicy_STD_V1() {
 
 266         String expUrl = RIC_1_URL + "/A1-P/v1/policies/policy1";
 
 267         putPolicy(A1ProtocolType.CCSDK_A1_ADAPTER_STD_V1_1, expUrl);
 
 271     void putPolicy_STD_V2() {
 
 273                 RIC_1_URL + "/A1-P/v2/policytypes/type1/policies/policy1?notificationDestination=https://test.com";
 
 274         putPolicy(A1ProtocolType.CCSDK_A1_ADAPTER_STD_V2_0_0, expUrl);
 
 278     void postRejected() {
 
 279         clientUnderTest = new CcsdkA1AdapterClient(A1ProtocolType.CCSDK_A1_ADAPTER_STD_V1_1, //
 
 280                 A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
 
 281                 controllerConfig(), asyncRestClientMock);
 
 283         final String policyJson = "{}";
 
 284         AdapterOutput adapterOutput = ImmutableAdapterOutput.builder() //
 
 286                 .httpStatus(HttpStatus.BAD_REQUEST.value()) // ERROR
 
 289         String resp = A1AdapterJsonHelper.createOutputJsonString(adapterOutput);
 
 290         whenAsyncPostThenReturn(Mono.just(resp));
 
 292         Mono<String> returnedMono = clientUnderTest
 
 293                 .putPolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, policyJson, POLICY_TYPE_1_ID));
 
 294         StepVerifier.create(returnedMono) //
 
 295                 .expectSubscription() //
 
 296                 .expectErrorMatches(t -> t instanceof WebClientResponseException) //
 
 299         StepVerifier.create(returnedMono).expectErrorMatches(throwable -> {
 
 300             return throwable instanceof WebClientResponseException;
 
 304     private void deleteAllPolicies(A1ProtocolType protocolType, String expUrl) {
 
 305         clientUnderTest = new CcsdkA1AdapterClient(protocolType, //
 
 306                 A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
 
 307                 controllerConfig(), asyncRestClientMock);
 
 308         String resp = createOkResponseWithBody(Arrays.asList("xxx"));
 
 309         whenAsyncPostThenReturn(Mono.just(resp));
 
 311         clientUnderTest.deleteAllPolicies().blockLast();
 
 313         ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() //
 
 314                 .nearRtRicUrl(expUrl) //
 
 316         String expInput = A1AdapterJsonHelper.createInputJsonString(expectedParams);
 
 317         verify(asyncRestClientMock).postWithAuthHeader(DELETE_A1_URL, expInput, CONTROLLER_USERNAME,
 
 318                 CONTROLLER_PASSWORD);
 
 322     void deleteAllPolicies_STD_V2() {
 
 323         String expUrl1 = RIC_1_URL + "/A1-P/v2/policytypes/xxx/policies/xxx";
 
 324         deleteAllPolicies(A1ProtocolType.CCSDK_A1_ADAPTER_STD_V2_0_0, expUrl1);
 
 328     void deleteAllPolicies_STD_V1() {
 
 329         String expUrl1 = RIC_1_URL + "/A1-P/v1/policies/xxx";
 
 330         deleteAllPolicies(A1ProtocolType.CCSDK_A1_ADAPTER_STD_V1_1, expUrl1);
 
 334     void deleteAllPolicies_OSC() {
 
 335         String expUrl1 = RIC_1_URL + "/a1-p/policytypes/xxx/policies/xxx";
 
 336         deleteAllPolicies(A1ProtocolType.CCSDK_A1_ADAPTER_OSC_V1, expUrl1);
 
 340     void getVersion_OSC() {
 
 341         clientUnderTest = new CcsdkA1AdapterClient(A1ProtocolType.CCSDK_A1_ADAPTER_OSC_V1, // Version irrelevant here
 
 342                 A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
 
 343                 controllerConfig(), asyncRestClientMock);
 
 345         whenAsyncPostThenReturn(Mono.error(new Exception("Error"))).thenReturn(Mono.just(createOkResponseString(true)));
 
 347         A1ProtocolType returnedVersion = clientUnderTest.getProtocolVersion().block();
 
 349         assertEquals(A1ProtocolType.CCSDK_A1_ADAPTER_STD_V1_1, returnedVersion);
 
 353     void testGetStatus() {
 
 354         clientUnderTest = new CcsdkA1AdapterClient(A1ProtocolType.CCSDK_A1_ADAPTER_STD_V2_0_0, //
 
 355                 A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
 
 356                 controllerConfig(), asyncRestClientMock);
 
 357         whenPostReturnOkResponse();
 
 359         Policy policy = A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID);
 
 361         String response = clientUnderTest.getPolicyStatus(policy).block();
 
 362         assertEquals("OK", response);
 
 364         String expUrl = RIC_1_URL + "/A1-P/v2/policytypes/type1/policies/policy1/status";
 
 365         ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() //
 
 366                 .nearRtRicUrl(expUrl) //
 
 368         String expInput = A1AdapterJsonHelper.createInputJsonString(expectedParams);
 
 369         verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_STATUS_URL, expInput, CONTROLLER_USERNAME,
 
 370                 CONTROLLER_PASSWORD);
 
 374     private Gson gson() {
 
 375         return CcsdkA1AdapterClient.gson;
 
 378     private String loadFile(String fileName) throws IOException {
 
 379         ClassLoader loader = Thread.currentThread().getContextClassLoader();
 
 380         URL url = loader.getResource(fileName);
 
 381         File file = new File(url.getFile());
 
 382         return new String(Files.readAllBytes(file.toPath()));
 
 385     private void whenPostReturnOkResponse() {
 
 386         whenAsyncPostThenReturn(Mono.just(createOkResponseString(true)));
 
 389     void whenPostReturnOkResponseNoBody() {
 
 390         whenAsyncPostThenReturn(Mono.just(createOkResponseString(false)));
 
 393     private String createOkResponseWithBody(Object body) {
 
 394         AdapterOutput output = ImmutableAdapterOutput.builder() //
 
 395                 .body(gson().toJson(body)) //
 
 396                 .httpStatus(HttpStatus.OK.value()) //
 
 398         return A1AdapterJsonHelper.createOutputJsonString(output);
 
 401     private String createOkResponseString(boolean withBody) {
 
 402         Builder responseBuilder = ImmutableAdapterOutput.builder().httpStatus(HttpStatus.OK.value());
 
 404             responseBuilder.body(HttpStatus.OK.name());
 
 406             responseBuilder.body(Optional.empty());
 
 408         return A1AdapterJsonHelper.createOutputJsonString(responseBuilder.build());
 
 411     private OngoingStubbing<Mono<String>> whenAsyncPostThenReturn(Mono<String> response) {
 
 412         return when(asyncRestClientMock.postWithAuthHeader(anyString(), anyString(), anyString(), anyString()))
 
 413                 .thenReturn(response);