Add subrequest ID to OperationOutcome
[policy/models.git] / models-interactions / model-actors / actor.guard / src / test / java / org / onap / policy / controlloop / actor / guard / GuardOperationTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
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
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.policy.controlloop.actor.guard;
22
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.assertTrue;
27 import static org.mockito.ArgumentMatchers.any;
28 import static org.mockito.Mockito.mock;
29 import static org.mockito.Mockito.never;
30 import static org.mockito.Mockito.verify;
31 import static org.mockito.Mockito.when;
32
33 import java.util.Map;
34 import java.util.TreeMap;
35 import java.util.concurrent.CompletableFuture;
36 import java.util.function.Consumer;
37 import org.junit.Before;
38 import org.junit.Test;
39 import org.mockito.Mock;
40 import org.onap.policy.common.utils.coder.CoderException;
41 import org.onap.policy.controlloop.actor.test.BasicHttpOperation;
42 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
43 import org.onap.policy.controlloop.actorserviceprovider.Util;
44 import org.onap.policy.controlloop.policy.PolicyResult;
45 import org.onap.policy.models.decisions.concepts.DecisionRequest;
46 import org.onap.policy.models.decisions.concepts.DecisionResponse;
47
48 public class GuardOperationTest extends BasicHttpOperation<DecisionRequest> {
49
50     @Mock
51     private Consumer<OperationOutcome> started;
52     @Mock
53     private Consumer<OperationOutcome> completed;
54
55     private GuardConfig guardConfig;
56     private GuardOperation oper;
57
58     /**
59      * Sets up.
60      */
61     @Before
62     public void setUp() throws Exception {
63         super.setUpBasic();
64
65         guardConfig = mock(GuardConfig.class);
66         when(guardConfig.makeRequest()).thenAnswer(args -> new TreeMap<>(Map.of("action", "guard")));
67
68         config = guardConfig;
69         initConfig();
70
71         params = params.toBuilder().startCallback(started).completeCallback(completed).build();
72
73         oper = new GuardOperation(params, config);
74     }
75
76     @Test
77     public void testConstructor() {
78         assertEquals(DEFAULT_ACTOR, oper.getActorName());
79         assertEquals(DEFAULT_OPERATION, oper.getName());
80     }
81
82     @Test
83     public void testStartOperationAsync() throws Exception {
84         CompletableFuture<OperationOutcome> future2 = oper.start();
85         executor.runAll(100);
86         assertFalse(future2.isDone());
87
88         DecisionResponse resp = new DecisionResponse();
89         resp.setStatus(GuardOperation.PERMIT);
90         when(rawResponse.readEntity(String.class)).thenReturn(Util.translate("", resp, String.class));
91
92         verify(client).post(callbackCaptor.capture(), any(), requestCaptor.capture(), any());
93         callbackCaptor.getValue().completed(rawResponse);
94
95         executor.runAll(100);
96         assertTrue(future2.isDone());
97
98         assertEquals(PolicyResult.SUCCESS, future2.get().getResult());
99
100         assertEquals("1", future2.get().getSubRequestId());
101     }
102
103     /**
104      * Tests startOperationAsync() when the guard is disabled.
105      */
106     @Test
107     public void testStartOperationAsyncDisabled() throws Exception {
108         // indicate that it's disabled
109         when(guardConfig.isDisabled()).thenReturn(true);
110
111         CompletableFuture<OperationOutcome> future2 = oper.start();
112         executor.runAll(100);
113
114         verify(client, never()).post(any(), any(), any(), any());
115
116         // should already be done
117         assertTrue(future2.isDone());
118
119         assertEquals(PolicyResult.SUCCESS, future2.get().getResult());
120
121         // ensure callbacks were invoked
122         verify(started).accept(any());
123         verify(completed).accept(any());
124     }
125
126     @Test
127     public void testMakeRequest() throws CoderException {
128         verifyPayload("makeReqStd.json", makePayload());
129         verifyPayload("makeReqDefault.json", new TreeMap<>());
130
131         Map<String, Object> payload = new TreeMap<>();
132         payload.put("action", "some action");
133         payload.put("hello", "world");
134         payload.put("r u there?", "yes");
135         payload.put("requestId", "some request id");
136
137         Map<String, Object> resource = new TreeMap<>();
138         payload.put("resource", resource);
139         resource.put("abc", "def");
140         resource.put("ghi", "jkl");
141
142         verifyPayload("makeReq.json", payload);
143
144         // null payload - start with fresh parameters and operation
145         params = params.toBuilder().payload(null).build();
146         oper = new GuardOperation(params, config);
147         assertThatIllegalArgumentException().isThrownBy(() -> oper.makeRequest());
148     }
149
150     private void verifyPayload(String expectedJsonFile, Map<String, Object> payload) throws CoderException {
151         params.getPayload().clear();
152         params.getPayload().putAll(payload);
153
154         Map<String, Object> requestMap = oper.makeRequest();
155
156         verifyRequest(expectedJsonFile, requestMap, "requestId");
157     }
158
159     @Test
160     public void testPostProcessResponse() {
161         DecisionResponse response = new DecisionResponse();
162
163         // null status
164         response.setStatus(null);
165         verifyOutcome(response, PolicyResult.FAILURE, "response contains no status");
166
167         // permit, mixed case
168         response.setStatus("peRmit");
169         verifyOutcome(response, PolicyResult.SUCCESS, "peRmit");
170
171         // indeterminate, mixed case
172         response.setStatus("inDETerminate");
173         verifyOutcome(response, PolicyResult.SUCCESS, "inDETerminate");
174
175         // deny, mixed case
176         response.setStatus("deNY");
177         verifyOutcome(response, PolicyResult.FAILURE, "deNY");
178
179         // unknown status
180         response.setStatus("unknown");
181         verifyOutcome(response, PolicyResult.FAILURE, "unknown");
182     }
183
184     private void verifyOutcome(DecisionResponse response, PolicyResult expectedResult, String expectedMessage) {
185         oper.postProcessResponse(outcome, BASE_URI, rawResponse, response);
186         assertEquals(expectedResult, outcome.getResult());
187         assertEquals(expectedMessage, outcome.getMessage());
188     }
189
190     @Override
191     protected Map<String, Object> makePayload() {
192         DecisionRequest req = new DecisionRequest();
193         req.setAction("my-action");
194         req.setOnapComponent("my-onap-component");
195         req.setOnapInstance("my-onap-instance");
196         req.setOnapName("my-onap-name");
197         req.setRequestId("my-request-id");
198
199         // add resources
200         Map<String, Object> resource = new TreeMap<>();
201         req.setResource(resource);
202         resource.put("actor", "resource-actor");
203         resource.put("operation", "resource-operation");
204
205         @SuppressWarnings("unchecked")
206         Map<String, Object> map = Util.translate("", req, TreeMap.class);
207
208         return map;
209     }
210 }