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