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