2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2021 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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.policy.controlloop.eventmanager;
23 import java.util.Deque;
24 import java.util.LinkedList;
25 import java.util.UUID;
26 import java.util.stream.Collectors;
28 import lombok.ToString;
29 import org.drools.core.WorkingMemory;
30 import org.onap.policy.controlloop.ControlLoopException;
31 import org.onap.policy.controlloop.ControlLoopNotificationType;
32 import org.onap.policy.controlloop.ControlLoopOperation;
33 import org.onap.policy.controlloop.ControlLoopResponse;
34 import org.onap.policy.controlloop.VirtualControlLoopNotification;
35 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
36 import org.onap.policy.controlloop.actorserviceprovider.OperationResult;
37 import org.onap.policy.controlloop.drl.legacy.ControlLoopParams;
38 import org.onap.policy.drools.domain.models.operational.OperationalTarget;
41 * Manager for a single control loop event, with operation outcomes.
43 public abstract class ClEventManagerWithOutcome<T extends Step> extends ClEventManagerWithSteps<T>
44 implements StepContext {
46 private static final long serialVersionUID = -1216568161322872641L;
49 * Number of attempts, so far, for the current step.
55 * Full history of operations that have been processed by the rules. This includes the
56 * items in {@link #partialHistory}.
59 private final transient Deque<OperationOutcome2> fullHistory = new LinkedList<>();
62 * History of operations that have been processed by the rules for the current policy.
63 * When a step is started, its "start" outcome is added. However, once it completes,
64 * its "start" outcome is removed and the "completed" outcome is added.
67 private final transient Deque<OperationOutcome2> partialHistory = new LinkedList<>();
71 * Constructs the object.
73 * @param services services the manager should use when processing the event
74 * @param params control loop parameters
75 * @param requestId event request ID
76 * @param workMem working memory to update if this changes
77 * @throws ControlLoopException if the event is invalid or if a YAML processor cannot
80 protected ClEventManagerWithOutcome(EventManagerServices services, ControlLoopParams params, UUID requestId,
81 WorkingMemory workMem) throws ControlLoopException {
83 super(services, params, requestId, workMem);
87 protected void loadPolicy() throws ControlLoopException {
88 partialHistory.clear();
93 public boolean executeStep() {
95 return super.executeStep();
99 * Increments the number of attempts.
101 public void bumpAttempts() {
106 * Determines if the TOSCA should be aborted due to the given outcome.
108 * @param outcome outcome to examine
109 * @return {@code true} if the TOSCA should be aborted, {@code false} otherwise
111 public boolean isAbort(OperationOutcome outcome) {
112 return (outcome.getResult() != OperationResult.SUCCESS);
116 * Adds the outcome to the history.
118 * @param outcome outcome to add
120 public void addToHistory(OperationOutcome outcome) {
121 OperationOutcome2 last = partialHistory.peekLast();
123 if (last != null && last.getOutcome().getEnd() == null
124 && last.getOutcome().isFor(outcome.getActor(), outcome.getOperation())) {
125 // last item was a "start" - remove it
126 partialHistory.removeLast();
128 if (fullHistory.peekLast() == last) {
129 fullHistory.removeLast();
133 var outcome2 = makeOperationOutcome2(outcome);
134 partialHistory.add(outcome2);
135 fullHistory.add(outcome2);
139 * Makes a notification message for the current operation.
141 * @return a new notification
143 public VirtualControlLoopNotification makeNotification() {
144 var notif = new VirtualControlLoopNotification();
145 populateNotification(notif);
147 if (getFinalResult() != null) {
151 OperationOutcome2 last = partialHistory.peekLast();
156 notif.setMessage(last.getClOperation().toHistory());
157 notif.setHistory(partialHistory.stream().map(OperationOutcome2::getClOperation).collect(Collectors.toList()));
163 * Populates a notification structure.
165 * @param notif the notification to populate
167 protected void populateNotification(VirtualControlLoopNotification notif) {
168 notif.setNotification(ControlLoopNotificationType.OPERATION);
169 notif.setFrom("policy");
170 notif.setPolicyVersion(getPolicyVersion());
174 * Get the last operation, as a message.
176 * @return the last operation, as a message
178 public String getOperationMessage() {
179 OperationOutcome2 last = fullHistory.peekLast();
180 return (last == null ? null : last.getClOperation().toMessage());
184 * Makes a control loop response.
186 * @param outcome operation outcome
187 * @return a new control loop response, or {@code null} if none is required
189 public ControlLoopResponse makeControlLoopResponse(OperationOutcome outcome) {
190 var clRsp = new ControlLoopResponse();
191 clRsp.setFrom(outcome.getActor());
198 public class OperationOutcome2 {
199 private final int attempt;
200 private final OperationOutcome outcome;
201 private final ControlLoopOperation clOperation;
204 * Constructs the object.
206 * @param outcome outcome of the operation
208 public OperationOutcome2(OperationOutcome outcome) {
209 this.outcome = outcome;
210 this.attempt = attempts;
212 clOperation = outcome.toControlLoopOperation();
215 OperationalTarget target = getPolicy().getActorOperation().getTarget();
216 String targetStr = (target != null ? target.toString() : null);
217 clOperation.setTarget(targetStr);
219 if (outcome.getEnd() == null) {
220 clOperation.setOutcome("Started");
221 } else if (clOperation.getOutcome() == null) {
222 clOperation.setOutcome("");
227 protected OperationOutcome2 makeOperationOutcome2(OperationOutcome outcome) {
228 return new OperationOutcome2(outcome);