Merge "Changes for Checkstyle 8.32"
[policy/models.git] / models-interactions / model-actors / actor.aai / src / test / java / org / onap / policy / controlloop / actor / aai / AaiCustomQueryOperationTest.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.aai;
22
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.assertj.core.api.Assertions.assertThatCode;
25 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertNotNull;
28 import static org.junit.Assert.assertSame;
29 import static org.junit.Assert.assertTrue;
30 import static org.mockito.ArgumentMatchers.any;
31 import static org.mockito.Mockito.verify;
32 import static org.mockito.Mockito.when;
33
34 import java.util.Arrays;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.TreeMap;
38 import java.util.concurrent.CompletableFuture;
39 import java.util.concurrent.ExecutionException;
40 import java.util.concurrent.TimeoutException;
41 import javax.ws.rs.client.InvocationCallback;
42 import org.junit.AfterClass;
43 import org.junit.Before;
44 import org.junit.BeforeClass;
45 import org.junit.Test;
46 import org.mockito.Mock;
47 import org.onap.policy.aai.AaiConstants;
48 import org.onap.policy.aai.AaiCqResponse;
49 import org.onap.policy.common.endpoints.http.client.HttpClientFactory;
50 import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance;
51 import org.onap.policy.common.utils.coder.StandardCoder;
52 import org.onap.policy.common.utils.coder.StandardCoderObject;
53 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
54 import org.onap.policy.controlloop.actorserviceprovider.Util;
55 import org.onap.policy.controlloop.actorserviceprovider.impl.HttpOperation;
56 import org.onap.policy.controlloop.actorserviceprovider.impl.HttpOperator;
57 import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
58 import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
59 import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpParams;
60 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
61 import org.onap.policy.controlloop.policy.PolicyResult;
62
63 public class AaiCustomQueryOperationTest extends BasicAaiOperation<Map<String, String>> {
64     private static final StandardCoder coder = new StandardCoder();
65
66     private static final String MY_LINK = "my-link";
67     private static final String MY_VSERVER = "my-vserver-name";
68     private static final String SIM_VSERVER = "OzVServer";
69
70     @Mock
71     private Actor tenantActor;
72
73     private AaiCustomQueryOperation oper;
74
75     public AaiCustomQueryOperationTest() {
76         super(AaiConstants.ACTOR_NAME, AaiCustomQueryOperation.NAME);
77     }
78
79     @BeforeClass
80     public static void setUpBeforeClass() throws Exception {
81         initBeforeClass();
82     }
83
84     @AfterClass
85     public static void tearDownAfterClass() {
86         destroyAfterClass();
87     }
88
89     /**
90      * Sets up.
91      */
92     @Before
93     public void setUp() throws Exception {
94         super.setUpBasic();
95
96         params.getContext().getEnrichment().put(AaiCustomQueryOperation.VSERVER_VSERVER_NAME, MY_VSERVER);
97
98         MyTenantOperator tenantOperator = new MyTenantOperator();
99
100         when(service.getActor(AaiConstants.ACTOR_NAME)).thenReturn(tenantActor);
101         when(tenantActor.getOperator(AaiGetTenantOperation.NAME)).thenReturn(tenantOperator);
102
103         oper = new AaiCustomQueryOperation(params, config);
104     }
105
106     /**
107      * Tests "success" case with simulator.
108      */
109     @Test
110     public void testSuccess() throws Exception {
111         HttpParams opParams = HttpParams.builder().clientName(MY_CLIENT).path("v16/query").build();
112         config = new HttpConfig(blockingExecutor, opParams, HttpClientFactoryInstance.getClientFactory());
113
114         preloadTenantData();
115
116         params = params.toBuilder().targetEntity(SIM_VSERVER).retry(0).timeoutSec(5).executor(blockingExecutor).build();
117         oper = new AaiCustomQueryOperation(params, config);
118
119         outcome = oper.start().get();
120         assertEquals(PolicyResult.SUCCESS, outcome.getResult());
121
122         String resp = outcome.getResponse();
123         assertThat(resp).isNotNull().contains("relationship-list");
124     }
125
126     @Test
127     public void testConstructor() {
128         assertEquals(AaiConstants.ACTOR_NAME, oper.getActorName());
129         assertEquals(AaiCustomQueryOperation.NAME, oper.getName());
130         assertEquals(MY_VSERVER, oper.getVserver());
131
132         // verify that it works with an empty target entity
133         params = params.toBuilder().targetEntity("").build();
134         assertThatCode(() -> new AaiCustomQueryOperation(params, config)).doesNotThrowAnyException();
135
136         // try without enrichment data
137         params.getContext().getEnrichment().remove(AaiCustomQueryOperation.VSERVER_VSERVER_NAME);
138         assertThatIllegalArgumentException().isThrownBy(() -> new AaiCustomQueryOperation(params, config))
139                         .withMessage("missing " + AaiCustomQueryOperation.VSERVER_VSERVER_NAME + " in enrichment data");
140     }
141
142     @Test
143     public void testGenerateSubRequestId() {
144         oper.generateSubRequestId(3);
145         assertEquals("3", oper.getSubRequestId());
146     }
147
148     @Test
149     @SuppressWarnings("unchecked")
150     public void testStartOperationAsync_testStartPreprocessorAsync_testMakeRequest_testPostProcess() throws Exception {
151         // need two responses
152         when(rawResponse.readEntity(String.class)).thenReturn(makeTenantReply()).thenReturn(makeCqReply());
153         when(webAsync.get(any(InvocationCallback.class))).thenAnswer(provideResponse(rawResponse));
154         when(webAsync.put(any(), any(InvocationCallback.class))).thenAnswer(provideResponse(rawResponse, 1));
155
156         CompletableFuture<OperationOutcome> future2 = oper.start();
157
158         assertEquals(PolicyResult.SUCCESS, getResult(future2));
159
160         // tenant response should have been cached within the context
161         assertNotNull(context.getProperty(AaiGetTenantOperation.getKey(MY_VSERVER)));
162
163         // custom query response should have been cached within the context
164         AaiCqResponse cqData = context.getProperty(AaiCqResponse.CONTEXT_KEY);
165         assertNotNull(cqData);
166
167         assertEquals("1", future2.get().getSubRequestId());
168     }
169
170     /**
171      * Tests when preprocessor step is not needed.
172      */
173     @Test
174     @SuppressWarnings("unchecked")
175     public void testStartOperationAsync_testStartPreprocessorAsyncNotNeeded() throws Exception {
176         // pre-load the tenant data
177         final StandardCoderObject data = preloadTenantData();
178
179         // only need one response
180         when(rawResponse.readEntity(String.class)).thenReturn(makeCqReply());
181         when(webAsync.put(any(), any(InvocationCallback.class))).thenAnswer(provideResponse(rawResponse, 1));
182
183         CompletableFuture<OperationOutcome> future2 = oper.start();
184
185         assertEquals(PolicyResult.SUCCESS, getResult(future2));
186
187         // should not have replaced tenant response
188         assertSame(data, context.getProperty(AaiGetTenantOperation.getKey(MY_VSERVER)));
189
190         // custom query response should have been cached within the context
191         AaiCqResponse cqData = context.getProperty(AaiCqResponse.CONTEXT_KEY);
192         assertNotNull(cqData);
193     }
194
195     @Test
196     public void testMakeHeaders() {
197         verifyHeaders(oper.makeHeaders());
198     }
199
200     @Test
201     @SuppressWarnings("unchecked")
202     public void testMakeRequest() throws Exception {
203         // preload
204         preloadTenantData();
205
206         when(rawResponse.readEntity(String.class)).thenReturn(makeCqReply());
207         when(webAsync.put(any(), any(InvocationCallback.class))).thenAnswer(provideResponse(rawResponse, 1));
208
209         oper.start();
210         executor.runAll(100);
211
212         verify(webAsync).put(requestCaptor.capture(), any(InvocationCallback.class));
213
214         String reqText = requestCaptor.getValue().getEntity();
215         Map<String, String> reqMap = coder.decode(reqText, Map.class);
216
217         // sort the request fields so they match the order in cq.json
218         Map<String, String> request = new TreeMap<>(reqMap);
219
220         verifyRequest("cq.json", request);
221     }
222
223     @Test
224     @SuppressWarnings("unchecked")
225     public void testMakeRequestNoResourceLink() throws Exception {
226         // pre-load EMPTY tenant data
227         preloadTenantData(new StandardCoderObject());
228
229         when(rawResponse.readEntity(String.class)).thenReturn(makeCqReply());
230         when(webAsync.put(any(), any(InvocationCallback.class))).thenAnswer(provideResponse(rawResponse, 1));
231
232         CompletableFuture<OperationOutcome> future2 = oper.start();
233
234         assertEquals(PolicyResult.FAILURE_EXCEPTION, getResult(future2));
235     }
236
237     private String makeTenantReply() throws Exception {
238         Map<String, String> links = Map.of(AaiCustomQueryOperation.RESOURCE_LINK, MY_LINK);
239         List<Map<String, String>> data = Arrays.asList(links);
240
241         Map<String, Object> reply = Map.of(AaiCustomQueryOperation.RESULT_DATA, data);
242         return coder.encode(reply);
243     }
244
245     private String makeCqReply() {
246         return "{}";
247     }
248
249     private StandardCoderObject preloadTenantData() throws Exception {
250         StandardCoderObject data = coder.decode(makeTenantReply(), StandardCoderObject.class);
251         preloadTenantData(data);
252         return data;
253     }
254
255     private void preloadTenantData(StandardCoderObject data) {
256         context.setProperty(AaiGetTenantOperation.getKey(MY_VSERVER), data);
257         context.setProperty(AaiGetTenantOperation.getKey(SIM_VSERVER), data);
258     }
259
260     private PolicyResult getResult(CompletableFuture<OperationOutcome> future2)
261                     throws InterruptedException, ExecutionException, TimeoutException {
262
263         executor.runAll(100);
264         assertTrue(future2.isDone());
265
266         return future2.get().getResult();
267     }
268
269     protected class MyTenantOperator extends HttpOperator {
270         public MyTenantOperator() {
271             super(AaiConstants.ACTOR_NAME, AaiGetTenantOperation.NAME);
272
273             HttpParams http = HttpParams.builder().clientName(MY_CLIENT).path(PATH).timeoutSec(1).build();
274
275             configure(Util.translateToMap(AaiGetTenantOperation.NAME, http));
276             start();
277         }
278
279         @Override
280         public HttpOperation<?> buildOperation(ControlLoopOperationParams params) {
281             return new AaiGetTenantOperation(params, getCurrentConfig());
282         }
283
284         @Override
285         protected HttpClientFactory getClientFactory() {
286             return factory;
287         }
288     }
289 }