2  * ============LICENSE_START=======================================================
 
   3  *  Copyright (C) 2023-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.models.acm.persistence.provider;
 
  23 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 
  24 import org.onap.policy.clamp.models.acm.concepts.LockState;
 
  25 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
 
  26 import org.onap.policy.clamp.models.acm.concepts.SubState;
 
  27 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
 
  28 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder;
 
  29 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.SubOrder;
 
  30 import org.onap.policy.clamp.models.acm.utils.StateDefinition;
 
  31 import org.springframework.stereotype.Component;
 
  34 public class AcInstanceStateResolver {
 
  35     private final StateDefinition<String> graph;
 
  37     private static final String DEPLOYED = DeployState.DEPLOYED.name();
 
  38     private static final String DEPLOYING = DeployState.DEPLOYING.name();
 
  39     private static final String UNDEPLOYED = DeployState.UNDEPLOYED.name();
 
  40     private static final String UNDEPLOYING = DeployState.UNDEPLOYING.name();
 
  41     private static final String UPDATING = DeployState.UPDATING.name();
 
  42     private static final String DELETING = DeployState.DELETING.name();
 
  43     private static final String MIGRATING = DeployState.MIGRATING.name();
 
  44     private static final String MIGRATION_PRECHECKING = SubState.MIGRATION_PRECHECKING.name();
 
  45     private static final String MIGRATION_REVERTING = DeployState.MIGRATION_REVERTING.name();
 
  46     private static final String SUB_STATE_NONE = SubState.NONE.name();
 
  47     private static final String PREPARING = SubState.PREPARING.name();
 
  48     private static final String REVIEWING = SubState.REVIEWING.name();
 
  50     private static final String LOCKED = LockState.LOCKED.name();
 
  51     private static final String LOCKING = LockState.LOCKING.name();
 
  52     private static final String UNLOCKED = LockState.UNLOCKED.name();
 
  53     private static final String UNLOCKING = LockState.UNLOCKING.name();
 
  54     private static final String STATE_LOCKED_NONE = LockState.NONE.name();
 
  56     private static final String DEPLOY_NONE = DeployOrder.NONE.name();
 
  57     private static final String LOCK_NONE = LockOrder.NONE.name();
 
  58     private static final String SUB_NONE = SubOrder.NONE.name();
 
  60     private static final String NO_ERROR = StateChangeResult.NO_ERROR.name();
 
  61     private static final String FAILED = StateChangeResult.FAILED.name();
 
  62     private static final String TIMEOUT = StateChangeResult.TIMEOUT.name();
 
  65     public static final String DEPLOY = DeployOrder.DEPLOY.name();
 
  66     public static final String UNDEPLOY = DeployOrder.UNDEPLOY.name();
 
  67     public static final String DELETE = DeployOrder.DELETE.name();
 
  68     public static final String LOCK = LockOrder.LOCK.name();
 
  69     public static final String UNLOCK = LockOrder.UNLOCK.name();
 
  70     public static final String MIGRATE = DeployOrder.MIGRATE.name();
 
  71     public static final String MIGRATE_PRECHECK = SubOrder.MIGRATE_PRECHECK.name();
 
  72     public static final String PREPARE = SubOrder.PREPARE.name();
 
  73     public static final String REVIEW = SubOrder.REVIEW.name();
 
  74     public static final String UPDATE = DeployOrder.UPDATE.name();
 
  75     public static final String NONE = "NONE";
 
  80     public AcInstanceStateResolver() {
 
  81         this.graph = new StateDefinition<>(7, NONE);
 
  83         // make an order when there are no fails
 
  84         addDeployOrder(DEPLOY, UNDEPLOYED, STATE_LOCKED_NONE);
 
  85         addDeployOrder(UNDEPLOY, DEPLOYED, LOCKED);
 
  86         addDeployOrder(DELETE, UNDEPLOYED, STATE_LOCKED_NONE);
 
  87         addDeployOrder(MIGRATE, DEPLOYED, LOCKED);
 
  88         addDeployOrder(UPDATE, DEPLOYED, LOCKED);
 
  90         addLockOrder(UNLOCK, LOCKED);
 
  91         addLockOrder(LOCK, UNLOCKED);
 
  93         addSubOrder(REVIEW, DEPLOYED, LOCKED);
 
  94         addSubOrder(PREPARE, UNDEPLOYED, STATE_LOCKED_NONE);
 
  95         addSubOrder(MIGRATE_PRECHECK, DEPLOYED, LOCKED);
 
  97         // failed or timeout scenario
 
 101         // undeploy order in a failed or timeout scenario
 
 102         addDeployOrderWithFail(UNDEPLOY, UPDATING, LOCKED, SUB_STATE_NONE);
 
 103         addDeployOrderWithFail(UNDEPLOY, MIGRATING, LOCKED, SUB_STATE_NONE);
 
 104         addDeployOrderWithFail(UNDEPLOY, MIGRATION_PRECHECKING, LOCKED, SUB_STATE_NONE);
 
 105         addDeployOrderWithFail(UNDEPLOY, REVIEWING, LOCKED, SUB_STATE_NONE);
 
 107         // delete order in a failed or timeout scenario
 
 108         addDeployOrderWithFail(DELETE, DELETING, LOCK_NONE, SUB_STATE_NONE);
 
 109         addDeployOrderWithFail(DELETE, UNDEPLOYED, LOCK_NONE, PREPARING);
 
 111         // update order in a failed or timeout scenario
 
 112         addDeployOrderWithFail(UPDATE, UPDATING, LOCKED, SUB_STATE_NONE);
 
 114         // unlock order in a failed or timeout scenario
 
 115         addLockOrderWithFail(UNLOCK, LOCKING);
 
 116         addLockOrderWithFail(UNLOCK, UNLOCKING);
 
 118         // lock order in a failed or timeout scenario
 
 119         addLockOrderWithFail(LOCK, LOCKING);
 
 120         addLockOrderWithFail(LOCK, UNLOCKING);
 
 122         // migrate-precheck order in a failed or timeout scenario
 
 123         addSubOrderWithFail(MIGRATE_PRECHECK, DEPLOYED, LOCKED, MIGRATION_PRECHECKING);
 
 125         // prepare order in a failed or timeout scenario
 
 126         addSubOrderWithFail(PREPARE, UNDEPLOYED, LOCK_NONE, PREPARING);
 
 128         // review order in a failed or timeout scenario
 
 129         addSubOrderWithFail(REVIEW, DEPLOYED, LOCKED, REVIEWING);
 
 132         addDeployOrderWithFail(MIGRATION_REVERTING, MIGRATING, LOCKED, SUB_STATE_NONE);
 
 133         addDeployOrderWithFail(UNDEPLOY, MIGRATION_REVERTING, LOCKED, SUB_STATE_NONE);
 
 136     private void addDeployOrder(String deployOrder, String deployState, String lockState) {
 
 137         this.graph.put(new String[] {
 
 138             deployOrder, LOCK_NONE, SUB_NONE, deployState, lockState, STATE_LOCKED_NONE, NO_ERROR}, deployOrder);
 
 141     private void addDeployOrderWithFail(String deployOrder, String deployState, String lockState, String subState) {
 
 142         this.graph.put(new String[] {
 
 143             deployOrder, LOCK_NONE, SUB_NONE, deployState, lockState, subState, FAILED}, deployOrder);
 
 144         this.graph.put(new String[] {
 
 145             deployOrder, LOCK_NONE, SUB_NONE, deployState, lockState, subState, TIMEOUT}, deployOrder);
 
 148     private void addSubOrder(String subOrder, String deployState, String lockState) {
 
 149         this.graph.put(new String[] {
 
 150             DEPLOY_NONE, LOCK_NONE, subOrder, deployState, lockState, SUB_STATE_NONE, NO_ERROR}, subOrder);
 
 153     private void addSubOrderWithFail(String subOrder, String deployState, String lockState, String subState) {
 
 154         this.graph.put(new String[] {
 
 155             DEPLOY_NONE, LOCK_NONE, subOrder, deployState, lockState, subState, FAILED}, subOrder);
 
 156         this.graph.put(new String[] {
 
 157             DEPLOY_NONE, LOCK_NONE, subOrder, deployState, lockState, subState, TIMEOUT}, subOrder);
 
 160     private void addLockOrder(String lockOrder, String lockState) {
 
 161         this.graph.put(new String[] {
 
 162             DEPLOY_NONE, lockOrder, SUB_NONE, DEPLOYED, lockState, SUB_STATE_NONE, NO_ERROR}, lockOrder);
 
 165     private void addLockOrderWithFail(String lockOrder, String lockState) {
 
 166         this.graph.put(new String[] {
 
 167             DEPLOY_NONE, lockOrder, SUB_NONE, DEPLOYED, lockState, SUB_STATE_NONE, FAILED}, lockOrder);
 
 168         this.graph.put(new String[] {
 
 169             DEPLOY_NONE, lockOrder, SUB_NONE, DEPLOYED, lockState, SUB_STATE_NONE, TIMEOUT}, lockOrder);
 
 172     private void setAllowed(String deployOrder) {
 
 173         addDeployOrderWithFail(deployOrder, UNDEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE);
 
 174         addDeployOrderWithFail(deployOrder, UNDEPLOYING, LOCKED, SUB_STATE_NONE);
 
 175         addDeployOrderWithFail(deployOrder, DEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE);
 
 176         addDeployOrderWithFail(deployOrder, DEPLOYING, LOCKED, SUB_STATE_NONE);
 
 180      * Check if Deploy Order and Lock Order are consistent with current DeployState and LockState.
 
 182      * @param acDeployOrder the Deploy Ordered
 
 183      * @param acLockOrder the Lock Ordered
 
 184      * @param acSubOrder the Sub Ordered
 
 185      * @param acDeployState the current Deploy State
 
 186      * @param acLockState the current Lock State
 
 187      * @param acSubState the current Sub State
 
 188      * @param acStateChangeResult the current Result of the State Change
 
 189      * @return the order (DEPLOY/UNDEPLOY/LOCK/UNLOCK) to send to participant or NONE if order is not consistent
 
 191     public String resolve(DeployOrder acDeployOrder, LockOrder acLockOrder, SubOrder acSubOrder,
 
 192         DeployState acDeployState, LockState acLockState, SubState acSubState, StateChangeResult acStateChangeResult) {
 
 193         var deployOrder = acDeployOrder != null ? acDeployOrder : DeployOrder.NONE;
 
 194         var lockOrder = acLockOrder != null ? acLockOrder : LockOrder.NONE;
 
 195         var subOrder = acSubOrder != null ? acSubOrder : SubOrder.NONE;
 
 196         var stateChangeResult = acStateChangeResult != null ? acStateChangeResult : StateChangeResult.NO_ERROR;
 
 198         var deployState = acDeployState != null ? acDeployState : DeployState.UNDEPLOYED;
 
 199         var lockState = acLockState != null ? acLockState : LockState.NONE;
 
 200         var subState = acSubState != null ? acSubState : SubState.NONE;
 
 201         return this.graph.get(new String[] {deployOrder.name(), lockOrder.name(), subOrder.name(),
 
 202                 deployState.name(), lockState.name(), subState.name(), stateChangeResult.name()});