2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2023-2024 Nordix Foundation.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.controlloop.eventmanager;
24 import java.util.Deque;
25 import java.util.LinkedList;
26 import java.util.UUID;
27 import java.util.stream.Collectors;
29 import lombok.ToString;
30 import org.drools.core.WorkingMemory;
31 import org.onap.policy.controlloop.ControlLoopException;
32 import org.onap.policy.controlloop.ControlLoopNotificationType;
33 import org.onap.policy.controlloop.ControlLoopOperation;
34 import org.onap.policy.controlloop.ControlLoopResponse;
35 import org.onap.policy.controlloop.VirtualControlLoopNotification;
36 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
37 import org.onap.policy.controlloop.actorserviceprovider.OperationResult;
38 import org.onap.policy.controlloop.drl.legacy.ControlLoopParams;
39 import org.onap.policy.drools.domain.models.operational.OperationalTarget;
42 * Manager for a single control loop event, with operation outcomes.
45 public abstract class ClEventManagerWithOutcome<T extends Step> extends ClEventManagerWithSteps<T>
46 implements StepContext {
48 private static final long serialVersionUID = -1216568161322872641L;
51 * Number of attempts, so far, for the current step.
56 * Full history of operations that have been processed by the rules. This includes the
57 * 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.
66 private final transient Deque<OperationOutcome2> partialHistory = new LinkedList<>();
70 * Constructs the object.
72 * @param services services the manager should use when processing the event
73 * @param params control loop parameters
74 * @param requestId event request ID
75 * @param workMem working memory to update if this changes
76 * @throws ControlLoopException if the event is invalid or if a YAML processor cannot
79 protected ClEventManagerWithOutcome(EventManagerServices services, ControlLoopParams params, UUID requestId,
80 WorkingMemory workMem) throws ControlLoopException {
82 super(services, params, requestId, workMem);
86 protected void loadPolicy() throws ControlLoopException {
87 partialHistory.clear();
92 public boolean executeStep() {
94 return super.executeStep();
98 * Increments the number of attempts.
100 public void bumpAttempts() {
105 * Determines if the TOSCA should be aborted due to the given outcome.
107 * @param outcome outcome to examine
108 * @return {@code true} if the TOSCA should be aborted, {@code false} otherwise
110 public boolean isAbort(OperationOutcome outcome) {
111 return (outcome.getResult() != OperationResult.SUCCESS);
115 * Adds the outcome to the history.
117 * @param outcome outcome to add
119 public void addToHistory(OperationOutcome outcome) {
120 OperationOutcome2 last = partialHistory.peekLast();
122 if (last != null && last.getOutcome().getEnd() == null
123 && last.getOutcome().isFor(outcome.getActor(), outcome.getOperation())) {
124 // last item was a "start" - remove it
125 partialHistory.removeLast();
127 if (fullHistory.peekLast() == last) {
128 fullHistory.removeLast();
132 var outcome2 = makeOperationOutcome2(outcome);
133 partialHistory.add(outcome2);
134 fullHistory.add(outcome2);
138 * Makes a notification message for the current operation.
140 * @return a new notification
142 public VirtualControlLoopNotification makeNotification() {
143 var notif = new VirtualControlLoopNotification();
144 populateNotification(notif);
146 if (getFinalResult() != null) {
150 OperationOutcome2 last = partialHistory.peekLast();
155 notif.setMessage(last.getClOperation().toHistory());
156 notif.setHistory(partialHistory.stream().map(OperationOutcome2::getClOperation).collect(Collectors.toList()));
162 * Populates a notification structure.
164 * @param notif the notification to populate
166 protected void populateNotification(VirtualControlLoopNotification notif) {
167 notif.setNotification(ControlLoopNotificationType.OPERATION);
168 notif.setFrom("policy");
169 notif.setPolicyVersion(getPolicyVersion());
173 * Get the last operation, as a message.
175 * @return the last operation, as a message
177 public String getOperationMessage() {
178 OperationOutcome2 last = fullHistory.peekLast();
179 return (last == null ? null : last.getClOperation().toMessage());
183 * Makes a control loop response.
185 * @param outcome operation outcome
186 * @return a new control loop response, or {@code null} if none is required
188 public ControlLoopResponse makeControlLoopResponse(OperationOutcome outcome) {
189 var clRsp = new ControlLoopResponse();
190 clRsp.setFrom(outcome.getActor());
197 public class OperationOutcome2 {
198 private final int attempt;
199 private final OperationOutcome outcome;
200 private final ControlLoopOperation clOperation;
203 * Constructs the object.
205 * @param outcome outcome of the operation
207 public OperationOutcome2(OperationOutcome outcome) {
208 this.outcome = outcome;
209 this.attempt = attempts;
211 clOperation = outcome.toControlLoopOperation();
214 OperationalTarget target = getPolicy().getActorOperation().getTarget();
215 String targetStr = (target != null ? target.toString() : null);
216 clOperation.setTarget(targetStr);
218 if (outcome.getEnd() == null) {
219 clOperation.setOutcome("Started");
220 } else if (clOperation.getOutcome() == null) {
221 clOperation.setOutcome("");
226 protected OperationOutcome2 makeOperationOutcome2(OperationOutcome outcome) {
227 return new OperationOutcome2(outcome);