Logical links creation bug
[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 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.buffer.ByteBuf;
40 import io.netty.handler.codec.http.HttpResponseStatus;
41 import java.nio.charset.StandardCharsets;
42 import java.util.List;
43 import java.util.Scanner;
44 import org.junit.jupiter.api.Test;
45 import org.mockito.ArgumentCaptor;
46 import org.mockito.ArgumentMatchers;
47 import org.onap.dcaegen2.services.prh.TestAppConfiguration;
48 import org.onap.dcaegen2.services.prh.configuration.CbsConfiguration;
49 import org.onap.dcaegen2.services.prh.exceptions.AaiFailureException;
50 import org.onap.dcaegen2.services.prh.model.ConsumerDmaapModel;
51 import org.onap.dcaegen2.services.prh.model.ImmutableConsumerDmaapModel;
52 import org.onap.dcaegen2.services.sdk.rest.services.aai.client.config.AaiClientConfiguration;
53 import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpRequest;
54 import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpResponse;
55 import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.ImmutableHttpResponse;
56 import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.RxHttpClient;
57 import reactor.core.publisher.Mono;
58
59 class BbsActionsTaskTest {
60
61     private static final String AAI_URL = "https://aai.onap.svc.cluster.local:8443/aai/v12/network";
62     private static final String PNF_URL = "/pnfs/pnf";
63     private static final String LOGICAL_LINK_URL = "/logical-links/logical-link";
64     private static final String ATTACHMENT_POINT = "attachment-point";
65
66     private static final String PNF_WITHOUT_LINK_JSON = "BbsActionsTaskTestFiles/pnfWithoutLinks.json";
67     private static final String PNF_WITH_LINK_JSON = "BbsActionsTaskTestFiles/pnfWithLogicalLink.json";
68     private static final String LOGICAL_LINK_JSON = "BbsActionsTaskTestFiles/oldLogicalLink.json";
69     private static final String LOGICAL_LINK_BODY = "BbsActionsTaskTestFiles/logicalLinkBody.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         additionalFields.addProperty(ATTACHMENT_POINT, linkName);
117         ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
118
119         given(httpClient.call(any()))
120             .willReturn(Mono.just(buildAaiResponse(OK, getBodyJson(PNF_WITHOUT_LINK_JSON))),
121                 Mono.just(buildAaiResponse(OK, "")));
122
123         // when
124         Mono<ConsumerDmaapModel> response = new BbsActionsTaskImpl(cbsConfiguration, httpClient).execute(consumerDmaapModel);
125
126         // then
127         assertEquals(consumerDmaapModel, response.block());
128
129         ArgumentCaptor<HttpRequest> captor = ArgumentCaptor.forClass(HttpRequest.class);
130         verify(httpClient, times(2)).call(captor.capture());
131
132         List<HttpRequest> args = captor.getAllValues();
133         assertEquals(2, args.size());
134
135         HttpRequest pnfGet = args.get(0);
136         HttpRequest linkPut = args.get(1);
137
138         assertEquals(AAI_URL + PNF_URL + "/Nokia123", pnfGet.url());
139         assertEquals(GET, pnfGet.method());
140         assertEquals(AAI_URL + LOGICAL_LINK_URL + "/" + linkName, linkPut.url());
141         assertEquals(PUT, linkPut.method());
142         assertEquals(getBodyJson(LOGICAL_LINK_BODY), extractBodyFromRequest(linkPut));
143     }
144
145     @Test
146     void whenPassedObjectHasLogicalLink_and_pnfHasLogicalLink_deleteOldLogicalLink_and_createLogicalLink_and_associateWithPnf_and_ReturnPayloadTransparently() {
147         // given
148         given(cbsConfiguration.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
149
150         JsonObject additionalFields = new JsonObject();
151         String linkName = "some-link";
152         additionalFields.addProperty(ATTACHMENT_POINT, linkName);
153         ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
154
155         given(httpClient.call(any()))
156             .willReturn(Mono.just(buildAaiResponse(OK, getBodyJson(PNF_WITH_LINK_JSON))),
157                 Mono.just(buildAaiResponse(OK, "")),
158                 Mono.just(buildAaiResponse(OK, getBodyJson(LOGICAL_LINK_JSON))),
159                 Mono.just(buildAaiResponse(OK, "")));
160
161         // when
162         Mono<ConsumerDmaapModel> response = new BbsActionsTaskImpl(cbsConfiguration, httpClient).execute(consumerDmaapModel);
163
164         // then
165         assertEquals(consumerDmaapModel, response.block());
166
167         ArgumentCaptor<HttpRequest> captor = ArgumentCaptor.forClass(HttpRequest.class);
168         verify(httpClient, times(4)).call(captor.capture());
169
170         List<HttpRequest> args = captor.getAllValues();
171         assertEquals(4, args.size());
172
173         HttpRequest pnfGet = args.get(0);
174         HttpRequest linkPut = args.get(1);
175         HttpRequest linkGet = args.get(2);
176         HttpRequest linkDelete = args.get(3);
177
178         assertEquals(AAI_URL + PNF_URL + "/Nokia123", pnfGet.url());
179         assertEquals(GET, pnfGet.method());
180         assertEquals(AAI_URL + LOGICAL_LINK_URL + "/" + linkName, linkPut.url());
181         assertEquals(PUT, linkPut.method());
182         assertEquals(AAI_URL + LOGICAL_LINK_URL + "/" + linkName, linkGet.url());
183         assertEquals(GET, linkGet.method());
184         assertEquals(AAI_URL + LOGICAL_LINK_URL + "/" + linkName + "?resource-version=1560171816043", linkDelete.url());
185         assertEquals(DELETE, linkDelete.method());
186         assertEquals(getBodyJson(LOGICAL_LINK_BODY), extractBodyFromRequest(linkPut));
187     }
188
189     @Test
190     void whenPassedObjectHasLogicalLink_butAaiQueryFails_returnError() {
191         // given
192         given(cbsConfiguration.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
193
194         JsonObject additionalFields = new JsonObject();
195         String linkName = "some-link";
196         additionalFields.addProperty(ATTACHMENT_POINT, linkName);
197         ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
198
199         given(httpClient.call(
200                 ArgumentMatchers.argThat(argument -> argument.url().equals(AAI_URL + PNF_URL + "/Nokia123")
201                     || argument.url().equals(AAI_URL + LOGICAL_LINK_URL + "/" + linkName))))
202             .willReturn(Mono.just(buildAaiResponse(INTERNAL_SERVER_ERROR, "")));
203
204         // when
205         Mono<ConsumerDmaapModel> response = new BbsActionsTaskImpl(cbsConfiguration, httpClient)
206             .execute(consumerDmaapModel);
207
208         // then
209         assertThatThrownBy(response::block).hasCauseInstanceOf(AaiFailureException.class).hasMessage(
210             "org.onap.dcaegen2.services.prh.exceptions.AaiFailureException: "
211                 + "Incorrect response when performing BBS-related actions: 500. Occurred in GET PNF request. Pnf name: Nokia123");
212     }
213
214     private ConsumerDmaapModel buildConsumerDmaapModel(JsonObject additionalFields) {
215         return ImmutableConsumerDmaapModel.builder()
216             .ipv4("10.16.123.234")
217             .ipv6("0:0:0:0:0:FFFF:0A10:7BEA")
218             .correlationId("Nokia123")
219             .serialNumber("QTFCOC540002E")
220             .equipVendor("nokia")
221             .equipModel("3310")
222             .equipType("type")
223             .nfRole("role")
224             .swVersion("v4.5.0.1")
225             .additionalFields(additionalFields)
226             .build();
227     }
228
229     private HttpResponse buildAaiResponse(HttpResponseStatus status, String body) {
230         return ImmutableHttpResponse
231             .builder()
232             .statusCode(status.code())
233             .url("")
234             .rawBody(body.getBytes())
235             .build();
236     }
237
238     private String extractBodyFromRequest(HttpRequest request) {
239         return Mono.from(request.body().contents()).block().toString(StandardCharsets.UTF_8);
240     }
241
242     private String getBodyJson(String filename) {
243         return new Scanner(loader.getResourceAsStream(filename)).useDelimiter("\\A").next();
244     }
245 }