Enhancements of the test env and test scripts
[nonrtric.git] / policy-agent / src / test / java / org / oransc / policyagent / clients / SdncOscA1ClientTest.java
1 /*-
2  * ========================LICENSE_START=================================
3  * O-RAN-SC
4  * %%
5  * Copyright (C) 2020 Nordix Foundation
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.oransc.policyagent.clients;
22
23 import static org.junit.Assert.fail;
24 import static org.junit.jupiter.api.Assertions.assertEquals;
25 import static org.mockito.ArgumentMatchers.anyString;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.when;
28
29 import com.google.gson.Gson;
30 import com.google.gson.JsonElement;
31
32 import java.io.File;
33 import java.io.IOException;
34 import java.net.URL;
35 import java.nio.file.Files;
36 import java.util.Arrays;
37 import java.util.List;
38 import java.util.Optional;
39
40 import org.junit.jupiter.api.BeforeEach;
41 import org.junit.jupiter.api.Test;
42 import org.junit.jupiter.api.extension.ExtendWith;
43 import org.mockito.Mock;
44 import org.mockito.junit.jupiter.MockitoExtension;
45 import org.mockito.stubbing.OngoingStubbing;
46 import org.oransc.policyagent.clients.A1Client.A1ProtocolType;
47 import org.oransc.policyagent.clients.ImmutableAdapterOutput.Builder;
48 import org.oransc.policyagent.clients.SdncOscA1Client.AdapterOutput;
49 import org.oransc.policyagent.clients.SdncOscA1Client.AdapterRequest;
50 import org.oransc.policyagent.configuration.ControllerConfig;
51 import org.oransc.policyagent.configuration.ImmutableControllerConfig;
52 import org.oransc.policyagent.repository.Policy;
53 import org.oransc.policyagent.repository.Ric;
54 import org.springframework.http.HttpStatus;
55 import org.springframework.web.reactive.function.client.WebClientResponseException;
56
57 import reactor.core.publisher.Mono;
58 import reactor.test.StepVerifier;
59
60 @ExtendWith(MockitoExtension.class)
61 class SdncOscA1ClientTest {
62     private static final String CONTROLLER_USERNAME = "username";
63     private static final String CONTROLLER_PASSWORD = "password";
64     private static final String RIC_1_URL = "RicUrl";
65     private static final String GET_A1_POLICY_URL = "/A1-ADAPTER-API:getA1Policy";
66     private static final String PUT_A1_URL = "/A1-ADAPTER-API:putA1Policy";
67     private static final String DELETE_A1_URL = "/A1-ADAPTER-API:deleteA1Policy";
68     private static final String GET_A1_POLICY_STATUS_URL = "/A1-ADAPTER-API:getA1PolicyStatus";
69     private static final String POLICY_TYPE_1_ID = "type1";
70     private static final String POLICY_1_ID = "policy1";
71     private static final String POLICY_2_ID = "policy2";
72     private static final String POLICY_JSON_VALID = "{\"scope\":{\"ueId\":\"ue1\"}}";
73
74     SdncOscA1Client clientUnderTest;
75
76     @Mock
77     AsyncRestClient asyncRestClientMock;
78
79     private ControllerConfig controllerConfig() {
80         return ImmutableControllerConfig.builder() //
81             .name("name") //
82             .baseUrl("baseUrl") //
83             .password(CONTROLLER_PASSWORD) //
84             .userName(CONTROLLER_USERNAME) //
85             .build();
86     }
87
88     @BeforeEach
89     void init() {
90         Ric ric = A1ClientHelper.createRic(RIC_1_URL);
91
92         clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_STD_V1_1, ric.getConfig(), controllerConfig(),
93             asyncRestClientMock);
94     }
95
96     @Test
97     void createClientWithWrongProtocol_thenErrorIsThrown() {
98         try {
99             new SdncOscA1Client(A1ProtocolType.STD_V1_1, null, null, new AsyncRestClient("", null));
100             fail("Should have thrown exception.");
101         } catch (IllegalArgumentException e) {
102             return;
103         }
104     }
105
106     @Test
107     void getPolicyTypeIdentities_STD() {
108         List<String> policyTypeIds = clientUnderTest.getPolicyTypeIdentities().block();
109         assertEquals(1, policyTypeIds.size(), "should hardcoded to one");
110         assertEquals("", policyTypeIds.get(0), "should hardcoded to empty");
111     }
112
113     @Test
114     void getPolicyTypeIdentities_OSC() {
115         clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, //
116             A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
117             controllerConfig(), asyncRestClientMock);
118
119         String response = createOkResponseWithBody(Arrays.asList(POLICY_TYPE_1_ID));
120         whenAsyncPostThenReturn(Mono.just(response));
121
122         List<String> policyTypeIds = clientUnderTest.getPolicyTypeIdentities().block();
123
124         assertEquals(1, policyTypeIds.size());
125         assertEquals(POLICY_TYPE_1_ID, policyTypeIds.get(0));
126
127         String expUrl = RIC_1_URL + "/a1-p/policytypes";
128         ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() //
129             .nearRtRicUrl(expUrl) //
130             .build();
131         String expInput = SdncJsonHelper.createInputJsonString(expectedParams);
132         verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME,
133             CONTROLLER_PASSWORD);
134     }
135
136     @Test
137     void getTypeSchema_STD() {
138         String policyType = clientUnderTest.getPolicyTypeSchema("").block();
139
140         assertEquals("{}", policyType);
141     }
142
143     @Test
144     void getTypeSchema_OSC() throws IOException {
145         clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, //
146             A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
147             controllerConfig(), asyncRestClientMock);
148
149         String ricResponse = loadFile("test_osc_get_schema_response.json");
150         JsonElement elem = gson().fromJson(ricResponse, JsonElement.class);
151         String responseFromController = createOkResponseWithBody(elem);
152         whenAsyncPostThenReturn(Mono.just(responseFromController));
153
154         String response = clientUnderTest.getPolicyTypeSchema("policyTypeId").block();
155
156         JsonElement respJson = gson().fromJson(response, JsonElement.class);
157         assertEquals("policyTypeId", respJson.getAsJsonObject().get("title").getAsString(),
158             "title should be updated to contain policyType ID");
159     }
160
161     @Test
162     void parseJsonArrayOfString() {
163         // One integer and one string
164         String inputString = "[1, \"1\" ]";
165
166         List<String> result = SdncJsonHelper.parseJsonArrayOfString(inputString).collectList().block();
167         assertEquals(2, result.size());
168         assertEquals("1", result.get(0));
169         assertEquals("1", result.get(1));
170     }
171
172     @Test
173     void getPolicyIdentities_STD() {
174
175         String policyIdsResp = createOkResponseWithBody(Arrays.asList(POLICY_1_ID, POLICY_2_ID));
176         whenAsyncPostThenReturn(Mono.just(policyIdsResp));
177
178         List<String> returned = clientUnderTest.getPolicyIdentities().block();
179
180         assertEquals(2, returned.size());
181
182         ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() //
183             .nearRtRicUrl(policiesUrl()) //
184             .build();
185         String expInput = SdncJsonHelper.createInputJsonString(expectedParams);
186         verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME,
187             CONTROLLER_PASSWORD);
188
189     }
190
191     @Test
192     void getPolicyIdentities_OSC() {
193         clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, //
194             A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
195             controllerConfig(), asyncRestClientMock);
196
197         String policytypeIdsResp = createOkResponseWithBody(Arrays.asList(POLICY_TYPE_1_ID));
198         String policyIdsResp = createOkResponseWithBody(Arrays.asList(POLICY_1_ID, POLICY_2_ID));
199         whenAsyncPostThenReturn(Mono.just(policytypeIdsResp)).thenReturn(Mono.just(policyIdsResp));
200
201         List<String> returned = clientUnderTest.getPolicyIdentities().block();
202
203         assertEquals(2, returned.size());
204
205         ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() //
206             .nearRtRicUrl(RIC_1_URL + "/a1-p/policytypes/type1/policies") //
207             .build();
208         String expInput = SdncJsonHelper.createInputJsonString(expectedParams);
209         verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME,
210             CONTROLLER_PASSWORD);
211     }
212
213     @Test
214     void putPolicyValidResponse() {
215         whenPostReturnOkResponse();
216
217         String returned = clientUnderTest
218             .putPolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID))
219             .block();
220
221         assertEquals("OK", returned);
222         final String expUrl = policiesUrl() + "/" + POLICY_1_ID;
223         AdapterRequest expectedInputParams = ImmutableAdapterRequest.builder() //
224             .nearRtRicUrl(expUrl) //
225             .body(POLICY_JSON_VALID) //
226             .build();
227         String expInput = SdncJsonHelper.createInputJsonString(expectedInputParams);
228
229         verify(asyncRestClientMock).postWithAuthHeader(PUT_A1_URL, expInput, CONTROLLER_USERNAME, CONTROLLER_PASSWORD);
230     }
231
232     @Test
233     void putPolicyRejected() {
234         final String policyJson = "{}";
235         AdapterOutput adapterOutput = ImmutableAdapterOutput.builder() //
236             .body("NOK") //
237             .httpStatus(HttpStatus.BAD_REQUEST.value()) // ERROR
238             .build();
239
240         String resp = SdncJsonHelper.createOutputJsonString(adapterOutput);
241         whenAsyncPostThenReturn(Mono.just(resp));
242
243         Mono<String> returnedMono = clientUnderTest
244             .putPolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, policyJson, POLICY_TYPE_1_ID));
245         StepVerifier.create(returnedMono) //
246             .expectSubscription() //
247             .expectErrorMatches(t -> t instanceof WebClientResponseException) //
248             .verify();
249
250         final String expUrl = policiesUrl() + "/" + POLICY_1_ID;
251         AdapterRequest expRequestParams = ImmutableAdapterRequest.builder() //
252             .nearRtRicUrl(expUrl) //
253             .body(policyJson) //
254             .build();
255         String expRequest = SdncJsonHelper.createInputJsonString(expRequestParams);
256         verify(asyncRestClientMock).postWithAuthHeader(PUT_A1_URL, expRequest, CONTROLLER_USERNAME,
257             CONTROLLER_PASSWORD);
258         StepVerifier.create(returnedMono)
259             .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify();
260     }
261
262     @Test
263     void deletePolicy() {
264         whenPostReturnOkResponse();
265
266         String returned = clientUnderTest
267             .deletePolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID))
268             .block();
269
270         assertEquals("OK", returned);
271         final String expUrl = policiesUrl() + "/" + POLICY_1_ID;
272         AdapterRequest expectedInputParams = ImmutableAdapterRequest.builder() //
273             .nearRtRicUrl(expUrl) //
274             .build();
275         String expInput = SdncJsonHelper.createInputJsonString(expectedInputParams);
276
277         verify(asyncRestClientMock).postWithAuthHeader(DELETE_A1_URL, expInput, CONTROLLER_USERNAME,
278             CONTROLLER_PASSWORD);
279     }
280
281     @Test
282     void getStatus() {
283         whenPostReturnOkResponse();
284
285         Policy policy = A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID);
286
287         String returnedStatus = clientUnderTest.getPolicyStatus(policy).block();
288
289         assertEquals("OK", returnedStatus, "unexpected status");
290
291         final String expUrl = policiesUrl() + "/" + POLICY_1_ID + "/status";
292         AdapterRequest expectedInputParams = ImmutableAdapterRequest.builder() //
293             .nearRtRicUrl(expUrl) //
294             .build();
295         String expInput = SdncJsonHelper.createInputJsonString(expectedInputParams);
296
297         verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_STATUS_URL, expInput, CONTROLLER_USERNAME,
298             CONTROLLER_PASSWORD);
299     }
300
301     @Test
302     void getVersion_STD() {
303         whenPostReturnOkResponse();
304
305         A1ProtocolType returnedVersion = clientUnderTest.getProtocolVersion().block();
306
307         assertEquals(A1ProtocolType.SDNC_OSC_STD_V1_1, returnedVersion);
308
309         whenPostReturnOkResponseNoBody();
310
311         returnedVersion = clientUnderTest.getProtocolVersion().block();
312
313         assertEquals(A1ProtocolType.SDNC_OSC_STD_V1_1, returnedVersion);
314     }
315
316     @Test
317     void getVersion_OSC() {
318         clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, //
319             A1ClientHelper.createRic(RIC_1_URL).getConfig(), //
320             controllerConfig(), asyncRestClientMock);
321
322         whenAsyncPostThenReturn(Mono.error(new Exception("Error"))).thenReturn(Mono.just(createOkResponseString(true)));
323
324         A1ProtocolType returnedVersion = clientUnderTest.getProtocolVersion().block();
325
326         assertEquals(A1ProtocolType.SDNC_OSC_OSC_V1, returnedVersion);
327     }
328
329     private String policiesUrl() {
330         return RIC_1_URL + "/A1-P/v1/policies";
331     }
332
333     private Gson gson() {
334         return SdncOscA1Client.gson;
335     }
336
337     private String loadFile(String fileName) throws IOException {
338         ClassLoader loader = Thread.currentThread().getContextClassLoader();
339         URL url = loader.getResource(fileName);
340         File file = new File(url.getFile());
341         return new String(Files.readAllBytes(file.toPath()));
342     }
343
344     private void whenPostReturnOkResponse() {
345         whenAsyncPostThenReturn(Mono.just(createOkResponseString(true)));
346     }
347
348     private void whenPostReturnOkResponseNoBody() {
349         whenAsyncPostThenReturn(Mono.just(createOkResponseString(false)));
350     }
351
352     private String createOkResponseWithBody(Object body) {
353         AdapterOutput output = ImmutableAdapterOutput.builder() //
354             .body(gson().toJson(body)) //
355             .httpStatus(HttpStatus.OK.value()) //
356             .build();
357         return SdncJsonHelper.createOutputJsonString(output);
358     }
359
360     private String createOkResponseString(boolean withBody) {
361         Builder responseBuilder = ImmutableAdapterOutput.builder().httpStatus(HttpStatus.OK.value());
362         if (withBody) {
363             responseBuilder.body(HttpStatus.OK.name());
364         } else {
365             responseBuilder.body(Optional.empty());
366         }
367         return SdncJsonHelper.createOutputJsonString(responseBuilder.build());
368     }
369
370     private OngoingStubbing<Mono<String>> whenAsyncPostThenReturn(Mono<String> response) {
371         return when(asyncRestClientMock.postWithAuthHeader(anyString(), anyString(), anyString(), anyString()))
372             .thenReturn(response);
373     }
374 }