02feae12258671be8c22319650dfb42fbf2cbddf
[policy/models.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2023-2024 Nordix Foundation.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.controlloop.actor.appclcm;
23
24 import static org.assertj.core.api.Assertions.assertThat;
25 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
26 import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
27 import static org.junit.jupiter.api.Assertions.assertEquals;
28 import static org.junit.jupiter.api.Assertions.assertFalse;
29 import static org.junit.jupiter.api.Assertions.assertNotNull;
30 import static org.junit.jupiter.api.Assertions.assertNull;
31 import static org.junit.jupiter.api.Assertions.assertSame;
32 import static org.junit.jupiter.api.Assertions.assertTrue;
33
34 import java.util.HashMap;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Set;
38 import java.util.stream.Collectors;
39 import org.junit.jupiter.api.AfterAll;
40 import org.junit.jupiter.api.AfterEach;
41 import org.junit.jupiter.api.BeforeAll;
42 import org.junit.jupiter.api.BeforeEach;
43 import org.junit.jupiter.api.Test;
44 import org.junit.jupiter.api.extension.ExtendWith;
45 import org.mockito.junit.jupiter.MockitoExtension;
46 import org.onap.policy.appclcm.AppcLcmBody;
47 import org.onap.policy.appclcm.AppcLcmCommonHeader;
48 import org.onap.policy.appclcm.AppcLcmMessageWrapper;
49 import org.onap.policy.appclcm.AppcLcmOutput;
50 import org.onap.policy.appclcm.AppcLcmResponseStatus;
51 import org.onap.policy.common.message.bus.event.TopicSink;
52 import org.onap.policy.common.message.bus.event.TopicSource;
53 import org.onap.policy.common.utils.coder.Coder;
54 import org.onap.policy.common.utils.coder.CoderException;
55 import org.onap.policy.common.utils.coder.StandardCoder;
56 import org.onap.policy.controlloop.ControlLoopOperation;
57 import org.onap.policy.controlloop.actor.test.BasicBidirectionalTopicOperation;
58 import org.onap.policy.controlloop.actorserviceprovider.OperationProperties;
59 import org.onap.policy.controlloop.actorserviceprovider.OperationResult;
60 import org.onap.policy.controlloop.actorserviceprovider.impl.BidirectionalTopicOperation.Status;
61 import org.onap.policy.controlloop.actorserviceprovider.parameters.BidirectionalTopicConfig;
62 import org.onap.policy.controlloop.actorserviceprovider.parameters.BidirectionalTopicParams;
63 import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
64 import org.onap.policy.simulators.AppcLcmTopicServer;
65 import org.onap.policy.simulators.TopicServer;
66
67 @ExtendWith(MockitoExtension.class)
68  class AppcLcmOperationTest extends BasicBidirectionalTopicOperation<AppcLcmMessageWrapper> {
69
70     private static final String EXPECTED_EXCEPTION = "expected exception";
71     private static final String PAYLOAD_KEY1 = "key-A";
72     private static final String PAYLOAD_VALUE1 = "value-A";
73     private static final String MY_MESSAGE = "my-message";
74     protected static final String MY_VNF = "my-vnf";
75     protected static final String RESOURCE_ID = "my-resource";
76     private static final int SUCCESS_CODE = 400;
77
78     private AppcLcmMessageWrapper response;
79     private AppcLcmOperation oper;
80
81     @BeforeAll
82      static void setUpBeforeClass() throws Exception {
83         initBeforeClass(MY_SINK, MY_SOURCE);
84     }
85
86     @AfterAll
87      static void tearDownAfterClass() {
88         destroyAfterClass();
89     }
90
91     /**
92      * Sets up.
93      */
94     @BeforeEach
95      void setUp() {
96         super.setUpBasic();
97
98         response = makeResponse();
99
100         oper = new AppcLcmOperation(params, config);
101         oper.setProperty(OperationProperties.AAI_TARGET_ENTITY, TARGET_ENTITY);
102     }
103
104     @AfterEach
105      void tearDown() {
106         super.tearDownBasic();
107     }
108
109     @Override
110     protected TopicServer<AppcLcmMessageWrapper> makeServer(TopicSink sink, TopicSource source) {
111         return new AppcLcmTopicServer(sink, source);
112     }
113
114     /**
115      * Tests "success" case with simulator.
116      */
117     @Test
118      void testSuccess() throws Exception {
119         BidirectionalTopicParams opParams =
120                         BidirectionalTopicParams.builder().sinkTopic(MY_SINK).sourceTopic(MY_SOURCE).build();
121         config = new BidirectionalTopicConfig(blockingExecutor, opParams, topicMgr, AppcLcmOperation.SELECTOR_KEYS);
122
123         params = params.toBuilder().retry(0).timeoutSec(5).executor(blockingExecutor).build();
124
125         oper = new AppcLcmOperation(params, config);
126         oper.setProperty(OperationProperties.AAI_TARGET_ENTITY, TARGET_ENTITY);
127
128         outcome = oper.start().get();
129         assertNotNull(outcome);
130     }
131
132     @Test
133      void testConstructor() {
134         assertEquals(DEFAULT_ACTOR, oper.getActorName());
135         assertEquals(DEFAULT_OPERATION, oper.getName());
136     }
137
138     @Test
139      void testGetPropertyNames() {
140         assertThat(oper.getPropertyNames()).isEqualTo(List.of(OperationProperties.AAI_TARGET_ENTITY));
141     }
142
143     @Test
144      void testMakeRequest() {
145         oper.generateSubRequestId(2);
146         String subreq = oper.getSubRequestId();
147         assertNotNull(subreq);
148
149         AppcLcmMessageWrapper request = oper.makeRequest(2);
150         assertEquals("DefaultOperation", request.getBody().getInput().getAction());
151
152         AppcLcmCommonHeader header = request.getBody().getInput().getCommonHeader();
153         assertNotNull(header);
154         assertEquals(params.getRequestId(), header.getRequestId());
155
156         assertEquals(subreq, header.getSubRequestId());
157
158         assertEquals("{vnf-id=my-target}", request.getBody().getInput().getActionIdentifiers().toString());
159
160         request = oper.makeRequest(2);
161         assertEquals(subreq, request.getBody().getInput().getCommonHeader().getSubRequestId());
162     }
163
164     /**
165      * Tests makeRequest() when a property is missing.
166      */
167     @Test
168      void testMakeRequestMissingProperty() {
169         oper = new AppcLcmOperation(params, config);
170         oper.generateSubRequestId(1);
171
172         assertThatIllegalStateException().isThrownBy(() -> oper.makeRequest(1))
173                         .withMessageContaining("missing target entity");
174     }
175
176     @Test
177      void testConvertPayload() {
178         // only builds a payload for ConfigModify
179         params = params.toBuilder().operation(AppcLcmConstants.OPERATION_CONFIG_MODIFY).build();
180         oper = new AppcLcmOperation(params, config);
181         oper.setProperty(OperationProperties.AAI_TARGET_ENTITY, TARGET_ENTITY);
182
183         oper.generateSubRequestId(2);
184         AppcLcmMessageWrapper req = oper.makeRequest(2);
185         assertEquals("{\"key-A\":\"value-A\"}", req.getBody().getInput().getPayload());
186
187         // coder exception
188         oper = new AppcLcmOperation(params, config) {
189             @Override
190             protected Coder getCoder() {
191                 return new StandardCoder() {
192                     @Override
193                     public String encode(Object object) throws CoderException {
194                         throw new CoderException(EXPECTED_EXCEPTION);
195                     }
196                 };
197             }
198         };
199
200         oper.setProperty(OperationProperties.AAI_TARGET_ENTITY, TARGET_ENTITY);
201         oper.generateSubRequestId(2);
202
203         assertThatIllegalArgumentException().isThrownBy(() -> oper.makeRequest(2))
204                         .withMessageContaining("Cannot convert payload");
205     }
206
207     @Test
208      void testGetExpectedKeyValues() {
209         oper.generateSubRequestId(2);
210         AppcLcmMessageWrapper request = oper.makeRequest(2);
211         assertEquals(List.of(request.getBody().getInput().getCommonHeader().getSubRequestId()),
212                         oper.getExpectedKeyValues(50, request));
213     }
214
215     @Test
216      void testDetmStatus() {
217         assertEquals(Status.SUCCESS, oper.detmStatus(null, response));
218
219         // failure
220         response.getBody().getOutput().getStatus().setCode(405);
221         assertEquals(Status.FAILURE, oper.detmStatus(null, response));
222
223         // error
224         response.getBody().getOutput().getStatus().setCode(200);
225         assertThatIllegalArgumentException().isThrownBy(() -> oper.detmStatus(null, response));
226
227         // reject
228         response.getBody().getOutput().getStatus().setCode(305);
229         assertThatIllegalArgumentException().isThrownBy(() -> oper.detmStatus(null, response));
230
231         // accepted
232         response.getBody().getOutput().getStatus().setCode(100);
233         assertEquals(Status.STILL_WAITING, oper.detmStatus(null, response));
234
235         // other
236         response.getBody().getOutput().getStatus().setCode(-1);
237         assertThatIllegalArgumentException().isThrownBy(() -> oper.detmStatus(null, response));
238
239         // null status
240         response.getBody().getOutput().setStatus(null);
241         assertThatIllegalArgumentException().isThrownBy(() -> oper.detmStatus(null, response));
242     }
243
244     @Test
245      void testSetOutcome() {
246         oper.setOutcome(outcome, OperationResult.SUCCESS, response);
247         assertEquals(OperationResult.SUCCESS, outcome.getResult());
248         assertEquals(MY_MESSAGE, outcome.getMessage());
249         assertSame(response, outcome.getResponse());
250
251         // failure
252         oper.setOutcome(outcome, OperationResult.FAILURE, response);
253         assertEquals(OperationResult.FAILURE, outcome.getResult());
254         assertEquals(MY_MESSAGE, outcome.getMessage());
255         assertSame(response, outcome.getResponse());
256
257         // null message
258         response.getBody().getOutput().getStatus().setMessage(null);
259         oper.setOutcome(outcome, OperationResult.SUCCESS, response);
260         assertEquals(ControlLoopOperation.SUCCESS_MSG, outcome.getMessage());
261         assertSame(response, outcome.getResponse());
262
263         // null status
264         response.getBody().getOutput().setStatus(null);
265         oper.setOutcome(outcome, OperationResult.SUCCESS, response);
266         assertEquals(ControlLoopOperation.SUCCESS_MSG, outcome.getMessage());
267         assertSame(response, outcome.getResponse());
268     }
269
270     @Test
271      void testGetStatus() {
272         assertNotNull(oper.getStatus(response));
273
274         // null status
275         response.getBody().getOutput().setStatus(null);
276         assertNull(oper.getStatus(response));
277
278         // null outcome
279         response.getBody().setOutput(null);
280         assertNull(oper.getStatus(response));
281
282         // null body
283         response.setBody(null);
284         assertNull(oper.getStatus(response));
285
286         // null response
287         assertNull(oper.getStatus(null));
288     }
289
290     @Test
291      void testOperationSupportsPayload() {
292         // these should support a payload
293         Set<String> supported = Set.of(AppcLcmConstants.OPERATION_CONFIG_MODIFY);
294
295         for (String name : supported) {
296             params = params.toBuilder().operation(name).build();
297             oper = new AppcLcmOperation(params, config);
298             assertTrue(oper.operationSupportsPayload(), name);
299         }
300
301         // these should NOT support a payload
302         Set<String> unsupported = AppcLcmConstants.OPERATION_NAMES.stream().filter(name -> !supported.contains(name))
303                         .collect(Collectors.toSet());
304
305         for (String name : unsupported) {
306             params = params.toBuilder().operation(name).build();
307             oper = new AppcLcmOperation(params, config);
308             assertFalse(oper.operationSupportsPayload(), name);
309         }
310
311         // pick an operation that would ordinarily support payloads
312         String sup = supported.iterator().next();
313
314         // verify that it still supports payload
315         params = params.toBuilder().operation(sup).build();
316         oper = new AppcLcmOperation(params, config);
317         assertTrue(oper.operationSupportsPayload());
318
319         // try with empty payload
320         params = params.toBuilder().payload(Map.of()).build();
321         oper = new AppcLcmOperation(params, config);
322         assertFalse(oper.operationSupportsPayload());
323
324         // try with null payload
325         params = params.toBuilder().payload(null).build();
326         oper = new AppcLcmOperation(params, config);
327         assertFalse(oper.operationSupportsPayload());
328     }
329
330     @Override
331     protected void makeContext() {
332         super.makeContext();
333
334         Map<String, String> targetEntities = new HashMap<>();
335         targetEntities.put(ControlLoopOperationParams.PARAMS_ENTITY_RESOURCEID, RESOURCE_ID);
336
337         params = params.toBuilder().targetEntityIds(targetEntities).build();
338     }
339
340     @Override
341     protected Map<String, Object> makePayload() {
342         return Map.of(PAYLOAD_KEY1, PAYLOAD_VALUE1);
343     }
344
345     private AppcLcmMessageWrapper makeResponse() {
346         AppcLcmMessageWrapper response = new AppcLcmMessageWrapper();
347
348         AppcLcmBody body = new AppcLcmBody();
349         response.setBody(body);
350
351         AppcLcmOutput output = new AppcLcmOutput();
352         body.setOutput(output);
353
354         AppcLcmResponseStatus status = new AppcLcmResponseStatus();
355         output.setStatus(status);
356         status.setMessage(MY_MESSAGE);
357         status.setCode(SUCCESS_CODE);
358
359         return response;
360     }
361 }