2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2025 OpenInfra Foundation Europe. All rights reserved.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.clamp.acm.runtime.supervision.scanner;
23 import java.util.UUID;
24 import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
25 import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
26 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
27 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
28 import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils;
29 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
30 import org.onap.policy.clamp.models.acm.document.concepts.DocMessage;
31 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
32 import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35 import org.springframework.stereotype.Component;
38 public class AcDefinitionScanner {
39 private static final Logger LOGGER = LoggerFactory.getLogger(AcDefinitionScanner.class);
41 private final long maxOperationWaitMs;
43 private final AcDefinitionProvider acDefinitionProvider;
44 private final ParticipantSyncPublisher participantSyncPublisher;
47 * Constructor for instantiating AcDefinitionScanner.
49 * @param acDefinitionProvider the Policy Models Provider
50 * @param participantSyncPublisher the Participant Sync Publisher
51 * @param acRuntimeParameterGroup the parameters for the automation composition runtime
53 public AcDefinitionScanner(final AcDefinitionProvider acDefinitionProvider,
54 final ParticipantSyncPublisher participantSyncPublisher,
55 final AcRuntimeParameterGroup acRuntimeParameterGroup) {
56 this.acDefinitionProvider = acDefinitionProvider;
57 this.participantSyncPublisher = participantSyncPublisher;
58 this.maxOperationWaitMs = acRuntimeParameterGroup.getParticipantParameters().getMaxOperationWaitMs();
61 private UpdateSync handlePrimeAckElement(DocMessage message, AutomationCompositionDefinition acDefinition) {
62 var result = new UpdateSync();
63 if (StateChangeResult.FAILED.equals(message.getStateChangeResult())) {
64 acDefinition.setStateChangeResult(StateChangeResult.FAILED);
65 result.setUpdated(true);
66 result.setToBeSync(true);
68 for (var element : acDefinition.getElementStateMap().values()) {
69 if (message.getParticipantId().equals(element.getParticipantId())) {
70 element.setMessage(message.getMessage());
71 element.setState(message.getCompositionState());
72 result.setUpdated(true);
78 private UpdateSync handleOutProperties(DocMessage message, AutomationCompositionDefinition acDefinition) {
79 var elementOpt = acDefinition.getElementStateMap().values().stream()
80 .filter(element -> element.getNodeTemplateId().equals(message.getAcElementDefinitionId())).findFirst();
82 var result = new UpdateSync();
83 if (elementOpt.isPresent()) {
84 elementOpt.get().setOutProperties(message.getOutProperties());
85 result.setUpdated(true);
86 result.setToBeSync(true);
94 * @param acDefinition the AutomationComposition Definition
95 * @param message the message
97 public UpdateSync scanMessage(AutomationCompositionDefinition acDefinition, DocMessage message) {
98 return switch (message.getMessageType()) {
99 case PARTICIPANT_STATUS -> handleOutProperties(message, acDefinition);
100 case PARTICIPANT_PRIME_ACK -> handlePrimeAckElement(message, acDefinition);
102 LOGGER.debug("Not valid MessageType {}", message.getMessageType());
103 yield new UpdateSync();
109 * Scan an AutomationComposition Definition.
111 * @param acDefinition the AutomationComposition Definition
112 * @param updateSync defines if true if the composition has to be saved or sync
114 public void scanAutomationCompositionDefinition(AutomationCompositionDefinition acDefinition,
115 UpdateSync updateSync) {
116 if (StateChangeResult.FAILED.equals(acDefinition.getStateChangeResult())) {
117 LOGGER.debug("automation definition {} scanned, OK", acDefinition.getCompositionId());
118 updateAcDefinitionState(acDefinition, updateSync);
122 boolean completed = true;
123 var finalState = AcTypeState.PRIMING.equals(acDefinition.getState())
124 || AcTypeState.PRIMED.equals(acDefinition.getState()) ? AcTypeState.PRIMED : AcTypeState.COMMISSIONED;
125 for (var element : acDefinition.getElementStateMap().values()) {
126 if (!finalState.equals(element.getState())) {
132 acDefinition.setState(finalState);
133 acDefinition.setStateChangeResult(StateChangeResult.NO_ERROR);
134 updateSync.setUpdated(true);
135 updateSync.setToBeSync(true);
137 updateSync.or(handleTimeout(acDefinition));
139 updateAcDefinitionState(acDefinition, updateSync);
142 private UpdateSync handleTimeout(AutomationCompositionDefinition acDefinition) {
143 var result = new UpdateSync();
144 if (StateChangeResult.TIMEOUT.equals(acDefinition.getStateChangeResult())) {
145 LOGGER.debug("The ac definition is in timeout {}", acDefinition.getCompositionId());
148 var name = ParticipantUtils.getOpName(acDefinition.getState());
149 var maxWaitMs = ParticipantUtils
150 .getTimeout(acDefinition.getServiceTemplate().getMetadata(), name, maxOperationWaitMs);
151 var lastMsg = TimestampHelper.toEpochMilli(acDefinition.getLastMsg());
152 var now = TimestampHelper.nowEpochMilli();
153 if ((now - lastMsg) > maxWaitMs) {
154 LOGGER.debug("Report timeout for the ac definition {}", acDefinition.getCompositionId());
155 acDefinition.setStateChangeResult(StateChangeResult.TIMEOUT);
156 result.setUpdated(true);
157 result.setToBeSync(true);
162 private void updateAcDefinitionState(AutomationCompositionDefinition acDefinition,
163 UpdateSync updateSync) {
164 if (updateSync.isUpdated()) {
165 acDefinition.setRevisionId(UUID.randomUUID());
166 acDefinitionProvider.updateAcDefinitionState(acDefinition);
168 if (updateSync.isToBeSync()) {
169 participantSyncPublisher.sendSync(acDefinition, null);