Change payload to Map<String,Object> so it's more versatile
[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.OperationOutcome;
38 import org.onap.policy.controlloop.actorserviceprovider.Util;
39 import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext;
40 import org.onap.policy.controlloop.policy.Target;
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     /**
56      * Actor name.
57      */
58     @NotNull
59     private String actor;
60
61     /**
62      * Actor service in which to find the actor/operation.
63      */
64     @NotNull
65     private ActorService actorService;
66
67     /**
68      * Event for which the operation applies.
69      */
70     @NotNull
71     private ControlLoopEventContext context;
72
73     /**
74      * Executor to use to run the operation.
75      */
76     @NotNull
77     @Builder.Default
78     private Executor executor = ForkJoinPool.commonPool();
79
80     /**
81      * Operation name.
82      */
83     @NotNull
84     private String operation;
85
86     /**
87      * Payload data for the request.
88      */
89     private Map<String, Object> payload;
90
91     /**
92      * Number of retries allowed, or {@code null} if no retries.
93      */
94     private Integer retry;
95
96     /**
97      * The entity's target information. May be {@code null}, depending on the requirement
98      * of the operation to be invoked.
99      */
100     private Target target;
101
102     /**
103      * Target entity.
104      */
105     @NotNull
106     private String targetEntity;
107
108     /**
109      * Timeout, in seconds, or {@code null} if no timeout. Zero and negative values also
110      * imply no timeout.
111      */
112     @Builder.Default
113     private Integer timeoutSec = 300;
114
115     /**
116      * The function to invoke when the operation starts. This is optional.
117      * <p/>
118      * Note: this may be invoked multiple times, but with different actor/operations. That
119      * may happen if the current operation requires other operations to be performed first
120      * (e.g., A&AI queries, guard checks).
121      */
122     private Consumer<OperationOutcome> startCallback;
123
124     /**
125      * The function to invoke when the operation completes. This is optional.
126      * <p/>
127      * Note: this may be invoked multiple times, but with different actor/operations. That
128      * may happen if the current operation requires other operations to be performed first
129      * (e.g., A&AI queries, guard checks).
130      */
131     private Consumer<OperationOutcome> completeCallback;
132
133     /**
134      * Starts the specified operation.
135      *
136      * @return a future that will return the result of the operation
137      * @throws IllegalArgumentException if the parameters are invalid
138      */
139     public CompletableFuture<OperationOutcome> start() {
140         BeanValidationResult result = validate();
141         if (!result.isValid()) {
142             logger.warn("parameter error in operation {}.{} for {}:\n{}", getActor(), getOperation(), getRequestId(),
143                             result.getResult());
144             throw new IllegalArgumentException("invalid parameters");
145         }
146
147         // @formatter:off
148         return actorService
149                     .getActor(getActor())
150                     .getOperator(getOperation())
151                     .buildOperation(this)
152                     .start();
153         // @formatter:on
154     }
155
156     /**
157      * Gets the requested ID of the associated event.
158      *
159      * @return the event's request ID, or {@code null} if no request ID is available
160      */
161     public UUID getRequestId() {
162         return (context == null || context.getEvent() == null ? null : context.getEvent().getRequestId());
163     }
164
165     /**
166      * Makes an operation outcome, populating it from the parameters.
167      *
168      * @return a new operation outcome
169      */
170     public OperationOutcome makeOutcome() {
171         OperationOutcome outcome = new OperationOutcome();
172         outcome.setActor(getActor());
173         outcome.setOperation(getOperation());
174         outcome.setTarget(targetEntity);
175
176         return outcome;
177     }
178
179     /**
180      * Invokes the callback to indicate that the operation has started. Any exceptions
181      * generated by the callback are logged, but not re-thrown.
182      *
183      * @param operation the operation that is being started
184      */
185     public void callbackStarted(OperationOutcome operation) {
186         logger.info("started operation {}.{} for {}", operation.getActor(), operation.getOperation(), getRequestId());
187
188         if (startCallback != null) {
189             Util.runFunction(() -> startCallback.accept(operation), "{}.{}: start-callback threw an exception for {}",
190                             operation.getActor(), operation.getOperation(), getRequestId());
191         }
192     }
193
194     /**
195      * Invokes the callback to indicate that the operation has completed. Any exceptions
196      * generated by the callback are logged, but not re-thrown.
197      *
198      * @param operation the operation that is being started
199      */
200     public void callbackCompleted(OperationOutcome operation) {
201         logger.info("completed operation {}.{} outcome={} for {}", operation.getActor(), operation.getOperation(),
202                         operation.getResult(), getRequestId());
203
204         if (completeCallback != null) {
205             Util.runFunction(() -> completeCallback.accept(operation),
206                             "{}.{}: complete-callback threw an exception for {}", operation.getActor(),
207                             operation.getOperation(), getRequestId());
208         }
209     }
210
211     /**
212      * Validates the parameters.
213      *
214      * @return the validation result
215      */
216     public BeanValidationResult validate() {
217         return new BeanValidator().validateTop(ControlLoopOperationParams.class.getSimpleName(), this);
218     }
219 }