Release PRH 1.7.0
[dcaegen2/services/prh.git] / prh-app-server / src / test / java / org / onap / dcaegen2 / services / prh / tasks / BbsActionsTaskTest.java
1 /*
2  * ============LICENSE_START=======================================================
3  * PNF-REGISTRATION-HANDLER
4  * ================================================================================
5  * Copyright (C) 2019-2021 NOKIA Intellectual Property. 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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20
21 package org.onap.dcaegen2.services.prh.tasks;
22
23 import static io.netty.handler.codec.http.HttpResponseStatus.INTERNAL_SERVER_ERROR;
24 import static io.netty.handler.codec.http.HttpResponseStatus.OK;
25 import static org.assertj.core.api.Assertions.assertThat;
26 import static org.assertj.core.api.Assertions.assertThatThrownBy;
27 import static org.junit.jupiter.api.Assertions.assertEquals;
28 import static org.mockito.ArgumentMatchers.any;
29 import static org.mockito.BDDMockito.given;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.times;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.verifyZeroInteractions;
34 import static org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpMethod.DELETE;
35 import static org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpMethod.GET;
36 import static org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpMethod.PUT;
37
38 import com.google.gson.JsonObject;
39 import io.netty.handler.codec.http.HttpResponseStatus;
40 import java.nio.charset.StandardCharsets;
41 import java.util.List;
42 import java.util.Scanner;
43 import org.junit.jupiter.api.Test;
44 import org.mockito.ArgumentCaptor;
45 import org.mockito.ArgumentMatchers;
46 import org.onap.dcaegen2.services.prh.TestAppConfiguration;
47 import org.onap.dcaegen2.services.prh.adapter.aai.api.ConsumerDmaapModel;
48 import org.onap.dcaegen2.services.prh.adapter.aai.api.ImmutableConsumerDmaapModel;
49 import org.onap.dcaegen2.services.prh.adapter.aai.main.AaiClientConfiguration;
50 import org.onap.dcaegen2.services.prh.configuration.CbsConfiguration;
51 import org.onap.dcaegen2.services.prh.exceptions.AaiFailureException;
52 import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpRequest;
53 import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpResponse;
54 import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.ImmutableHttpResponse;
55 import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.RxHttpClient;
56 import reactor.core.publisher.Mono;
57
58 class BbsActionsTaskTest {
59
60     private static final String AAI_URL = "https://aai.onap.svc.cluster.local:8443/aai/v23/network";
61     private static final String PNF_URL = "/pnfs/pnf";
62     private static final String LOGICAL_LINK_URL = "/logical-links/logical-link";
63     private static final String ATTACHMENT_POINT = "attachment-point";
64
65     private static final String PNF_WITHOUT_LINK_JSON = "BbsActionsTaskTestFiles/pnfWithoutLinks.json";
66     private static final String PNF_WITH_LINK_JSON = "BbsActionsTaskTestFiles/pnfWithLogicalLink.json";
67     private static final String LOGICAL_LINK_JSON = "BbsActionsTaskTestFiles/oldLogicalLink.json";
68     private static final String LOGICAL_LINK_BODY = "BbsActionsTaskTestFiles/logicalLinkBody.json";
69     private static final String LOGICAL_LINK_BODY_WITH_SPACE = "BbsActionsTaskTestFiles/logicalLinkBodyWithSpace.json";
70
71
72     private CbsConfiguration cbsConfiguration = mock(CbsConfiguration.class);
73     private AaiClientConfiguration aaiClientConfiguration = TestAppConfiguration.createDefaultAaiClientConfiguration();
74     private RxHttpClient httpClient = mock(RxHttpClient.class);
75
76     private ClassLoader loader = getClass().getClassLoader();
77
78     @Test
79     void whenPassedObjectDoesntHaveAdditionalFields_ReturnPayloadTransparently() {
80         // given
81         given(cbsConfiguration.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
82         ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(null);
83
84         // when
85         ConsumerDmaapModel result = new BbsActionsTaskImpl(cbsConfiguration, httpClient).execute(consumerDmaapModel).block();
86
87         // then
88         verifyZeroInteractions(httpClient);
89         assertThat(result).isEqualTo(consumerDmaapModel);
90     }
91
92     @Test
93     void whenPassedObjectHasEmptyLogicalLink_ReturnPayloadTransparently() {
94         // given
95         given(cbsConfiguration.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
96
97         JsonObject additionalFields = new JsonObject();
98         additionalFields.addProperty(ATTACHMENT_POINT, "");
99         ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
100
101         // when
102         ConsumerDmaapModel result = new BbsActionsTaskImpl(cbsConfiguration, httpClient).execute(consumerDmaapModel).block();
103
104         // then
105         verifyZeroInteractions(httpClient);
106         assertThat(result).isEqualTo(consumerDmaapModel);
107     }
108
109     @Test
110     void whenPassedObjectHasLogicalLink_and_pnfHasNoLogicalLink_createLogicalLink_and_associateWithPnf_and_ReturnPayloadTransparently() {
111         // given
112         given(cbsConfiguration.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
113
114         JsonObject additionalFields = new JsonObject();
115         String linkName = "some link";
116         String encodedLinkName = "some%20link";
117         additionalFields.addProperty(ATTACHMENT_POINT, linkName);
118         ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
119
120         given(httpClient.call(any()))
121             .willReturn(Mono.just(buildAaiResponse(OK, getBodyJson(PNF_WITHOUT_LINK_JSON))),
122                 Mono.just(buildAaiResponse(OK, "")));
123
124         // when
125         Mono<ConsumerDmaapModel> response = new BbsActionsTaskImpl(cbsConfiguration, httpClient).execute(consumerDmaapModel);
126
127         // then
128         assertEquals(consumerDmaapModel, response.block());
129
130         ArgumentCaptor<HttpRequest> captor = ArgumentCaptor.forClass(HttpRequest.class);
131         verify(httpClient, times(2)).call(captor.capture());
132
133         List<HttpRequest> args = captor.getAllValues();
134         assertEquals(2, args.size());
135
136         HttpRequest pnfGet = args.get(0);
137         HttpRequest linkPut = args.get(1);
138
139         assertEquals(AAI_URL + PNF_URL + "/Nokia123", pnfGet.url());
140         assertEquals(GET, pnfGet.method());
141         assertEquals(AAI_URL + LOGICAL_LINK_URL + "/" + encodedLinkName, linkPut.url());
142         assertEquals(PUT, linkPut.method());
143         assertEquals(getBodyJson(LOGICAL_LINK_BODY_WITH_SPACE), extractBodyFromRequest(linkPut));
144     }
145
146     @Test
147     void whenPassedObjectHasLogicalLink_and_pnfHasLogicalLink_deleteOldLogicalLink_and_createLogicalLink_and_associateWithPnf_and_ReturnPayloadTransparently() {
148         // given
149         given(cbsConfiguration.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
150
151         JsonObject additionalFields = new JsonObject();
152         String linkName = "some-link";
153         additionalFields.addProperty(ATTACHMENT_POINT, linkName);
154         ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
155
156         given(httpClient.call(any()))
157             .willReturn(Mono.just(buildAaiResponse(OK, getBodyJson(PNF_WITH_LINK_JSON))),
158                 Mono.just(buildAaiResponse(OK, "")),
159                 Mono.just(buildAaiResponse(OK, getBodyJson(LOGICAL_LINK_JSON))),
160                 Mono.just(buildAaiResponse(OK, "")));
161
162         // when
163         Mono<ConsumerDmaapModel> response = new BbsActionsTaskImpl(cbsConfiguration, httpClient).execute(consumerDmaapModel);
164
165         // then
166         assertEquals(consumerDmaapModel, response.block());
167
168         ArgumentCaptor<HttpRequest> captor = ArgumentCaptor.forClass(HttpRequest.class);
169         verify(httpClient, times(4)).call(captor.capture());
170
171         List<HttpRequest> args = captor.getAllValues();
172         assertEquals(4, args.size());
173
174         HttpRequest pnfGet = args.get(0);
175         HttpRequest linkPut = args.get(1);
176         HttpRequest linkGet = args.get(2);
177         HttpRequest linkDelete = args.get(3);
178
179         assertEquals(AAI_URL + PNF_URL + "/Nokia123", pnfGet.url());
180         assertEquals(GET, pnfGet.method());
181         assertEquals(AAI_URL + LOGICAL_LINK_URL + "/" + linkName, linkPut.url());
182         assertEquals(PUT, linkPut.method());
183         assertEquals(AAI_URL + LOGICAL_LINK_URL + "/" + linkName, linkGet.url());
184         assertEquals(GET, linkGet.method());
185         assertEquals(AAI_URL + LOGICAL_LINK_URL + "/" + linkName + "?resource-version=1560171816043", linkDelete.url());
186         assertEquals(DELETE, linkDelete.method());
187         assertEquals(getBodyJson(LOGICAL_LINK_BODY), extractBodyFromRequest(linkPut));
188     }
189
190     @Test
191     void whenPassedObjectHasLogicalLink_butAaiQueryFails_returnError() {
192         // given
193         given(cbsConfiguration.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
194
195         JsonObject additionalFields = new JsonObject();
196         String linkName = "some-link";
197         additionalFields.addProperty(ATTACHMENT_POINT, linkName);
198         ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
199
200         given(httpClient.call(
201                 ArgumentMatchers.argThat(argument -> argument.url().equals(AAI_URL + PNF_URL + "/Nokia123")
202                     || argument.url().equals(AAI_URL + LOGICAL_LINK_URL + "/" + linkName))))
203             .willReturn(Mono.just(buildAaiResponse(INTERNAL_SERVER_ERROR, "")));
204
205         // when
206         Mono<ConsumerDmaapModel> response = new BbsActionsTaskImpl(cbsConfiguration, httpClient)
207             .execute(consumerDmaapModel);
208
209         // then
210         assertThatThrownBy(response::block).hasCauseInstanceOf(AaiFailureException.class).hasMessage(
211             "org.onap.dcaegen2.services.prh.exceptions.AaiFailureException: "
212                 + "Incorrect response when performing BBS-related actions: 500. Occurred in GET PNF request. Pnf name: Nokia123");
213     }
214
215     private ConsumerDmaapModel buildConsumerDmaapModel(JsonObject additionalFields) {
216         return ImmutableConsumerDmaapModel.builder()
217             .ipv4("10.16.123.234")
218             .ipv6("0:0:0:0:0:FFFF:0A10:7BEA")
219             .correlationId("Nokia123")
220             .serialNumber("QTFCOC540002E")
221             .equipVendor("nokia")
222             .equipModel("3310")
223             .equipType("type")
224             .nfRole("role")
225             .swVersion("v4.5.0.1")
226             .additionalFields(additionalFields)
227             .build();
228     }
229
230     private HttpResponse buildAaiResponse(HttpResponseStatus status, String body) {
231         return ImmutableHttpResponse
232             .builder()
233             .statusCode(status.code())
234             .url("")
235             .rawBody(body.getBytes())
236             .build();
237     }
238
239     private String extractBodyFromRequest(HttpRequest request) {
240         return Mono.from(request.body().contents()).block().toString(StandardCharsets.UTF_8);
241     }
242
243     private String getBodyJson(String filename) {
244         return new Scanner(loader.getResourceAsStream(filename)).useDelimiter("\\A").next();
245     }
246 }