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 org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
 
  24 import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
 
  25 import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
 
  26 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
 
  27 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 
  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.concepts.SubState;
 
  31 import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
 
  32 import org.onap.policy.clamp.models.acm.utils.AcmUtils;
 
  33 import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
 
  34 import org.slf4j.Logger;
 
  35 import org.slf4j.LoggerFactory;
 
  37 public abstract class AbstractScanner {
 
  39     protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractScanner.class);
 
  41     protected final long maxOperationWaitMs;
 
  43     protected final AutomationCompositionProvider acProvider;
 
  44     private final ParticipantSyncPublisher participantSyncPublisher;
 
  45     private final EncryptionUtils encryptionUtils;
 
  47     protected AbstractScanner(final AutomationCompositionProvider acProvider,
 
  48             final ParticipantSyncPublisher participantSyncPublisher,
 
  49             final AcRuntimeParameterGroup acRuntimeParameterGroup, final EncryptionUtils encryptionUtils) {
 
  50         this.acProvider = acProvider;
 
  51         this.participantSyncPublisher = participantSyncPublisher;
 
  52         this.maxOperationWaitMs = acRuntimeParameterGroup.getParticipantParameters().getMaxOperationWaitMs();
 
  53         this.encryptionUtils = encryptionUtils;
 
  56     protected void complete(final AutomationComposition automationComposition, UpdateSync updateSync) {
 
  57         LOGGER.debug("automation composition scan: transition state {} {} {} completed",
 
  58                 automationComposition.getDeployState(), automationComposition.getLockState(),
 
  59                 automationComposition.getSubState());
 
  61         var deployState = automationComposition.getDeployState();
 
  62         if (DeployState.MIGRATING.equals(automationComposition.getDeployState())) {
 
  64             automationComposition.setCompositionId(automationComposition.getCompositionTargetId());
 
  65             automationComposition.setCompositionTargetId(null);
 
  67         automationComposition.setDeployState(AcmUtils.deployCompleted(deployState));
 
  68         automationComposition.setLockState(AcmUtils.lockCompleted(deployState, automationComposition.getLockState()));
 
  69         automationComposition.setPhase(null);
 
  70         automationComposition.setSubState(SubState.NONE);
 
  71         automationComposition.setPrecheck(null);
 
  72         if (StateChangeResult.TIMEOUT.equals(automationComposition.getStateChangeResult())) {
 
  73             automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
 
  75         if (DeployState.DELETED.equals(automationComposition.getDeployState())) {
 
  76             updateSync.setToBeDelete(true);
 
  77             updateSync.setUpdated(false);
 
  79             updateSync.setUpdated(true);
 
  81         updateSync.setToBeSync(true);
 
  82         saveAndSync(automationComposition, updateSync);
 
  85     protected void savePhase(AutomationComposition automationComposition, int startPhase) {
 
  86         automationComposition.setLastMsg(TimestampHelper.now());
 
  87         automationComposition.setPhase(startPhase);
 
  90     protected void handleTimeout(AutomationComposition automationComposition, UpdateSync updateSync) {
 
  91         LOGGER.debug("automation composition scan: transition from state {} to {} {} not completed",
 
  92                 automationComposition.getDeployState(), automationComposition.getLockState(),
 
  93                 automationComposition.getSubState());
 
  95         if (StateChangeResult.TIMEOUT.equals(automationComposition.getStateChangeResult())) {
 
  96             LOGGER.debug("The ac instance is in timeout {}", automationComposition.getInstanceId());
 
  97             saveAndSync(automationComposition, updateSync);
 
 100         var name = ParticipantUtils.getOpName(automationComposition.getDeployState());
 
 101         var element = automationComposition.getElements().values().stream()
 
 102                 .filter(el -> automationComposition.getDeployState().equals(el.getDeployState())).findFirst();
 
 103         var maxWaitMs = element.map(automationCompositionElement -> ParticipantUtils.getTimeout(
 
 104                 automationCompositionElement.getProperties(), name, maxOperationWaitMs)).orElse(maxOperationWaitMs);
 
 105         var now = TimestampHelper.nowEpochMilli();
 
 106         var lastMsg = TimestampHelper.toEpochMilli(automationComposition.getLastMsg());
 
 107         if ((now - lastMsg) > maxWaitMs) {
 
 108             LOGGER.debug("Report timeout for the ac instance {}", automationComposition.getInstanceId());
 
 109             automationComposition.setStateChangeResult(StateChangeResult.TIMEOUT);
 
 110             updateSync.setUpdated(true);
 
 111             updateSync.setToBeSync(true);
 
 113         saveAndSync(automationComposition, updateSync);
 
 117      * Save AutomationComposition and Sync.
 
 119      * @param automationComposition the AutomationComposition
 
 120      * @param updateSync the update/sync information
 
 122     public void saveAndSync(AutomationComposition automationComposition, UpdateSync updateSync) {
 
 123         if (updateSync.isUpdated()) {
 
 124             acProvider.updateAutomationComposition(automationComposition);
 
 126         if (updateSync.isToBeDelete()) {
 
 127             acProvider.deleteAutomationComposition(automationComposition.getInstanceId());
 
 129         if (updateSync.isToBeSync()) {
 
 130             decryptInstanceProperties(automationComposition);
 
 131             participantSyncPublisher.sendSync(automationComposition);
 
 135     protected void decryptInstanceProperties(AutomationComposition automationComposition) {
 
 136         if (encryptionUtils.encryptionEnabled()) {
 
 137             encryptionUtils.findAndDecryptSensitiveData(automationComposition);