Merge "Actor redesign."
[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.UUID;
24 import java.util.concurrent.CompletableFuture;
25 import java.util.concurrent.Executor;
26 import java.util.concurrent.ForkJoinPool;
27 import java.util.function.Consumer;
28 import lombok.AllArgsConstructor;
29 import lombok.Builder;
30 import lombok.EqualsAndHashCode;
31 import lombok.Getter;
32 import org.onap.policy.common.parameters.BeanValidationResult;
33 import org.onap.policy.common.parameters.BeanValidator;
34 import org.onap.policy.common.parameters.annotations.NotNull;
35 import org.onap.policy.controlloop.ControlLoopOperation;
36 import org.onap.policy.controlloop.actorserviceprovider.ActorService;
37 import org.onap.policy.controlloop.actorserviceprovider.Util;
38 import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext;
39 import org.onap.policy.controlloop.policy.Policy;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 /**
44  * Parameters for control loop operations. The executor defaults to
45  * {@link ForkJoinPool#commonPool()}, but may be overridden.
46  */
47 @Getter
48 @Builder(toBuilder = true)
49 @AllArgsConstructor
50 @EqualsAndHashCode
51 public class ControlLoopOperationParams {
52
53     private static final Logger logger = LoggerFactory.getLogger(ControlLoopOperationParams.class);
54
55     public static final String UNKNOWN = "-unknown-";
56
57
58     /**
59      * The actor service in which to find the actor/operation.
60      */
61     @NotNull
62     private ActorService actorService;
63
64     /**
65      * The event for which the operation applies.
66      */
67     @NotNull
68     private ControlLoopEventContext context;
69
70     /**
71      * The executor to use to run the operation.
72      */
73     @NotNull
74     @Builder.Default
75     private Executor executor = ForkJoinPool.commonPool();
76
77     /**
78      * The policy associated with the operation.
79      */
80     @NotNull
81     private Policy policy;
82
83     /**
84      * The function to invoke when the operation starts. This is optional.
85      * <p/>
86      * Note: this may be invoked multiple times, but with different actor/operations. That
87      * may happen if the current operation requires other operations to be performed first
88      * (e.g., A&AI queries, guard checks).
89      */
90     private Consumer<ControlLoopOperation> startCallback;
91
92     /**
93      * The function to invoke when the operation completes. This is optional.
94      * <p/>
95      * Note: this may be invoked multiple times, but with different actor/operations. That
96      * may happen if the current operation requires other operations to be performed first
97      * (e.g., A&AI queries, guard checks).
98      */
99     private Consumer<ControlLoopOperation> completeCallback;
100
101     /**
102      * Target entity.
103      */
104     @NotNull
105     private String target;
106
107     /**
108      * Starts the specified operation.
109      *
110      * @return a future that will return the result of the operation
111      * @throws IllegalArgumentException if the parameters are invalid
112      */
113     public CompletableFuture<ControlLoopOperation> start() {
114         BeanValidationResult result = validate();
115         if (!result.isValid()) {
116             logger.warn("parameter error in operation {}.{} for {}:\n{}", getActor(), getOperation(), getRequestId(),
117                             result.getResult());
118             throw new IllegalArgumentException("invalid parameters");
119         }
120
121         // @formatter:off
122         return actorService
123                     .getActor(policy.getActor())
124                     .getOperator(policy.getRecipe())
125                     .startOperation(this);
126         // @formatter:on
127     }
128
129     /**
130      * Gets the name of the actor from the policy.
131      *
132      * @return the actor name, or {@link #UNKNOWN} if no name is available
133      */
134     public String getActor() {
135         return (policy == null || policy.getActor() == null ? UNKNOWN : policy.getActor());
136     }
137
138     /**
139      * Gets the name of the operation from the policy.
140      *
141      * @return the operation name, or {@link #UNKNOWN} if no name is available
142      */
143     public String getOperation() {
144         return (policy == null || policy.getRecipe() == null ? UNKNOWN : policy.getRecipe());
145     }
146
147     /**
148      * Gets the requested ID of the associated event.
149      *
150      * @return the event's request ID, or {@code null} if no request ID is available
151      */
152     public UUID getRequestId() {
153         return (context == null || context.getEvent() == null ? null : context.getEvent().getRequestId());
154     }
155
156     /**
157      * Makes an operation outcome, populating it from the parameters.
158      *
159      * @return a new operation outcome
160      */
161     public ControlLoopOperation makeOutcome() {
162         ControlLoopOperation operation = new ControlLoopOperation();
163         operation.setActor(getActor());
164         operation.setOperation(getOperation());
165         operation.setTarget(target);
166
167         return operation;
168     }
169
170     /**
171      * Invokes the callback to indicate that the operation has started. Any exceptions
172      * generated by the callback are logged, but not re-thrown.
173      *
174      * @param operation the operation that is being started
175      */
176     public void callbackStarted(ControlLoopOperation operation) {
177         logger.info("started operation {}.{} for {}", operation.getActor(), operation.getOperation(), getRequestId());
178
179         if (startCallback != null) {
180             Util.logException(() -> startCallback.accept(operation), "{}.{}: start-callback threw an exception for {}",
181                             operation.getActor(), operation.getOperation(), getRequestId());
182         }
183     }
184
185     /**
186      * Invokes the callback to indicate that the operation has completed. Any exceptions
187      * generated by the callback are logged, but not re-thrown.
188      *
189      * @param operation the operation that is being started
190      */
191     public void callbackCompleted(ControlLoopOperation operation) {
192         logger.info("completed operation {}.{} outcome={} for {}", operation.getActor(), operation.getOperation(),
193                         operation.getOutcome(), getRequestId());
194
195         if (completeCallback != null) {
196             Util.logException(() -> completeCallback.accept(operation),
197                             "{}.{}: complete-callback threw an exception for {}", operation.getActor(),
198                             operation.getOperation(), getRequestId());
199         }
200     }
201
202     /**
203      * Validates the parameters.
204      *
205      * @return the validation result
206      */
207     public BeanValidationResult validate() {
208         return new BeanValidator().validateTop(ControlLoopOperationParams.class.getSimpleName(), this);
209     }
210 }