Remove Target and TargetType
[policy/models.git] / models-interactions / model-actors / actorServiceProvider / src / main / java / org / onap / policy / controlloop / actorserviceprovider / parameters / ControlLoopOperationParams.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.actorserviceprovider.parameters;
22
23 import java.util.Map;
24 import java.util.UUID;
25 import java.util.concurrent.CompletableFuture;
26 import java.util.concurrent.Executor;
27 import java.util.concurrent.ForkJoinPool;
28 import java.util.function.Consumer;
29 import lombok.AllArgsConstructor;
30 import lombok.Builder;
31 import lombok.EqualsAndHashCode;
32 import lombok.Getter;
33 import org.onap.policy.common.parameters.BeanValidationResult;
34 import org.onap.policy.common.parameters.BeanValidator;
35 import org.onap.policy.common.parameters.annotations.NotNull;
36 import org.onap.policy.controlloop.VirtualControlLoopEvent;
37 import org.onap.policy.controlloop.actorserviceprovider.ActorService;
38 import org.onap.policy.controlloop.actorserviceprovider.Operation;
39 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
40 import org.onap.policy.controlloop.actorserviceprovider.TargetType;
41 import org.onap.policy.controlloop.actorserviceprovider.Util;
42 import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 /**
47  * Parameters for control loop operations. The executor defaults to
48  * {@link ForkJoinPool#commonPool()}, but may be overridden.
49  */
50 @Getter
51 @Builder(toBuilder = true)
52 @AllArgsConstructor
53 @EqualsAndHashCode
54 public class ControlLoopOperationParams {
55     private static final Logger logger = LoggerFactory.getLogger(ControlLoopOperationParams.class);
56
57     public static final String PARAMS_ENTITY_RESOURCEID = "resourceID";
58     public static final String PARAMS_ENTITY_MODEL_INVARIANT_ID = "modelInvariantId";
59     public static final String PARAMS_ENTITY_MODEL_VERSION_ID = "modelVersionId";
60     public static final String PARAMS_ENTITY_MODEL_NAME = "modelName";
61     public static final String PARAMS_ENTITY_MODEL_VERSION = "modelVersion";
62     public static final String PARAMS_ENTITY_MODEL_CUSTOMIZATION_ID = "modelCustomizationId";
63
64     /**
65      * Actor name.
66      */
67     @NotNull
68     private String actor;
69
70     /**
71      * Actor service in which to find the actor/operation.
72      */
73     @NotNull
74     private ActorService actorService;
75
76     /**
77      * Event for which the operation applies.
78      */
79     // TODO to be removed
80     private ControlLoopEventContext context;
81
82     /**
83      * If {@code null}, this value is extracted from the context.
84      */
85     private UUID requestId;
86
87     /**
88      * Executor to use to run the operation.
89      */
90     @NotNull
91     @Builder.Default
92     private Executor executor = ForkJoinPool.commonPool();
93
94     /**
95      * Operation name.
96      */
97     @NotNull
98     private String operation;
99
100     /**
101      * Payload data for the request.
102      */
103     private Map<String, Object> payload;
104
105     /**
106      * {@code True} if the preprocessing steps have already been executed, {@code false}
107      * otherwise.
108      */
109     private boolean preprocessed;
110
111     /**
112      * Number of retries allowed, or {@code null} if no retries.
113      */
114     private Integer retry;
115
116     /**
117      * The Target Type information, extracted from the Policy. May be {@code null}, depending
118      * on the requirement of the operation to be invoked.
119      */
120     private TargetType targetType;
121
122     /**
123      * Target entitiy ids, extracted from the Policy. May be (@code null}, depending on
124      * the requirement of the operation to be invoked.
125      */
126     private Map<String, String> targetEntityIds;
127
128     /**
129      * Target entity.
130      */
131     // TODO to be removed
132     private String targetEntity;
133
134     /**
135      * Timeout, in seconds, or {@code null} if no timeout. Zero and negative values also
136      * imply no timeout.
137      */
138     @Builder.Default
139     private Integer timeoutSec = 300;
140
141     /**
142      * The function to invoke when the operation starts. This is optional.
143      * <p/>
144      * Note: this may be invoked multiple times, but with different actor/operations. That
145      * may happen if the current operation requires other operations to be performed first
146      * (e.g., A&AI queries, guard checks).
147      */
148     private Consumer<OperationOutcome> startCallback;
149
150     /**
151      * The function to invoke when the operation completes. This is optional.
152      * <p/>
153      * Note: this may be invoked multiple times, but with different actor/operations. That
154      * may happen if the current operation requires other operations to be performed first
155      * (e.g., A&AI queries, guard checks).
156      */
157     private Consumer<OperationOutcome> completeCallback;
158
159     /**
160      * Starts the specified operation.
161      *
162      * @return a future that will return the result of the operation
163      * @throws IllegalArgumentException if the parameters are invalid
164      */
165     public CompletableFuture<OperationOutcome> start() {
166         return build().start();
167     }
168
169     /**
170      * Builds the specified operation.
171      *
172      * @return a new operation
173      * @throws IllegalArgumentException if the parameters are invalid
174      */
175     public Operation build() {
176         BeanValidationResult result = validate();
177         if (!result.isValid()) {
178             logger.warn("parameter error in operation {}.{} for {}:\n{}", getActor(), getOperation(), getRequestId(),
179                             result.getResult());
180             throw new IllegalArgumentException("invalid parameters");
181         }
182
183         // @formatter:off
184         return actorService
185                     .getActor(getActor())
186                     .getOperator(getOperation())
187                     .buildOperation(this);
188         // @formatter:on
189     }
190
191     /**
192      * Gets the requested ID of the associated event.
193      *
194      * @return the event's request ID, or {@code null} if no request ID is available
195      */
196     public UUID getRequestId() {
197         if (requestId == null && context != null && context.getEvent() != null) {
198             // cache the request ID
199             requestId = context.getEvent().getRequestId();
200         }
201
202         return requestId;
203     }
204
205     /**
206      * Makes an operation outcome, populating it from the parameters.
207      *
208      * @return a new operation outcome
209      */
210     // TODO to be removed
211     public OperationOutcome makeOutcome() {
212         return makeOutcome(getTargetEntity());
213     }
214
215     /**
216      * Makes an operation outcome, populating it from the parameters.
217      *
218      * @param targetEntity the target entity
219      *
220      * @return a new operation outcome
221      */
222     public OperationOutcome makeOutcome(String targetEntity) {
223         OperationOutcome outcome = new OperationOutcome();
224         outcome.setActor(getActor());
225         outcome.setOperation(getOperation());
226         outcome.setTarget(targetEntity);
227
228         return outcome;
229     }
230
231     /**
232      * Invokes the callback to indicate that the operation has started. Any exceptions
233      * generated by the callback are logged, but not re-thrown.
234      *
235      * @param operation the operation that is being started
236      */
237     public void callbackStarted(OperationOutcome operation) {
238         logger.info("started operation {}.{} for {}", operation.getActor(), operation.getOperation(), getRequestId());
239
240         if (startCallback != null) {
241             Util.runFunction(() -> startCallback.accept(operation), "{}.{}: start-callback threw an exception for {}",
242                             operation.getActor(), operation.getOperation(), getRequestId());
243         }
244     }
245
246     /**
247      * Invokes the callback to indicate that the operation has completed. Any exceptions
248      * generated by the callback are logged, but not re-thrown.
249      *
250      * @param operation the operation that is being started
251      */
252     public void callbackCompleted(OperationOutcome operation) {
253         logger.info("completed operation {}.{} outcome={} for {}", operation.getActor(), operation.getOperation(),
254                         operation.getResult(), getRequestId());
255
256         if (completeCallback != null) {
257             Util.runFunction(() -> completeCallback.accept(operation),
258                             "{}.{}: complete-callback threw an exception for {}", operation.getActor(),
259                             operation.getOperation(), getRequestId());
260         }
261     }
262
263     /**
264      * Validates the parameters.
265      *
266      * @return the validation result
267      */
268     public BeanValidationResult validate() {
269         BeanValidationResult result =
270                         new BeanValidator().validateTop(ControlLoopOperationParams.class.getSimpleName(), this);
271
272         // validate that we have a request ID, or that we can get it from the context's
273         // event
274
275         if (context == null) {
276             // no context specified - invoker must provide a request ID then
277             result.validateNotNull("requestId", requestId);
278
279         } else if (requestId == null) {
280             // have a context, but no request ID - check the context's event for the
281             // request ID
282             BeanValidationResult contextResult = new BeanValidationResult("context", context);
283             VirtualControlLoopEvent event = context.getEvent();
284             contextResult.validateNotNull("event", event);
285
286             if (event != null) {
287                 // cache the request id for later use
288                 BeanValidationResult eventResult = new BeanValidationResult("event", event);
289                 eventResult.validateNotNull("requestId", event.getRequestId());
290
291                 contextResult.addResult(eventResult);
292             }
293
294             result.addResult(contextResult);
295         }
296
297         return result;
298     }
299 }