2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020 AT&T 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
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.policy.controlloop.actor.appclcm;
23 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertFalse;
26 import static org.junit.Assert.assertNotNull;
27 import static org.junit.Assert.assertNull;
28 import static org.junit.Assert.assertTrue;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.when;
32 import java.util.Arrays;
35 import java.util.concurrent.CompletableFuture;
36 import java.util.concurrent.atomic.AtomicBoolean;
37 import java.util.stream.Collectors;
38 import org.junit.After;
39 import org.junit.AfterClass;
40 import org.junit.Before;
41 import org.junit.BeforeClass;
42 import org.junit.Test;
43 import org.onap.policy.appclcm.AppcLcmBody;
44 import org.onap.policy.appclcm.AppcLcmCommonHeader;
45 import org.onap.policy.appclcm.AppcLcmDmaapWrapper;
46 import org.onap.policy.appclcm.AppcLcmOutput;
47 import org.onap.policy.appclcm.AppcLcmResponseStatus;
48 import org.onap.policy.common.endpoints.event.comm.TopicSink;
49 import org.onap.policy.common.endpoints.event.comm.TopicSource;
50 import org.onap.policy.common.utils.coder.Coder;
51 import org.onap.policy.common.utils.coder.CoderException;
52 import org.onap.policy.common.utils.coder.StandardCoder;
53 import org.onap.policy.controlloop.ControlLoopOperation;
54 import org.onap.policy.controlloop.actor.test.BasicBidirectionalTopicOperation;
55 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
56 import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext;
57 import org.onap.policy.controlloop.actorserviceprovider.impl.BidirectionalTopicOperation.Status;
58 import org.onap.policy.controlloop.actorserviceprovider.parameters.BidirectionalTopicConfig;
59 import org.onap.policy.controlloop.actorserviceprovider.parameters.BidirectionalTopicParams;
60 import org.onap.policy.controlloop.policy.PolicyResult;
61 import org.onap.policy.controlloop.policy.Target;
62 import org.onap.policy.simulators.AppcLcmTopicServer;
63 import org.onap.policy.simulators.TopicServer;
65 public class AppcLcmOperationTest extends BasicBidirectionalTopicOperation {
67 private static final String EXPECTED_EXCEPTION = "expected exception";
68 private static final String PAYLOAD_KEY1 = "key-A";
69 private static final String PAYLOAD_VALUE1 = "value-A";
70 private static final String MY_MESSAGE = "my-message";
71 protected static final String MY_VNF = "my-vnf";
72 protected static final String RESOURCE_ID = "my-resource";
73 private static final int SUCCESS_CODE = 400;
75 private AppcLcmDmaapWrapper response;
76 private AppcLcmOperation oper;
79 public static void setUpBeforeClass() throws Exception {
80 initBeforeClass(MY_SINK, MY_SOURCE);
84 public static void tearDownAfterClass() {
95 response = makeResponse();
97 oper = new AppcLcmOperation(params, config);
101 public void tearDown() {
102 super.tearDownBasic();
105 @SuppressWarnings("rawtypes")
106 protected TopicServer makeServer(TopicSink sink, TopicSource source) {
107 return new AppcLcmTopicServer(sink, source);
111 * Tests "success" case with simulator.
114 public void testSuccess() throws Exception {
115 BidirectionalTopicParams opParams =
116 BidirectionalTopicParams.builder().sinkTopic(MY_SINK).sourceTopic(MY_SOURCE).build();
117 config = new BidirectionalTopicConfig(blockingExecutor, opParams, topicMgr, AppcLcmOperation.SELECTOR_KEYS);
119 params = params.toBuilder().retry(0).timeoutSec(5).executor(blockingExecutor).build();
121 oper = new AppcLcmOperation(params, config) {
123 protected CompletableFuture<OperationOutcome> startGuardAsync() {
128 outcome = oper.start().get();
129 assertEquals(PolicyResult.SUCCESS, outcome.getResult());
133 public void testConstructor() {
134 assertEquals(DEFAULT_ACTOR, oper.getActorName());
135 assertEquals(DEFAULT_OPERATION, oper.getName());
137 // missing target entity
138 params = params.toBuilder().targetEntity("").build();
139 assertThatIllegalArgumentException().isThrownBy(() -> new AppcLcmOperation(params, config))
140 .withMessage("missing targetEntity");
144 public void testStartPreprocessorAsync() throws Exception {
145 context = mock(ControlLoopEventContext.class);
146 when(context.getEvent()).thenReturn(event);
147 params = params.toBuilder().context(context).build();
149 AtomicBoolean guardStarted = new AtomicBoolean();
151 oper = new AppcLcmOperation(params, config) {
153 protected CompletableFuture<OperationOutcome> startGuardAsync() {
154 guardStarted.set(true);
155 return super.startGuardAsync();
159 CompletableFuture<OperationOutcome> future2 = oper.startPreprocessorAsync();
160 assertNotNull(future2);
161 assertFalse(future.isDone());
162 assertTrue(guardStarted.get());
164 assertTrue(executor.runAll(100));
165 assertTrue(future2.isDone());
166 assertEquals(PolicyResult.SUCCESS, future2.get().getResult());
170 public void testMakeRequest() {
171 oper.generateSubRequestId(2);
172 String subreq = oper.getSubRequestId();
173 assertNotNull(subreq);
175 AppcLcmDmaapWrapper request = oper.makeRequest(2);
176 assertEquals("DefaultOperation", request.getBody().getInput().getAction());
178 AppcLcmCommonHeader header = request.getBody().getInput().getCommonHeader();
179 assertNotNull(header);
180 assertEquals(params.getRequestId(), header.getRequestId());
182 assertEquals(subreq, header.getSubRequestId());
184 assertEquals("{vnf-id=my-target}", request.getBody().getInput().getActionIdentifiers().toString());
186 request = oper.makeRequest(2);
187 assertEquals(subreq, request.getBody().getInput().getCommonHeader().getSubRequestId());
191 public void testConvertPayload() {
192 // only builds a payload for ConfigModify
193 params = params.toBuilder().operation(AppcLcmConstants.OPERATION_CONFIG_MODIFY).build();
194 oper = new AppcLcmOperation(params, config);
196 oper.generateSubRequestId(2);
197 AppcLcmDmaapWrapper req = oper.makeRequest(2);
198 assertEquals("{\"key-A\":\"value-A\"}", req.getBody().getInput().getPayload());
201 oper = new AppcLcmOperation(params, config) {
203 protected Coder makeCoder() {
204 return new StandardCoder() {
206 public String encode(Object object) throws CoderException {
207 throw new CoderException(EXPECTED_EXCEPTION);
213 oper.generateSubRequestId(2);
215 assertThatIllegalArgumentException().isThrownBy(() -> oper.makeRequest(2))
216 .withMessage("Cannot convert payload");
220 public void testGetExpectedKeyValues() {
221 oper.generateSubRequestId(2);
222 AppcLcmDmaapWrapper request = oper.makeRequest(2);
223 assertEquals(Arrays.asList(request.getBody().getInput().getCommonHeader().getSubRequestId()),
224 oper.getExpectedKeyValues(50, request));
228 public void testDetmStatus() {
229 assertEquals(Status.SUCCESS, oper.detmStatus(null, response));
232 response.getBody().getOutput().getStatus().setCode(405);
233 assertEquals(Status.FAILURE, oper.detmStatus(null, response));
236 response.getBody().getOutput().getStatus().setCode(200);
237 assertThatIllegalArgumentException().isThrownBy(() -> oper.detmStatus(null, response));
240 response.getBody().getOutput().getStatus().setCode(305);
241 assertThatIllegalArgumentException().isThrownBy(() -> oper.detmStatus(null, response));
244 response.getBody().getOutput().getStatus().setCode(100);
245 assertEquals(Status.STILL_WAITING, oper.detmStatus(null, response));
248 response.getBody().getOutput().getStatus().setCode(-1);
249 assertThatIllegalArgumentException().isThrownBy(() -> oper.detmStatus(null, response));
252 response.getBody().getOutput().setStatus(null);
253 assertThatIllegalArgumentException().isThrownBy(() -> oper.detmStatus(null, response));
257 public void testSetOutcome() {
258 oper.setOutcome(outcome, PolicyResult.SUCCESS, response);
259 assertEquals(PolicyResult.SUCCESS, outcome.getResult());
260 assertEquals(MY_MESSAGE, outcome.getMessage());
263 oper.setOutcome(outcome, PolicyResult.FAILURE, response);
264 assertEquals(PolicyResult.FAILURE, outcome.getResult());
265 assertEquals(MY_MESSAGE, outcome.getMessage());
268 response.getBody().getOutput().getStatus().setMessage(null);
269 oper.setOutcome(outcome, PolicyResult.SUCCESS, response);
270 assertEquals(ControlLoopOperation.SUCCESS_MSG, outcome.getMessage());
273 response.getBody().getOutput().setStatus(null);
274 oper.setOutcome(outcome, PolicyResult.SUCCESS, response);
275 assertEquals(ControlLoopOperation.SUCCESS_MSG, outcome.getMessage());
279 public void testGetStatus() {
280 assertNotNull(oper.getStatus(response));
283 response.getBody().getOutput().setStatus(null);
284 assertNull(oper.getStatus(response));
287 response.getBody().setOutput(null);
288 assertNull(oper.getStatus(response));
291 response.setBody(null);
292 assertNull(oper.getStatus(response));
295 assertNull(oper.getStatus(null));
299 public void testOperationSupportsPayload() {
300 // these should support a payload
301 Set<String> supported = Set.of(AppcLcmConstants.OPERATION_CONFIG_MODIFY);
303 for (String name : supported) {
304 params = params.toBuilder().operation(name).build();
305 oper = new AppcLcmOperation(params, config);
306 assertTrue(name, oper.operationSupportsPayload());
309 // these should NOT support a payload
310 Set<String> unsupported = AppcLcmConstants.OPERATION_NAMES.stream().filter(name -> !supported.contains(name))
311 .collect(Collectors.toSet());
313 for (String name : unsupported) {
314 params = params.toBuilder().operation(name).build();
315 oper = new AppcLcmOperation(params, config);
316 assertFalse(name, oper.operationSupportsPayload());
319 // pick an operation that would ordinarily support payloads
320 String sup = supported.iterator().next();
322 // verify that it still supports payload
323 params = params.toBuilder().operation(sup).build();
324 oper = new AppcLcmOperation(params, config);
325 assertTrue(oper.operationSupportsPayload());
327 // try with empty payload
328 params = params.toBuilder().payload(Map.of()).build();
329 oper = new AppcLcmOperation(params, config);
330 assertFalse(oper.operationSupportsPayload());
332 // try with null payload
333 params = params.toBuilder().payload(null).build();
334 oper = new AppcLcmOperation(params, config);
335 assertFalse(oper.operationSupportsPayload());
339 protected void makeContext() {
342 Target target = new Target();
343 target.setResourceID(RESOURCE_ID);
345 params = params.toBuilder().target(target).build();
349 protected Map<String, Object> makePayload() {
350 return Map.of(PAYLOAD_KEY1, PAYLOAD_VALUE1);
353 private AppcLcmDmaapWrapper makeResponse() {
354 AppcLcmDmaapWrapper response = new AppcLcmDmaapWrapper();
356 AppcLcmBody body = new AppcLcmBody();
357 response.setBody(body);
359 AppcLcmOutput output = new AppcLcmOutput();
360 body.setOutput(output);
362 AppcLcmResponseStatus status = new AppcLcmResponseStatus();
363 output.setStatus(status);
364 status.setMessage(MY_MESSAGE);
365 status.setCode(SUCCESS_CODE);