1502da8b25d342e2389013df6825b21bf1e0d943
[policy/clamp.git] /
1 /*-
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
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.clamp.acm.runtime.supervision.scanner;
22
23 import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
24 import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
25 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
26 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
27 import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils;
28 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
29 import org.onap.policy.clamp.models.acm.document.concepts.DocMessage;
30 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
31 import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import org.springframework.stereotype.Component;
35
36 @Component
37 public class AcDefinitionScanner {
38     private static final Logger LOGGER = LoggerFactory.getLogger(AcDefinitionScanner.class);
39
40     private final long maxOperationWaitMs;
41
42     private final AcDefinitionProvider acDefinitionProvider;
43     private final ParticipantSyncPublisher participantSyncPublisher;
44
45     /**
46      * Constructor for instantiating AcDefinitionScanner.
47      *
48      * @param acDefinitionProvider the Policy Models Provider
49      * @param participantSyncPublisher the Participant Sync Publisher
50      * @param acRuntimeParameterGroup the parameters for the automation composition runtime
51      */
52     public AcDefinitionScanner(final AcDefinitionProvider acDefinitionProvider,
53             final ParticipantSyncPublisher participantSyncPublisher,
54             final AcRuntimeParameterGroup acRuntimeParameterGroup) {
55         this.acDefinitionProvider = acDefinitionProvider;
56         this.participantSyncPublisher = participantSyncPublisher;
57         this.maxOperationWaitMs = acRuntimeParameterGroup.getParticipantParameters().getMaxOperationWaitMs();
58     }
59
60     private UpdateSync handlePrimeAckElement(DocMessage message, AutomationCompositionDefinition acDefinition) {
61         var result = new UpdateSync();
62         if (StateChangeResult.FAILED.equals(message.getStateChangeResult())) {
63             acDefinition.setStateChangeResult(StateChangeResult.FAILED);
64             result.setUpdated(true);
65             result.setToBeSync(true);
66         }
67         for (var element : acDefinition.getElementStateMap().values()) {
68             if (message.getParticipantId().equals(element.getParticipantId())) {
69                 element.setMessage(message.getMessage());
70                 element.setState(message.getCompositionState());
71                 result.setUpdated(true);
72             }
73         }
74         return result;
75     }
76
77     private UpdateSync handleOutProperties(DocMessage message, AutomationCompositionDefinition acDefinition) {
78         var elementOpt = acDefinition.getElementStateMap().values().stream()
79                 .filter(element -> element.getNodeTemplateId().equals(message.getAcElementDefinitionId())).findFirst();
80
81         var result = new UpdateSync();
82         if (elementOpt.isPresent()) {
83             elementOpt.get().setOutProperties(message.getOutProperties());
84             result.setUpdated(true);
85             result.setToBeSync(true);
86         }
87         return result;
88     }
89
90     /**
91      * Scan Message.
92      *
93      * @param acDefinition the AutomationComposition Definition
94      * @param message the message
95      */
96     public UpdateSync scanMessage(AutomationCompositionDefinition acDefinition, DocMessage message) {
97         return switch (message.getMessageType()) {
98             case PARTICIPANT_STATUS -> handleOutProperties(message, acDefinition);
99             case PARTICIPANT_PRIME_ACK -> handlePrimeAckElement(message, acDefinition);
100             default -> {
101                 LOGGER.debug("Not valid MessageType {}", message.getMessageType());
102                 yield new UpdateSync();
103             }
104         };
105     }
106
107     /**
108      * Scan an AutomationComposition Definition.
109      *
110      * @param acDefinition the AutomationComposition Definition
111      * @param updateSync defines if true if the composition has to be saved or sync
112      */
113     public void scanAutomationCompositionDefinition(AutomationCompositionDefinition acDefinition,
114             UpdateSync updateSync) {
115         if (StateChangeResult.FAILED.equals(acDefinition.getStateChangeResult())) {
116             LOGGER.debug("automation definition {} scanned, OK", acDefinition.getCompositionId());
117             updateAcDefinitionState(acDefinition, updateSync);
118             return;
119         }
120
121         boolean completed = true;
122         var finalState = AcTypeState.PRIMING.equals(acDefinition.getState())
123                 || AcTypeState.PRIMED.equals(acDefinition.getState()) ? AcTypeState.PRIMED : AcTypeState.COMMISSIONED;
124         for (var element : acDefinition.getElementStateMap().values()) {
125             if (!finalState.equals(element.getState())) {
126                 completed = false;
127                 break;
128             }
129         }
130         if (completed) {
131             acDefinition.setState(finalState);
132             acDefinition.setStateChangeResult(StateChangeResult.NO_ERROR);
133             updateSync.setUpdated(true);
134             updateSync.setToBeSync(true);
135         } else {
136             updateSync.or(handleTimeout(acDefinition));
137         }
138         updateAcDefinitionState(acDefinition, updateSync);
139     }
140
141     private UpdateSync handleTimeout(AutomationCompositionDefinition acDefinition) {
142         var result = new UpdateSync();
143         if (StateChangeResult.TIMEOUT.equals(acDefinition.getStateChangeResult())) {
144             LOGGER.debug("The ac definition is in timeout {}", acDefinition.getCompositionId());
145             return result;
146         }
147         var name = ParticipantUtils.getOpName(acDefinition.getState());
148         var maxWaitMs = ParticipantUtils
149                 .getTimeout(acDefinition.getServiceTemplate().getMetadata(), name, maxOperationWaitMs);
150         var lastMsg = TimestampHelper.toEpochMilli(acDefinition.getLastMsg());
151         var now = TimestampHelper.nowEpochMilli();
152         if ((now - lastMsg) > maxWaitMs) {
153             LOGGER.debug("Report timeout for the ac definition {}", acDefinition.getCompositionId());
154             acDefinition.setStateChangeResult(StateChangeResult.TIMEOUT);
155             result.setUpdated(true);
156             result.setToBeSync(true);
157         }
158         return result;
159     }
160
161     private void updateAcDefinitionState(AutomationCompositionDefinition acDefinition,
162             UpdateSync updateSync) {
163         if (updateSync.isUpdated()) {
164             acDefinitionProvider.updateAcDefinitionState(acDefinition);
165         }
166         if (updateSync.isToBeSync()) {
167             participantSyncPublisher.sendSync(acDefinition, null);
168         }
169     }
170 }