a0bb58e095c96031eb774d51dd2330259e2c6315
[policy/models.git] / models-interactions / model-actors / actor.test / src / main / java / org / onap / policy / controlloop / actor / test / BasicOperation.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.test;
22
23 import static org.junit.Assert.assertEquals;
24 import static org.mockito.ArgumentMatchers.any;
25 import static org.mockito.Mockito.when;
26
27 import java.util.Map;
28 import java.util.TreeMap;
29 import java.util.UUID;
30 import java.util.concurrent.CompletableFuture;
31 import java.util.concurrent.Executor;
32 import javax.ws.rs.core.Response;
33 import org.mockito.Mock;
34 import org.mockito.MockitoAnnotations;
35 import org.onap.policy.aai.AaiConstants;
36 import org.onap.policy.aai.AaiCqResponse;
37 import org.onap.policy.common.utils.coder.Coder;
38 import org.onap.policy.common.utils.coder.CoderException;
39 import org.onap.policy.common.utils.coder.StandardCoder;
40 import org.onap.policy.common.utils.resources.ResourceUtils;
41 import org.onap.policy.common.utils.time.PseudoExecutor;
42 import org.onap.policy.controlloop.VirtualControlLoopEvent;
43 import org.onap.policy.controlloop.actorserviceprovider.ActorService;
44 import org.onap.policy.controlloop.actorserviceprovider.Operation;
45 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
46 import org.onap.policy.controlloop.actorserviceprovider.Operator;
47 import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext;
48 import org.onap.policy.controlloop.actorserviceprovider.impl.OperationPartial;
49 import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
50 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
51 import org.onap.policy.controlloop.policy.PolicyResult;
52
53 /**
54  * Superclass for various Operation tests.
55  */
56 public class BasicOperation {
57     protected static final UUID REQ_ID = UUID.randomUUID();
58     protected static final String SUB_REQ_ID = "my-sub-request-id";
59     protected static final String DEFAULT_ACTOR = "default-Actor";
60     protected static final String DEFAULT_OPERATION = "default-Operation";
61     protected static final String TARGET_ENTITY = "my-target";
62     protected static final String CL_NAME = "my-closed-loop";
63     protected static final String EVENT_POLICY_NAME = "my-event-policy-name";
64     protected static final String EVENT_POLICY_VERSION = "my-event-policy-version";
65     protected static final String EVENT_VERSION = "my-event-version";
66
67     protected static final Executor blockingExecutor = command -> {
68         Thread thread = new Thread(command);
69         thread.setDaemon(true);
70         thread.start();
71     };
72
73     protected final String actorName;
74     protected final String operationName;
75     protected Coder coder = new StandardCoder();
76
77     @Mock
78     protected ActorService service;
79     @Mock
80     protected Actor guardActor;
81     @Mock
82     protected Operator guardOperator;
83     @Mock
84     protected Operation guardOperation;
85     @Mock
86     protected Actor cqActor;
87     @Mock
88     protected Operator cqOperator;
89     @Mock
90     protected Operation cqOperation;
91     @Mock
92     protected AaiCqResponse cqResponse;
93
94     protected CompletableFuture<OperationOutcome> cqFuture;
95     protected CompletableFuture<Response> future;
96     protected ControlLoopOperationParams params;
97     protected Map<String, String> enrichment;
98     protected VirtualControlLoopEvent event;
99     protected ControlLoopEventContext context;
100     protected OperationOutcome outcome;
101     protected PseudoExecutor executor;
102
103     /**
104      * Constructs the object using a default actor and operation name.
105      */
106     public BasicOperation() {
107         this.actorName = DEFAULT_ACTOR;
108         this.operationName = DEFAULT_OPERATION;
109     }
110
111     /**
112      * Constructs the object.
113      *
114      * @param actor actor name
115      * @param operation operation name
116      */
117     public BasicOperation(String actor, String operation) {
118         this.actorName = actor;
119         this.operationName = operation;
120     }
121
122     /**
123      * Initializes mocks and sets up.
124      */
125     public void setUpBasic() {
126         MockitoAnnotations.initMocks(this);
127
128         cqFuture = new CompletableFuture<>();
129         future = new CompletableFuture<>();
130
131         executor = new PseudoExecutor();
132
133         makeContext();
134
135         when(service.getActor(OperationPartial.GUARD_ACTOR_NAME)).thenReturn(guardActor);
136         when(guardActor.getOperator(OperationPartial.GUARD_OPERATION_NAME)).thenReturn(guardOperator);
137         when(guardOperator.buildOperation(any())).thenReturn(guardOperation);
138
139         outcome = params.makeOutcome(TARGET_ENTITY);
140         outcome.setResult(PolicyResult.SUCCESS);
141         when(guardOperation.start()).thenReturn(CompletableFuture.completedFuture(outcome));
142
143         when(service.getActor(AaiConstants.ACTOR_NAME)).thenReturn(cqActor);
144         when(cqActor.getOperator("CustomQuery")).thenReturn(cqOperator);
145         when(cqOperator.buildOperation(any())).thenReturn(cqOperation);
146
147         when(cqOperation.start()).thenReturn(cqFuture);
148
149         // get a fresh outcome
150         outcome = params.makeOutcome(TARGET_ENTITY);
151     }
152
153     /**
154      * Reinitializes {@link #enrichment}, {@link #event}, {@link #context}, and
155      * {@link #params}.
156      * <p/>
157      * Note: {@link #params} is configured to use {@link #executor}.
158      */
159     protected void makeContext() {
160         enrichment = new TreeMap<>(makeEnrichment());
161
162         event = new VirtualControlLoopEvent();
163         event.setRequestId(REQ_ID);
164         event.setAai(enrichment);
165         event.setClosedLoopControlName(CL_NAME);
166         event.setPolicyName(EVENT_POLICY_NAME);
167         event.setPolicyVersion(EVENT_POLICY_VERSION);
168         event.setVersion(EVENT_VERSION);
169
170         context = new ControlLoopEventContext(event);
171
172         params = ControlLoopOperationParams.builder().executor(executor).context(context).actorService(service)
173                         .actor(actorName).operation(operationName).targetEntity(TARGET_ENTITY).payload(makePayload())
174                         .build();
175     }
176
177     /**
178      * Makes enrichment data.
179      *
180      * @return enrichment data
181      */
182     protected Map<String, String> makeEnrichment() {
183         return new TreeMap<>();
184     }
185
186
187     /**
188      * Makes payload data.
189      *
190      * @return payload data
191      */
192     protected Map<String, Object> makePayload() {
193         return null;
194     }
195
196     /**
197      * Pretty-prints a request and verifies that the result matches the expected JSON.
198      *
199      * @param <R> request type
200      * @param expectedJsonFile name of the file containing the expected JSON
201      * @param request request to verify
202      * @param ignore names of fields to be ignored, because they change with each request
203      * @throws CoderException if the request cannot be pretty-printed
204      */
205     protected <R> void verifyRequest(String expectedJsonFile, R request, String... ignore) throws CoderException {
206         String json = coder.encode(request, true);
207         String expected = ResourceUtils.getResourceAsString(expectedJsonFile);
208
209         // strip various items, because they change for each request
210         for (String stripper : ignore) {
211             stripper += "[^,]*";
212             json = json.replaceAll(stripper, "");
213             expected = expected.replaceAll(stripper, "");
214         }
215
216         json = json.trim();
217         expected = expected.trim();
218
219         assertEquals(expected, json);
220     }
221
222     /**
223      * Provides a response to a custom query.
224      *
225      * @param cq response to provide
226      */
227     protected void provideCqResponse(AaiCqResponse cq) {
228         context.setProperty(AaiCqResponse.CONTEXT_KEY, cq);
229         OperationOutcome outcome2 = params.makeOutcome(TARGET_ENTITY);
230         outcome2.setResult(PolicyResult.SUCCESS);
231         cqFuture.complete(outcome2);
232     }
233 }