Add support for Prepare, Review and Migrate pre-check in ACM model 05/138505/1
authorFrancescoFioraEst <francesco.fiora@est.tech>
Thu, 18 Jul 2024 10:25:13 +0000 (11:25 +0100)
committerFrancesco Fiora <francesco.fiora@est.tech>
Thu, 18 Jul 2024 10:40:22 +0000 (10:40 +0000)
Issue-ID: POLICY-5078
Change-Id: I22edfab66d35958c874f3322e573dec5bf8709d7
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
14 files changed:
models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java
models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionElement.java
models/src/main/java/org/onap/policy/clamp/models/acm/concepts/SubState.java [new file with mode: 0644]
models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/AutomationCompositionMigration.java
models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/AutomationCompositionPrepare.java [new file with mode: 0644]
models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantMessageType.java
models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/instantiation/AcInstanceStateUpdate.java
models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/instantiation/SubOrder.java [new file with mode: 0644]
models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java
models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElement.java
models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java
models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java
models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElementTest.java
models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionTest.java

index eb5b6dc..005d8a1 100644 (file)
@@ -46,6 +46,8 @@ public class AutomationComposition extends ToscaEntity implements Comparable<Aut
 
     private Boolean restarting;
 
+    private Boolean precheck;
+
     @NonNull
     private DeployState deployState = DeployState.UNDEPLOYED;
 
@@ -56,6 +58,9 @@ public class AutomationComposition extends ToscaEntity implements Comparable<Aut
 
     private Integer phase;
 
+    @NonNull
+    private SubState subState = SubState.NONE;
+
     private Map<UUID, AutomationCompositionElement> elements;
 
     private StateChangeResult stateChangeResult;
@@ -71,10 +76,12 @@ public class AutomationComposition extends ToscaEntity implements Comparable<Aut
         this.compositionId = otherAutomationComposition.compositionId;
         this.compositionTargetId = otherAutomationComposition.compositionTargetId;
         this.restarting = otherAutomationComposition.restarting;
+        this.precheck = otherAutomationComposition.precheck;
         this.deployState = otherAutomationComposition.deployState;
         this.lockState = otherAutomationComposition.lockState;
         this.lastMsg = otherAutomationComposition.lastMsg;
         this.phase = otherAutomationComposition.phase;
+        this.subState = otherAutomationComposition.subState;
         this.elements = PfUtils.mapMap(otherAutomationComposition.elements, AutomationCompositionElement::new);
         this.stateChangeResult = otherAutomationComposition.stateChangeResult;
     }
index 5afa7e0..16398e5 100644 (file)
@@ -55,6 +55,9 @@ public class AutomationCompositionElement {
     @NonNull
     private LockState lockState = LockState.LOCKED;
 
+    @NonNull
+    private SubState subState = SubState.NONE;
+
     private String operationalState;
     private String useState;
     private String description;
@@ -81,6 +84,7 @@ public class AutomationCompositionElement {
         this.restarting = otherElement.restarting;
         this.deployState = otherElement.deployState;
         this.lockState = otherElement.lockState;
+        this.subState = otherElement.subState;
         this.operationalState = otherElement.operationalState;
         this.useState = otherElement.useState;
         this.message = otherElement.message;
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/SubState.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/SubState.java
new file mode 100644 (file)
index 0000000..5f979c5
--- /dev/null
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2024 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.models.acm.concepts;
+
+public enum SubState {
+    NONE,
+    MIGRATION_PRECHECKING,
+    PREPARING,
+    REVIEWING
+}
index fb1f192..6ae812c 100644 (file)
@@ -37,6 +37,8 @@ public class AutomationCompositionMigration extends ParticipantMessage {
     // A list of updates to AC element properties
     private List<ParticipantDeploy> participantUpdatesList = new ArrayList<>();
 
+    private Boolean precheck = false;
+
     public AutomationCompositionMigration() {
         super(ParticipantMessageType.AUTOMATION_COMPOSITION_MIGRATION);
     }
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/AutomationCompositionPrepare.java b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/AutomationCompositionPrepare.java
new file mode 100644 (file)
index 0000000..343143e
--- /dev/null
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.models.acm.messages.kafka.participant;
+
+import java.util.ArrayList;
+import java.util.List;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy;
+import org.onap.policy.models.base.PfUtils;
+
+@Getter
+@Setter
+@ToString(callSuper = true)
+public class AutomationCompositionPrepare extends ParticipantMessage {
+
+    private List<ParticipantDeploy> participantList = new ArrayList<>();
+    private boolean preDeploy = true;
+
+    /**
+     * Constructor for instantiating class with message name.
+     *
+     */
+    public AutomationCompositionPrepare() {
+        super(ParticipantMessageType.AUTOMATION_COMPOSITION_PREPARE);
+    }
+
+    /**
+     * Constructs the object, making a deep copy.
+     *
+     * @param source source from which to copy
+     */
+    public AutomationCompositionPrepare(AutomationCompositionPrepare source) {
+        super(source);
+        this.preDeploy = source.preDeploy;
+        this.participantList = PfUtils.mapList(source.participantList, ParticipantDeploy::new);
+    }
+}
index e6e42e8..7e19f6f 100644 (file)
@@ -115,5 +115,10 @@ public enum ParticipantMessageType {
     /**
      * Used by runtime to send composition and instances to sync participant replicas.
      */
-    PARTICIPANT_SYNC_MSG
+    PARTICIPANT_SYNC_MSG,
+
+    /**
+     * Used by the acm runtime to ask for a preparation check to participants.
+     */
+    AUTOMATION_COMPOSITION_PREPARE
 }
index e47947a..68c597b 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2021-2022 Nordix Foundation.
+ * Copyright (C) 2021-2022,2024 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,4 +26,5 @@ import lombok.Data;
 public class AcInstanceStateUpdate {
     private DeployOrder deployOrder;
     private LockOrder lockOrder;
+    private SubOrder subOrder;
 }
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/instantiation/SubOrder.java b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/instantiation/SubOrder.java
new file mode 100644 (file)
index 0000000..9cf7efa
--- /dev/null
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2024 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.models.acm.messages.rest.instantiation;
+
+public enum SubOrder {
+    NONE,
+    MIGRATE_PRECHECK,
+    PREPARE,
+    REVIEW
+}
index 355fcaf..1f4768e 100644 (file)
@@ -45,6 +45,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
+import org.onap.policy.clamp.models.acm.concepts.SubState;
 import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
 import org.onap.policy.common.parameters.annotations.NotNull;
 import org.onap.policy.common.parameters.annotations.Valid;
@@ -96,6 +97,10 @@ public class JpaAutomationComposition extends Validated
     @NotNull
     private LockState lockState;
 
+    @Column
+    @NotNull
+    private SubState subState;
+
     @Column
     private StateChangeResult stateChangeResult;
 
@@ -119,7 +124,7 @@ public class JpaAutomationComposition extends Validated
      */
     public JpaAutomationComposition() {
         this(UUID.randomUUID().toString(), new PfConceptKey(), UUID.randomUUID().toString(), new ArrayList<>(),
-                DeployState.UNDEPLOYED, LockState.NONE);
+                DeployState.UNDEPLOYED, LockState.NONE, SubState.NONE);
     }
 
     /**
@@ -131,10 +136,12 @@ public class JpaAutomationComposition extends Validated
      * @param elements the elements of the automation composition in participants
      * @param deployState the Deploy State
      * @param lockState the Lock State
+     * @param subState the Sub State
      */
     public JpaAutomationComposition(@NonNull final String instanceId, @NonNull final PfConceptKey key,
             @NonNull final String compositionId, @NonNull final List<JpaAutomationCompositionElement> elements,
-            @NonNull final DeployState deployState, @NonNull final LockState lockState) {
+            @NonNull final DeployState deployState, @NonNull final LockState lockState,
+            @NonNull final SubState subState) {
         this.instanceId = instanceId;
         this.name = key.getName();
         this.version = key.getVersion();
@@ -142,6 +149,7 @@ public class JpaAutomationComposition extends Validated
         this.deployState = deployState;
         this.lockState = lockState;
         this.elements = elements;
+        this.subState = subState;
     }
 
     /**
@@ -160,6 +168,7 @@ public class JpaAutomationComposition extends Validated
         this.lockState = copyConcept.lockState;
         this.lastMsg = copyConcept.lastMsg;
         this.phase = copyConcept.phase;
+        this.subState = copyConcept.subState;
         this.description = copyConcept.description;
         this.stateChangeResult = copyConcept.stateChangeResult;
         this.elements = PfUtils.mapList(copyConcept.elements, JpaAutomationCompositionElement::new);
@@ -190,6 +199,7 @@ public class JpaAutomationComposition extends Validated
         automationComposition.setLockState(lockState);
         automationComposition.setLastMsg(lastMsg.toString());
         automationComposition.setPhase(phase);
+        automationComposition.setSubState(subState);
         automationComposition.setDescription(description);
         automationComposition.setStateChangeResult(stateChangeResult);
         automationComposition.setElements(new LinkedHashMap<>(this.elements.size()));
@@ -230,6 +240,7 @@ public class JpaAutomationComposition extends Validated
         this.lockState = automationComposition.getLockState();
         this.lastMsg = TimestampHelper.toTimestamp(automationComposition.getLastMsg());
         this.phase = automationComposition.getPhase();
+        this.subState = automationComposition.getSubState();
         this.description = automationComposition.getDescription();
         this.stateChangeResult = automationComposition.getStateChangeResult();
     }
@@ -293,6 +304,11 @@ public class JpaAutomationComposition extends Validated
             return result;
         }
 
+        result = ObjectUtils.compare(subState, other.subState);
+        if (result != 0) {
+            return result;
+        }
+
         result = ObjectUtils.compare(description, other.description);
         if (result != 0) {
             return result;
index 74426a7..79ca961 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2021-2023 Nordix Foundation.
+ * Copyright (C) 2021-2024 Nordix Foundation.
  * ================================================================================
  * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
@@ -42,6 +42,7 @@ import org.apache.commons.lang3.ObjectUtils;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
+import org.onap.policy.clamp.models.acm.concepts.SubState;
 import org.onap.policy.common.parameters.annotations.NotNull;
 import org.onap.policy.common.parameters.annotations.Valid;
 import org.onap.policy.models.base.PfAuthorative;
@@ -93,6 +94,10 @@ public class JpaAutomationCompositionElement extends Validated
     @NotNull
     private LockState lockState;
 
+    @Column
+    @NotNull
+    private SubState subState;
+
     @Column
     private String operationalState;
 
@@ -134,7 +139,7 @@ public class JpaAutomationCompositionElement extends Validated
      */
     public JpaAutomationCompositionElement(@NonNull final String elementId, @NonNull final String instanceId) {
         this(elementId, instanceId, new PfConceptKey(),
-            DeployState.UNDEPLOYED, LockState.LOCKED);
+            DeployState.UNDEPLOYED, LockState.NONE, SubState.NONE);
     }
 
     /**
@@ -145,15 +150,18 @@ public class JpaAutomationCompositionElement extends Validated
      * @param definition the TOSCA definition of the automation composition element
      * @param deployState the Deploy State of the automation composition
      * @param lockState the Lock State of the automation composition
+     * @param subState the Sub State of the automation composition
      */
     public JpaAutomationCompositionElement(@NonNull final String elementId, @NonNull final String instanceId,
             @NonNull final PfConceptKey definition,
-            @NonNull final DeployState deployState, @NonNull final LockState lockState) {
+            @NonNull final DeployState deployState, @NonNull final LockState lockState,
+            @NonNull final SubState subState) {
         this.elementId = elementId;
         this.instanceId = instanceId;
         this.definition = definition;
         this.deployState = deployState;
         this.lockState = lockState;
+        this.subState = subState;
     }
 
     /**
@@ -174,6 +182,7 @@ public class JpaAutomationCompositionElement extends Validated
         this.restarting = copyConcept.restarting;
         this.deployState = copyConcept.deployState;
         this.lockState = copyConcept.lockState;
+        this.subState = copyConcept.subState;
         this.operationalState = copyConcept.operationalState;
         this.useState = copyConcept.useState;
         this.message = copyConcept.message;
@@ -201,6 +210,7 @@ public class JpaAutomationCompositionElement extends Validated
         element.setRestarting(restarting);
         element.setDeployState(deployState);
         element.setLockState(lockState);
+        element.setSubState(subState);
         element.setOperationalState(operationalState);
         element.setUseState(useState);
         element.setMessage(message);
@@ -218,6 +228,7 @@ public class JpaAutomationCompositionElement extends Validated
         this.restarting = element.getRestarting();
         this.deployState = element.getDeployState();
         this.lockState = element.getLockState();
+        this.subState = element.getSubState();
         this.operationalState = element.getOperationalState();
         this.useState = element.getUseState();
         this.message = element.getMessage();
@@ -267,6 +278,11 @@ public class JpaAutomationCompositionElement extends Validated
             return result;
         }
 
+        result = ObjectUtils.compare(subState, other.subState);
+        if (result != 0) {
+            return result;
+        }
+
         result = ObjectUtils.compare(useState, other.useState);
         if (result != 0) {
             return result;
index ce25809..9b73648 100644 (file)
@@ -35,6 +35,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionInfo;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
+import org.onap.policy.clamp.models.acm.concepts.SubState;
 import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationComposition;
 import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionElement;
 import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionElementRepository;
@@ -172,6 +173,8 @@ public class AutomationCompositionProvider {
             DeployState.UNDEPLOYING, DeployState.DELETING, DeployState.UPDATING, DeployState.MIGRATING));
         jpaList.addAll(automationCompositionRepository.findByLockStateIn(
             List.of(LockState.LOCKING, LockState.UNLOCKING)));
+        jpaList.addAll(automationCompositionRepository.findBySubStateIn(
+                List.of(SubState.PREPARING, SubState.MIGRATION_PRECHECKING, SubState.REVIEWING)));
         return ProviderUtils.asEntityList(jpaList);
     }
 
@@ -258,6 +261,7 @@ public class AutomationCompositionProvider {
         jpaAcElement.setUseState(element.getUseState());
         jpaAcElement.setDeployState(element.getDeployState());
         jpaAcElement.setLockState(element.getLockState());
+        jpaAcElement.setSubState(element.getSubState());
         jpaAcElement.setRestarting(element.getRestarting());
 
         ProviderUtils.validate(element, jpaAcElement, "AutomationCompositionElement");
index d61dfb4..7a1c61f 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Collection;
 import java.util.List;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
+import org.onap.policy.clamp.models.acm.concepts.SubState;
 import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationComposition;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
@@ -36,4 +37,6 @@ public interface AutomationCompositionRepository extends JpaRepository<JpaAutoma
     List<JpaAutomationComposition> findByDeployStateIn(Collection<DeployState> deployStates);
 
     List<JpaAutomationComposition> findByLockStateIn(Collection<LockState> lockStates);
+
+    List<JpaAutomationComposition> findBySubStateIn(Collection<SubState> subStates);
 }
index a6b3c0f..609d4c1 100644 (file)
@@ -33,6 +33,7 @@ import org.junit.jupiter.api.Test;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
+import org.onap.policy.clamp.models.acm.concepts.SubState;
 import org.onap.policy.clamp.models.acm.utils.CommonTestData;
 import org.onap.policy.models.base.PfConceptKey;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
@@ -47,6 +48,8 @@ class JpaAutomationCompositionElementTest {
     private static final String NULL_ERROR = " is marked .*ull but is null";
     private static final String ELEMENT_ID = "a95757ba-b34a-4049-a2a8-46773abcbe5e";
     private static final String INSTANCE_ID = "a78757co-b34a-8949-a2a8-46773abcbe2a";
+    private static final String KEY = "key";
+    private static final String BAD_VALUE = "BadValue";
 
     private static final PfConceptKey CONCEPT_KEY = new PfConceptKey();
 
@@ -54,18 +57,18 @@ class JpaAutomationCompositionElementTest {
     void testJpaAutomationCompositionElementConstructor() {
         assertThatThrownBy(() -> {
             new JpaAutomationCompositionElement((AutomationCompositionElement) null);
-        }).hasMessageMatching("authorativeConcept is marked .*ull but is null");
+        }).hasMessageMatching("authorativeConcept" + NULL_ERROR);
 
         assertThatThrownBy(() -> {
             new JpaAutomationCompositionElement((JpaAutomationCompositionElement) null);
-        }).hasMessageMatching("copyConcept is marked .*ull but is null");
+        }).hasMessageMatching("copyConcept" + NULL_ERROR);
 
         assertThatThrownBy(() -> {
-            new JpaAutomationCompositionElement("key", null);
+            new JpaAutomationCompositionElement(KEY, null);
         }).hasMessageMatching(NULL_INSTANCE_ID_ERROR);
 
         assertThatThrownBy(() -> {
-            new JpaAutomationCompositionElement(null, "key");
+            new JpaAutomationCompositionElement(null, KEY);
         }).hasMessageMatching(NULL_ELEMENT_ID_ERROR);
 
         assertThatThrownBy(() -> {
@@ -73,33 +76,38 @@ class JpaAutomationCompositionElementTest {
         }).hasMessageMatching(NULL_ELEMENT_ID_ERROR);
 
         assertThatThrownBy(() -> {
-            new JpaAutomationCompositionElement(null, null, null, null, null);
+            new JpaAutomationCompositionElement(null, null, null, null, null, null);
         }).hasMessageMatching(NULL_ELEMENT_ID_ERROR);
 
         assertThatThrownBy(() -> {
-            new JpaAutomationCompositionElement("key", null, null,
-                DeployState.UNDEPLOYED, LockState.LOCKED);
+            new JpaAutomationCompositionElement(KEY, null, null,
+                DeployState.UNDEPLOYED, LockState.LOCKED, SubState.NONE);
         }).hasMessageMatching(NULL_INSTANCE_ID_ERROR);
 
         assertThatThrownBy(() -> {
-            new JpaAutomationCompositionElement("key", "key", null,
-                DeployState.UNDEPLOYED, LockState.LOCKED);
+            new JpaAutomationCompositionElement(KEY, KEY, null,
+                DeployState.UNDEPLOYED, LockState.LOCKED, SubState.NONE);
         }).hasMessageMatching("definition" + NULL_ERROR);
 
         assertThatThrownBy(() -> {
-            new JpaAutomationCompositionElement("key", "key", CONCEPT_KEY,
-                null, LockState.LOCKED);
+            new JpaAutomationCompositionElement(KEY, KEY, CONCEPT_KEY,
+                    null, LockState.LOCKED, SubState.NONE);
         }).hasMessageMatching("deployState" + NULL_ERROR);
 
         assertThatThrownBy(() -> {
-            new JpaAutomationCompositionElement("key", "key", CONCEPT_KEY,
-                DeployState.UNDEPLOYED, null);
+            new JpaAutomationCompositionElement(KEY, KEY, CONCEPT_KEY,
+                DeployState.UNDEPLOYED, null, SubState.NONE);
         }).hasMessageMatching("lockState" + NULL_ERROR);
 
+        assertThatThrownBy(() -> {
+            new JpaAutomationCompositionElement(KEY, KEY, CONCEPT_KEY,
+                    DeployState.UNDEPLOYED, LockState.NONE, null);
+        }).hasMessageMatching("subState" + NULL_ERROR);
+
         assertDoesNotThrow(() -> new JpaAutomationCompositionElement());
-        assertDoesNotThrow(() -> new JpaAutomationCompositionElement("key", "key"));
-        assertDoesNotThrow(() -> new JpaAutomationCompositionElement("key", "key",
-                CONCEPT_KEY, DeployState.UNDEPLOYED, LockState.LOCKED));
+        assertDoesNotThrow(() -> new JpaAutomationCompositionElement(KEY, KEY));
+        assertDoesNotThrow(() -> new JpaAutomationCompositionElement(KEY, KEY,
+            new PfConceptKey(), DeployState.UNDEPLOYED, LockState.LOCKED, SubState.NONE));
     }
 
     @Test
@@ -111,7 +119,7 @@ class JpaAutomationCompositionElementTest {
 
         assertThatThrownBy(() -> {
             testJpaAcElement.fromAuthorative(null);
-        }).hasMessageMatching("element is marked .*ull but is null");
+        }).hasMessageMatching("element" + NULL_ERROR);
 
         assertThatThrownBy(() -> new JpaAutomationCompositionElement((JpaAutomationCompositionElement) null))
                 .isInstanceOf(NullPointerException.class);
@@ -137,7 +145,7 @@ class JpaAutomationCompositionElementTest {
         var testJpaAutomationCompositionElement = createJpaAutomationCompositionElementInstance();
 
         assertThatThrownBy(() -> testJpaAutomationCompositionElement.validate(null))
-                .hasMessageMatching("fieldName is marked .*ull but is null");
+                .hasMessageMatching("fieldName" + NULL_ERROR);
 
         assertTrue(testJpaAutomationCompositionElement.validate("").isValid());
     }
@@ -164,17 +172,17 @@ class JpaAutomationCompositionElementTest {
         var otherJpaAcElement =
                 new JpaAutomationCompositionElement(testJpaAcElement);
 
-        testJpaAcElement.setElementId("BadValue");
+        testJpaAcElement.setElementId(BAD_VALUE);
         assertNotEquals(0, testJpaAcElement.compareTo(otherJpaAcElement));
         testJpaAcElement.setElementId(ELEMENT_ID);
         assertEquals(0, testJpaAcElement.compareTo(otherJpaAcElement));
 
-        testJpaAcElement.setInstanceId("BadValue");
+        testJpaAcElement.setInstanceId(BAD_VALUE);
         assertNotEquals(0, testJpaAcElement.compareTo(otherJpaAcElement));
         testJpaAcElement.setInstanceId(INSTANCE_ID);
         assertEquals(0, testJpaAcElement.compareTo(otherJpaAcElement));
 
-        testJpaAcElement.setDefinition(new PfConceptKey("BadValue", "0.0.1"));
+        testJpaAcElement.setDefinition(new PfConceptKey(BAD_VALUE, "0.0.1"));
         assertNotEquals(0, testJpaAcElement.compareTo(otherJpaAcElement));
         testJpaAcElement.setDefinition(new PfConceptKey("aceDef", "0.0.1"));
         assertEquals(0, testJpaAcElement.compareTo(otherJpaAcElement));
@@ -194,12 +202,17 @@ class JpaAutomationCompositionElementTest {
         testJpaAcElement.setLockState(LockState.LOCKED);
         assertEquals(0, testJpaAcElement.compareTo(otherJpaAcElement));
 
-        testJpaAcElement.setUseState("BadValue");
+        testJpaAcElement.setSubState(SubState.PREPARING);
+        assertNotEquals(0, testJpaAcElement.compareTo(otherJpaAcElement));
+        testJpaAcElement.setSubState(SubState.NONE);
+        assertEquals(0, testJpaAcElement.compareTo(otherJpaAcElement));
+
+        testJpaAcElement.setUseState(BAD_VALUE);
         assertNotEquals(0, testJpaAcElement.compareTo(otherJpaAcElement));
         testJpaAcElement.setUseState("IDLE");
         assertEquals(0, testJpaAcElement.compareTo(otherJpaAcElement));
 
-        testJpaAcElement.setOperationalState("BadValue");
+        testJpaAcElement.setOperationalState(BAD_VALUE);
         assertNotEquals(0, testJpaAcElement.compareTo(otherJpaAcElement));
         testJpaAcElement.setOperationalState("DEFAULT");
         assertEquals(0, testJpaAcElement.compareTo(otherJpaAcElement));
@@ -249,7 +262,7 @@ class JpaAutomationCompositionElementTest {
         var testJpaAcElement =
                 new JpaAutomationCompositionElement(testAce.getId().toString(), INSTANCE_ID);
         testJpaAcElement.fromAuthorative(testAce);
-        testJpaAcElement.setProperties(Map.of("key", "{}"));
+        testJpaAcElement.setProperties(Map.of(KEY, "{}"));
 
         return testJpaAcElement;
     }
@@ -259,7 +272,7 @@ class JpaAutomationCompositionElementTest {
         automationCompositionElement.setId(UUID.fromString(ELEMENT_ID));
         automationCompositionElement.setDefinition(new ToscaConceptIdentifier("aceDef", "0.0.1"));
         automationCompositionElement.setParticipantId(CommonTestData.getParticipantId());
-        automationCompositionElement.setProperties(Map.of("key", "{}"));
+        automationCompositionElement.setProperties(Map.of(KEY, "{}"));
         automationCompositionElement.setUseState("IDLE");
         automationCompositionElement.setOperationalState("DEFAULT");
 
index b56e778..541e9ba 100644 (file)
@@ -37,6 +37,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
+import org.onap.policy.clamp.models.acm.concepts.SubState;
 import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
 import org.onap.policy.models.base.PfConceptKey;
 
@@ -46,7 +47,7 @@ import org.onap.policy.models.base.PfConceptKey;
 class JpaAutomationCompositionTest {
 
     private static final String NULL_INSTANCE_ID_ERROR = "instanceId is marked .*ull but is null";
-    private static final String NULL_TEXT_ERROR = " is marked .*ull but is null";
+    private static final String NULL_ERROR = " is marked .*ull but is null";
     private static final String INSTANCE_ID = "709c62b3-8918-41b9-a747-d21eb79c6c20";
     private static final String COMPOSITION_ID = "709c62b3-8918-41b9-a747-e21eb79c6c41";
 
@@ -54,44 +55,49 @@ class JpaAutomationCompositionTest {
     void testJpaAutomationCompositionConstructor() {
         assertThatThrownBy(() -> {
             new JpaAutomationComposition((JpaAutomationComposition) null);
-        }).hasMessageMatching("copyConcept is marked .*ull but is null");
+        }).hasMessageMatching("copyConcept" + NULL_ERROR);
 
         assertThatThrownBy(() -> {
             new JpaAutomationComposition((AutomationComposition) null);
-        }).hasMessageMatching("authorativeConcept is marked .*ull but is null");
+        }).hasMessageMatching("authorativeConcept" + NULL_ERROR);
 
         assertThatThrownBy(() -> {
-            new JpaAutomationComposition(null, null, null, null, null, null);
+            new JpaAutomationComposition(null, null, null, null, null, null, null);
         }).hasMessageMatching(NULL_INSTANCE_ID_ERROR);
 
         assertThatThrownBy(() -> {
             new JpaAutomationComposition(INSTANCE_ID, null, null, new ArrayList<>(), DeployState.UNDEPLOYED,
-                    LockState.LOCKED);
-        }).hasMessageMatching("key" + NULL_TEXT_ERROR);
+                    LockState.LOCKED, SubState.NONE);
+        }).hasMessageMatching("key" + NULL_ERROR);
 
         assertThatThrownBy(() -> {
             new JpaAutomationComposition(INSTANCE_ID, new PfConceptKey(), null, new ArrayList<>(),
-                    DeployState.UNDEPLOYED, LockState.LOCKED);
-        }).hasMessageMatching("compositionId" + NULL_TEXT_ERROR);
+                    DeployState.UNDEPLOYED, LockState.LOCKED, SubState.NONE);
+        }).hasMessageMatching("compositionId" + NULL_ERROR);
 
         assertThatThrownBy(() -> {
             new JpaAutomationComposition(INSTANCE_ID, new PfConceptKey(), COMPOSITION_ID, null,
-                    DeployState.UNDEPLOYED, LockState.LOCKED);
-        }).hasMessageMatching("elements" + NULL_TEXT_ERROR);
+                    DeployState.UNDEPLOYED, LockState.LOCKED, SubState.NONE);
+        }).hasMessageMatching("elements" + NULL_ERROR);
 
         assertThatThrownBy(() -> {
             new JpaAutomationComposition(INSTANCE_ID, new PfConceptKey(), COMPOSITION_ID, new ArrayList<>(),
-                    null, LockState.LOCKED);
-        }).hasMessageMatching("deployState" + NULL_TEXT_ERROR);
+                    null, LockState.LOCKED, SubState.NONE);
+        }).hasMessageMatching("deployState" + NULL_ERROR);
 
         assertThatThrownBy(() -> {
             new JpaAutomationComposition(INSTANCE_ID, new PfConceptKey(), COMPOSITION_ID, new ArrayList<>(),
-                    DeployState.UNDEPLOYED, null);
-        }).hasMessageMatching("lockState" + NULL_TEXT_ERROR);
+                    DeployState.UNDEPLOYED, null, SubState.NONE);
+        }).hasMessageMatching("lockState" + NULL_ERROR);
+
+        assertThatThrownBy(() -> {
+            new JpaAutomationComposition(INSTANCE_ID, new PfConceptKey(), COMPOSITION_ID, new ArrayList<>(),
+                    DeployState.UNDEPLOYED, LockState.NONE, null);
+        }).hasMessageMatching("subState" + NULL_ERROR);
 
         assertDoesNotThrow(() -> new JpaAutomationComposition());
         assertDoesNotThrow(() -> new JpaAutomationComposition(INSTANCE_ID, new PfConceptKey(), COMPOSITION_ID,
-                new ArrayList<>(), DeployState.UNDEPLOYED, LockState.LOCKED));
+                new ArrayList<>(), DeployState.UNDEPLOYED, LockState.LOCKED, SubState.NONE));
     }
 
     @Test
@@ -108,7 +114,7 @@ class JpaAutomationCompositionTest {
 
         assertThatThrownBy(() -> {
             jpaAutomationComposition.fromAuthorative(null);
-        }).hasMessageMatching("automationComposition is marked .*ull but is null");
+        }).hasMessageMatching("automationComposition" + NULL_ERROR);
 
         assertThatThrownBy(() -> new JpaAutomationComposition((JpaAutomationComposition) null))
                 .isInstanceOf(NullPointerException.class);
@@ -137,7 +143,7 @@ class JpaAutomationCompositionTest {
     }
 
     @Test
-    void testJpaAutomationCompositionCompareTo() {
+    void testJpaAutomationCompositionCompareTo1() {
         var jpaAutomationComposition = new JpaAutomationComposition(createAutomationCompositionInstance());
 
         var otherJpaAutomationComposition = new JpaAutomationComposition(jpaAutomationComposition);
@@ -180,6 +186,12 @@ class JpaAutomationCompositionTest {
         assertNotEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition));
         jpaAutomationComposition.setPhase(null);
         assertEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition));
+    }
+
+    @Test
+    void testJpaAutomationCompositionCompareTo2() {
+        var jpaAutomationComposition = new JpaAutomationComposition(createAutomationCompositionInstance());
+        var otherJpaAutomationComposition = new JpaAutomationComposition(jpaAutomationComposition);
 
         jpaAutomationComposition.setDeployState(DeployState.DEPLOYED);
         assertNotEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition));
@@ -191,6 +203,11 @@ class JpaAutomationCompositionTest {
         jpaAutomationComposition.setLockState(LockState.NONE);
         assertEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition));
 
+        jpaAutomationComposition.setSubState(SubState.PREPARING);
+        assertNotEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition));
+        jpaAutomationComposition.setSubState(SubState.NONE);
+        assertEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition));
+
         jpaAutomationComposition.setDescription("A description");
         assertNotEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition));
         jpaAutomationComposition.setDescription(null);