diff options
235 files changed, 6279 insertions, 3035 deletions
@@ -31,16 +31,6 @@ repositories: - 'policy/clamp' committers: - <<: *onap_releng_ptl - - name: 'Gervais-Martial Ngueko' - email: 'gervais-martial.ngueko@intl.att.com' - company: 'ATT' - id: 'osgn422w' - timezone: 'Europe/Brussels' - - name: 'Pamela Dragosh' - email: 'pd1248@att.com' - company: 'ATT' - id: 'pdragosh' - timezone: 'America/New_York' - name: 'Jorge Hernandez' email: 'jorge.hernandez-herrero@att.com' company: 'ATT' @@ -51,6 +41,11 @@ committers: company: 'Bell Canada' id: 'ramverma' timezone: 'America/Montreal' + - name: 'Liam Fallon' + email: 'liam.fallon@est.tech' + id: 'liamfallon' + company: 'Ericsson' + timezone: 'Europe/Ireland' - name: 'Ramesh Murugan Iyer' email: 'ramesh.murugan.iyer@est.tech' company: 'Ericsson' @@ -129,3 +124,10 @@ tsc: - type: 'Addition' name: 'Adheli Tavares' link: https://lists.onap.org/g/onap-tsc/message/9296 + #Stepped Down + - type: 'Removal' + name: 'Pamela Dragosh' + link: https://lists.onap.org/g/onap-tsc/message/9550 + - type: 'Removal' + name: 'Gervais-Martial Ngueko' + link: https://lists.onap.org/g/onap-tsc/message/9551 diff --git a/common/pom.xml b/common/pom.xml index 478d122b6..b5ff9e247 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -27,7 +27,7 @@ <parent> <groupId>org.onap.policy.clamp</groupId> <artifactId>policy-clamp</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>policy-clamp-common</artifactId> diff --git a/examples/pom.xml b/examples/pom.xml index 6fec30015..33a0173fb 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -26,7 +26,7 @@ <parent> <groupId>org.onap.policy.clamp</groupId> <artifactId>policy-clamp</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/models/pom.xml b/models/pom.xml index b833277b9..9ff408551 100644 --- a/models/pom.xml +++ b/models/pom.xml @@ -27,7 +27,7 @@ <parent> <groupId>org.onap.policy.clamp</groupId> <artifactId>policy-clamp</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>policy-clamp-models</artifactId> diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java index eb5b6dc9b..61610bb47 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java @@ -44,7 +44,7 @@ public class AutomationComposition extends ToscaEntity implements Comparable<Aut private UUID compositionTargetId; - private Boolean restarting; + private Boolean precheck; @NonNull private DeployState deployState = DeployState.UNDEPLOYED; @@ -56,6 +56,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; @@ -70,11 +73,12 @@ public class AutomationComposition extends ToscaEntity implements Comparable<Aut this.instanceId = otherAutomationComposition.instanceId; 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; } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionDefinition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionDefinition.java index 987cb8832..57b6837af 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionDefinition.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionDefinition.java @@ -41,8 +41,6 @@ public class AutomationCompositionDefinition { @NonNull private ToscaServiceTemplate serviceTemplate; - private Boolean restarting; - @NonNull private AcTypeState state; @@ -63,7 +61,6 @@ public class AutomationCompositionDefinition { public AutomationCompositionDefinition(final AutomationCompositionDefinition otherAcmDefinition) { this.compositionId = otherAcmDefinition.compositionId; this.serviceTemplate = new ToscaServiceTemplate(otherAcmDefinition.serviceTemplate); - this.restarting = otherAcmDefinition.restarting; this.state = otherAcmDefinition.state; this.lastMsg = otherAcmDefinition.lastMsg; this.elementStateMap = PfUtils.mapMap(otherAcmDefinition.elementStateMap, NodeTemplateState::new); diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionElement.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionElement.java index 5afa7e0bb..7d3acaa52 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionElement.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionElement.java @@ -55,6 +55,11 @@ public class AutomationCompositionElement { @NonNull private LockState lockState = LockState.LOCKED; + @NonNull + private SubState subState = SubState.NONE; + + private Integer stage; + private String operationalState; private String useState; private String description; @@ -81,8 +86,10 @@ 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.stage = otherElement.stage; this.message = otherElement.message; } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositions.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositions.java index 1802f814c..76443ab37 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositions.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositions.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021,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. @@ -40,9 +40,9 @@ public class AutomationCompositions { /** * Copy constructor, does a deep copy. * - * @param otherAutomationCompositions the other element to copy from + * @param other the other element to copy from */ - public AutomationCompositions(final AutomationCompositions otherAutomationCompositions) { - this.automationCompositionList = PfUtils.mapList(automationCompositionList, AutomationComposition::new); + public AutomationCompositions(final AutomationCompositions other) { + this.automationCompositionList = PfUtils.mapList(other.automationCompositionList, AutomationComposition::new); } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/Participant.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/Participant.java index 6ddec6179..457eb65e3 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/Participant.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/Participant.java @@ -41,12 +41,6 @@ public class Participant { private UUID participantId; @NonNull - private ParticipantState participantState = ParticipantState.ON_LINE; - - @NonNull - private String lastMsg; - - @NonNull private Map<UUID, ParticipantSupportedElementType> participantSupportedElementTypes = new HashMap<>(); @NonNull @@ -58,9 +52,7 @@ public class Participant { * @param otherParticipant the participant to copy from */ public Participant(Participant otherParticipant) { - this.participantState = otherParticipant.participantState; this.participantId = otherParticipant.participantId; - this.lastMsg = otherParticipant.lastMsg; this.participantSupportedElementTypes = PfUtils.mapMap(otherParticipant.getParticipantSupportedElementTypes(), ParticipantSupportedElementType::new); this.replicas = PfUtils.mapMap(otherParticipant.replicas, ParticipantReplica::new); diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantReplica.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantReplica.java index 23f72191a..73dfad564 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantReplica.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantReplica.java @@ -37,6 +37,7 @@ public class ParticipantReplica { @NonNull private ParticipantState participantState = ParticipantState.ON_LINE; + // last time ACM-R has received a status message from participant replica @NonNull private String lastMsg; diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantRestartAc.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantRestartAc.java index e5f4ad4ae..3312752fa 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantRestartAc.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantRestartAc.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation. + * Copyright (C) 2023-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. @@ -37,6 +37,9 @@ public class ParticipantRestartAc { private UUID automationCompositionId; + private DeployState deployState; + private LockState lockState; + private List<AcElementRestart> acElementList = new ArrayList<>(); /** @@ -46,6 +49,8 @@ public class ParticipantRestartAc { */ public ParticipantRestartAc(ParticipantRestartAc copyConstructor) { this.automationCompositionId = copyConstructor.automationCompositionId; + this.deployState = copyConstructor.deployState; + this.lockState = copyConstructor.lockState; this.acElementList = PfUtils.mapList(copyConstructor.acElementList, AcElementRestart::new); } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtils.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtils.java index d6079d0e7..9c827d701 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtils.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtils.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation. + * Copyright (C) 2021-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. @@ -20,7 +20,11 @@ package org.onap.policy.clamp.models.acm.concepts; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; @@ -50,8 +54,26 @@ public final class ParticipantUtils { } return DeployState.DEPLOYING.equals(automationComposition.getDeployState()) - || LockState.UNLOCKING.equals(automationComposition.getLockState()) ? minStartPhase - : maxStartPhase; + || LockState.UNLOCKING.equals(automationComposition.getLockState()) ? minStartPhase : maxStartPhase; + } + + /** + * Get the First Stage. + * + * @param automationComposition the automation composition + * @param toscaServiceTemplate the ToscaServiceTemplate + * @return the First stage + */ + public static int getFirstStage( + AutomationComposition automationComposition, ToscaServiceTemplate toscaServiceTemplate) { + Set<Integer> minStage = new HashSet<>(); + for (var element : automationComposition.getElements().values()) { + var toscaNodeTemplate = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates() + .get(element.getDefinition().getName()); + var stage = ParticipantUtils.findStageSet(toscaNodeTemplate.getProperties()); + minStage.addAll(stage); + } + return minStage.stream().min(Integer::compare).orElse(0); } /** @@ -63,8 +85,25 @@ public final class ParticipantUtils { public static int findStartPhase(Map<String, Object> properties) { var objStartPhase = properties.get("startPhase"); if (objStartPhase != null) { - return Integer.valueOf(objStartPhase.toString()); + return Integer.parseInt(objStartPhase.toString()); } return 0; } + + + /** + * Finds stage from a map of properties. + * + * @param properties Map of properties + * @return stage + */ + public static Set<Integer> findStageSet(Map<String, Object> properties) { + var objStage = properties.get("stage"); + if (objStage instanceof List<?> stageSet) { + return stageSet.stream() + .map(obj -> Integer.valueOf(obj.toString())) + .collect(Collectors.toSet()); + } + return Set.of(0); + } } 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 index 000000000..5f979c50f --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/SubState.java @@ -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 +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaCapabilityAssignment.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaCapabilityAssignment.java index 572332eeb..e675e2387 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaCapabilityAssignment.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaCapabilityAssignment.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -42,7 +42,10 @@ public class DocToscaCapabilityAssignment extends DocToscaWithTypeAndStringPrope @Serial private static final long serialVersionUID = 1L; + @SuppressWarnings("squid:S1948") private Map<@NotNull String, @NotNull Object> attributes; + + @SuppressWarnings("squid:S1948") private List<@NotNull Object> occurrences; /** diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaEntity.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaEntity.java index c8484654b..b931d4e0a 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaEntity.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaEntity.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -59,6 +59,7 @@ public class DocToscaEntity<T extends ToscaEntity> extends Validated @SerializedName("derived_from") private String derivedFrom; + @SuppressWarnings("squid:S1948") private Map<@NotNull @NotBlank String, @NotNull @NotBlank Object> metadata = new LinkedHashMap<>(); @NotBlank diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaParameter.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaParameter.java index 2904962fc..5a252b8d2 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaParameter.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaParameter.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -48,6 +48,7 @@ public class DocToscaParameter implements PfAuthorative<ToscaParameter>, Seriali @SerializedName("type_version") private String typeVersion; + @SuppressWarnings("squid:S1948") private Object value; /** diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaProperty.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaProperty.java index b47ef56aa..774f045f5 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaProperty.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaProperty.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -60,6 +60,7 @@ public class DocToscaProperty implements PfAuthorative<ToscaProperty>, Serializa @SerializedName("default") @NotBlank + @SuppressWarnings("squid:S1948") private Object defaultValue; private boolean required = false; @@ -208,7 +209,7 @@ public class DocToscaProperty implements PfAuthorative<ToscaProperty>, Serializa return result; } - result = entrySchema.compareTo(other.entrySchema); + result = ObjectUtils.compare(entrySchema, other.entrySchema); if (result != 0) { return result; } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaRequirement.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaRequirement.java index fd67fb68d..9d3cc1051 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaRequirement.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaRequirement.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -42,6 +42,8 @@ public class DocToscaRequirement extends DocToscaWithTypeAndStringProperties<Tos private String capability; private String node; private String relationship; + + @SuppressWarnings("squid:S1948") private List<Object> occurrences; public DocToscaRequirement(ToscaRequirement toscaRequirement) { diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaWithToscaProperties.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaWithToscaProperties.java index 9a6d60c1c..bcb63a2f1 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaWithToscaProperties.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaWithToscaProperties.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -33,6 +33,7 @@ import lombok.NoArgsConstructor; import lombok.NonNull; import org.apache.commons.collections4.CollectionUtils; import org.onap.policy.clamp.models.acm.document.base.DocConceptKey; +import org.onap.policy.clamp.models.acm.document.base.DocUtil; import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.common.parameters.annotations.NotBlank; import org.onap.policy.common.parameters.annotations.NotNull; @@ -49,6 +50,7 @@ public class DocToscaWithToscaProperties<T extends ToscaWithToscaProperties> ext @Serial private static final long serialVersionUID = 1L; + @SuppressWarnings("squid:S1948") private Map<@NotNull @NotBlank String, @NotNull @Valid DocToscaProperty> properties; /** @@ -121,4 +123,20 @@ public class DocToscaWithToscaProperties<T extends ToscaWithToscaProperties> ext referencedDataTypes.removeAll(set); return referencedDataTypes; } + + @Override + public int compareTo(final DocToscaEntity<T> otherConcept) { + if (this == otherConcept) { + return 0; + } + + int result = super.compareTo(otherConcept); + if (result != 0) { + return result; + } + + final var other = (DocToscaWithToscaProperties<T>) otherConcept; + + return DocUtil.compareMaps(properties, other.properties); + } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaWithTypeAndStringProperties.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaWithTypeAndStringProperties.java index 55b7364c9..2d62e36ea 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaWithTypeAndStringProperties.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaWithTypeAndStringProperties.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -50,6 +50,7 @@ public class DocToscaWithTypeAndStringProperties<T extends ToscaWithTypeAndObjec @SerializedName("type_version") private String typeVersion; + @SuppressWarnings("squid:S1948") private Map<String, Object> properties; /** diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/AutomationCompositionDeployAck.java b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/AutomationCompositionDeployAck.java index 2c7d51fe7..9807ff9ca 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/AutomationCompositionDeployAck.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/AutomationCompositionDeployAck.java @@ -41,7 +41,7 @@ import org.onap.policy.models.base.PfUtils; public class AutomationCompositionDeployAck extends ParticipantAckMessage { private UUID automationCompositionId; - private Integer startPhase; + private Integer stage; // A map with AutomationCompositionElementID as its key, and a pair of result and message as value per // AutomationCompositionElement. @@ -63,7 +63,7 @@ public class AutomationCompositionDeployAck extends ParticipantAckMessage { public AutomationCompositionDeployAck(final AutomationCompositionDeployAck source) { super(source); this.automationCompositionId = source.automationCompositionId; - this.startPhase = source.startPhase; + this.stage = source.stage; this.automationCompositionResultMap = PfUtils.mapMap(source.automationCompositionResultMap, UnaryOperator.identity()); } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/AutomationCompositionMigration.java b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/AutomationCompositionMigration.java index fb1f1925c..2d7608afd 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/AutomationCompositionMigration.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/AutomationCompositionMigration.java @@ -37,6 +37,9 @@ public class AutomationCompositionMigration extends ParticipantMessage { // A list of updates to AC element properties private List<ParticipantDeploy> participantUpdatesList = new ArrayList<>(); + private Boolean precheck = false; + private Integer stage = 0; + public AutomationCompositionMigration() { super(ParticipantMessageType.AUTOMATION_COMPOSITION_MIGRATION); } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantRestart.java b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/AutomationCompositionPrepare.java index 98c7d1071..343143eed 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantRestart.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/AutomationCompositionPrepare.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023-2024 Nordix Foundation. + * 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. @@ -25,38 +25,23 @@ import java.util.List; import lombok.Getter; import lombok.Setter; import lombok.ToString; -import org.onap.policy.clamp.models.acm.concepts.AcTypeState; -import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; -import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc; +import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy; import org.onap.policy.models.base.PfUtils; @Getter @Setter @ToString(callSuper = true) -public class ParticipantRestart extends ParticipantMessage { +public class AutomationCompositionPrepare extends ParticipantMessage { - // composition state - AcTypeState state; - - // element definition - private List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>(); - - // automation composition instances list - private List<ParticipantRestartAc> automationcompositionList = new ArrayList<>(); + private List<ParticipantDeploy> participantList = new ArrayList<>(); + private boolean preDeploy = true; /** - * Constructor. - */ - public ParticipantRestart() { - super(ParticipantMessageType.PARTICIPANT_RESTART); - } - - /** - * Constructor with message type. - * @param messageType messageType + * Constructor for instantiating class with message name. + * */ - public ParticipantRestart(ParticipantMessageType messageType) { - super(messageType); + public AutomationCompositionPrepare() { + super(ParticipantMessageType.AUTOMATION_COMPOSITION_PREPARE); } /** @@ -64,11 +49,9 @@ public class ParticipantRestart extends ParticipantMessage { * * @param source source from which to copy */ - public ParticipantRestart(ParticipantRestart source) { + public AutomationCompositionPrepare(AutomationCompositionPrepare source) { super(source); - this.state = source.state; - this.participantDefinitionUpdates = - PfUtils.mapList(source.participantDefinitionUpdates, ParticipantDefinition::new); - this.automationcompositionList = PfUtils.mapList(source.automationcompositionList, ParticipantRestartAc::new); + this.preDeploy = source.preDeploy; + this.participantList = PfUtils.mapList(source.participantList, ParticipantDeploy::new); } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantMessageType.java b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantMessageType.java index e6e42e851..7e19f6f79 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantMessageType.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantMessageType.java @@ -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 } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantSync.java b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantSync.java index 962b6137c..85b715b86 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantSync.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantSync.java @@ -20,17 +20,32 @@ package org.onap.policy.clamp.models.acm.messages.kafka.participant; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.UUID; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.onap.policy.clamp.models.acm.concepts.AcTypeState; +import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; +import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc; +import org.onap.policy.models.base.PfUtils; @Getter @Setter @ToString(callSuper = true) -public class ParticipantSync extends ParticipantRestart { +public class ParticipantSync extends ParticipantMessage { + + // composition state + private AcTypeState state; + + // element definition + private List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>(); + + // automation composition instances list + private List<ParticipantRestartAc> automationcompositionList = new ArrayList<>(); private Set<UUID> excludeReplicas = new HashSet<>(); private boolean restarting = false; @@ -50,6 +65,10 @@ public class ParticipantSync extends ParticipantRestart { */ public ParticipantSync(ParticipantSync source) { super(source); + this.state = source.state; + this.participantDefinitionUpdates = + PfUtils.mapList(source.participantDefinitionUpdates, ParticipantDefinition::new); + this.automationcompositionList = PfUtils.mapList(source.automationcompositionList, ParticipantRestartAc::new); this.excludeReplicas = new HashSet<>(source.excludeReplicas); this.restarting = source.restarting; this.delete = source.delete; diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/GenericNameVersion.java b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/GenericNameVersion.java deleted file mode 100644 index 3e39e970d..000000000 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/GenericNameVersion.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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; - -import lombok.Data; - -@Data -public class GenericNameVersion { - - private String name; - - private String version; -} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/instantiation/AcInstanceStateUpdate.java b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/instantiation/AcInstanceStateUpdate.java index e47947a02..68c597b32 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/instantiation/AcInstanceStateUpdate.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/instantiation/AcInstanceStateUpdate.java @@ -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 index 000000000..9cf7efaa6 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/instantiation/SubOrder.java @@ -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 +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java index 0bf6a9e1a..001f2e7f3 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java @@ -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; @@ -86,9 +87,6 @@ public class JpaAutomationComposition extends Validated private String compositionTargetId; @Column - private Boolean restarting; - - @Column @NotNull private DeployState deployState; @@ -97,6 +95,10 @@ public class JpaAutomationComposition extends Validated private LockState lockState; @Column + @NotNull + private SubState subState; + + @Column private StateChangeResult stateChangeResult; @Column @@ -119,7 +121,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 +133,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 +146,7 @@ public class JpaAutomationComposition extends Validated this.deployState = deployState; this.lockState = lockState; this.elements = elements; + this.subState = subState; } /** @@ -155,11 +160,11 @@ public class JpaAutomationComposition extends Validated this.version = copyConcept.version; this.compositionId = copyConcept.compositionId; this.compositionTargetId = copyConcept.compositionTargetId; - this.restarting = copyConcept.restarting; this.deployState = copyConcept.deployState; 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); @@ -185,11 +190,11 @@ public class JpaAutomationComposition extends Validated if (compositionTargetId != null) { automationComposition.setCompositionTargetId(UUID.fromString(compositionTargetId)); } - automationComposition.setRestarting(restarting); automationComposition.setDeployState(deployState); 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())); @@ -202,6 +207,22 @@ public class JpaAutomationComposition extends Validated @Override public void fromAuthorative(@NonNull final AutomationComposition automationComposition) { + this.fromAuthorativeBase(automationComposition); + this.elements = new ArrayList<>(automationComposition.getElements().size()); + for (var elementEntry : automationComposition.getElements().entrySet()) { + var jpaAutomationCompositionElement = + new JpaAutomationCompositionElement(elementEntry.getKey().toString(), this.instanceId); + jpaAutomationCompositionElement.fromAuthorative(elementEntry.getValue()); + this.elements.add(jpaAutomationCompositionElement); + } + } + + /** + * Set an instance of the persist concept to the equivalent values as the other concept without copy the elements. + * + * @param automationComposition the authorative concept + */ + public void fromAuthorativeBase(@NonNull final AutomationComposition automationComposition) { this.instanceId = automationComposition.getInstanceId().toString(); this.name = automationComposition.getName(); this.version = automationComposition.getVersion(); @@ -209,20 +230,13 @@ public class JpaAutomationComposition extends Validated if (automationComposition.getCompositionTargetId() != null) { this.compositionTargetId = automationComposition.getCompositionTargetId().toString(); } - this.restarting = automationComposition.getRestarting(); this.deployState = automationComposition.getDeployState(); 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(); - this.elements = new ArrayList<>(automationComposition.getElements().size()); - for (var elementEntry : automationComposition.getElements().entrySet()) { - var jpaAutomationCompositionElement = - new JpaAutomationCompositionElement(elementEntry.getKey().toString(), this.instanceId); - jpaAutomationCompositionElement.fromAuthorative(elementEntry.getValue()); - this.elements.add(jpaAutomationCompositionElement); - } } @Override @@ -269,17 +283,17 @@ public class JpaAutomationComposition extends Validated return result; } - result = ObjectUtils.compare(restarting, other.restarting); + result = ObjectUtils.compare(deployState, other.deployState); if (result != 0) { return result; } - result = ObjectUtils.compare(deployState, other.deployState); + result = ObjectUtils.compare(lockState, other.lockState); if (result != 0) { return result; } - result = ObjectUtils.compare(lockState, other.lockState); + result = ObjectUtils.compare(subState, other.subState); if (result != 0) { return result; } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java index 1cab89d5d..3d61c4ed9 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java @@ -79,9 +79,6 @@ public class JpaAutomationCompositionDefinition extends Validated private String version; @Column - private Boolean restarting; - - @Column @NotNull private AcTypeState state; @@ -107,7 +104,6 @@ public class JpaAutomationCompositionDefinition extends Validated public AutomationCompositionDefinition toAuthorative() { var acmDefinition = new AutomationCompositionDefinition(); acmDefinition.setCompositionId(UUID.fromString(this.compositionId)); - acmDefinition.setRestarting(this.restarting); acmDefinition.setState(this.state); acmDefinition.setStateChangeResult(this.stateChangeResult); acmDefinition.setLastMsg(this.lastMsg.toString()); @@ -122,7 +118,6 @@ public class JpaAutomationCompositionDefinition extends Validated @Override public void fromAuthorative(final AutomationCompositionDefinition copyConcept) { this.compositionId = copyConcept.getCompositionId().toString(); - this.restarting = copyConcept.getRestarting(); this.state = copyConcept.getState(); this.stateChangeResult = copyConcept.getStateChangeResult(); this.lastMsg = TimestampHelper.toTimestamp(copyConcept.getLastMsg()); diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElement.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElement.java index 74426a747..e511ba1fc 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElement.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElement.java @@ -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; @@ -94,12 +95,19 @@ public class JpaAutomationCompositionElement extends Validated private LockState lockState; @Column + @NotNull + private SubState subState; + + @Column private String operationalState; @Column private String useState; @Column + private Integer stage; + + @Column private String description; @Column @@ -134,7 +142,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 +153,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,8 +185,10 @@ 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.stage = copyConcept.stage; this.message = copyConcept.message; } @@ -201,8 +214,10 @@ public class JpaAutomationCompositionElement extends Validated element.setRestarting(restarting); element.setDeployState(deployState); element.setLockState(lockState); + element.setSubState(subState); element.setOperationalState(operationalState); element.setUseState(useState); + element.setStage(stage); element.setMessage(message); return element; @@ -218,8 +233,10 @@ 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.stage = element.getStage(); this.message = element.getMessage(); } @@ -267,11 +284,21 @@ 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; } + result = ObjectUtils.compare(stage, other.stage); + if (result != 0) { + return result; + } + result = ObjectUtils.compare(operationalState, other.operationalState); if (result != 0) { return result; diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipant.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipant.java index f35fff9e7..5bc2fc4cf 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipant.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipant.java @@ -32,7 +32,6 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import java.io.Serializable; -import java.sql.Timestamp; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -44,8 +43,6 @@ import org.apache.commons.lang3.ObjectUtils; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; import org.onap.policy.clamp.models.acm.concepts.Participant; -import org.onap.policy.clamp.models.acm.concepts.ParticipantState; -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; import org.onap.policy.models.base.PfAuthorative; @@ -70,51 +67,42 @@ public class JpaParticipant extends Validated private String participantId; @Column - @NotNull - private ParticipantState participantState; - - @Column private String description; - @Column - @NotNull - private Timestamp lastMsg; - @NotNull @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(name = "participantId", referencedColumnName = "participantId", foreignKey = @ForeignKey(name = "supported_element_fk")) + @SuppressWarnings("squid:S1948") private List<@NotNull @Valid JpaParticipantSupportedElementType> supportedElements; @NotNull - @OneToMany + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @LazyCollection(LazyCollectionOption.FALSE) @JoinColumn(name = "participantId", referencedColumnName = "participantId", foreignKey = @ForeignKey(name = "participant_replica_fk")) + @SuppressWarnings("squid:S1948") private List<@NotNull @Valid JpaParticipantReplica> replicas; /** * The Default Constructor creates a {@link JpaParticipant} object with a null key. */ public JpaParticipant() { - this(UUID.randomUUID().toString(), ParticipantState.ON_LINE, new ArrayList<>(), new ArrayList<>()); + this(UUID.randomUUID().toString(), new ArrayList<>(), new ArrayList<>()); } /** * The Key Constructor creates a {@link JpaParticipant} object with all mandatory fields. * * @param participantId the participant id - * @param participantState the state of the participant * @param supportedElements the list of supported Element Type * @param replicas the list of replica */ - public JpaParticipant(@NonNull String participantId, @NonNull final ParticipantState participantState, + public JpaParticipant(@NonNull String participantId, @NonNull final List<JpaParticipantSupportedElementType> supportedElements, @NonNull final List<JpaParticipantReplica> replicas) { this.participantId = participantId; - this.participantState = participantState; this.supportedElements = supportedElements; - this.lastMsg = TimestampHelper.nowTimestamp(); this.replicas = replicas; } @@ -124,12 +112,10 @@ public class JpaParticipant extends Validated * @param copyConcept the concept to copy from */ public JpaParticipant(@NonNull final JpaParticipant copyConcept) { - this.participantState = copyConcept.participantState; this.description = copyConcept.description; this.participantId = copyConcept.participantId; this.supportedElements = copyConcept.supportedElements; this.replicas = copyConcept.replicas; - this.lastMsg = copyConcept.lastMsg; } /** @@ -145,9 +131,7 @@ public class JpaParticipant extends Validated public Participant toAuthorative() { var participant = new Participant(); - participant.setParticipantState(participantState); participant.setParticipantId(UUID.fromString(participantId)); - participant.setLastMsg(this.lastMsg.toString()); participant.setParticipantSupportedElementTypes(new LinkedHashMap<>(this.supportedElements.size())); for (var element : this.supportedElements) { participant.getParticipantSupportedElementTypes() @@ -161,9 +145,7 @@ public class JpaParticipant extends Validated @Override public void fromAuthorative(@NonNull final Participant participant) { - this.setParticipantState(participant.getParticipantState()); this.participantId = participant.getParticipantId().toString(); - this.lastMsg = TimestampHelper.toTimestamp(participant.getLastMsg()); this.supportedElements = new ArrayList<>(participant.getParticipantSupportedElementTypes().size()); for (var elementEntry : participant.getParticipantSupportedElementTypes().entrySet()) { @@ -196,16 +178,6 @@ public class JpaParticipant extends Validated return result; } - result = lastMsg.compareTo(other.lastMsg); - if (result != 0) { - return result; - } - - result = ObjectUtils.compare(participantState, other.participantState); - if (result != 0) { - return result; - } - return ObjectUtils.compare(description, other.description); } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java index 46b43f950..bb05c46c6 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java @@ -138,10 +138,8 @@ public class AcDefinitionProvider { * @param compositionId The UUID of the automation composition definition to update * @param state the AcTypeState * @param stateChangeResult the StateChangeResult - * @param restarting restarting process */ - public void updateAcDefinitionState(UUID compositionId, AcTypeState state, StateChangeResult stateChangeResult, - Boolean restarting) { + public void updateAcDefinitionState(UUID compositionId, AcTypeState state, StateChangeResult stateChangeResult) { var jpaUpdate = acmDefinitionRepository.findById(compositionId.toString()); if (jpaUpdate.isEmpty()) { String errorMessage = "update of Automation Composition Definition \"" + compositionId @@ -151,7 +149,6 @@ public class AcDefinitionProvider { var acDefinition = jpaUpdate.get(); acDefinition.setState(state); acDefinition.setStateChangeResult(stateChangeResult); - acDefinition.setRestarting(restarting); acmDefinitionRepository.save(acDefinition); acmDefinitionRepository.flush(); } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java index ace246c5d..7bffdd966 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation. + * Copyright (C) 2023-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. @@ -23,8 +23,10 @@ package org.onap.policy.clamp.models.acm.persistence.provider; 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.messages.rest.instantiation.DeployOrder; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.SubOrder; import org.onap.policy.clamp.models.acm.utils.StateDefinition; import org.springframework.stereotype.Component; @@ -39,6 +41,8 @@ public class AcInstanceStateResolver { private static final String UPDATING = DeployState.UPDATING.name(); private static final String DELETING = DeployState.DELETING.name(); private static final String MIGRATING = DeployState.MIGRATING.name(); + private static final String MIGRATION_PRECHECKING = SubState.MIGRATION_PRECHECKING.name(); + private static final String SUB_STATE_NONE = SubState.NONE.name(); private static final String LOCKED = LockState.LOCKED.name(); private static final String LOCKING = LockState.LOCKING.name(); @@ -48,6 +52,7 @@ public class AcInstanceStateResolver { private static final String DEPLOY_NONE = DeployOrder.NONE.name(); private static final String LOCK_NONE = LockOrder.NONE.name(); + private static final String SUB_NONE = SubOrder.NONE.name(); private static final String NO_ERROR = StateChangeResult.NO_ERROR.name(); private static final String FAILED = StateChangeResult.FAILED.name(); @@ -60,55 +65,105 @@ public class AcInstanceStateResolver { public static final String LOCK = LockOrder.LOCK.name(); public static final String UNLOCK = LockOrder.UNLOCK.name(); public static final String MIGRATE = DeployOrder.MIGRATE.name(); + public static final String MIGRATE_PRECHECK = SubOrder.MIGRATE_PRECHECK.name(); + public static final String PREPARE = SubOrder.PREPARE.name(); + public static final String REVIEW = SubOrder.REVIEW.name(); + public static final String UPDATE = DeployOrder.UPDATE.name(); public static final String NONE = "NONE"; /** * Construct. */ public AcInstanceStateResolver() { - this.graph = new StateDefinition<>(5, NONE); - - // no error - this.graph.put(new String[] {DEPLOY, LOCK_NONE, UNDEPLOYED, STATE_LOCKED_NONE, NO_ERROR}, DEPLOY); - this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, DEPLOYED, LOCKED, NO_ERROR}, UNDEPLOY); - this.graph.put(new String[] {DELETE, LOCK_NONE, UNDEPLOYED, LOCK_NONE, NO_ERROR}, DELETE); - this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, DEPLOYED, LOCKED, NO_ERROR}, UNLOCK); - this.graph.put(new String[] {DEPLOY_NONE, LOCK, DEPLOYED, UNLOCKED, NO_ERROR}, LOCK); - this.graph.put(new String[] {MIGRATE, LOCK_NONE, DEPLOYED, LOCKED, NO_ERROR}, MIGRATE); - - // failed - this.graph.put(new String[] {DEPLOY, LOCK_NONE, UNDEPLOYING, STATE_LOCKED_NONE, FAILED}, DEPLOY); - this.graph.put(new String[] {DEPLOY, LOCK_NONE, DEPLOYING, STATE_LOCKED_NONE, FAILED}, DEPLOY); - - this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, UNDEPLOYING, STATE_LOCKED_NONE, FAILED}, UNDEPLOY); - this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, UPDATING, LOCKED, FAILED}, UNDEPLOY); - this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, MIGRATING, LOCKED, FAILED}, UNDEPLOY); - this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, DEPLOYING, STATE_LOCKED_NONE, FAILED}, UNDEPLOY); - - this.graph.put(new String[] {DELETE, LOCK_NONE, DELETING, LOCK_NONE, FAILED}, DELETE); - - this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, DEPLOYED, LOCKING, FAILED}, UNLOCK); - this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, DEPLOYED, UNLOCKING, FAILED}, UNLOCK); - - this.graph.put(new String[] {DEPLOY_NONE, LOCK, DEPLOYED, LOCKING, FAILED}, LOCK); - this.graph.put(new String[] {DEPLOY_NONE, LOCK, DEPLOYED, UNLOCKING, FAILED}, LOCK); + this.graph = new StateDefinition<>(7, NONE); + + // make an order when there are no fails + this.graph.put(new String[] {DEPLOY, LOCK_NONE, SUB_NONE, + UNDEPLOYED, STATE_LOCKED_NONE, SUB_STATE_NONE, NO_ERROR}, DEPLOY); + this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE, + DEPLOYED, LOCKED, SUB_STATE_NONE, NO_ERROR}, UNDEPLOY); + this.graph.put(new String[] {DELETE, LOCK_NONE, SUB_NONE, + UNDEPLOYED, LOCK_NONE, SUB_STATE_NONE, NO_ERROR}, DELETE); + this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, SUB_NONE, + DEPLOYED, LOCKED, SUB_STATE_NONE, NO_ERROR}, UNLOCK); + this.graph.put(new String[] {DEPLOY_NONE, LOCK, SUB_NONE, + DEPLOYED, UNLOCKED, SUB_STATE_NONE, NO_ERROR}, LOCK); + this.graph.put(new String[] {MIGRATE, LOCK_NONE, SUB_NONE, + DEPLOYED, LOCKED, SUB_STATE_NONE, NO_ERROR}, MIGRATE); + this.graph.put(new String[] {UPDATE, LOCK_NONE, SUB_NONE, + DEPLOYED, LOCKED, SUB_STATE_NONE, NO_ERROR}, UPDATE); + this.graph.put(new String[] {DEPLOY_NONE, LOCK_NONE, REVIEW, + DEPLOYED, LOCKED, SUB_STATE_NONE, NO_ERROR}, REVIEW); + this.graph.put(new String[] {DEPLOY_NONE, LOCK_NONE, PREPARE, + UNDEPLOYED, STATE_LOCKED_NONE, SUB_STATE_NONE, NO_ERROR}, PREPARE); + this.graph.put(new String[] {DEPLOY_NONE, LOCK_NONE, MIGRATE_PRECHECK, + DEPLOYED, LOCKED, SUB_STATE_NONE, NO_ERROR}, MIGRATE_PRECHECK); + + // make an order in a failed scenario + this.graph.put(new String[] {DEPLOY, LOCK_NONE, SUB_NONE, + UNDEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, FAILED}, DEPLOY); + this.graph.put(new String[] {DEPLOY, LOCK_NONE, SUB_NONE, + DEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, FAILED}, DEPLOY); + + this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE, + UNDEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, FAILED}, UNDEPLOY); + this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE, + UPDATING, LOCKED, SUB_STATE_NONE, FAILED}, UNDEPLOY); + this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE, + MIGRATING, LOCKED, SUB_STATE_NONE, FAILED}, UNDEPLOY); + this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE, + DEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, FAILED}, UNDEPLOY); + + this.graph.put(new String[] {DELETE, LOCK_NONE, SUB_NONE, + DELETING, LOCK_NONE, SUB_STATE_NONE, FAILED}, DELETE); + + this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, SUB_NONE, + DEPLOYED, LOCKING, SUB_STATE_NONE, FAILED}, UNLOCK); + this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, SUB_NONE, + DEPLOYED, UNLOCKING, SUB_STATE_NONE, FAILED}, UNLOCK); + + this.graph.put(new String[] {DEPLOY_NONE, LOCK, SUB_NONE, DEPLOYED, LOCKING, SUB_STATE_NONE, FAILED}, LOCK); + this.graph.put(new String[] {DEPLOY_NONE, LOCK, SUB_NONE, DEPLOYED, UNLOCKING, SUB_STATE_NONE, FAILED}, LOCK); + + this.graph.put(new String[] {UPDATE, LOCK_NONE, SUB_NONE, UPDATING, LOCKED, SUB_STATE_NONE, FAILED}, UPDATE); + + this.graph.put(new String[] {DEPLOY_NONE, LOCK_NONE, MIGRATE_PRECHECK, + DEPLOYED, LOCKED, MIGRATION_PRECHECKING, FAILED}, MIGRATE_PRECHECK); // timeout - this.graph.put(new String[] {DEPLOY, LOCK_NONE, UNDEPLOYING, STATE_LOCKED_NONE, TIMEOUT}, DEPLOY); - this.graph.put(new String[] {DEPLOY, LOCK_NONE, DEPLOYING, STATE_LOCKED_NONE, TIMEOUT}, DEPLOY); - - this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, UNDEPLOYING, STATE_LOCKED_NONE, TIMEOUT}, UNDEPLOY); - this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, UPDATING, LOCKED, TIMEOUT}, UNDEPLOY); - this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, MIGRATING, LOCKED, TIMEOUT}, UNDEPLOY); - this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, DEPLOYING, STATE_LOCKED_NONE, TIMEOUT}, UNDEPLOY); - - this.graph.put(new String[] {DELETE, LOCK_NONE, DELETING, LOCK_NONE, TIMEOUT}, DELETE); - - this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, DEPLOYED, LOCKING, TIMEOUT}, UNLOCK); - this.graph.put(new String[] {DEPLOY_NONE, LOCK, DEPLOYED, LOCKING, TIMEOUT}, LOCK); - - this.graph.put(new String[] {DEPLOY_NONE, LOCK, DEPLOYED, UNLOCKING, TIMEOUT}, LOCK); - this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, DEPLOYED, UNLOCKING, TIMEOUT}, UNLOCK); + this.graph.put(new String[] {DEPLOY, LOCK_NONE, SUB_NONE, + UNDEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, TIMEOUT}, DEPLOY); + this.graph.put(new String[] {DEPLOY, LOCK_NONE, SUB_NONE, + DEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, TIMEOUT}, DEPLOY); + + this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE, + UNDEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, TIMEOUT}, UNDEPLOY); + this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE, + UPDATING, LOCKED, SUB_STATE_NONE, TIMEOUT}, UNDEPLOY); + this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE, + MIGRATING, LOCKED, SUB_STATE_NONE, TIMEOUT}, UNDEPLOY); + this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE, + MIGRATION_PRECHECKING, LOCKED, SUB_STATE_NONE, TIMEOUT}, UNDEPLOY); + this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE, + DEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, TIMEOUT}, UNDEPLOY); + + this.graph.put(new String[] {DELETE, LOCK_NONE, SUB_NONE, + DELETING, LOCK_NONE, SUB_STATE_NONE, TIMEOUT}, DELETE); + + this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, SUB_NONE, + DEPLOYED, LOCKING, SUB_STATE_NONE, TIMEOUT}, UNLOCK); + this.graph.put(new String[] {DEPLOY_NONE, LOCK, SUB_NONE, + DEPLOYED, LOCKING, SUB_STATE_NONE, TIMEOUT}, LOCK); + + this.graph.put(new String[] {DEPLOY_NONE, LOCK, SUB_NONE, + DEPLOYED, UNLOCKING, SUB_STATE_NONE, TIMEOUT}, LOCK); + this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, SUB_NONE, + DEPLOYED, UNLOCKING, SUB_STATE_NONE, TIMEOUT}, UNLOCK); + + this.graph.put(new String[] {UPDATE, LOCK_NONE, SUB_NONE, UPDATING, LOCKED, SUB_STATE_NONE, TIMEOUT}, UPDATE); + + this.graph.put(new String[] {DEPLOY_NONE, LOCK_NONE, MIGRATE_PRECHECK, + DEPLOYED, LOCKED, MIGRATION_PRECHECKING, TIMEOUT}, MIGRATE_PRECHECK); } /** @@ -116,20 +171,24 @@ public class AcInstanceStateResolver { * * @param acDeployOrder the Deploy Ordered * @param acLockOrder the Lock Ordered + * @param acSubOrder the Sub Ordered * @param acDeployState then current Deploy State * @param acLockState the current Lock State + * @param acSubState the current Sub State * @param acStateChangeResult the current Result of the State Change * @return the order (DEPLOY/UNDEPLOY/LOCK/UNLOCK) to send to participant or NONE if order is not consistent */ - public String resolve(DeployOrder acDeployOrder, LockOrder acLockOrder, DeployState acDeployState, - LockState acLockState, StateChangeResult acStateChangeResult) { + public String resolve(DeployOrder acDeployOrder, LockOrder acLockOrder, SubOrder acSubOrder, + DeployState acDeployState, LockState acLockState, SubState acSubState, StateChangeResult acStateChangeResult) { var deployOrder = acDeployOrder != null ? acDeployOrder : DeployOrder.NONE; var lockOrder = acLockOrder != null ? acLockOrder : LockOrder.NONE; + var subOrder = acSubOrder != null ? acSubOrder : SubOrder.NONE; var stateChangeResult = acStateChangeResult != null ? acStateChangeResult : StateChangeResult.NO_ERROR; var deployState = acDeployState != null ? acDeployState : DeployState.UNDEPLOYED; var lockState = acLockState != null ? acLockState : LockState.NONE; - return this.graph.get(new String[] {deployOrder.name(), lockOrder.name(), deployState.name(), lockState.name(), - stateChangeResult.name()}); + var subState = acSubState != null ? acSubState : SubState.NONE; + return this.graph.get(new String[] {deployOrder.name(), lockOrder.name(), subOrder.name(), + deployState.name(), lockState.name(), subState.name(), stateChangeResult.name()}); } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java index 8be12960b..ab80bc277 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java @@ -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; @@ -117,6 +118,23 @@ public class AutomationCompositionProvider { return result.toAuthorative(); } + + /** + * Update automation composition state. + * + * @param acSource the automation composition to update + * @return the updated automation composition + */ + public AutomationComposition updateAcState(final AutomationComposition acSource) { + var automationComposition = automationCompositionRepository + .getReferenceById(acSource.getInstanceId().toString()); + automationComposition.fromAuthorativeBase(acSource); + var result = automationCompositionRepository.save(automationComposition); + automationCompositionRepository.flush(); + // Return the saved automation composition + return result.toAuthorative(); + } + /** * Update automation composition. * @@ -155,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); } @@ -232,17 +252,33 @@ public class AutomationCompositionProvider { * Update AutomationCompositionElement. * * @param element the AutomationCompositionElement - * @param instanceId the instance Id */ - public void updateAutomationCompositionElement(@NonNull final AutomationCompositionElement element, - @NonNull final UUID instanceId) { - var jpaAcElement = new JpaAutomationCompositionElement(element.getId().toString(), instanceId.toString()); - jpaAcElement.fromAuthorative(element); + public void updateAutomationCompositionElement(@NonNull final AutomationCompositionElement element) { + var jpaAcElement = acElementRepository.getReferenceById(element.getId().toString()); + jpaAcElement.setMessage(element.getMessage()); + jpaAcElement.setOutProperties(element.getOutProperties()); + jpaAcElement.setOperationalState(element.getOperationalState()); + jpaAcElement.setUseState(element.getUseState()); + jpaAcElement.setDeployState(element.getDeployState()); + jpaAcElement.setLockState(element.getLockState()); + jpaAcElement.setSubState(element.getSubState()); + jpaAcElement.setStage(element.getStage()); + jpaAcElement.setRestarting(element.getRestarting()); + ProviderUtils.validate(element, jpaAcElement, "AutomationCompositionElement"); acElementRepository.save(jpaAcElement); } /** + * Delete AutomationCompositionElement. + * + * @param elementId the AutomationCompositionElement Id + */ + public void deleteAutomationCompositionElement(@NonNull final UUID elementId) { + acElementRepository.deleteById(elementId.toString()); + } + + /** * Validate ElementIds. * * @param automationComposition the AutomationComposition diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProvider.java index b3437c06f..85c9e67cb 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProvider.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProvider.java @@ -116,20 +116,6 @@ public class ParticipantProvider { } /** - * Updates an existing participant. - * - * @param participant participant to update - * @return the participant updated - */ - public Participant updateParticipant(@NonNull final Participant participant) { - var result = participantRepository - .save(ProviderUtils.getJpaAndValidate(participant, JpaParticipant::new, "participant")); - - // Return the saved participant - return result.toAuthorative(); - } - - /** * Delete a participant. * * @param participantId the Id of the participant to delete diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionElementRepository.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionElementRepository.java index 19d791e6c..d0a996e20 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionElementRepository.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionElementRepository.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation. + * 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. @@ -20,14 +20,19 @@ package org.onap.policy.clamp.models.acm.persistence.repository; +import jakarta.persistence.LockModeType; import java.util.List; import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionElement; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.repository.query.QueryByExampleExecutor; +import org.springframework.data.jpa.repository.Lock; +import org.springframework.lang.NonNull; -public interface AutomationCompositionElementRepository extends - JpaRepository<JpaAutomationCompositionElement, String>, - QueryByExampleExecutor<JpaAutomationCompositionElement> { +public interface AutomationCompositionElementRepository extends JpaRepository<JpaAutomationCompositionElement, String> { + + @NonNull + @Override + @Lock(LockModeType.PESSIMISTIC_READ) + JpaAutomationCompositionElement getReferenceById(@NonNull String id); List<JpaAutomationCompositionElement> findByParticipantId(String participantId); } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java index d61dfb41b..7a1c61f5a 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java @@ -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); } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java index f19d5db8b..172de34fe 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java @@ -42,6 +42,7 @@ import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; import org.onap.policy.clamp.models.acm.concepts.AcElementRestart; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; import org.onap.policy.clamp.models.acm.concepts.DeployState; @@ -49,6 +50,8 @@ import org.onap.policy.clamp.models.acm.concepts.LockState; import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState; import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy; +import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc; +import org.onap.policy.clamp.models.acm.concepts.SubState; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder; import org.onap.policy.clamp.models.acm.persistence.concepts.StringToMapConverter; @@ -62,6 +65,8 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Utility functions used in acm-runtime and participants. @@ -72,6 +77,8 @@ public final class AcmUtils { public static final String ENTRY = "entry "; private static final StringToMapConverter MAP_CONVERTER = new StringToMapConverter(); + private static final Logger LOGGER = LoggerFactory.getLogger(AcmUtils.class); + /** * Get the Policy information in the service template for the deploy message to participants. * @@ -115,6 +122,10 @@ public final class AcmUtils { return false; } + public static ToscaConceptIdentifier getType(ToscaNodeTemplate nodeTemplate) { + return new ToscaConceptIdentifier(nodeTemplate.getType(), nodeTemplate.getTypeVersion()); + } + /** * Prepare list of ParticipantDefinition for the Priming message. * @@ -126,8 +137,7 @@ public final class AcmUtils { Map<UUID, List<AutomationCompositionElementDefinition>> map = new HashMap<>(); for (var elementEntry : acElements) { - var type = new ToscaConceptIdentifier(elementEntry.getValue().getType(), - elementEntry.getValue().getTypeVersion()); + var type = getType(elementEntry.getValue()); var participantId = supportedElementMap.get(type); if (participantId == null) { throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, @@ -283,16 +293,20 @@ public final class AcmUtils { // @formatter:on } + /** - * Return true if DeployState and LockState are in a Transitional State. + * Return true if DeployState, LockState and SubState are in a Transitional State. * - * @return true if DeployState and LockState are in a Transitional State + * @param deployState the DeployState + * @param lockState the LockState + * @param subState the SubState + * @return true if there is a state in a Transitional State */ - public static boolean isInTransitionalState(DeployState deployState, LockState lockState) { + public static boolean isInTransitionalState(DeployState deployState, LockState lockState, SubState subState) { return DeployState.DEPLOYING.equals(deployState) || DeployState.UNDEPLOYING.equals(deployState) || LockState.LOCKING.equals(lockState) || LockState.UNLOCKING.equals(lockState) || DeployState.DELETING.equals(deployState) || DeployState.UPDATING.equals(deployState) - || DeployState.MIGRATING.equals(deployState); + || DeployState.MIGRATING.equals(deployState) || !SubState.NONE.equals(subState); } /** @@ -376,9 +390,23 @@ public final class AcmUtils { */ public static void setCascadedState(final AutomationComposition automationComposition, final DeployState deployState, final LockState lockState) { + setCascadedState(automationComposition, deployState, lockState, SubState.NONE); + } + + /** + /** + * Set the states on the automation composition and on all its automation composition elements. + * + * @param deployState the DeployState we want the automation composition to transition to + * @param lockState the LockState we want the automation composition to transition to + * @param subState the SubState we want the automation composition to transition to + */ + public static void setCascadedState(final AutomationComposition automationComposition, + final DeployState deployState, final LockState lockState, final SubState subState) { automationComposition.setDeployState(deployState); automationComposition.setLockState(lockState); automationComposition.setLastMsg(TimestampHelper.now()); + automationComposition.setSubState(subState); if (MapUtils.isEmpty(automationComposition.getElements())) { return; @@ -387,7 +415,9 @@ public final class AcmUtils { for (var element : automationComposition.getElements().values()) { element.setDeployState(deployState); element.setLockState(lockState); + element.setSubState(subState); element.setMessage(null); + element.setStage(null); } } @@ -432,6 +462,30 @@ public final class AcmUtils { } /** + * Create a new ParticipantRestartAc for restarting scenario. + * + * @param automationComposition the AutomationComposition + * @param participantId the participantId of the participant restarted + * @param serviceTemplateFragment the ToscaServiceTemplate with policies and policy types + * @return the ParticipantRestartAc + */ + public static ParticipantRestartAc createAcRestart(AutomationComposition automationComposition, + UUID participantId, ToscaServiceTemplate serviceTemplateFragment) { + var syncAc = new ParticipantRestartAc(); + syncAc.setDeployState(automationComposition.getDeployState()); + syncAc.setLockState(automationComposition.getLockState()); + syncAc.setAutomationCompositionId(automationComposition.getInstanceId()); + for (var element : automationComposition.getElements().values()) { + if (participantId.equals(element.getParticipantId())) { + var acElementSync = createAcElementRestart(element); + acElementSync.setToscaServiceTemplateFragment(serviceTemplateFragment); + syncAc.getAcElementList().add(acElementSync); + } + } + return syncAc; + } + + /** * Create a new AcElementRestart from an AutomationCompositionElement. * * @param element the AutomationCompositionElement @@ -452,6 +506,55 @@ public final class AcmUtils { } /** + * Prepare the list of ParticipantDefinition for Participant Restarting/Sync msg. + * + * @param participantId the participantId + * @param acmDefinition the AutomationCompositionDefinition + * @param toscaElementName the ElementName + * @return List of ParticipantDefinition + */ + public static List<ParticipantDefinition> prepareParticipantRestarting(UUID participantId, + AutomationCompositionDefinition acmDefinition, String toscaElementName) { + var acElements = extractAcElementsFromServiceTemplate(acmDefinition.getServiceTemplate(), + toscaElementName); + + // list of entry filtered by participantId + List<Entry<String, ToscaNodeTemplate>> elementList = new ArrayList<>(); + Map<ToscaConceptIdentifier, UUID> supportedElementMap = new HashMap<>(); + for (var elementEntry : acElements) { + var elementState = acmDefinition.getElementStateMap().get(elementEntry.getKey()); + if (participantId == null || participantId.equals(elementState.getParticipantId())) { + supportedElementMap.put(getType(elementEntry.getValue()), elementState.getParticipantId()); + elementList.add(elementEntry); + } + } + var list = prepareParticipantPriming(elementList, supportedElementMap); + for (var participantDefinition : list) { + for (var elementDe : participantDefinition.getAutomationCompositionElementDefinitionList()) { + var state = acmDefinition.getElementStateMap().get(elementDe.getAcElementDefinitionId().getName()); + if (state != null) { + elementDe.setOutProperties(state.getOutProperties()); + } + } + } + return list; + } + + /** + * Validated the Message field. + * + * @param message the message + * @return a validated message + */ + public static String validatedMessage(String message) { + if (message != null && message.length() > 255) { + LOGGER.warn("message too long {}", message); + return message.substring(0, 255); + } + return message; + } + + /** * Recursive Merge. * * @param map1 Map where to merge diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/StateDefinition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/StateDefinition.java index b7c6a31ac..491ae101e 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/StateDefinition.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/StateDefinition.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation. + * Copyright (C) 2023-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. @@ -74,7 +74,7 @@ public class StateDefinition<V> { if (key == null || key.contains(separator)) { throw new PfModelRuntimeException(Status.INTERNAL_SERVER_ERROR, "wrong key " + key); } - sb.append(key + separator); + sb.append(key).append(separator); } return sb.toString(); } diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionsTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionsTest.java new file mode 100644 index 000000000..5262b1316 --- /dev/null +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionsTest.java @@ -0,0 +1,37 @@ +/*- + * ============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; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class AutomationCompositionsTest { + + @Test + void testAutomationCompositions() { + var ac0 = new AutomationCompositions(); + ac0.setAutomationCompositionList(List.of(new AutomationComposition())); + var ac1 = new AutomationCompositions(ac0); + assertEquals(ac0.getAutomationCompositionList(), ac1.getAutomationCompositionList()); + } +} diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantInformationTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantInformationTest.java index a843c8279..1a7a419d6 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantInformationTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantInformationTest.java @@ -25,7 +25,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.HashMap; import java.util.UUID; import org.junit.jupiter.api.Test; -import org.onap.policy.clamp.models.acm.utils.TimestampHelper; class ParticipantInformationTest { @@ -33,8 +32,6 @@ class ParticipantInformationTest { void testCopyConstructor() { var participant = new Participant(); participant.setParticipantId(UUID.randomUUID()); - participant.setParticipantState(ParticipantState.ON_LINE); - participant.setLastMsg(TimestampHelper.now()); participant.setParticipantSupportedElementTypes(new HashMap<>()); var participantInfo1 = new ParticipantInformation(); participantInfo1.setParticipant(participant); diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantTest.java index 7486d0d70..2c6c60edc 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation. + * Copyright (C) 2021-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. @@ -21,7 +21,6 @@ package org.onap.policy.clamp.models.acm.concepts; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -46,7 +45,6 @@ class ParticipantTest { var p1 = new Participant(); p1.setParticipantId(CommonTestData.getParticipantId()); - p1.setParticipantState(ParticipantState.ON_LINE); assertThat(p1.toString()).contains("Participant("); assertNotEquals(0, p1.hashCode()); @@ -56,11 +54,6 @@ class ParticipantTest { assertNotEquals(p1, p0); var p2 = new Participant(); - - // @formatter:off - assertThatThrownBy(() -> p2.setParticipantState(null)).isInstanceOf(NullPointerException.class); - // @formatter:on - assertEquals(p2, p0); } @@ -68,7 +61,6 @@ class ParticipantTest { void testCopyConstructor() { var p0 = new Participant(); p0.setParticipantId(UUID.randomUUID()); - p0.setParticipantState(ParticipantState.ON_LINE); var supportedElementType = new ParticipantSupportedElementType(); supportedElementType.setId(UUID.randomUUID()); supportedElementType.setTypeName("type"); diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtilsTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtilsTest.java index 6bb7f1eb7..bac0842f1 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtilsTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtilsTest.java @@ -47,9 +47,31 @@ class ParticipantUtilsTest { @Test void testGetFirstStartPhase() throws CoderException { var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); + var automationComposition = + CODER.decode(ResourceUtils.getResourceAsString(AUTOMATION_COMPOSITION_JSON), AutomationCompositions.class) + .getAutomationCompositionList().get(0); + automationComposition.setDeployState(DeployState.DEPLOYING); + automationComposition.setLockState(LockState.NONE); + var result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.UNLOCKING); + result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + automationComposition.setDeployState(DeployState.UNDEPLOYING); + automationComposition.setLockState(LockState.NONE); + result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isEqualTo(1); + } + + @Test + void testGetFirstStage() throws CoderException { + var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); var automationCompositions = CODER.decode(ResourceUtils.getResourceAsString(AUTOMATION_COMPOSITION_JSON), AutomationCompositions.class); - var result = ParticipantUtils.getFirstStartPhase(automationCompositions.getAutomationCompositionList().get(0), + var result = ParticipantUtils.getFirstStage(automationCompositions.getAutomationCompositionList().get(0), serviceTemplate); assertThat(result).isZero(); } diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantAckMessageTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantAckMessageTest.java index 72e4efb49..2535c375a 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantAckMessageTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantAckMessageTest.java @@ -32,7 +32,6 @@ import org.onap.policy.clamp.models.acm.utils.CommonTestData; import org.onap.policy.common.utils.coder.CoderException; class ParticipantAckMessageTest { - private ParticipantAckMessage message; @Test void testCopyConstructor() throws CoderException { @@ -40,8 +39,8 @@ class ParticipantAckMessageTest { .isInstanceOf(NullPointerException.class); // verify with null values - message = new ParticipantAckMessage(ParticipantMessageType.PARTICIPANT_STATE_CHANGE); - ParticipantAckMessage newmsg = new ParticipantAckMessage(message); + var message = new ParticipantAckMessage(ParticipantMessageType.PARTICIPANT_STATE_CHANGE); + var newmsg = new ParticipantAckMessage(message); newmsg.setResponseTo(message.getResponseTo()); assertEquals(message.toString(), newmsg.toString()); @@ -56,14 +55,15 @@ class ParticipantAckMessageTest { @Test void testAppliesTo_NullParticipantId() { - message = makeMessage(); - assertThatThrownBy(() -> message.appliesTo(UUID.randomUUID(), null)).isInstanceOf(NullPointerException.class); - assertThatThrownBy(() -> message.appliesTo(null, UUID.randomUUID())).isInstanceOf(NullPointerException.class); + var message = makeMessage(); + var participantId = CommonTestData.getRndParticipantId(); + assertThatThrownBy(() -> message.appliesTo(participantId, null)).isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> message.appliesTo(null, participantId)).isInstanceOf(NullPointerException.class); } @Test void testAppliesTo_ParticipantIdMatches() { - message = makeMessage(); + var message = makeMessage(); // ParticipantId matches assertTrue(message.appliesTo(CommonTestData.getParticipantId(), CommonTestData.getReplicaId())); @@ -72,7 +72,7 @@ class ParticipantAckMessageTest { @Test void testAppliesTo_ParticipantIdNoMatch() { - message = makeMessage(); + var message = makeMessage(); // ParticipantId does not match assertFalse(message.appliesTo(CommonTestData.getRndParticipantId(), CommonTestData.getReplicaId())); @@ -80,7 +80,7 @@ class ParticipantAckMessageTest { } private ParticipantAckMessage makeMessage() { - ParticipantAckMessage msg = new ParticipantAckMessage(ParticipantMessageType.PARTICIPANT_DEREGISTER_ACK); + var msg = new ParticipantAckMessage(ParticipantMessageType.PARTICIPANT_DEREGISTER_ACK); msg.setParticipantId(CommonTestData.getParticipantId()); msg.setMessage("Successfull Ack"); diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantMessageTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantMessageTest.java index db31d0f01..c6386a571 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantMessageTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantMessageTest.java @@ -33,7 +33,6 @@ import org.onap.policy.clamp.models.acm.utils.CommonTestData; import org.onap.policy.common.utils.coder.CoderException; class ParticipantMessageTest { - private ParticipantMessage message; @Test void testCopyConstructor() throws CoderException { @@ -41,7 +40,7 @@ class ParticipantMessageTest { .isInstanceOf(NullPointerException.class); // verify with null values - message = new ParticipantMessage(ParticipantMessageType.PARTICIPANT_STATE_CHANGE); + var message = new ParticipantMessage(ParticipantMessageType.PARTICIPANT_STATE_CHANGE); var newmsg = new ParticipantMessage(message); newmsg.setMessageId(message.getMessageId()); newmsg.setTimestamp(message.getTimestamp()); @@ -59,15 +58,15 @@ class ParticipantMessageTest { @Test void testAppliesTo_NullParticipantId() { - message = makeMessage(); - - assertThatThrownBy(() -> message.appliesTo(UUID.randomUUID(), null)).isInstanceOf(NullPointerException.class); - assertThatThrownBy(() -> message.appliesTo(null, UUID.randomUUID())).isInstanceOf(NullPointerException.class); + var message = makeMessage(); + var participantId = CommonTestData.getParticipantId(); + assertThatThrownBy(() -> message.appliesTo(participantId, null)).isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> message.appliesTo(null, participantId)).isInstanceOf(NullPointerException.class); } @Test void testAppliesTo_ParticipantIdMatches() { - message = makeMessage(); + var message = makeMessage(); // ParticipantId matches assertTrue(message.appliesTo(CommonTestData.getParticipantId(), CommonTestData.getReplicaId())); @@ -76,7 +75,7 @@ class ParticipantMessageTest { @Test void testAppliesTo_ParticipantIdNoMatch() { - message = makeMessage(); + var message = makeMessage(); assertFalse(message.appliesTo(CommonTestData.getRndParticipantId(), CommonTestData.getReplicaId())); assertTrue(message.appliesTo(CommonTestData.getParticipantId(), CommonTestData.getReplicaId())); } diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantRestartTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantRestartTest.java deleted file mode 100644 index 95b718e68..000000000 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantRestartTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2023-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 static org.junit.jupiter.api.Assertions.assertEquals; -import static org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMessageUtils.assertSerializable; -import static org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMessageUtils.removeVariableFields; - -import java.time.Instant; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import org.junit.jupiter.api.Test; -import org.onap.policy.clamp.models.acm.concepts.AcElementRestart; -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.ParticipantDefinition; -import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc; -import org.onap.policy.clamp.models.acm.utils.CommonTestData; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; - -class ParticipantRestartTest { - - @Test - void testCopyConstructor() throws CoderException { - - final var orig = new ParticipantRestart(); - // verify with null values - assertEquals(removeVariableFields(orig.toString()), - removeVariableFields(new ParticipantRestart(orig).toString())); - - orig.setMessageId(UUID.randomUUID()); - orig.setCompositionId(UUID.randomUUID()); - orig.setTimestamp(Instant.ofEpochMilli(3000)); - orig.setParticipantId(CommonTestData.getParticipantId()); - - var participantDefinitionUpdate = new ParticipantDefinition(); - var type = new ToscaConceptIdentifier("id", "1.2.3"); - var acDefinition = CommonTestData.getAcElementDefinition(type); - participantDefinitionUpdate.setAutomationCompositionElementDefinitionList(List.of(acDefinition)); - orig.setParticipantDefinitionUpdates(List.of(participantDefinitionUpdate)); - - var acElement = new AcElementRestart(); - acElement.setId(UUID.randomUUID()); - var id = new ToscaConceptIdentifier("id", "1.2.3"); - acElement.setDefinition(id); - acElement.setDeployState(DeployState.DEPLOYED); - acElement.setLockState(LockState.LOCKED); - acElement.setOperationalState("OperationalState"); - acElement.setUseState("UseState"); - acElement.setProperties(Map.of("key", "value")); - acElement.setOutProperties(Map.of("keyOut", "valueOut")); - - var acRestart = new ParticipantRestartAc(); - acRestart.setAcElementList(List.of(acElement)); - acRestart.setAutomationCompositionId(UUID.randomUUID()); - - orig.setAutomationcompositionList(List.of(acRestart)); - - assertEquals(removeVariableFields(orig.toString()), - removeVariableFields(new ParticipantRestart(orig).toString())); - - assertSerializable(orig, ParticipantRestart.class); - } -} diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantSyncTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantSyncTest.java index 970b94824..2fee9c55a 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantSyncTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/messages/kafka/participant/ParticipantSyncTest.java @@ -40,7 +40,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -public class ParticipantSyncTest { +class ParticipantSyncTest { @Test void testCopyConstructor() throws CoderException { diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElementTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElementTest.java index 2eda9a9b3..fab3dac9b 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElementTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElementTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation. + * Copyright (C) 2021-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. @@ -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,23 +48,27 @@ 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(); @Test 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(() -> { @@ -71,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", new PfConceptKey(), - null, LockState.LOCKED); + new JpaAutomationCompositionElement(KEY, KEY, CONCEPT_KEY, + null, LockState.LOCKED, SubState.NONE); }).hasMessageMatching("deployState" + NULL_ERROR); assertThatThrownBy(() -> { - new JpaAutomationCompositionElement("key", "key", new PfConceptKey(), - 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", - new PfConceptKey(), DeployState.UNDEPLOYED, LockState.LOCKED)); + assertDoesNotThrow(() -> new JpaAutomationCompositionElement(KEY, KEY)); + assertDoesNotThrow(() -> new JpaAutomationCompositionElement(KEY, KEY, + new PfConceptKey(), DeployState.UNDEPLOYED, LockState.LOCKED, SubState.NONE)); } @Test @@ -109,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); @@ -135,13 +145,13 @@ 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()); } @Test - void testJpaAutomationCompositionElementCompareTo() { + void testJpaAcElementCompareTo() { var testJpaAcElement = createJpaAutomationCompositionElementInstance(); var otherJpaAcElement = @@ -152,17 +162,27 @@ class JpaAutomationCompositionElementTest { assertNotEquals(0, testJpaAcElement.compareTo(new DummyJpaAutomationCompositionElementChild())); - testJpaAcElement.setElementId("BadValue"); + assertEquals(testJpaAcElement, new JpaAutomationCompositionElement(testJpaAcElement)); + } + + @Test + void testJpaAutomationCompositionElementCompareTo() { + var testJpaAcElement = createJpaAutomationCompositionElementInstance(); + + var otherJpaAcElement = + new JpaAutomationCompositionElement(testJpaAcElement); + + 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)); @@ -182,16 +202,26 @@ 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)); + testJpaAcElement.setStage(1); + assertNotEquals(0, testJpaAcElement.compareTo(otherJpaAcElement)); + testJpaAcElement.setStage(null); + assertEquals(0, testJpaAcElement.compareTo(otherJpaAcElement)); + testJpaAcElement.setMessage("Message"); assertNotEquals(0, testJpaAcElement.compareTo(otherJpaAcElement)); testJpaAcElement.setMessage(null); @@ -205,7 +235,6 @@ class JpaAutomationCompositionElementTest { testJpaAcElement.setParticipantId(UUID.randomUUID().toString()); assertNotEquals(0, testJpaAcElement.compareTo(otherJpaAcElement)); - assertEquals(testJpaAcElement, new JpaAutomationCompositionElement(testJpaAcElement)); } @Test @@ -238,7 +267,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; } @@ -248,7 +277,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"); diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionTest.java index b56e77801..38153d488 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionTest.java @@ -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,14 +203,14 @@ class JpaAutomationCompositionTest { jpaAutomationComposition.setLockState(LockState.NONE); assertEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition)); - jpaAutomationComposition.setDescription("A description"); + jpaAutomationComposition.setSubState(SubState.PREPARING); assertNotEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition)); - jpaAutomationComposition.setDescription(null); + jpaAutomationComposition.setSubState(SubState.NONE); assertEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition)); - jpaAutomationComposition.setRestarting(true); + jpaAutomationComposition.setDescription("A description"); assertNotEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition)); - jpaAutomationComposition.setRestarting(null); + jpaAutomationComposition.setDescription(null); assertEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition)); jpaAutomationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantReplicaTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantReplicaTest.java index d77760860..8cc9580cb 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantReplicaTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantReplicaTest.java @@ -28,9 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; import java.util.UUID; import org.junit.jupiter.api.Test; -import org.onap.policy.clamp.models.acm.concepts.ParticipantReplica; import org.onap.policy.clamp.models.acm.concepts.ParticipantState; -import org.onap.policy.clamp.models.acm.utils.TimestampHelper; class JpaParticipantReplicaTest { diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantTest.java index e0f2f55c1..d2d253e06 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantTest.java @@ -27,15 +27,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.sql.Timestamp; -import java.time.Instant; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.UUID; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.models.acm.concepts.Participant; -import org.onap.policy.clamp.models.acm.concepts.ParticipantState; -import org.onap.policy.clamp.models.acm.utils.TimestampHelper; /** * Test the {@link JpaParticipant} class. @@ -47,30 +43,23 @@ class JpaParticipantTest { @Test void testJpaParticipantConstructor() { assertThatThrownBy(() -> new JpaParticipant((Participant) null)) - .hasMessageMatching("authorativeConcept is marked .*ull but is null"); + .hasMessageMatching("authorativeConcept is marked .*ull but is null"); assertThatThrownBy(() -> new JpaParticipant((JpaParticipant) null)) .hasMessageMatching("copyConcept is marked .*ull but is null"); - assertThatThrownBy(() -> new JpaParticipant(null, ParticipantState.ON_LINE, - new ArrayList<>(), new ArrayList<>())) + assertThatThrownBy(() -> new JpaParticipant(null, new ArrayList<>(), new ArrayList<>())) .hasMessageMatching(NULL_KEY_ERROR); - assertThatThrownBy(() -> new JpaParticipant(UUID.randomUUID().toString(), null, - new ArrayList<>(), new ArrayList<>())) - .hasMessageMatching("participantState is marked .*ull but is null"); - - assertThatThrownBy(() -> new JpaParticipant(UUID.randomUUID().toString(), ParticipantState.ON_LINE, - null, new ArrayList<>())) + assertThatThrownBy(() -> new JpaParticipant(UUID.randomUUID().toString(), null, new ArrayList<>())) .hasMessageMatching("supportedElements is marked .*ull but is null"); - assertThatThrownBy(() -> new JpaParticipant(UUID.randomUUID().toString(), ParticipantState.ON_LINE, - new ArrayList<>(), null)) - .hasMessageMatching("replicas is marked .*ull but is null"); + assertThatThrownBy(() -> new JpaParticipant(UUID.randomUUID().toString(), new ArrayList<>(), null)) + .hasMessageMatching("replicas is marked .*ull but is null"); assertDoesNotThrow(() -> new JpaParticipant()); assertDoesNotThrow(() -> new JpaParticipant(UUID.randomUUID().toString(), - ParticipantState.ON_LINE, new ArrayList<>(), new ArrayList<>())); + new ArrayList<>(), new ArrayList<>())); } @Test @@ -116,18 +105,6 @@ class JpaParticipantTest { assertEquals(0, testJpaParticipant.compareTo(testJpaParticipant)); assertNotEquals(0, testJpaParticipant.compareTo(new DummyJpaParticipantChild())); - testJpaParticipant.setParticipantState(ParticipantState.OFF_LINE); - assertNotEquals(0, testJpaParticipant.compareTo(otherJpaParticipant)); - testJpaParticipant.setParticipantState(ParticipantState.ON_LINE); - assertEquals(0, testJpaParticipant.compareTo(otherJpaParticipant)); - assertEquals(testJpaParticipant, new JpaParticipant(testJpaParticipant)); - - testJpaParticipant.setLastMsg(Timestamp.from(Instant.EPOCH)); - assertNotEquals(0, testJpaParticipant.compareTo(otherJpaParticipant)); - testJpaParticipant.setLastMsg(otherJpaParticipant.getLastMsg()); - assertEquals(0, testJpaParticipant.compareTo(otherJpaParticipant)); - assertEquals(testJpaParticipant, new JpaParticipant(testJpaParticipant)); - var newJpaParticipant = new JpaParticipant(testJpaParticipant); newJpaParticipant.setParticipantId(testJpaParticipant.getParticipantId()); assertEquals(testJpaParticipant, newJpaParticipant); @@ -143,8 +120,6 @@ class JpaParticipantTest { var p1 = new JpaParticipant(); - p1.setParticipantState(ParticipantState.ON_LINE); - assertThat(p1.toString()).contains("Participant("); assertNotEquals(0, p1.hashCode()); assertNotEquals(p1, p0); @@ -154,14 +129,12 @@ class JpaParticipantTest { var p2 = new JpaParticipant(); p2.setParticipantId(p0.getParticipantId()); - p2.setLastMsg(p0.getLastMsg()); assertEquals(p2, p0); } private Participant createParticipantInstance() { var testParticipant = new Participant(); testParticipant.setParticipantId(UUID.randomUUID()); - testParticipant.setLastMsg(TimestampHelper.now()); testParticipant.setParticipantSupportedElementTypes(new LinkedHashMap<>()); testParticipant.setReplicas(new LinkedHashMap<>()); diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToMapConverterTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToMapConverterTest.java new file mode 100644 index 000000000..67240047a --- /dev/null +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToMapConverterTest.java @@ -0,0 +1,53 @@ +/*- + * ============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.persistence.concepts; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.onap.policy.models.base.PfModelRuntimeException; + +class StringToMapConverterTest { + + @Test + void testConvert() { + var stringToMapConverter = new StringToMapConverter(); + Map<String, Object> map = Map.of("key", List.of("value")); + var dbData = stringToMapConverter.convertToDatabaseColumn(map); + var result = stringToMapConverter.convertToEntityAttribute(dbData); + assertEquals(map, result); + } + + @Test + void testNull() { + var stringToMapConverter = new StringToMapConverter(); + var dbData = stringToMapConverter.convertToDatabaseColumn(null); + assertThat(dbData).isNull(); + var map = stringToMapConverter.convertToEntityAttribute(null); + assertThat(map).isNotNull(); + assertThatThrownBy(() -> stringToMapConverter.convertToEntityAttribute("1")) + .isInstanceOf(PfModelRuntimeException.class); + } +} diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToServiceTemplateConverterTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToServiceTemplateConverterTest.java new file mode 100644 index 000000000..98f22afcc --- /dev/null +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToServiceTemplateConverterTest.java @@ -0,0 +1,58 @@ +/*- + * ============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.persistence.concepts; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.models.acm.document.concepts.DocToscaServiceTemplate; +import org.onap.policy.clamp.models.acm.utils.CommonTestData; +import org.onap.policy.models.base.PfModelRuntimeException; + +class StringToServiceTemplateConverterTest { + + private static final String TOSCA_SERVICE_TEMPLATE_YAML_PROP = + "clamp/acm/test/tosca-template-additional-properties.yaml"; + + @Test + void testConvert() { + var inputServiceTemplateProperties = CommonTestData.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML_PROP); + var docServiceTemplate = new DocToscaServiceTemplate(inputServiceTemplateProperties); + var stringToServiceTemplateConverter = new StringToServiceTemplateConverter(); + var dbData = stringToServiceTemplateConverter.convertToDatabaseColumn(docServiceTemplate); + var result = stringToServiceTemplateConverter.convertToEntityAttribute(dbData); + assertThat(docServiceTemplate.compareTo(result)).isEqualByComparingTo(0); + } + + @Test + void testNull() { + var stringToServiceTemplateConverter = new StringToServiceTemplateConverter(); + var dbData = stringToServiceTemplateConverter.convertToDatabaseColumn(null); + assertThat(dbData).isNull(); + var docServiceTemplate = stringToServiceTemplateConverter.convertToEntityAttribute(null); + assertThat(docServiceTemplate).isNotNull(); + docServiceTemplate = stringToServiceTemplateConverter.convertToEntityAttribute(""); + assertThat(docServiceTemplate).isNull(); + assertThatThrownBy(() -> stringToServiceTemplateConverter.convertToEntityAttribute("1")) + .isInstanceOf(PfModelRuntimeException.class); + } +} diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java index 85dadc3de..95811917d 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java @@ -83,7 +83,7 @@ class AcDefinitionProviderTest { .hasMessageStartingWith("\"AutomationCompositionDefinition\" INVALID, item has status INVALID"); assertThatThrownBy(() -> acDefinitionProvider.updateAcDefinitionState(compositionId, AcTypeState.PRIMED, - StateChangeResult.NO_ERROR, false)) + StateChangeResult.NO_ERROR)) .hasMessageStartingWith("update of Automation Composition Definition"); } @@ -195,7 +195,7 @@ class AcDefinitionProviderTest { when(acmDefinitionRepository.findById(acmDefinition.getCompositionId().toString())) .thenReturn(Optional.of(jpa)); acDefinitionProvider.updateAcDefinitionState(acmDefinition.getCompositionId(), AcTypeState.PRIMED, - StateChangeResult.NO_ERROR, false); + StateChangeResult.NO_ERROR); verify(acmDefinitionRepository).save(jpa); } diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolverTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolverTest.java index 7f6cb2f0c..a807a1179 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolverTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolverTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation. + * Copyright (C) 2023-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,42 +26,78 @@ import org.junit.jupiter.api.Test; 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.messages.rest.instantiation.DeployOrder; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.SubOrder; class AcInstanceStateResolverTest { @Test void testResolve() { var acTypeStateResolver = new AcInstanceStateResolver(); - var result = acTypeStateResolver.resolve(DeployOrder.DEPLOY, LockOrder.NONE, DeployState.UNDEPLOYED, - LockState.NONE, StateChangeResult.NO_ERROR); + // deploy + var result = acTypeStateResolver.resolve(DeployOrder.DEPLOY, LockOrder.NONE, SubOrder.NONE, + DeployState.UNDEPLOYED, LockState.NONE, SubState.NONE, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(AcInstanceStateResolver.DEPLOY); - result = acTypeStateResolver.resolve(DeployOrder.UNDEPLOY, LockOrder.NONE, DeployState.DEPLOYED, - LockState.LOCKED, StateChangeResult.NO_ERROR); + + // undeploy + result = acTypeStateResolver.resolve(DeployOrder.UNDEPLOY, LockOrder.NONE, SubOrder.NONE, + DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(AcInstanceStateResolver.UNDEPLOY); - result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.UNLOCK, DeployState.DEPLOYED, LockState.LOCKED, - StateChangeResult.NO_ERROR); + + // unlock + result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.UNLOCK, SubOrder.NONE, + DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(AcInstanceStateResolver.UNLOCK); - result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.LOCK, DeployState.DEPLOYED, LockState.UNLOCKED, - StateChangeResult.NO_ERROR); + + // lock + result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.LOCK, SubOrder.NONE, + DeployState.DEPLOYED, LockState.UNLOCKED, SubState.NONE, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(AcInstanceStateResolver.LOCK); - result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.NONE, DeployState.UNDEPLOYED, LockState.NONE, - StateChangeResult.NO_ERROR); + // migrate + result = acTypeStateResolver.resolve(DeployOrder.MIGRATE, LockOrder.NONE, SubOrder.NONE, + DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE, StateChangeResult.NO_ERROR); + assertThat(result).isEqualTo(AcInstanceStateResolver.MIGRATE); + + // migrate-precheck + result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.NONE, SubOrder.MIGRATE_PRECHECK, + DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE, StateChangeResult.NO_ERROR); + assertThat(result).isEqualTo(AcInstanceStateResolver.MIGRATE_PRECHECK); + + // prepare + result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.NONE, SubOrder.PREPARE, + DeployState.UNDEPLOYED, LockState.NONE, SubState.NONE, StateChangeResult.NO_ERROR); + assertThat(result).isEqualTo(AcInstanceStateResolver.PREPARE); + + // review + result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.NONE, SubOrder.REVIEW, + DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE, StateChangeResult.NO_ERROR); + assertThat(result).isEqualTo(AcInstanceStateResolver.REVIEW); + } + + @Test + void testResolveWrongOrder() { + var acTypeStateResolver = new AcInstanceStateResolver(); + + var result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.NONE, SubOrder.NONE, + DeployState.UNDEPLOYED, LockState.NONE, SubState.NONE, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(AcInstanceStateResolver.NONE); - result = acTypeStateResolver.resolve(DeployOrder.UNDEPLOY, LockOrder.UNLOCK, DeployState.DEPLOYED, - LockState.LOCKED, StateChangeResult.NO_ERROR); + + result = acTypeStateResolver.resolve(DeployOrder.UNDEPLOY, LockOrder.UNLOCK, SubOrder.NONE, + DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(AcInstanceStateResolver.NONE); - result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.UNLOCK, DeployState.UNDEPLOYED, LockState.NONE, - StateChangeResult.NO_ERROR); + + result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.UNLOCK, SubOrder.NONE, + DeployState.UNDEPLOYED, LockState.NONE, SubState.NONE, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(AcInstanceStateResolver.NONE); - result = acTypeStateResolver.resolve(DeployOrder.UNDEPLOY, LockOrder.NONE, DeployState.DEPLOYING, - LockState.NONE, StateChangeResult.NO_ERROR); + + result = acTypeStateResolver.resolve(DeployOrder.UNDEPLOY, LockOrder.NONE, SubOrder.NONE, + DeployState.DEPLOYING, LockState.NONE, SubState.NONE, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(AcInstanceStateResolver.NONE); - result = acTypeStateResolver.resolve(null, null, null, null, null); + result = acTypeStateResolver.resolve(null, null, null, null, null, null, null); assertThat(result).isEqualTo(AcInstanceStateResolver.NONE); } - } diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProviderTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProviderTest.java index 8e7e50de7..c2368fe10 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProviderTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProviderTest.java @@ -56,6 +56,7 @@ class AutomationCompositionProviderTest { private static final String AC_IS_NULL = "automationComposition is marked non-null but is null"; private static final String ACELEMENT_IS_NULL = "element is marked non-null but is null"; + private static final String ACELEMENT_ID_IS_NULL = "elementId is marked non-null but is null"; private static final Coder CODER = new StandardCoder(); private static final String AUTOMATION_COMPOSITION_JSON = @@ -225,16 +226,34 @@ class AutomationCompositionProviderTest { var automationCompositionProvider = new AutomationCompositionProvider( mock(AutomationCompositionRepository.class), acElementRepository); - assertThatThrownBy(() -> automationCompositionProvider.updateAutomationCompositionElement(null, null)) + assertThatThrownBy(() -> automationCompositionProvider.updateAutomationCompositionElement(null)) .hasMessageMatching(ACELEMENT_IS_NULL); var acElement = inputAutomationCompositions.getAutomationCompositionList().get(0).getElements().values() .iterator().next(); - automationCompositionProvider.updateAutomationCompositionElement(acElement, UUID.randomUUID()); + var jpa = new JpaAutomationCompositionElement(); + jpa.setElementId(acElement.getId().toString()); + jpa.setInstanceId(UUID.randomUUID().toString()); + jpa.fromAuthorative(acElement); + when(acElementRepository.getReferenceById(acElement.getId().toString())).thenReturn(jpa); + + automationCompositionProvider.updateAutomationCompositionElement(acElement); verify(acElementRepository).save(any()); } @Test + void testDeleteElementById() { + var acElementRepository = mock(AutomationCompositionElementRepository.class); + var automationCompositionProvider = new AutomationCompositionProvider( + mock(AutomationCompositionRepository.class), acElementRepository); + assertThatThrownBy(() -> automationCompositionProvider.deleteAutomationCompositionElement(null)) + .hasMessageMatching(ACELEMENT_ID_IS_NULL); + var elementId = UUID.randomUUID(); + automationCompositionProvider.deleteAutomationCompositionElement(elementId); + verify(acElementRepository).deleteById(elementId.toString()); + } + + @Test void testValidateElementIds() { var acElementRepository = mock(AutomationCompositionElementRepository.class); var automationCompositionProvider = new AutomationCompositionProvider( diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProviderTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProviderTest.java index 9ceeef640..ac3aa87c5 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProviderTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProviderTest.java @@ -114,25 +114,6 @@ class ParticipantProviderTest { } @Test - void testParticipantUpdate() { - var participantRepository = mock(ParticipantRepository.class); - var automationCompositionElementRepository = mock(AutomationCompositionElementRepository.class); - var nodeTemplateStateRepository = mock(NodeTemplateStateRepository.class); - - var participantProvider = new ParticipantProvider(participantRepository, - automationCompositionElementRepository, nodeTemplateStateRepository, - mock(ParticipantReplicaRepository.class)); - - assertThatThrownBy(() -> participantProvider.updateParticipant(null)).hasMessageMatching(LIST_IS_NULL); - - when(participantRepository.save(any())).thenReturn(jpaParticipantList.get(0)); - - var updatedParticipant = participantProvider.updateParticipant(inputParticipants.get(0)); - updatedParticipant.setParticipantId(inputParticipants.get(0).getParticipantId()); - assertThat(updatedParticipant).usingRecursiveComparison().isEqualTo(inputParticipants.get(0)); - } - - @Test void testGetAutomationCompositions() { var participantRepository = mock(ParticipantRepository.class); var automationCompositionElementRepository = mock(AutomationCompositionElementRepository.class); @@ -240,7 +221,6 @@ class ParticipantProviderTest { assertThrows(NullPointerException.class, () -> participantProvider.getParticipantById(null)); assertThrows(NullPointerException.class, () -> participantProvider.findParticipant(null)); assertThrows(NullPointerException.class, () -> participantProvider.saveParticipant(null)); - assertThrows(NullPointerException.class, () -> participantProvider.updateParticipant(null)); assertThrows(NullPointerException.class, () -> participantProvider.deleteParticipant(null)); assertThrows(NullPointerException.class, () -> participantProvider.getAutomationCompositionElements(null)); assertThrows(NullPointerException.class, () -> participantProvider.getAcNodeTemplateStates(null)); diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/rest/RestUtilsTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/rest/RestUtilsTest.java index e6135fe5b..91f26f7c1 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/rest/RestUtilsTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/rest/RestUtilsTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021,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. @@ -47,7 +47,7 @@ class RestUtilsTest { var response = RestUtils.toSimpleResponse(ex); - assertThat(response.getStatusCodeValue()).isEqualTo(STATUS_ERROR.getStatusCode()); + assertThat(response.getStatusCode().value()).isEqualTo(STATUS_ERROR.getStatusCode()); assertThat(response.getBody()).isNotNull(); assertThat(response.getBody().getErrorDetails()).isEqualTo(MESSAGE_ERROR); } diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java index a5c93e86a..97af64cf7 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java @@ -37,10 +37,13 @@ import java.util.List; import java.util.Map; import java.util.UUID; import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; 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.document.concepts.DocToscaServiceTemplate; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder; @@ -66,14 +69,16 @@ class AcmUtilsTest { @Test void testIsInTransitionalState() { - assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKED)).isFalse(); - assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYING, LockState.NONE)).isTrue(); - assertThat(AcmUtils.isInTransitionalState(DeployState.UNDEPLOYING, LockState.NONE)).isTrue(); - assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKING)).isTrue(); - assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.UNLOCKING)).isTrue(); - assertThat(AcmUtils.isInTransitionalState(DeployState.DELETING, LockState.NONE)).isTrue(); - assertThat(AcmUtils.isInTransitionalState(DeployState.UPDATING, LockState.LOCKED)).isTrue(); - assertThat(AcmUtils.isInTransitionalState(DeployState.MIGRATING, LockState.LOCKED)).isTrue(); + assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE)).isFalse(); + assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYING, LockState.NONE, SubState.NONE)).isTrue(); + assertThat(AcmUtils.isInTransitionalState(DeployState.UNDEPLOYING, LockState.NONE, SubState.NONE)).isTrue(); + assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKING, SubState.NONE)).isTrue(); + assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.UNLOCKING, SubState.NONE)).isTrue(); + assertThat(AcmUtils.isInTransitionalState(DeployState.DELETING, LockState.NONE, SubState.NONE)).isTrue(); + assertThat(AcmUtils.isInTransitionalState(DeployState.UPDATING, LockState.LOCKED, SubState.NONE)).isTrue(); + assertThat(AcmUtils.isInTransitionalState(DeployState.MIGRATING, LockState.LOCKED, SubState.NONE)).isTrue(); + assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKED, + SubState.MIGRATION_PRECHECKING)).isTrue(); } @Test @@ -233,6 +238,16 @@ class AcmUtilsTest { assertEquals(element.getOutProperties(), result.getOutProperties()); } + @Test + void testValidatedMessage() { + var message = "completed"; + assertEquals(message, AcmUtils.validatedMessage(message)); + + var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); + message = serviceTemplate.toString(); + assertEquals(message.substring(0, 255), AcmUtils.validatedMessage(message)); + } + private AutomationComposition getDummyAutomationComposition() { var automationComposition = new AutomationComposition(); automationComposition.setCompositionId(UUID.randomUUID()); @@ -276,9 +291,7 @@ class AcmUtilsTest { } private Map<String, ToscaPolicyType> getDummyPolicyTypesMap() { - Map<String, ToscaPolicyType> policyTypes = new HashMap<>(); - policyTypes.put("onap.policies.Match", new ToscaPolicyType()); - return policyTypes; + return Map.of("onap.policies.Match", new ToscaPolicyType()); } private Map<String, ToscaDataType> getDummyToscaDataTypeMap() { @@ -290,12 +303,45 @@ class AcmUtilsTest { private Map<String, ToscaNodeTemplate> getDummyNodeTemplates() { Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>(); var nodeTemplate = new ToscaNodeTemplate(); - nodeTemplate.setType("org.onap.policy.clamp.acm.AutomationCompositionElement"); + nodeTemplate.setType(AUTOMATION_COMPOSITION_ELEMENT); nodeTemplates.put("org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant", nodeTemplate); return nodeTemplates; } @Test + void testcreateAcRestart() { + var automationComposition = getDummyAutomationComposition(); + automationComposition.setInstanceId(UUID.randomUUID()); + var toscaServiceTemplate = getDummyToscaServiceTemplate(); + var participantId = automationComposition.getElements().values().iterator().next().getParticipantId(); + var serviceTemplateFragment = AcmUtils.getToscaServiceTemplateFragment(toscaServiceTemplate); + var result = AcmUtils.createAcRestart(automationComposition, participantId, serviceTemplateFragment); + assertEquals(result.getAutomationCompositionId(), automationComposition.getInstanceId()); + assertThat(result.getAcElementList()).hasSize(1); + } + + @Test + void testPrepareParticipantRestarting() { + var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); + var acmDefinition = new AutomationCompositionDefinition(); + acmDefinition.setElementStateMap(Map.of()); + acmDefinition.setServiceTemplate(serviceTemplate); + var acElements = AcmUtils.extractAcElementsFromServiceTemplate(serviceTemplate, AUTOMATION_COMPOSITION_ELEMENT); + acmDefinition.setElementStateMap(AcmUtils.createElementStateMap(acElements, AcTypeState.COMMISSIONED)); + acmDefinition.getElementStateMap() + .values().forEach(element -> element.setParticipantId(UUID.randomUUID())); + var participantId = UUID.randomUUID(); + var result = AcmUtils.prepareParticipantRestarting(participantId, acmDefinition, + AUTOMATION_COMPOSITION_ELEMENT); + assertThat(result).isEmpty(); + + participantId = acmDefinition.getElementStateMap().values().iterator().next().getParticipantId(); + result = AcmUtils.prepareParticipantRestarting(participantId, acmDefinition, + AUTOMATION_COMPOSITION_ELEMENT); + assertThat(result).hasSize(1); + } + + @Test void testRecursiveMergeMap() { var oldProperties = """ chart: diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/TimestampHelperTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/TimestampHelperTest.java index aaba0bcc8..d87b8bcd2 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/TimestampHelperTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/TimestampHelperTest.java @@ -30,7 +30,7 @@ class TimestampHelperTest { void testNow() { assertThat(TimestampHelper.nowTimestamp()).isNotNull(); assertThat(TimestampHelper.now()).isNotNull(); - assertThat(TimestampHelper.nowEpochMilli()).isNotNull(); + assertThat(TimestampHelper.nowEpochMilli()).isNotZero(); } @Test diff --git a/models/src/test/resources/examples/acm/test-pm-subscription-handling.yaml b/models/src/test/resources/examples/acm/test-pm-subscription-handling.yaml index 2b0b4feff..6539a9c75 100644 --- a/models/src/test/resources/examples/acm/test-pm-subscription-handling.yaml +++ b/models/src/test/resources/examples/acm/test-pm-subscription-handling.yaml @@ -317,6 +317,15 @@ node_types: provider: type: string required: false + stage: + type: array + required: false + items: + type: integer + constraints: + - greater-or-equal: 0 + metadata: + common: true startPhase: type: integer required: false @@ -394,6 +403,7 @@ topology_template: description: Participant for DCAE microservices properties: provider: ONAP + startPhase: 0 org.onap.policy.acm.PolicyAutomationCompositionParticipant: version: 2.3.1 type: org.onap.policy.clamp.acm.Participant @@ -401,6 +411,7 @@ topology_template: description: Participant for DCAE microservices properties: provider: ONAP + startPhase: 0 org.onap.ccsdk.cds.acm.CdsAutomationCompositionParticipant: version: 2.2.1 type: org.onap.policy.clamp.acm.Participant @@ -408,6 +419,7 @@ topology_template: description: Participant for DCAE microservices properties: provider: ONAP + startPhase: 1 org.onap.domain.pmsh.PMSH_DCAEMicroservice: version: 1.2.3 type: org.onap.policy.clamp.acm.DCAEMicroserviceAutomationCompositionElement @@ -415,6 +427,7 @@ topology_template: description: Automation composition element for the DCAE microservice for Performance Management Subscription Handling properties: provider: Ericsson + startPhase: 1 dcae_blueprint: tosca_definitions_version: cloudify_dsl_1_3 imports: @@ -641,6 +654,7 @@ topology_template: version: 1.0.0 policy_id: get_input: pmsh_monitoring_policy + stage: [0,1,2] org.onap.domain.pmsh.PMSH_OperationalPolicyAutomationCompositionElement: version: 1.2.3 type: org.onap.policy.clamp.acm.PolicyAutomationCompositionElement diff --git a/packages/policy-clamp-docker/pom.xml b/packages/policy-clamp-docker/pom.xml index 01fba5cd6..d2deb4bfc 100644 --- a/packages/policy-clamp-docker/pom.xml +++ b/packages/policy-clamp-docker/pom.xml @@ -26,7 +26,7 @@ <parent> <groupId>org.onap.policy.clamp</groupId> <artifactId>clamp-packages</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <packaging>pom</packaging> diff --git a/packages/policy-clamp-docker/src/main/docker/A1pmsParticipant.Dockerfile b/packages/policy-clamp-docker/src/main/docker/A1pmsParticipant.Dockerfile index 24de4135e..7bd8b2b00 100644 --- a/packages/policy-clamp-docker/src/main/docker/A1pmsParticipant.Dockerfile +++ b/packages/policy-clamp-docker/src/main/docker/A1pmsParticipant.Dockerfile @@ -23,7 +23,7 @@ RUN mkdir /packages /extracted COPY /maven/lib/a1pms-participant.tar.gz /packages/ RUN tar xvzf /packages/a1pms-participant.tar.gz --directory /extracted/ -FROM onap/policy-jre-alpine:4.0.0-SNAPSHOT +FROM onap/policy-jre-alpine:4.0.1-SNAPSHOT LABEL maintainer="Policy Team" LABEL org.opencontainers.image.title="Policy CLAMP ACM A1 PMS Participant" diff --git a/packages/policy-clamp-docker/src/main/docker/AcmRuntime.Dockerfile b/packages/policy-clamp-docker/src/main/docker/AcmRuntime.Dockerfile index accc1ff89..4cb4ad9ea 100644 --- a/packages/policy-clamp-docker/src/main/docker/AcmRuntime.Dockerfile +++ b/packages/policy-clamp-docker/src/main/docker/AcmRuntime.Dockerfile @@ -23,7 +23,7 @@ RUN mkdir /packages /extracted COPY /maven/lib/policy-clamp-runtime-acm.tar.gz /packages/ RUN tar xvzf /packages/policy-clamp-runtime-acm.tar.gz --directory /extracted/ -FROM onap/policy-jre-alpine:4.0.0-SNAPSHOT +FROM onap/policy-jre-alpine:4.0.1-SNAPSHOT LABEL maintainer="Policy Team" LABEL org.opencontainers.image.title="Policy CLAMP ACM runtime" diff --git a/packages/policy-clamp-docker/src/main/docker/ElementParticipant.Dockerfile b/packages/policy-clamp-docker/src/main/docker/ElementParticipant.Dockerfile index 6aa5448ea..6b32330b3 100644 --- a/packages/policy-clamp-docker/src/main/docker/ElementParticipant.Dockerfile +++ b/packages/policy-clamp-docker/src/main/docker/ElementParticipant.Dockerfile @@ -23,7 +23,7 @@ RUN mkdir /packages /extracted COPY /maven/lib/element-participant.tar.gz /packages RUN tar xvfz /packages/element-participant.tar.gz --directory /extracted/ -FROM onap/policy-jre-alpine:4.0.0-SNAPSHOT +FROM onap/policy-jre-alpine:4.0.1-SNAPSHOT LABEL maintainer="Policy Team" LABEL org.opencontainers.image.title="Policy CLAMP ACM Element" diff --git a/packages/policy-clamp-docker/src/main/docker/HttpParticipant.Dockerfile b/packages/policy-clamp-docker/src/main/docker/HttpParticipant.Dockerfile index e83321969..68e5ac955 100644 --- a/packages/policy-clamp-docker/src/main/docker/HttpParticipant.Dockerfile +++ b/packages/policy-clamp-docker/src/main/docker/HttpParticipant.Dockerfile @@ -23,7 +23,7 @@ RUN mkdir /packages /extracted COPY /maven/lib/http-participant.tar.gz /packages/ RUN tar xvzf /packages/http-participant.tar.gz --directory /extracted/ -FROM onap/policy-jre-alpine:4.0.0-SNAPSHOT +FROM onap/policy-jre-alpine:4.0.1-SNAPSHOT LABEL maintainer="Policy Team" LABEL org.opencontainers.image.title="Policy CLAMP ACM HTTP Participant" diff --git a/packages/policy-clamp-docker/src/main/docker/KserveParticipant.Dockerfile b/packages/policy-clamp-docker/src/main/docker/KserveParticipant.Dockerfile index eeb7938a6..a020d99df 100644 --- a/packages/policy-clamp-docker/src/main/docker/KserveParticipant.Dockerfile +++ b/packages/policy-clamp-docker/src/main/docker/KserveParticipant.Dockerfile @@ -23,7 +23,7 @@ RUN mkdir /packages /extracted COPY /maven/lib/kserve-participant.tar.gz /packages/ RUN tar xvzf /packages/kserve-participant.tar.gz --directory /extracted/ -FROM onap/policy-jre-alpine:4.0.0-SNAPSHOT +FROM onap/policy-jre-alpine:4.0.1-SNAPSHOT LABEL maintainer="Policy Team" LABEL org.opencontainers.image.title="Policy CLAMP ACM KSERVE Participant" diff --git a/packages/policy-clamp-docker/src/main/docker/KubernetesParticipant.Dockerfile b/packages/policy-clamp-docker/src/main/docker/KubernetesParticipant.Dockerfile index 3ea2e9ed6..0d5b721d6 100644 --- a/packages/policy-clamp-docker/src/main/docker/KubernetesParticipant.Dockerfile +++ b/packages/policy-clamp-docker/src/main/docker/KubernetesParticipant.Dockerfile @@ -23,7 +23,7 @@ RUN mkdir /packages /extracted COPY /maven/lib/kubernetes-participant.tar.gz /packages/ RUN tar xvzf /packages/kubernetes-participant.tar.gz --directory /extracted/ -FROM onap/policy-jre-alpine:4.0.0-SNAPSHOT +FROM onap/policy-jre-alpine:4.0.1-SNAPSHOT LABEL maintainer="Policy Team" LABEL org.opencontainers.image.title="Policy CLAMP ACM K8S Participant" diff --git a/packages/policy-clamp-docker/src/main/docker/PolicyParticipant.Dockerfile b/packages/policy-clamp-docker/src/main/docker/PolicyParticipant.Dockerfile index 60debf2cb..f19f44f51 100644 --- a/packages/policy-clamp-docker/src/main/docker/PolicyParticipant.Dockerfile +++ b/packages/policy-clamp-docker/src/main/docker/PolicyParticipant.Dockerfile @@ -23,7 +23,7 @@ RUN mkdir /packages /extracted COPY /maven/lib/policy-participant.tar.gz /packages/ RUN tar xvzf /packages/policy-participant.tar.gz --directory /extracted/ -FROM onap/policy-jre-alpine:4.0.0-SNAPSHOT +FROM onap/policy-jre-alpine:4.0.1-SNAPSHOT LABEL maintainer="Policy Team" LABEL org.opencontainers.image.title="Policy CLAMP ACM Policy Framework Participant" diff --git a/packages/policy-clamp-docker/src/main/docker/SimParticipant.Dockerfile b/packages/policy-clamp-docker/src/main/docker/SimParticipant.Dockerfile index 931c05669..3ee6e3192 100644 --- a/packages/policy-clamp-docker/src/main/docker/SimParticipant.Dockerfile +++ b/packages/policy-clamp-docker/src/main/docker/SimParticipant.Dockerfile @@ -23,7 +23,7 @@ RUN mkdir /packages /extracted COPY /maven/lib/sim-participant.tar.gz /packages/ RUN tar xvzf /packages/sim-participant.tar.gz --directory /extracted/ -FROM onap/policy-jre-alpine:4.0.0-SNAPSHOT +FROM onap/policy-jre-alpine:4.0.1-SNAPSHOT LABEL maintainer="Policy Team" LABEL org.opencontainers.image.title="Policy CLAMP ACM Simulator Participant" diff --git a/packages/policy-clamp-tarball/pom.xml b/packages/policy-clamp-tarball/pom.xml index 37dcd2dd4..a5d2ab908 100644 --- a/packages/policy-clamp-tarball/pom.xml +++ b/packages/policy-clamp-tarball/pom.xml @@ -24,7 +24,7 @@ <parent> <groupId>org.onap.policy.clamp</groupId> <artifactId>clamp-packages</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>policy-clamp-tarball</artifactId> diff --git a/packages/pom.xml b/packages/pom.xml index 583832eb5..e1e89e94e 100644 --- a/packages/pom.xml +++ b/packages/pom.xml @@ -23,7 +23,7 @@ <parent> <groupId>org.onap.policy.clamp</groupId> <artifactId>policy-clamp</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>clamp-packages</artifactId> diff --git a/participant/participant-impl/participant-impl-a1pms/pom.xml b/participant/participant-impl/participant-impl-a1pms/pom.xml index 189d201a6..f4a72e59c 100644 --- a/participant/participant-impl/participant-impl-a1pms/pom.xml +++ b/participant/participant-impl/participant-impl-a1pms/pom.xml @@ -25,7 +25,7 @@ <parent> <groupId>org.onap.policy.clamp.participant</groupId> <artifactId>policy-clamp-participant-impl</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>policy-clamp-participant-impl-a1pms</artifactId> diff --git a/participant/participant-impl/participant-impl-a1pms/src/main/java/org/onap/policy/clamp/acm/participant/a1pms/config/MicrometerConfig.java b/participant/participant-impl/participant-impl-a1pms/src/main/java/org/onap/policy/clamp/acm/participant/a1pms/config/MicrometerConfig.java index 5e3441d82..e599b7c43 100644 --- a/participant/participant-impl/participant-impl-a1pms/src/main/java/org/onap/policy/clamp/acm/participant/a1pms/config/MicrometerConfig.java +++ b/participant/participant-impl/participant-impl-a1pms/src/main/java/org/onap/policy/clamp/acm/participant/a1pms/config/MicrometerConfig.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -23,6 +23,7 @@ package org.onap.policy.clamp.acm.participant.a1pms.config; import io.micrometer.core.aop.TimedAspect; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,8 +35,9 @@ public class MicrometerConfig { * Load up the metrics registry. */ @Bean - public InitializingBean forcePrometheusPostProcessor(BeanPostProcessor meterRegistryPostProcessor, - MeterRegistry registry) { + public InitializingBean forcePrometheusPostProcessor(@Qualifier("meterRegistryPostProcessor") + BeanPostProcessor meterRegistryPostProcessor, + MeterRegistry registry) { return () -> meterRegistryPostProcessor.postProcessAfterInitialization(registry, ""); } diff --git a/participant/participant-impl/participant-impl-acelement/pom.xml b/participant/participant-impl/participant-impl-acelement/pom.xml index 4bea98171..d428c45c0 100644 --- a/participant/participant-impl/participant-impl-acelement/pom.xml +++ b/participant/participant-impl/participant-impl-acelement/pom.xml @@ -26,7 +26,7 @@ <parent> <groupId>org.onap.policy.clamp.participant</groupId> <artifactId>policy-clamp-participant-impl</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>policy-clamp-acm-element-impl</artifactId> @@ -67,7 +67,7 @@ <generateModels>false</generateModels> <generateSupportingFiles>false</generateSupportingFiles> <importMappings> - ElementConfig=org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig + ElementConfig=org.onap.policy.clamp.acm.element.main.concepts.ElementConfig </importMappings> <configOptions> <sourceFolder>src/gen/java</sourceFolder> diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/config/MicrometerConfig.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/config/MicrometerConfig.java index d34b34add..5621587a2 100644 --- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/config/MicrometerConfig.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/config/MicrometerConfig.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -23,6 +23,7 @@ package org.onap.policy.clamp.acm.element.config; import io.micrometer.core.aop.TimedAspect; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,8 +35,9 @@ public class MicrometerConfig { * Load up the metrics registry. */ @Bean - public InitializingBean forcePrometheusPostProcessor(BeanPostProcessor meterRegistryPostProcessor, - MeterRegistry registry) { + public InitializingBean forcePrometheusPostProcessor(@Qualifier("meterRegistryPostProcessor") + BeanPostProcessor meterRegistryPostProcessor, + MeterRegistry registry) { return () -> meterRegistryPostProcessor.postProcessAfterInitialization(registry, ""); } diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageActivator.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageActivator.java index b3ba26223..61f05db51 100644 --- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageActivator.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageActivator.java @@ -22,7 +22,7 @@ package org.onap.policy.clamp.acm.element.handler; import java.io.IOException; import java.util.List; -import org.onap.policy.clamp.models.acm.messages.kafka.element.ElementMessageType; +import org.onap.policy.clamp.acm.element.handler.messages.ElementMessageType; import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager; import org.onap.policy.common.endpoints.event.comm.TopicSource; import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher; diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageHandler.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageHandler.java index bbafa071a..12d14c7f2 100644 --- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageHandler.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageHandler.java @@ -26,12 +26,12 @@ import java.util.EnumMap; import java.util.List; import java.util.Map; import lombok.NonNull; +import org.onap.policy.clamp.acm.element.handler.messages.ElementMessage; +import org.onap.policy.clamp.acm.element.main.concepts.ElementConfig; +import org.onap.policy.clamp.acm.element.main.concepts.ElementType; import org.onap.policy.clamp.acm.element.main.parameters.AcElement; import org.onap.policy.clamp.acm.element.service.ElementService; import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException; -import org.onap.policy.clamp.models.acm.messages.kafka.element.ElementMessage; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementType; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.springframework.stereotype.Component; diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageListener.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageListener.java index 5e3dfa4e1..162d9bc8e 100644 --- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageListener.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageListener.java @@ -20,7 +20,7 @@ package org.onap.policy.clamp.acm.element.handler; -import org.onap.policy.clamp.models.acm.messages.kafka.element.ElementStatus; +import org.onap.policy.clamp.acm.element.handler.messages.ElementStatus; import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; import org.onap.policy.common.endpoints.listeners.ScoListener; import org.onap.policy.common.utils.coder.StandardCoderObject; diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessagePublisher.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessagePublisher.java index bd53cec0f..ab733d777 100644 --- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessagePublisher.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessagePublisher.java @@ -23,8 +23,8 @@ package org.onap.policy.clamp.acm.element.handler; import io.micrometer.core.annotation.Timed; import jakarta.ws.rs.core.Response; import java.util.List; +import org.onap.policy.clamp.acm.element.handler.messages.ElementMessage; import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException; -import org.onap.policy.clamp.models.acm.messages.kafka.element.ElementMessage; import org.onap.policy.common.endpoints.event.comm.TopicSink; import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; import org.slf4j.Logger; diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/element/ElementMessage.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/messages/ElementMessage.java index 13a1b735b..0b6da78dd 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/element/ElementMessage.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/messages/ElementMessage.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.clamp.models.acm.messages.kafka.element; +package org.onap.policy.clamp.acm.element.handler.messages; import java.time.Instant; import java.util.UUID; diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/element/ElementMessageType.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/messages/ElementMessageType.java index cb2eaae95..31c8d5c2c 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/element/ElementMessageType.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/messages/ElementMessageType.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.clamp.models.acm.messages.kafka.element; +package org.onap.policy.clamp.acm.element.handler.messages; public enum ElementMessageType { STATUS, ACK_MSG diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/element/ElementStatus.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/messages/ElementStatus.java index 497dca408..b8f03eb95 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/kafka/element/ElementStatus.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/messages/ElementStatus.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.clamp.models.acm.messages.kafka.element; +package org.onap.policy.clamp.acm.element.handler.messages; import lombok.Getter; import lombok.Setter; diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/element/ElementConfig.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/concepts/ElementConfig.java index bb3670cb7..31a1ef6c1 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/element/ElementConfig.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/concepts/ElementConfig.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.clamp.models.acm.messages.rest.element; +package org.onap.policy.clamp.acm.element.main.concepts; import lombok.Data; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/element/ElementType.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/concepts/ElementType.java index 4bc08a36e..3a24bfbdc 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/element/ElementType.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/concepts/ElementType.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.clamp.models.acm.messages.rest.element; +package org.onap.policy.clamp.acm.element.main.concepts; public enum ElementType { diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/element/KafkaConfig.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/concepts/KafkaConfig.java index 35871fcbf..0da934f1c 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/element/KafkaConfig.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/concepts/KafkaConfig.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.clamp.models.acm.messages.rest.element; +package org.onap.policy.clamp.acm.element.main.concepts; import lombok.Data; diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/parameters/ElementTopicParameters.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/parameters/ElementTopicParameters.java index ba9fcf327..3e16d6352 100644 --- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/parameters/ElementTopicParameters.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/parameters/ElementTopicParameters.java @@ -23,7 +23,7 @@ package org.onap.policy.clamp.acm.element.main.parameters; import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; -import org.onap.policy.clamp.models.acm.messages.rest.element.KafkaConfig; +import org.onap.policy.clamp.acm.element.main.concepts.KafkaConfig; import org.onap.policy.common.endpoints.parameters.TopicParameters; @Data diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/AcElementController.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/AcElementController.java index 021567a7b..bc4bbe86f 100644 --- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/AcElementController.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/AcElementController.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -22,9 +22,9 @@ package org.onap.policy.clamp.acm.element.main.rest; import java.util.UUID; import lombok.RequiredArgsConstructor; +import org.onap.policy.clamp.acm.element.main.concepts.ElementConfig; import org.onap.policy.clamp.acm.element.main.rest.genapi.AcElementControllerApi; import org.onap.policy.clamp.acm.element.service.ConfigService; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RestController; diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/AbstractElementService.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/AbstractElementService.java index 04449252b..f8c8a2936 100644 --- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/AbstractElementService.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/AbstractElementService.java @@ -20,8 +20,8 @@ package org.onap.policy.clamp.acm.element.service; -import org.onap.policy.clamp.models.acm.messages.kafka.element.ElementMessage; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig; +import org.onap.policy.clamp.acm.element.handler.messages.ElementMessage; +import org.onap.policy.clamp.acm.element.main.concepts.ElementConfig; public abstract class AbstractElementService implements ElementService { diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/BridgeService.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/BridgeService.java index e21a5cc99..68cfcefee 100644 --- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/BridgeService.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/BridgeService.java @@ -21,11 +21,11 @@ package org.onap.policy.clamp.acm.element.service; import org.onap.policy.clamp.acm.element.handler.MessagePublisher; +import org.onap.policy.clamp.acm.element.handler.messages.ElementMessage; +import org.onap.policy.clamp.acm.element.handler.messages.ElementStatus; +import org.onap.policy.clamp.acm.element.main.concepts.ElementConfig; +import org.onap.policy.clamp.acm.element.main.concepts.ElementType; import org.onap.policy.clamp.acm.element.main.parameters.AcElement; -import org.onap.policy.clamp.models.acm.messages.kafka.element.ElementMessage; -import org.onap.policy.clamp.models.acm.messages.kafka.element.ElementStatus; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementType; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.springframework.stereotype.Service; diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/ConfigService.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/ConfigService.java index b3f662c86..947566685 100644 --- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/ConfigService.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/ConfigService.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -22,13 +22,14 @@ package org.onap.policy.clamp.acm.element.service; import jakarta.ws.rs.core.Response; import java.util.List; +import lombok.Getter; import lombok.NonNull; import lombok.RequiredArgsConstructor; import org.onap.policy.clamp.acm.element.handler.MessageActivator; import org.onap.policy.clamp.acm.element.handler.MessageHandler; +import org.onap.policy.clamp.acm.element.main.concepts.ElementConfig; import org.onap.policy.clamp.acm.element.main.parameters.ElementTopicParameters; import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig; import org.onap.policy.common.endpoints.parameters.TopicParameterGroup; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,6 +41,7 @@ public class ConfigService { private static final Logger LOGGER = LoggerFactory.getLogger(ConfigService.class); + @Getter private ElementConfig elementConfig = new ElementConfig(); private final MessageHandler handler; @@ -78,15 +80,6 @@ public class ConfigService { } /** - * Fetch element configuration. - * - * @return element configuration present - */ - public ElementConfig getElementConfig() { - return elementConfig; - } - - /** * Deactivate messages and service and delete the element config. */ public void deleteConfig() { diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/ElementService.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/ElementService.java index 425def915..0768e0ad8 100644 --- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/ElementService.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/ElementService.java @@ -20,9 +20,9 @@ package org.onap.policy.clamp.acm.element.service; -import org.onap.policy.clamp.models.acm.messages.kafka.element.ElementMessage; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementType; +import org.onap.policy.clamp.acm.element.handler.messages.ElementMessage; +import org.onap.policy.clamp.acm.element.main.concepts.ElementConfig; +import org.onap.policy.clamp.acm.element.main.concepts.ElementType; public interface ElementService { diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/SinkService.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/SinkService.java index 3f28f461e..d8fc38ec0 100644 --- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/SinkService.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/SinkService.java @@ -20,8 +20,8 @@ package org.onap.policy.clamp.acm.element.service; -import org.onap.policy.clamp.models.acm.messages.kafka.element.ElementMessage; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementType; +import org.onap.policy.clamp.acm.element.handler.messages.ElementMessage; +import org.onap.policy.clamp.acm.element.main.concepts.ElementType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/StarterService.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/StarterService.java index cb1a6ac51..8cf878e03 100644 --- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/StarterService.java +++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/StarterService.java @@ -25,10 +25,10 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.onap.policy.clamp.acm.element.handler.MessagePublisher; +import org.onap.policy.clamp.acm.element.handler.messages.ElementStatus; +import org.onap.policy.clamp.acm.element.main.concepts.ElementConfig; +import org.onap.policy.clamp.acm.element.main.concepts.ElementType; import org.onap.policy.clamp.acm.element.main.parameters.AcElement; -import org.onap.policy.clamp.models.acm.messages.kafka.element.ElementStatus; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementType; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.springframework.stereotype.Service; diff --git a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/handler/MessageHandlerTest.java b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/handler/MessageHandlerTest.java index 1b0fe60d9..5aaeb23e6 100644 --- a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/handler/MessageHandlerTest.java +++ b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/handler/MessageHandlerTest.java @@ -28,12 +28,12 @@ import static org.mockito.Mockito.when; import java.util.List; import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.acm.element.handler.messages.ElementStatus; +import org.onap.policy.clamp.acm.element.main.concepts.ElementConfig; +import org.onap.policy.clamp.acm.element.main.concepts.ElementType; import org.onap.policy.clamp.acm.element.main.parameters.AcElement; import org.onap.policy.clamp.acm.element.service.ElementService; import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException; -import org.onap.policy.clamp.models.acm.messages.kafka.element.ElementStatus; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementType; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; class MessageHandlerTest { @@ -57,7 +57,12 @@ class MessageHandlerTest { var bridge = createMockElementService(ElementType.BRIDGE); var messageHandler = createMessageHandler(List.of(starter, bridge)); - assertThatThrownBy(() -> messageHandler.getActiveService()) + assertThatThrownBy(() -> messageHandler.active(null)) + .isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> messageHandler.update(null)) + .isInstanceOf(NullPointerException.class); + + assertThatThrownBy(messageHandler::getActiveService) .isInstanceOf(AutomationCompositionRuntimeException.class); var elementConfig = new ElementConfig(); diff --git a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/handler/MessagePublisherTest.java b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/handler/MessagePublisherTest.java new file mode 100644 index 000000000..f3cc885b9 --- /dev/null +++ b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/handler/MessagePublisherTest.java @@ -0,0 +1,54 @@ +/*- + * ============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.acm.element.handler; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.util.List; +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.acm.element.handler.messages.ElementMessage; +import org.onap.policy.clamp.acm.element.handler.messages.ElementMessageType; +import org.onap.policy.common.endpoints.event.comm.TopicSink; + + +class MessagePublisherTest { + + @Test + void testActiveEmpty() { + var messagePublisher = new MessagePublisher(); + var list = List.<TopicSink>of(); + assertThatThrownBy(() -> messagePublisher.active(list)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testPublishMsg() { + var topic = mock(TopicSink.class); + var messagePublisher = new MessagePublisher(); + messagePublisher.active(List.of(topic)); + messagePublisher.publishMsg(new ElementMessage(ElementMessageType.STATUS)); + messagePublisher.stop(); + verify(topic).send(any()); + } +} diff --git a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/rest/AcElementControllerTest.java b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/rest/AcElementControllerTest.java index a2ed1ca34..a5e8e2c3d 100644 --- a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/rest/AcElementControllerTest.java +++ b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/rest/AcElementControllerTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022-2023 Nordix Foundation. + * Copyright (C) 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. @@ -40,11 +40,11 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.onap.policy.clamp.acm.element.main.concepts.ElementConfig; import org.onap.policy.clamp.acm.element.main.parameters.AcElement; import org.onap.policy.clamp.acm.element.main.rest.AcElementController; import org.onap.policy.clamp.acm.element.service.ConfigService; import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; diff --git a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/rest/ActuatorControllerTest.java b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/rest/ActuatorControllerTest.java index 5ccee7b31..453ccc916 100644 --- a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/rest/ActuatorControllerTest.java +++ b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/rest/ActuatorControllerTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022-2023 Nordix Foundation. + * Copyright (C) 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. @@ -45,6 +45,8 @@ class ActuatorControllerTest extends CommonActuatorController { private static final String PROMETHEUS_ENDPOINT = "onap/policy/clamp/acelement/v2/prometheus"; private static final String SWAGGER_ENDPOINT = "onap/policy/clamp/acelement/v2/v3/api-docs"; + private static final String WRONG_ENDPOINT = "onap/policy/clamp/acelement/v2/wrong"; + @LocalServerPort private int randomServerPort; @@ -76,28 +78,40 @@ class ActuatorControllerTest extends CommonActuatorController { @Test void testGetHealth() { var invocationBuilder = super.sendActRequest(HEALTH_ENDPOINT); - var rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + try (var rawresp = invocationBuilder.buildGet().invoke()) { + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } } @Test void testGetMetrics() { var invocationBuilder = super.sendActRequest(METRICS_ENDPOINT); - var rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + try (var rawresp = invocationBuilder.buildGet().invoke()) { + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } } @Test void testGetPrometheus() { var invocationBuilder = super.sendActRequest(PROMETHEUS_ENDPOINT); - var rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + try (var rawresp = invocationBuilder.buildGet().invoke()) { + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } } @Test void testGetSwagger() { var invocationBuilder = super.sendActRequest(SWAGGER_ENDPOINT); - var rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + try (var rawresp = invocationBuilder.buildGet().invoke()) { + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } + } + + @Test + void testWrongEndPoint() { + var invocationBuilder = super.sendActRequest(WRONG_ENDPOINT); + try (var rawresp = invocationBuilder.buildGet().invoke()) { + assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawresp.getStatus()); + } } } diff --git a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/BridgeServiceTest.java b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/BridgeServiceTest.java index 386e9e74d..1eac5cba4 100644 --- a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/BridgeServiceTest.java +++ b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/BridgeServiceTest.java @@ -22,23 +22,34 @@ package org.onap.policy.clamp.acm.element.service; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.element.handler.MessagePublisher; +import org.onap.policy.clamp.acm.element.handler.messages.ElementMessage; +import org.onap.policy.clamp.acm.element.handler.messages.ElementStatus; +import org.onap.policy.clamp.acm.element.main.concepts.ElementConfig; +import org.onap.policy.clamp.acm.element.main.concepts.ElementType; import org.onap.policy.clamp.acm.element.main.parameters.AcElement; import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException; -import org.onap.policy.clamp.models.acm.messages.kafka.element.ElementMessage; -import org.onap.policy.clamp.models.acm.messages.kafka.element.ElementStatus; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementType; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; class BridgeServiceTest { @Test + void testNotThrow() { + var acElement = new AcElement(); + acElement.setElementId(new ToscaConceptIdentifier("onap.policy.clamp.ac.element1", "1.0.0")); + var bridgeService = new BridgeService(mock(MessagePublisher.class), acElement); + assertDoesNotThrow(bridgeService::deactivate); + var elementConfig = new ElementConfig(); + assertDoesNotThrow(() -> bridgeService.update(elementConfig)); + } + + @Test void testHandleMessage() { var acElement = new AcElement(); acElement.setElementId(new ToscaConceptIdentifier("onap.policy.clamp.ac.element1", "1.0.0")); diff --git a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/ConfigServiceTest.java b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/ConfigServiceTest.java index 086676fd4..57db855c8 100644 --- a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/ConfigServiceTest.java +++ b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/ConfigServiceTest.java @@ -28,8 +28,8 @@ import static org.mockito.Mockito.verify; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.element.handler.MessageActivator; import org.onap.policy.clamp.acm.element.handler.MessageHandler; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig; -import org.onap.policy.clamp.models.acm.messages.rest.element.KafkaConfig; +import org.onap.policy.clamp.acm.element.main.concepts.ElementConfig; +import org.onap.policy.clamp.acm.element.main.concepts.KafkaConfig; import org.onap.policy.common.endpoints.parameters.TopicParameterGroup; class ConfigServiceTest { diff --git a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/SinkServiceTest.java b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/SinkServiceTest.java new file mode 100644 index 000000000..03710b988 --- /dev/null +++ b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/SinkServiceTest.java @@ -0,0 +1,44 @@ +/*- + * ============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.acm.element.service; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.acm.element.handler.messages.ElementMessage; +import org.onap.policy.clamp.acm.element.handler.messages.ElementMessageType; +import org.onap.policy.clamp.acm.element.main.concepts.ElementConfig; +import org.onap.policy.clamp.acm.element.main.parameters.AcElement; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +class SinkServiceTest { + + @Test + void testNotThrow() { + var acElement = new AcElement(); + acElement.setElementId(new ToscaConceptIdentifier("onap.policy.clamp.ac.element1", "1.0.0")); + var sinkService = new SinkService(); + var elementConfig = new ElementConfig(); + assertDoesNotThrow(() -> sinkService.active(elementConfig)); + var message = new ElementMessage(ElementMessageType.STATUS); + assertDoesNotThrow(() -> sinkService.handleMessage(message)); + } +} diff --git a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/StarterServiceTest.java b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/StarterServiceTest.java index 71bb4c6b6..2e1341bb9 100644 --- a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/StarterServiceTest.java +++ b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/service/StarterServiceTest.java @@ -29,10 +29,10 @@ import static org.mockito.Mockito.verify; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.element.handler.MessagePublisher; +import org.onap.policy.clamp.acm.element.handler.messages.ElementMessage; +import org.onap.policy.clamp.acm.element.main.concepts.ElementConfig; +import org.onap.policy.clamp.acm.element.main.concepts.ElementType; import org.onap.policy.clamp.acm.element.main.parameters.AcElement; -import org.onap.policy.clamp.models.acm.messages.kafka.element.ElementMessage; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig; -import org.onap.policy.clamp.models.acm.messages.rest.element.ElementType; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; diff --git a/participant/participant-impl/participant-impl-cds/pom.xml b/participant/participant-impl/participant-impl-cds/pom.xml index 38ed06919..86d9ee6d2 100644 --- a/participant/participant-impl/participant-impl-cds/pom.xml +++ b/participant/participant-impl/participant-impl-cds/pom.xml @@ -25,7 +25,7 @@ <parent> <groupId>org.onap.policy.clamp.participant</groupId> <artifactId>policy-clamp-participant-impl</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>policy-clamp-participant-impl-cds</artifactId> diff --git a/participant/participant-impl/participant-impl-http/pom.xml b/participant/participant-impl/participant-impl-http/pom.xml index 5d9d7a0df..0f094db47 100644 --- a/participant/participant-impl/participant-impl-http/pom.xml +++ b/participant/participant-impl/participant-impl-http/pom.xml @@ -25,7 +25,7 @@ <parent> <groupId>org.onap.policy.clamp.participant</groupId> <artifactId>policy-clamp-participant-impl</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>policy-clamp-participant-impl-http</artifactId> diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/config/MicrometerConfig.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/config/MicrometerConfig.java index 06cecc6f5..ec9c95a19 100644 --- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/config/MicrometerConfig.java +++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/config/MicrometerConfig.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -23,6 +23,7 @@ package org.onap.policy.clamp.acm.participant.http.config; import io.micrometer.core.aop.TimedAspect; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,8 +35,9 @@ public class MicrometerConfig { * Load up the metrics registry. */ @Bean - public InitializingBean forcePrometheusPostProcessor(BeanPostProcessor meterRegistryPostProcessor, - MeterRegistry registry) { + public InitializingBean forcePrometheusPostProcessor(@Qualifier("meterRegistryPostProcessor") + BeanPostProcessor meterRegistryPostProcessor, + MeterRegistry registry) { return () -> meterRegistryPostProcessor.postProcessAfterInitialization(registry, ""); } diff --git a/participant/participant-impl/participant-impl-kserve/pom.xml b/participant/participant-impl/participant-impl-kserve/pom.xml index 2f6272b52..05cc2dcd2 100644 --- a/participant/participant-impl/participant-impl-kserve/pom.xml +++ b/participant/participant-impl/participant-impl-kserve/pom.xml @@ -25,7 +25,7 @@ <parent> <groupId>org.onap.policy.clamp.participant</groupId> <artifactId>policy-clamp-participant-impl</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>policy-clamp-participant-impl-kserve</artifactId> @@ -52,7 +52,7 @@ <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> - <version>2022.0.5</version> + <version>2023.0.3</version> <type>pom</type> <scope>import</scope> </dependency> diff --git a/participant/participant-impl/participant-impl-kserve/src/main/java/org/onap/policy/clamp/acm/participant/kserve/config/MicrometerConfig.java b/participant/participant-impl/participant-impl-kserve/src/main/java/org/onap/policy/clamp/acm/participant/kserve/config/MicrometerConfig.java index 92dc5d3d6..1192f7703 100644 --- a/participant/participant-impl/participant-impl-kserve/src/main/java/org/onap/policy/clamp/acm/participant/kserve/config/MicrometerConfig.java +++ b/participant/participant-impl/participant-impl-kserve/src/main/java/org/onap/policy/clamp/acm/participant/kserve/config/MicrometerConfig.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation. + * Copyright (C) 2023-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. @@ -23,6 +23,7 @@ package org.onap.policy.clamp.acm.participant.kserve.config; import io.micrometer.core.aop.TimedAspect; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,8 +35,9 @@ public class MicrometerConfig { * Load up the metrics registry. */ @Bean - public InitializingBean forcePrometheusPostProcessor(BeanPostProcessor meterRegistryPostProcessor, - MeterRegistry registry) { + public InitializingBean forcePrometheusPostProcessor(@Qualifier("meterRegistryPostProcessor") + BeanPostProcessor meterRegistryPostProcessor, + MeterRegistry registry) { return () -> meterRegistryPostProcessor.postProcessAfterInitialization(registry, ""); } diff --git a/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/handler/AcElementHandlerTest.java b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/handler/AcElementHandlerTest.java index ccdb31f82..919562acb 100644 --- a/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/handler/AcElementHandlerTest.java +++ b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/handler/AcElementHandlerTest.java @@ -42,7 +42,6 @@ import org.onap.policy.clamp.acm.participant.kserve.exception.KserveException; import org.onap.policy.clamp.acm.participant.kserve.k8s.KserveClient; import org.onap.policy.clamp.acm.participant.kserve.utils.CommonTestData; import org.onap.policy.clamp.acm.participant.kserve.utils.ToscaUtils; -import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; class AcElementHandlerTest { diff --git a/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/k8s/InferenceServiceValidatorTest.java b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/k8s/InferenceServiceValidatorTest.java index 5bf7bf13b..70285f778 100644 --- a/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/k8s/InferenceServiceValidatorTest.java +++ b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/k8s/InferenceServiceValidatorTest.java @@ -36,15 +36,15 @@ class InferenceServiceValidatorTest { private static final int TIMEOUT = 2; private static final int STATUS_CHECK_INTERVAL = 1; - private static final String inferenceSvcName = "inference-test"; - private static final String namespace = "test"; + private static final String INFERENCE_SVC_NAME = "inference-test"; + private static final String NAMESPACE = "test"; @Test void test_runningPodState() throws IOException, ApiException { var kserveClient = mock(KserveClient.class); doReturn("True").when(kserveClient).getInferenceServiceStatus(any(), any()); var inferenceServiceValidator = - new InferenceServiceValidator(inferenceSvcName, namespace, TIMEOUT, STATUS_CHECK_INTERVAL, + new InferenceServiceValidator(INFERENCE_SVC_NAME, NAMESPACE, TIMEOUT, STATUS_CHECK_INTERVAL, kserveClient); assertDoesNotThrow(inferenceServiceValidator::run); } @@ -54,7 +54,7 @@ class InferenceServiceValidatorTest { var kserveClient = mock(KserveClient.class); doReturn("").when(kserveClient).getInferenceServiceStatus(any(), any()); var inferenceServiceValidator = - new InferenceServiceValidator("", namespace, TIMEOUT, STATUS_CHECK_INTERVAL, + new InferenceServiceValidator("", NAMESPACE, TIMEOUT, STATUS_CHECK_INTERVAL, kserveClient); assertThatThrownBy(inferenceServiceValidator::run).isInstanceOf(KserveException.class) .cause().hasMessage("Kserve setup is unavailable for inference service to be deployed"); @@ -65,7 +65,7 @@ class InferenceServiceValidatorTest { var kserveClient = mock(KserveClient.class); doReturn("False").when(kserveClient).getInferenceServiceStatus(any(), any()); var inferenceServiceValidator = - new InferenceServiceValidator(inferenceSvcName, namespace, TIMEOUT, STATUS_CHECK_INTERVAL, + new InferenceServiceValidator(INFERENCE_SVC_NAME, NAMESPACE, TIMEOUT, STATUS_CHECK_INTERVAL, kserveClient); assertThatThrownBy(inferenceServiceValidator::run).isInstanceOf(KserveException.class) .hasMessage("Error verifying the status of the inference service. Exiting"); diff --git a/participant/participant-impl/participant-impl-kubernetes/pom.xml b/participant/participant-impl/participant-impl-kubernetes/pom.xml index 1fe1c1bc5..fff3bd130 100644 --- a/participant/participant-impl/participant-impl-kubernetes/pom.xml +++ b/participant/participant-impl/participant-impl-kubernetes/pom.xml @@ -25,7 +25,7 @@ <parent> <groupId>org.onap.policy.clamp.participant</groupId> <artifactId>policy-clamp-participant-impl</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>policy-clamp-participant-impl-kubernetes</artifactId> diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/MicrometerConfig.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/MicrometerConfig.java index 0532dc97d..b4afe5e89 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/MicrometerConfig.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/MicrometerConfig.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -23,6 +23,7 @@ package org.onap.policy.clamp.acm.participant.kubernetes.configurations; import io.micrometer.core.aop.TimedAspect; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,8 +35,9 @@ public class MicrometerConfig { * Load up the metrics registry. */ @Bean - public InitializingBean forcePrometheusPostProcessor(BeanPostProcessor meterRegistryPostProcessor, - MeterRegistry registry) { + public InitializingBean forcePrometheusPostProcessor(@Qualifier("meterRegistryPostProcessor") + BeanPostProcessor meterRegistryPostProcessor, + MeterRegistry registry) { return () -> meterRegistryPostProcessor.postProcessAfterInitialization(registry, ""); } diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java index 1c40c7281..b93085e91 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java @@ -24,20 +24,16 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; import java.io.IOException; import java.lang.invoke.MethodHandles; -import java.util.HashMap; import java.util.Map; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import lombok.AccessLevel; -import lombok.Getter; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.acm.participant.intermediary.api.impl.AcElementListenerV1; +import org.onap.policy.clamp.acm.participant.intermediary.api.impl.AcElementListenerV2; import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; import org.onap.policy.clamp.acm.participant.kubernetes.helm.PodStatusValidator; import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; import org.onap.policy.clamp.acm.participant.kubernetes.service.ChartService; -import org.onap.policy.clamp.common.acm.exception.AutomationCompositionException; -import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; import org.onap.policy.clamp.models.acm.concepts.DeployState; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.common.utils.coder.Coder; @@ -53,25 +49,19 @@ import org.springframework.stereotype.Component; * This class handles implementation of automationCompositionElement updates. */ @Component -public class AutomationCompositionElementHandler extends AcElementListenerV1 { +public class AutomationCompositionElementHandler extends AcElementListenerV2 { private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - // Map of helm installation and the status of corresponding pods - @Getter - private static Map<String, Map<String, String>> podStatusMap = new ConcurrentHashMap<>(); private static final Coder CODER = new StandardCoder(); - @Autowired - private ChartService chartService; + private final ChartService chartService; - // Map of acElement Id and installed Helm charts - @Getter(AccessLevel.PACKAGE) - private final Map<UUID, ChartInfo> chartMap = new HashMap<>(); - - public AutomationCompositionElementHandler(ParticipantIntermediaryApi intermediaryApi) { + public AutomationCompositionElementHandler(ParticipantIntermediaryApi intermediaryApi, ChartService chartService) { super(intermediaryApi); + this.chartService = chartService; } + // Default thread config values private static class ThreadConfig { private int uninitializedToPassiveTimeout = 60; @@ -79,97 +69,99 @@ public class AutomationCompositionElementHandler extends AcElementListenerV1 { } /** - * Callback method to handle a automation composition element state change. + * Handle an undeploy on a automation composition element. * - * @param automationCompositionElementId the ID of the automation composition element + * @param compositionElement the information of the Automation Composition Definition Element + * @param instanceElement the information of the Automation Composition Instance Element + * @throws PfModelException in case of a model exception */ @Override - public synchronized void undeploy(UUID automationCompositionId, UUID automationCompositionElementId) { - var chart = chartMap.get(automationCompositionElementId); + public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) + throws PfModelException { + + var chart = getChartInfo(instanceElement.inProperties()); if (chart != null) { LOGGER.info("Helm deployment to be deleted {} ", chart.getReleaseName()); try { chartService.uninstallChart(chart); - intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, - automationCompositionElementId, DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, + intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed"); - chartMap.remove(automationCompositionElementId); - podStatusMap.remove(chart.getReleaseName()); + instanceElement.outProperties().remove(chart.getReleaseName()); + intermediaryApi.sendAcElementInfo(instanceElement.instanceId(), instanceElement.elementId(), + null, null, instanceElement.outProperties()); } catch (ServiceException se) { - LOGGER.warn("Deletion of Helm deployment failed", se); + throw new PfModelException(Status.EXPECTATION_FAILED, "Deletion of Helm deployment failed", se); } } + } /** - * Callback method to handle an update on a automation composition element. + * Handle a deploy on a automation composition element. * - * @param automationCompositionId the automationComposition Id - * @param element the information on the automation composition element - * @param properties properties Map - * @throws PfModelException in case of an exception + * @param compositionElement the information of the Automation Composition Definition Element + * @param instanceElement the information of the Automation Composition Instance Element + * @throws PfModelException from Policy framework */ @Override - public synchronized void deploy(UUID automationCompositionId, AcElementDeploy element, - Map<String, Object> properties) throws PfModelException { - + public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) + throws PfModelException { try { - var chartInfo = getChartInfo(properties); + var chartInfo = getChartInfo(instanceElement.inProperties()); if (chartService.installChart(chartInfo)) { - chartMap.put(element.getId(), chartInfo); - - var config = getThreadConfig(properties); - checkPodStatus(automationCompositionId, element.getId(), chartInfo, - config.uninitializedToPassiveTimeout, config.podStatusCheckInterval); + var config = getThreadConfig(compositionElement.inProperties()); + checkPodStatus(instanceElement.instanceId(), instanceElement.elementId(), chartInfo, + config.uninitializedToPassiveTimeout, config.podStatusCheckInterval, instanceElement); } else { - intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(), - DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Chart not installed"); + throw new PfModelException(Response.Status.BAD_REQUEST, "Installation of Helm chart failed "); } - } catch (ServiceException | IOException e) { - throw new PfModelException(Response.Status.BAD_REQUEST, "Installation of Helm chart failed ", e); - } catch (InterruptedException e) { + } catch (ServiceException | IOException | InterruptedException e) { Thread.currentThread().interrupt(); - throw new PfModelException(Response.Status.BAD_REQUEST, "Error invoking ExecutorService ", e); - } catch (AutomationCompositionException e) { - intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(), - DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, e.getMessage()); + throw new PfModelException(Response.Status.BAD_REQUEST, "Installation of Helm chart failed ", e); } + } - private ThreadConfig getThreadConfig(Map<String, Object> properties) throws AutomationCompositionException { + private ThreadConfig getThreadConfig(Map<String, Object> properties) throws PfModelException { try { return CODER.convert(properties, ThreadConfig.class); } catch (CoderException e) { - throw new AutomationCompositionException(Status.BAD_REQUEST, "Error extracting ThreadConfig ", e); + throw new PfModelException(Status.BAD_REQUEST, "Error extracting ThreadConfig ", e); } } - private ChartInfo getChartInfo(Map<String, Object> properties) throws AutomationCompositionException { + private ChartInfo getChartInfo(Map<String, Object> properties) throws PfModelException { @SuppressWarnings("unchecked") var chartData = (Map<String, Object>) properties.get("chart"); - LOGGER.info("Installation request received for the Helm Chart {} ", chartData); try { return CODER.convert(chartData, ChartInfo.class); } catch (CoderException e) { - throw new AutomationCompositionException(Status.BAD_REQUEST, "Error extracting ChartInfo ", e); + throw new PfModelException(Status.BAD_REQUEST, "Error extracting ChartInfo", e); } + } /** * Invoke a new thread to check the status of deployed pods. * * @param chart ChartInfo - * @throws ServiceException in case of an exception + * @throws PfModelException in case of an exception */ public void checkPodStatus(UUID automationCompositionId, UUID elementId, ChartInfo chart, int timeout, - int podStatusCheckInterval) throws InterruptedException, ServiceException { + int podStatusCheckInterval, InstanceElementDto instanceElement) throws InterruptedException, + PfModelException { var result = new PodStatusValidator(chart, timeout, podStatusCheckInterval); result.run(); LOGGER.info("Pod Status Validator Completed"); intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, elementId, DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed"); + instanceElement.outProperties().put(chart.getReleaseName(), "Running"); + + intermediaryApi.sendAcElementInfo(automationCompositionId, elementId, null, null, + instanceElement.outProperties()); } } diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidator.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidator.java index 6c9656b78..3eba9427d 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidator.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidator.java @@ -1,6 +1,6 @@ /*- * ========================LICENSE_START================================= - * Copyright (C) 2021-2023 Nordix Foundation. All rights reserved. + * Copyright (C) 2021-2024 Nordix Foundation. All rights reserved. * ====================================================================== * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.onap.policy.clamp.acm.participant.kubernetes.helm; +import jakarta.ws.rs.core.Response; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -28,8 +29,8 @@ import java.util.Map; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; -import org.onap.policy.clamp.acm.participant.kubernetes.handler.AutomationCompositionElementHandler; import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; +import org.onap.policy.models.base.PfModelException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,17 +67,17 @@ public class PodStatusValidator { * @throws InterruptedException in case of an exception * @throws ServiceException in case of an exception */ - public void run() throws InterruptedException, ServiceException { + public void run() throws InterruptedException, PfModelException { logger.info("Polling the status of deployed pods for the chart {}", chart.getChartId().getName()); try { verifyPodStatus(); - } catch (IOException e) { - throw new ServiceException("Error verifying the status of the pod. Exiting", e); + } catch (IOException | ServiceException e) { + throw new PfModelException(Response.Status.BAD_REQUEST, "Error verifying the status of the pod. Exiting"); } } - private void verifyPodStatus() throws ServiceException, IOException, InterruptedException { + private void verifyPodStatus() throws ServiceException, IOException, InterruptedException, PfModelException { var isVerified = false; long endTime = System.currentTimeMillis() + (timeout * 1000L); @@ -92,11 +93,11 @@ public class PodStatusValidator { Thread.sleep(statusCheckInterval * 1000L); } else { logger.info("All pods are in running state for the helm chart {}", chart.getChartId().getName()); - AutomationCompositionElementHandler.getPodStatusMap().put(chart.getReleaseName(), podStatusMap); } } if (!isVerified) { - throw new ServiceException("Time out Exception verifying the status of the pod"); + throw new PfModelException(Response.Status.GATEWAY_TIMEOUT, + "Time out Exception verifying the status of the pod"); } } diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java index 26dcb05ff..260ef9918 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java @@ -21,7 +21,6 @@ package org.onap.policy.clamp.acm.participant.kubernetes.handler; -import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; @@ -30,7 +29,10 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; import java.io.IOException; import java.util.List; @@ -38,11 +40,8 @@ import java.util.Map; import java.util.UUID; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.Spy; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; @@ -55,28 +54,18 @@ import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; -import org.springframework.test.context.junit.jupiter.SpringExtension; -@ExtendWith(SpringExtension.class) class AutomationCompositionElementHandlerTest { private static final Coder CODER = new StandardCoder(); private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; - private static final String KEY_NAME = - "org.onap.domain.database.HelloWorld_K8SMicroserviceAutomationCompositionElement"; private static List<ChartInfo> charts; private static ToscaServiceTemplate toscaServiceTemplate; private static final String K8S_AUTOMATION_COMPOSITION_ELEMENT = "org.onap.domain.database.PMSH_K8SMicroserviceAutomationCompositionElement"; private final CommonTestData commonTestData = new CommonTestData(); - @InjectMocks - @Spy - private AutomationCompositionElementHandler automationCompositionElementHandler = - new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class)); - @Mock - private ChartService chartService; @BeforeAll static void init() throws CoderException { @@ -85,98 +74,139 @@ class AutomationCompositionElementHandlerTest { } @Test - void test_AutomationCompositionElementStateChange() throws ServiceException { - var automationCompositionElementId1 = UUID.randomUUID(); - var automationCompositionElementId2 = UUID.randomUUID(); - - automationCompositionElementHandler.getChartMap().put(automationCompositionElementId1, charts.get(0)); - automationCompositionElementHandler.getChartMap().put(automationCompositionElementId2, charts.get(1)); + void test_AutomationCompositionElementStateChange() throws ServiceException, PfModelException { + var chartService = Mockito.mock(ChartService.class); + var automationCompositionElementHandler = + new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); doNothing().when(chartService).uninstallChart(charts.get(0)); - automationCompositionElementHandler.undeploy(commonTestData.getAutomationCompositionId(), - automationCompositionElementId1); + ObjectMapper objectMapper = new ObjectMapper(); + Map<String, Object> inPropertiesMap = objectMapper.convertValue(charts.get(0), new TypeReference<>() {}); + + automationCompositionElementHandler.undeploy(commonTestData.createCompositionElementDto(), + commonTestData.createInstanceElementDto(Map.of("chart", inPropertiesMap))); doThrow(new ServiceException("Error uninstalling the chart")).when(chartService).uninstallChart(charts.get(0)); assertDoesNotThrow(() -> automationCompositionElementHandler - .undeploy(commonTestData.getAutomationCompositionId(), automationCompositionElementId1)); + .undeploy(commonTestData.createCompositionElementDto(), + commonTestData.createInstanceElementDto(inPropertiesMap))); } @Test void test_AutomationCompositionElementUpdate() throws PfModelException, IOException, ServiceException, InterruptedException { - doNothing().when(automationCompositionElementHandler).checkPodStatus(any(), any(), any(), anyInt(), anyInt()); - var element = CommonTestData.createAcElementDeploy(); + var chartService = Mockito.mock(ChartService.class); + var automationCompositionElementHandler = + spy(new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService)); + + doNothing().when(automationCompositionElementHandler).checkPodStatus(any(), any(), any(), anyInt(), anyInt(), + any()); var nodeTemplatesMap = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates(); + var instanceElementDto = commonTestData.createInstanceElementDto(nodeTemplatesMap + .get(K8S_AUTOMATION_COMPOSITION_ELEMENT).getProperties()); + var compositionElementDto = commonTestData.createCompositionElementDto(); doReturn(false).when(chartService).installChart(any()); - assertDoesNotThrow(() -> automationCompositionElementHandler.deploy(commonTestData.getAutomationCompositionId(), - element, nodeTemplatesMap.get(K8S_AUTOMATION_COMPOSITION_ELEMENT).getProperties())); + assertThrows(PfModelException.class, () -> automationCompositionElementHandler.deploy(compositionElementDto, + instanceElementDto)); doReturn(true).when(chartService).installChart(any()); - automationCompositionElementHandler.deploy(commonTestData.getAutomationCompositionId(), element, - nodeTemplatesMap.get(K8S_AUTOMATION_COMPOSITION_ELEMENT).getProperties()); - - assertThat(automationCompositionElementHandler.getChartMap()).hasSize(1).containsKey(element.getId()); + automationCompositionElementHandler.deploy(compositionElementDto, instanceElementDto); doThrow(new ServiceException("Error installing the chart")).when(chartService).installChart(Mockito.any()); - var elementId2 = UUID.randomUUID(); - element.setId(elementId2); assertThrows(PfModelException.class, - () -> automationCompositionElementHandler.deploy(commonTestData.getAutomationCompositionId(), element, - nodeTemplatesMap.get(K8S_AUTOMATION_COMPOSITION_ELEMENT).getProperties())); + () -> automationCompositionElementHandler.deploy(compositionElementDto, instanceElementDto)); - assertThat(automationCompositionElementHandler.getChartMap().containsKey(elementId2)).isFalse(); } @Test void test_checkPodStatus() { + var chartService = Mockito.mock(ChartService.class); + var automationCompositionElementHandler = + new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + var chartInfo = charts.get(0); var automationCompositionId = UUID.randomUUID(); - assertThrows(ServiceException.class, () -> automationCompositionElementHandler - .checkPodStatus(automationCompositionId, UUID.randomUUID(), chartInfo, 1, 1)); + assertThrows(PfModelException.class, () -> automationCompositionElementHandler + .checkPodStatus(automationCompositionId, UUID.randomUUID(), chartInfo, 1, 1, + commonTestData.createInstanceElementDto(Map.of()))); } @Test void testUpdate() { - var element = CommonTestData.createAcElementDeploy(); - var automationCompositionId = commonTestData.getAutomationCompositionId(); + var chartService = Mockito.mock(ChartService.class); + var automationCompositionElementHandler = + new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); assertDoesNotThrow( - () -> automationCompositionElementHandler.update(automationCompositionId, element, Map.of())); + () -> automationCompositionElementHandler.update(commonTestData.createCompositionElementDto(), + commonTestData.createInstanceElementDto(Map.of()), + commonTestData.createInstanceElementDto(Map.of()))); } @Test void testLock() { - assertDoesNotThrow(() -> automationCompositionElementHandler.lock(UUID.randomUUID(), UUID.randomUUID())); + var chartService = Mockito.mock(ChartService.class); + var automationCompositionElementHandler = + new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + + assertDoesNotThrow(() -> automationCompositionElementHandler.lock(commonTestData.createCompositionElementDto(), + commonTestData.createInstanceElementDto(Map.of()))); } @Test void testUnlock() { - assertDoesNotThrow(() -> automationCompositionElementHandler.unlock(UUID.randomUUID(), UUID.randomUUID())); + var chartService = Mockito.mock(ChartService.class); + var automationCompositionElementHandler = + new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + + assertDoesNotThrow(() -> automationCompositionElementHandler + .unlock(commonTestData.createCompositionElementDto(), + commonTestData.createInstanceElementDto(Map.of()))); } @Test void testDelete() { - assertDoesNotThrow(() -> automationCompositionElementHandler.delete(UUID.randomUUID(), UUID.randomUUID())); + var chartService = Mockito.mock(ChartService.class); + var automationCompositionElementHandler = + new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + + assertDoesNotThrow(() -> automationCompositionElementHandler + .delete(commonTestData.createCompositionElementDto(), + commonTestData.createInstanceElementDto(Map.of()))); } @Test void testPrime() { - assertDoesNotThrow(() -> automationCompositionElementHandler.prime(UUID.randomUUID(), List.of())); + var chartService = Mockito.mock(ChartService.class); + var automationCompositionElementHandler = + new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + + assertDoesNotThrow(() -> automationCompositionElementHandler.prime(new CompositionDto(UUID.randomUUID(), + Map.of(), Map.of()))); } @Test void testDeprime() { - assertDoesNotThrow(() -> automationCompositionElementHandler.deprime(UUID.randomUUID())); + var chartService = Mockito.mock(ChartService.class); + var automationCompositionElementHandler = + new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + + assertDoesNotThrow(() -> automationCompositionElementHandler.deprime(new CompositionDto(UUID.randomUUID(), + Map.of(), Map.of()))); } @Test void testMigrate() { - var element = CommonTestData.createAcElementDeploy(); - var automationCompositionId = commonTestData.getAutomationCompositionId(); - assertDoesNotThrow(() -> automationCompositionElementHandler.migrate(automationCompositionId, element, - UUID.randomUUID(), Map.of())); + var chartService = Mockito.mock(ChartService.class); + var automationCompositionElementHandler = + new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService); + + assertDoesNotThrow(() -> automationCompositionElementHandler + .migrate(commonTestData.createCompositionElementDto(), + commonTestData.createCompositionElementDto(), commonTestData.createInstanceElementDto(Map.of()), + commonTestData.createInstanceElementDto(Map.of()))); } } diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidatorTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidatorTest.java index 91aff830f..c9253856b 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidatorTest.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidatorTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation. + * Copyright (C) 2021-2022,2024 Nordix Foundation. * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,7 +21,6 @@ package org.onap.policy.clamp.acm.participant.kubernetes.helm; -import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; @@ -29,20 +28,18 @@ import static org.mockito.Mockito.doReturn; import java.io.File; import java.util.List; -import java.util.Map; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; -import org.onap.policy.clamp.acm.participant.kubernetes.handler.AutomationCompositionElementHandler; import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.base.PfModelException; import org.springframework.test.context.junit.jupiter.SpringExtension; @ExtendWith(SpringExtension.class) @@ -50,8 +47,8 @@ class PodStatusValidatorTest { private static final Coder CODER = new StandardCoder(); private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; - private static int TIMEOUT = 2; - private static int STATUS_CHECK_INTERVAL = 1; + private static final int TIMEOUT = 2; + private static final int STATUS_CHECK_INTERVAL = 1; private static List<ChartInfo> charts; @InjectMocks @@ -71,29 +68,19 @@ class PodStatusValidatorTest { charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); } - @AfterEach - void clearPodStatusMap() { - AutomationCompositionElementHandler.getPodStatusMap().clear(); - } - @Test void test_RunningPodState() throws ServiceException { String runningPod = "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\r\nHelloWorld-54777df9f8-qpzqr\t1/1\tRunning\t0\t9h"; doReturn(runningPod).when(client).executeCommand(any()); assertDoesNotThrow(() -> podStatusValidator.run()); - assertThat(AutomationCompositionElementHandler.getPodStatusMap()).hasSize(1); - assertThat(AutomationCompositionElementHandler.getPodStatusMap()).containsKey(charts.get(0).getReleaseName()); - assertThat(AutomationCompositionElementHandler.getPodStatusMap()) - .containsValue(Map.of("HelloWorld-54777df9f8-qpzqr", "Running")); } @Test void test_InvalidPodState() throws ServiceException { String invalidPod = "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\nhellofromdocker-54777df9f8-qpzqr\t1/1\tInit\t0\t9h"; doReturn(invalidPod).when(client).executeCommand(any()); - assertThrows(ServiceException.class, () -> podStatusValidator.run()); - assertThat(AutomationCompositionElementHandler.getPodStatusMap()).isEmpty(); + assertThrows(PfModelException.class, () -> podStatusValidator.run()); } // Use case scenario: Hard coded pod name @@ -102,9 +89,5 @@ class PodStatusValidatorTest { String runningPod = "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\r\nhelloallworld-54777df9f8-qpzqr\t1/1\tRunning\t0\t9h"; doReturn(runningPod).when(client).executeCommand(any()); assertDoesNotThrow(() -> podValidatorWithPodName.run()); - assertThat(AutomationCompositionElementHandler.getPodStatusMap()).hasSize(1); - assertThat(AutomationCompositionElementHandler.getPodStatusMap()).containsKey(charts.get(2).getReleaseName()); - assertThat(AutomationCompositionElementHandler.getPodStatusMap()) - .containsValue(Map.of("helloallworld-54777df9f8-qpzqr", "Running")); } } diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/CommonTestData.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/CommonTestData.java index 3bb6009a8..7c0c56a1d 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/CommonTestData.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/CommonTestData.java @@ -22,10 +22,13 @@ package org.onap.policy.clamp.acm.participant.kubernetes.parameters; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.UUID; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.parameters.Topics; import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; @@ -34,6 +37,7 @@ import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; public class CommonTestData { @@ -188,4 +192,25 @@ public class CommonTestData { element.setOrderedState(DeployOrder.DEPLOY); return element; } + + /** + * Create an InstanceElementDto. + * + * @return an InstanceElementDto + */ + public InstanceElementDto createInstanceElementDto(Map<String, Object> inProperties) { + return new InstanceElementDto(getAutomationCompositionId(), UUID.randomUUID(), + new ToscaServiceTemplate(), inProperties, new HashMap<>()); + } + + + /** + * Create an compositionElementDto. + * + * @return an compositionElementDto + */ + public CompositionElementDto createCompositionElementDto() { + return new CompositionElementDto(getAutomationCompositionId(), null, + Map.of("uninitializedToPassiveTimeout", 100, "podStatusCheckInterval", "30"), null); + } } diff --git a/participant/participant-impl/participant-impl-policy/pom.xml b/participant/participant-impl/participant-impl-policy/pom.xml index 41685817e..f01ce0565 100644 --- a/participant/participant-impl/participant-impl-policy/pom.xml +++ b/participant/participant-impl/participant-impl-policy/pom.xml @@ -25,7 +25,7 @@ <parent> <groupId>org.onap.policy.clamp.participant</groupId> <artifactId>policy-clamp-participant-impl</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>policy-clamp-participant-impl-policy</artifactId> diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/config/MicrometerConfig.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/config/MicrometerConfig.java index 2f942eaa8..de1242b9e 100644 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/config/MicrometerConfig.java +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/config/MicrometerConfig.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -23,6 +23,7 @@ package org.onap.policy.clamp.acm.participant.policy.config; import io.micrometer.core.aop.TimedAspect; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,8 +35,9 @@ public class MicrometerConfig { * Load up the metrics registry. */ @Bean - public InitializingBean forcePrometheusPostProcessor(BeanPostProcessor meterRegistryPostProcessor, - MeterRegistry registry) { + public InitializingBean forcePrometheusPostProcessor(@Qualifier("meterRegistryPostProcessor") + BeanPostProcessor meterRegistryPostProcessor, + MeterRegistry registry) { return () -> meterRegistryPostProcessor.postProcessAfterInitialization(registry, ""); } diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandler.java index ae906e1ef..5a3bc6328 100644 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandler.java +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandler.java @@ -27,13 +27,13 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; import org.apache.http.HttpStatus; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.acm.participant.intermediary.api.impl.AcElementListenerV1; +import org.onap.policy.clamp.acm.participant.intermediary.api.impl.AcElementListenerV2; import org.onap.policy.clamp.acm.participant.policy.client.PolicyApiHttpClient; import org.onap.policy.clamp.acm.participant.policy.client.PolicyPapHttpClient; -import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; import org.onap.policy.clamp.models.acm.concepts.DeployState; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.models.base.PfModelException; @@ -48,12 +48,10 @@ import org.springframework.stereotype.Component; * This class handles implementation of automationCompositionElement updates. */ @Component -public class AutomationCompositionElementHandler extends AcElementListenerV1 { +public class AutomationCompositionElementHandler extends AcElementListenerV2 { private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionElementHandler.class); - private final Map<UUID, ToscaServiceTemplate> serviceTemplateMap = new ConcurrentHashMap<>(); - private final PolicyApiHttpClient apiHttpClient; private final PolicyPapHttpClient papHttpClient; @@ -74,26 +72,28 @@ public class AutomationCompositionElementHandler extends AcElementListenerV1 { /** * Callback method to handle a automation composition element state change. * - * @param automationCompositionId the ID of the automation composition - * @param automationCompositionElementId the ID of the automation composition element + * @param compositionElement the information of the Automation Composition Definition Element + * @param instanceElement the information of the Automation Composition Instance Element + * @throws PfModelException in case of a model exception */ @Override - public void undeploy(UUID automationCompositionId, UUID automationCompositionElementId) throws PfModelException { - var automationCompositionDefinition = serviceTemplateMap.get(automationCompositionElementId); - if (automationCompositionDefinition == null) { - LOGGER.debug("No policies to undeploy to {}", automationCompositionElementId); - intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, - automationCompositionElementId, DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, + public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) + throws PfModelException { + var automationCompositionDefinition = instanceElement.toscaServiceTemplateFragment(); + if (automationCompositionDefinition.getToscaTopologyTemplate() == null) { + LOGGER.debug("No policies to undeploy to {}", instanceElement.elementId()); + intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed"); return; } var policyList = getPolicyList(automationCompositionDefinition); - undeployPolicies(policyList, automationCompositionElementId); + undeployPolicies(policyList, instanceElement.elementId()); var policyTypeList = getPolicyTypeList(automationCompositionDefinition); deletePolicyData(policyTypeList, policyList); - serviceTemplateMap.remove(automationCompositionElementId); - intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, automationCompositionElementId, - DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed"); + intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, + "Undeployed"); } private void deletePolicyData(List<ToscaConceptIdentifier> policyTypeList, @@ -151,24 +151,23 @@ public class AutomationCompositionElementHandler extends AcElementListenerV1 { /** * Callback method to handle an update on automation composition element. * - * @param automationCompositionId the automationComposition Id - * @param element the information on the automation composition element - * @param properties properties Map - * @throws PfModelException in case of an exception + * @param compositionElement the information of the Automation Composition Definition Element + * @param instanceElement the information of the Automation Composition Instance Element + * @throws PfModelException from Policy framework */ @Override - public void deploy(UUID automationCompositionId, AcElementDeploy element, Map<String, Object> properties) + public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException { var createPolicyTypeResp = HttpStatus.SC_OK; var createPolicyResp = HttpStatus.SC_OK; - var automationCompositionDefinition = element.getToscaServiceTemplateFragment(); + var automationCompositionDefinition = instanceElement.toscaServiceTemplateFragment(); if (automationCompositionDefinition.getToscaTopologyTemplate() == null) { - intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(), - DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "ToscaTopologyTemplate not defined"); + intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, + "ToscaTopologyTemplate not defined"); return; } - serviceTemplateMap.put(element.getId(), automationCompositionDefinition); if (automationCompositionDefinition.getPolicyTypes() != null) { LOGGER.info("Found Policy Types in automation composition definition: {} , Creating Policy Types", automationCompositionDefinition.getName()); @@ -183,19 +182,23 @@ public class AutomationCompositionElementHandler extends AcElementListenerV1 { createPolicyResp = response.getStatus(); } } - if (createPolicyTypeResp == HttpStatus.SC_OK && createPolicyResp == HttpStatus.SC_OK) { + if (isSuccess(createPolicyTypeResp) && isSuccess(createPolicyResp)) { LOGGER.info( "PolicyTypes/Policies for the automation composition element : {} are created " + "successfully", - element.getId()); + instanceElement.elementId()); var policyList = getPolicyList(automationCompositionDefinition); - deployPolicies(policyList, automationCompositionId, element.getId()); + deployPolicies(policyList, instanceElement.instanceId(), instanceElement.elementId()); } else { - intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(), - DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, + intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Creation of PolicyTypes/Policies failed. Policies will not be deployed."); } } + private boolean isSuccess(int status) { + return status == HttpStatus.SC_OK || status == HttpStatus.SC_CREATED; + } + private List<ToscaConceptIdentifier> getPolicyTypeList(ToscaServiceTemplate serviceTemplate) { List<ToscaConceptIdentifier> policyTypeList = new ArrayList<>(); if (serviceTemplate.getPolicyTypes() != null) { diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandlerTest.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandlerTest.java index 013cb3432..39f35e6df 100644 --- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandlerTest.java +++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandlerTest.java @@ -31,15 +31,13 @@ import java.util.List; import java.util.Map; import java.util.UUID; import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.clamp.acm.participant.policy.client.PolicyApiHttpClient; import org.onap.policy.clamp.acm.participant.policy.client.PolicyPapHttpClient; -import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; -import org.onap.policy.clamp.models.acm.concepts.AcTypeState; 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.messages.rest.instantiation.DeployOrder; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; @@ -49,11 +47,8 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate; class AutomationCompositionElementHandlerTest { - private static final String ID_NAME = "org.onap.PM_CDS_Blueprint"; - private static final String ID_VERSION = "1.0.1"; - private static final UUID automationCompositionElementId = UUID.randomUUID(); - public static final UUID AC_ID = UUID.randomUUID(); - private static final ToscaConceptIdentifier DEFINITION = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); + private static final ToscaConceptIdentifier DEFINITION = + new ToscaConceptIdentifier("1.0.1", "org.onap.PM_CDS_Blueprint"); @Test void testHandlerUndeployNoPolicy() throws PfModelException { @@ -61,22 +56,25 @@ class AutomationCompositionElementHandlerTest { var handler = new AutomationCompositionElementHandler(mock(PolicyApiHttpClient.class), mock(PolicyPapHttpClient.class), intermediaryApi); - handler.undeploy(AC_ID, automationCompositionElementId); - verify(intermediaryApi).updateAutomationCompositionElementState(AC_ID, automationCompositionElementId, - DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed"); + var compositionElement = getCompositionElement(); + var instanceElement = getInstanceElementWithNullTopology(); + + handler.undeploy(compositionElement, instanceElement); + verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, + "Undeployed"); + } + + private CompositionElementDto getCompositionElement() { + return new CompositionElementDto(UUID.randomUUID(), DEFINITION, Map.of(), Map.of()); } - private AcElementDeploy getTestingAcElement() { - var element = new AcElementDeploy(); - element.setDefinition(DEFINITION); - element.setId(automationCompositionElementId); - element.setOrderedState(DeployOrder.DEPLOY); + private InstanceElementDto getInstanceElement() { var template = new ToscaServiceTemplate(); template.setToscaTopologyTemplate(new ToscaTopologyTemplate()); template.getToscaTopologyTemplate().setPolicies(List.of(Map.of("DummyPolicy", new ToscaPolicy()))); template.setPolicyTypes(Map.of("dummy policy type", new ToscaPolicyType())); - element.setToscaServiceTemplateFragment(template); - return element; + return new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), template, Map.of(), Map.of()); } @Test @@ -92,13 +90,18 @@ class AutomationCompositionElementHandlerTest { var intermediaryApi = mock(ParticipantIntermediaryApi.class); var handler = new AutomationCompositionElementHandler(api, pap, intermediaryApi); - handler.deploy(AC_ID, getTestingAcElement(), Map.of()); - verify(intermediaryApi).updateAutomationCompositionElementState(AC_ID, automationCompositionElementId, - DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed"); + var compositionElement = getCompositionElement(); + var instanceElement = getInstanceElement(); + + handler.deploy(compositionElement, instanceElement); + verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, + "Deployed"); - handler.undeploy(AC_ID, automationCompositionElementId); - verify(intermediaryApi).updateAutomationCompositionElementState(AC_ID, automationCompositionElementId, - DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed"); + handler.undeploy(compositionElement, instanceElement); + verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, + "Undeployed"); } @Test @@ -107,11 +110,18 @@ class AutomationCompositionElementHandlerTest { var handler = new AutomationCompositionElementHandler(mock(PolicyApiHttpClient.class), mock(PolicyPapHttpClient.class), intermediaryApi); - var acElement = getTestingAcElement(); - acElement.getToscaServiceTemplateFragment().setToscaTopologyTemplate(null); - handler.deploy(AC_ID, acElement, Map.of()); - verify(intermediaryApi).updateAutomationCompositionElementState(AC_ID, automationCompositionElementId, - DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "ToscaTopologyTemplate not defined"); + var compositionElement = getCompositionElement(); + var instanceElement = getInstanceElementWithNullTopology(); + handler.deploy(compositionElement, instanceElement); + verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, + "ToscaTopologyTemplate not defined"); + } + + private InstanceElementDto getInstanceElementWithNullTopology() { + var template = new ToscaServiceTemplate(); + template.setToscaTopologyTemplate(null); + return new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), template, Map.of(), Map.of()); } @Test @@ -126,12 +136,13 @@ class AutomationCompositionElementHandlerTest { var intermediaryApi = mock(ParticipantIntermediaryApi.class); var handler = new AutomationCompositionElementHandler(api, pap, intermediaryApi); - var element = getTestingAcElement(); + var compositionElement = getCompositionElement(); + var instanceElement = getInstanceElement(); // Mock failure in policy type creation - handler.deploy(AC_ID, element, Map.of()); - verify(intermediaryApi).updateAutomationCompositionElementState(AC_ID, automationCompositionElementId, - DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, + handler.deploy(compositionElement, instanceElement); + verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Creation of PolicyTypes/Policies failed. Policies will not be deployed."); } @@ -147,88 +158,9 @@ class AutomationCompositionElementHandlerTest { var intermediaryApi = mock(ParticipantIntermediaryApi.class); var handler = new AutomationCompositionElementHandler(api, pap, intermediaryApi); - var element = getTestingAcElement(); - assertThatThrownBy(() -> handler.deploy(AC_ID, element, Map.of())) + var compositionElement = getCompositionElement(); + var instanceElement = getInstanceElement(); + assertThatThrownBy(() -> handler.deploy(compositionElement, instanceElement)) .hasMessageMatching("Deploy of Policy failed."); } - - @Test - void testUpdate() throws Exception { - var intermediaryApi = mock(ParticipantIntermediaryApi.class); - var handler = new AutomationCompositionElementHandler(mock(PolicyApiHttpClient.class), - mock(PolicyPapHttpClient.class), intermediaryApi); - - var acElement = getTestingAcElement(); - acElement.getToscaServiceTemplateFragment().setToscaTopologyTemplate(null); - handler.update(AC_ID, acElement, Map.of()); - verify(intermediaryApi).updateAutomationCompositionElementState(AC_ID, automationCompositionElementId, - DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Update not supported"); - } - - @Test - void testLock() throws Exception { - var intermediaryApi = mock(ParticipantIntermediaryApi.class); - var handler = new AutomationCompositionElementHandler(mock(PolicyApiHttpClient.class), - mock(PolicyPapHttpClient.class), intermediaryApi); - - handler.lock(AC_ID, automationCompositionElementId); - verify(intermediaryApi).updateAutomationCompositionElementState(AC_ID, automationCompositionElementId, null, - LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked"); - } - - @Test - void testUnlock() throws Exception { - var intermediaryApi = mock(ParticipantIntermediaryApi.class); - var handler = new AutomationCompositionElementHandler(mock(PolicyApiHttpClient.class), - mock(PolicyPapHttpClient.class), intermediaryApi); - - handler.unlock(AC_ID, automationCompositionElementId); - verify(intermediaryApi).updateAutomationCompositionElementState(AC_ID, automationCompositionElementId, null, - LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked"); - } - - @Test - void testDelete() throws Exception { - var intermediaryApi = mock(ParticipantIntermediaryApi.class); - var handler = new AutomationCompositionElementHandler(mock(PolicyApiHttpClient.class), - mock(PolicyPapHttpClient.class), intermediaryApi); - - handler.delete(AC_ID, automationCompositionElementId); - verify(intermediaryApi).updateAutomationCompositionElementState(AC_ID, automationCompositionElementId, - DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted"); - } - - @Test - void testPrime() throws Exception { - var intermediaryApi = mock(ParticipantIntermediaryApi.class); - var handler = new AutomationCompositionElementHandler(mock(PolicyApiHttpClient.class), - mock(PolicyPapHttpClient.class), intermediaryApi); - - handler.prime(AC_ID, List.of()); - verify(intermediaryApi).updateCompositionState(AC_ID, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Primed"); - } - - @Test - void testDeprime() throws Exception { - var intermediaryApi = mock(ParticipantIntermediaryApi.class); - var handler = new AutomationCompositionElementHandler(mock(PolicyApiHttpClient.class), - mock(PolicyPapHttpClient.class), intermediaryApi); - - handler.deprime(AC_ID); - verify(intermediaryApi).updateCompositionState(AC_ID, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR, - "Deprimed"); - } - - @Test - void testMigrate() throws Exception { - var intermediaryApi = mock(ParticipantIntermediaryApi.class); - var handler = new AutomationCompositionElementHandler(mock(PolicyApiHttpClient.class), - mock(PolicyPapHttpClient.class), intermediaryApi); - - var acElement = getTestingAcElement(); - acElement.getToscaServiceTemplateFragment().setToscaTopologyTemplate(null); - handler.migrate(AC_ID, acElement, UUID.randomUUID(), Map.of()); - verify(intermediaryApi).updateAutomationCompositionElementState(AC_ID, automationCompositionElementId, - DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated"); - } } diff --git a/participant/participant-impl/participant-impl-simulator/pom.xml b/participant/participant-impl/participant-impl-simulator/pom.xml index 49988df0b..26341e5f0 100644 --- a/participant/participant-impl/participant-impl-simulator/pom.xml +++ b/participant/participant-impl/participant-impl-simulator/pom.xml @@ -25,7 +25,7 @@ <parent> <groupId>org.onap.policy.clamp.participant</groupId> <artifactId>policy-clamp-participant-impl</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>policy-clamp-participant-impl-simulator</artifactId> diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/config/MicrometerConfig.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/config/MicrometerConfig.java index 2a319c3bd..4ddec02e5 100644 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/config/MicrometerConfig.java +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/config/MicrometerConfig.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation. + * Copyright (C) 2023-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. @@ -23,6 +23,7 @@ package org.onap.policy.clamp.acm.participant.sim.config; import io.micrometer.core.aop.TimedAspect; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,8 +35,9 @@ public class MicrometerConfig { * Load up the metrics registry. */ @Bean - public InitializingBean forcePrometheusPostProcessor(BeanPostProcessor meterRegistryPostProcessor, - MeterRegistry registry) { + public InitializingBean forcePrometheusPostProcessor(@Qualifier("meterRegistryPostProcessor") + BeanPostProcessor meterRegistryPostProcessor, + MeterRegistry registry) { return () -> meterRegistryPostProcessor.postProcessAfterInitialization(registry, ""); } diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV1.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV1.java index 03a0517e0..534b01b32 100644 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV1.java +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV1.java @@ -26,10 +26,7 @@ import java.util.UUID; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.clamp.acm.participant.intermediary.api.impl.AcElementListenerV1; import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; -import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; -import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; -import org.onap.policy.models.base.PfModelException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; @@ -50,61 +47,58 @@ public class AutomationCompositionElementHandlerV1 extends AcElementListenerV1 { } @Override - public void deploy(UUID instanceId, AcElementDeploy element, Map<String, Object> properties) - throws PfModelException { + public void deploy(UUID instanceId, AcElementDeploy element, Map<String, Object> properties) { LOGGER.debug("deploy call instanceId: {}, element: {}, properties: {}", instanceId, element, properties); simulatorService.deploy(instanceId, element.getId()); } @Override - public void undeploy(UUID instanceId, UUID elementId) throws PfModelException { + public void undeploy(UUID instanceId, UUID elementId) { LOGGER.debug("undeploy call instanceId: {}, elementId: {}", instanceId, elementId); simulatorService.undeploy(instanceId, elementId); } @Override - public void lock(UUID instanceId, UUID elementId) throws PfModelException { + public void lock(UUID instanceId, UUID elementId) { LOGGER.debug("lock call instanceId: {}, elementId: {}", instanceId, elementId); simulatorService.lock(instanceId, elementId); } @Override - public void unlock(UUID instanceId, UUID elementId) throws PfModelException { + public void unlock(UUID instanceId, UUID elementId) { LOGGER.debug("unlock call instanceId: {}, elementId: {}", instanceId, elementId); simulatorService.unlock(instanceId, elementId); } @Override - public void delete(UUID instanceId, UUID elementId) throws PfModelException { + public void delete(UUID instanceId, UUID elementId) { LOGGER.debug("delete call instanceId: {}, elementId: {}", instanceId, elementId); simulatorService.delete(instanceId, elementId); } @Override - public void update(UUID instanceId, AcElementDeploy element, Map<String, Object> properties) - throws PfModelException { + public void update(UUID instanceId, AcElementDeploy element, Map<String, Object> properties) { LOGGER.debug("update call instanceId: {}, element: {}, properties: {}", instanceId, element, properties); simulatorService.update(instanceId, element.getId()); } @Override - public void prime(UUID compositionId, List<AutomationCompositionElementDefinition> elementDefinitionList) - throws PfModelException { + public void prime(UUID compositionId, List<AutomationCompositionElementDefinition> elementDefinitionList) { LOGGER.debug("prime call compositionId: {}, elementDefinitionList: {}", compositionId, elementDefinitionList); simulatorService.prime(compositionId); } @Override - public void deprime(UUID compositionId) throws PfModelException { + public void deprime(UUID compositionId) { LOGGER.debug("deprime call compositionId: {}", compositionId); simulatorService.deprime(compositionId); } @Override public void migrate(UUID instanceId, AcElementDeploy element, UUID compositionTargetId, - Map<String, Object> properties) throws PfModelException { + Map<String, Object> properties) { LOGGER.debug("migrate call instanceId: {}, element: {}, compositionTargetId: {}, properties: {}", instanceId, element, compositionTargetId, properties); - simulatorService.migrate(instanceId, element.getId()); + simulatorService.migrate(instanceId, element.getId(), 0, Map.of()); } } diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2.java index 28bade22f..82602c1e1 100644 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2.java +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2.java @@ -22,15 +22,10 @@ package org.onap.policy.clamp.acm.participant.sim.main.handler; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState; import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.clamp.acm.participant.intermediary.api.impl.AcElementListenerV2; -import org.onap.policy.clamp.models.acm.concepts.AcTypeState; -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.utils.AcmUtils; -import org.onap.policy.models.base.PfModelException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; @@ -39,7 +34,7 @@ import org.springframework.stereotype.Component; /** * This class handles implementation of automationCompositionElement updates. */ -@ConditionalOnExpression("'${element.handler:AcElementHandlerV2}' == 'AcElementHandlerV2'") +@ConditionalOnExpression("'${element.handler}'=='AcElementHandlerV2'") @Component public class AutomationCompositionElementHandlerV2 extends AcElementListenerV2 { @@ -58,11 +53,9 @@ public class AutomationCompositionElementHandlerV2 extends AcElementListenerV2 { * * @param compositionElement the information of the Automation Composition Definition Element * @param instanceElement the information of the Automation Composition Instance Element - * @throws PfModelException from Policy framework */ @Override - public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) - throws PfModelException { + public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { LOGGER.debug("deploy call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); simulatorService.deploy(instanceElement.instanceId(), instanceElement.elementId()); } @@ -72,63 +65,90 @@ public class AutomationCompositionElementHandlerV2 extends AcElementListenerV2 { * * @param compositionElement the information of the Automation Composition Definition Element * @param instanceElement the information of the Automation Composition Instance Element - * @throws PfModelException from Policy framework */ @Override - public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) - throws PfModelException { + public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { LOGGER.debug("undeploy call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); simulatorService.undeploy(instanceElement.instanceId(), instanceElement.elementId()); } @Override - public void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) - throws PfModelException { + public void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { LOGGER.debug("lock call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); simulatorService.lock(instanceElement.instanceId(), instanceElement.elementId()); } @Override - public void unlock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) - throws PfModelException { + public void unlock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { LOGGER.debug("unlock call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); simulatorService.unlock(instanceElement.instanceId(), instanceElement.elementId()); } @Override - public void delete(CompositionElementDto compositionElement, InstanceElementDto instanceElement) - throws PfModelException { + public void delete(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { LOGGER.debug("delete call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); simulatorService.delete(instanceElement.instanceId(), instanceElement.elementId()); } @Override public void update(CompositionElementDto compositionElement, InstanceElementDto instanceElement, - InstanceElementDto instanceElementUpdated) throws PfModelException { + InstanceElementDto instanceElementUpdated) { LOGGER.debug("update call compositionElement: {}, instanceElement: {}, instanceElementUpdated: {}", compositionElement, instanceElement, instanceElementUpdated); simulatorService.update(instanceElement.instanceId(), instanceElement.elementId()); } @Override - public void prime(CompositionDto composition) throws PfModelException { + public void prime(CompositionDto composition) { LOGGER.debug("prime call composition: {}", composition); simulatorService.prime(composition.compositionId()); } @Override - public void deprime(CompositionDto composition) throws PfModelException { + public void deprime(CompositionDto composition) { LOGGER.debug("deprime call composition: {}", composition); simulatorService.deprime(composition.compositionId()); } @Override public void migrate(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, - InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate) - throws PfModelException { + InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate) { LOGGER.debug("migrate call compositionElement: {}, compositionElementTarget: {}, instanceElement: {}," + " instanceElementMigrate: {}", compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate); - simulatorService.migrate(instanceElement.instanceId(), instanceElement.elementId()); + + if (ElementState.NEW.equals(instanceElementMigrate.state())) { + LOGGER.debug("new element scenario"); + + } + if (ElementState.REMOVED.equals(instanceElementMigrate.state())) { + simulatorService.undeploy(instanceElement.instanceId(), instanceElement.elementId()); + simulatorService.delete(instanceElement.instanceId(), instanceElement.elementId()); + } else { + simulatorService.migrate(instanceElement.instanceId(), instanceElement.elementId(), + 0, compositionElementTarget.inProperties()); + } + } + + @Override + public void migratePrecheck(CompositionElementDto compositionElement, + CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, + InstanceElementDto instanceElementMigrate) { + LOGGER.debug("migrate precheck call compositionElement: {}, compositionElementTarget: {}, instanceElement: {}," + + " instanceElementMigrate: {}", + compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate); + simulatorService.migratePrecheck(instanceElement.instanceId(), instanceElement.elementId()); + } + + @Override + public void prepare(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + LOGGER.debug("prepare call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + simulatorService.prepare(instanceElement.instanceId(), instanceElement.elementId()); + } + + @Override + public void review(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + LOGGER.debug("review call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + simulatorService.review(instanceElement.instanceId(), instanceElement.elementId()); } } diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV3.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV3.java new file mode 100644 index 000000000..e406a6127 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV3.java @@ -0,0 +1,165 @@ +/*- + * ============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.acm.participant.sim.main.handler; + +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.Setter; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState; +import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.acm.participant.intermediary.api.impl.AcElementListenerV3; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.stereotype.Component; + +/** + * This class handles implementation of automationCompositionElement updates. + */ +@Getter +@Setter +@ConditionalOnExpression("'${element.handler:AcElementHandlerV3}' == 'AcElementHandlerV3'") +@Component +public class AutomationCompositionElementHandlerV3 extends AcElementListenerV3 { + + private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionElementHandlerV3.class); + + private final SimulatorService simulatorService; + + public AutomationCompositionElementHandlerV3(ParticipantIntermediaryApi intermediaryApi, + SimulatorService simulatorService) { + super(intermediaryApi); + this.simulatorService = simulatorService; + } + + /** + * Handle a deploy on a automation composition element. + * + * @param compositionElement the information of the Automation Composition Definition Element + * @param instanceElement the information of the Automation Composition Instance Element + */ + @Override + public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + LOGGER.debug("deploy call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + simulatorService.deploy(instanceElement.instanceId(), instanceElement.elementId()); + } + + /** + * Handle a automation composition element state change. + * + * @param compositionElement the information of the Automation Composition Definition Element + * @param instanceElement the information of the Automation Composition Instance Element + */ + @Override + public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + LOGGER.debug("undeploy call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + simulatorService.undeploy(instanceElement.instanceId(), instanceElement.elementId()); + } + + @Override + public void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + LOGGER.debug("lock call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + simulatorService.lock(instanceElement.instanceId(), instanceElement.elementId()); + } + + @Override + public void unlock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + LOGGER.debug("unlock call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + simulatorService.unlock(instanceElement.instanceId(), instanceElement.elementId()); + } + + @Override + public void delete(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + LOGGER.debug("delete call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + simulatorService.delete(instanceElement.instanceId(), instanceElement.elementId()); + } + + @Override + public void update(CompositionElementDto compositionElement, InstanceElementDto instanceElement, + InstanceElementDto instanceElementUpdated) { + LOGGER.debug("update call compositionElement: {}, instanceElement: {}, instanceElementUpdated: {}", + compositionElement, instanceElement, instanceElementUpdated); + simulatorService.update(instanceElement.instanceId(), instanceElement.elementId()); + } + + @Override + public void prime(CompositionDto composition) { + LOGGER.debug("prime call composition: {}", composition); + simulatorService.prime(composition.compositionId()); + } + + @Override + public void deprime(CompositionDto composition) { + LOGGER.debug("deprime call composition: {}", composition); + simulatorService.deprime(composition.compositionId()); + } + + @Override + public void migrate(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, + InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate, int stage) { + LOGGER.debug("migrate call compositionElement: {}, compositionElementTarget: {}, instanceElement: {}," + + " instanceElementMigrate: {}, stage: {}", + compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate, stage); + + if (ElementState.NEW.equals(instanceElementMigrate.state())) { + LOGGER.debug("new element scenario"); + } + if (ElementState.REMOVED.equals(instanceElementMigrate.state())) { + simulatorService.undeploy(instanceElement.instanceId(), instanceElement.elementId()); + simulatorService.delete(instanceElement.instanceId(), instanceElement.elementId()); + } else { + simulatorService.migrate(instanceElementMigrate.instanceId(), instanceElementMigrate.elementId(), stage, + compositionElementTarget.inProperties()); + instanceElementMigrate.outProperties().putIfAbsent("stage", new ArrayList<>()); + @SuppressWarnings("unchecked") + var stageList = (List<Integer>) instanceElementMigrate.outProperties().get("stage"); + stageList.add(stage); + intermediaryApi.sendAcElementInfo(instanceElementMigrate.instanceId(), instanceElementMigrate.elementId(), + null, null, instanceElementMigrate.outProperties()); + } + } + + @Override + public void migratePrecheck(CompositionElementDto compositionElement, + CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, + InstanceElementDto instanceElementMigrate) { + LOGGER.debug("migrate precheck call compositionElement: {}, compositionElementTarget: {}, instanceElement: {}," + + " instanceElementMigrate: {}", + compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate); + simulatorService.migratePrecheck(instanceElement.instanceId(), instanceElement.elementId()); + } + + @Override + public void prepare(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + LOGGER.debug("prepare call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + simulatorService.prepare(instanceElement.instanceId(), instanceElement.elementId()); + } + + @Override + public void review(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + LOGGER.debug("review call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + simulatorService.review(instanceElement.instanceId(), instanceElement.elementId()); + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/SimulatorService.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/SimulatorService.java index d37edf761..b0006f711 100644 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/SimulatorService.java +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/SimulatorService.java @@ -35,6 +35,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; 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.ParticipantUtils; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.slf4j.Logger; @@ -327,19 +328,98 @@ public class SimulatorService { * * @param instanceId the instanceId * @param elementId the elementId + * @param stage the stage */ - public void migrate(UUID instanceId, UUID elementId) { + public void migrate(UUID instanceId, UUID elementId, int stage, Map<String, Object> compositionInProperties) { if (!execution(getConfig().getMigrateTimerMs(), "Current Thread migrate is Interrupted during execution {}", elementId)) { return; } - if (getConfig().isMigrateSuccess()) { + if (config.isMigrateSuccess()) { + var stageSet = ParticipantUtils.findStageSet(compositionInProperties); + var nextStage = 1000; + for (var s : stageSet) { + if (s > stage) { + nextStage = Math.min(s, nextStage); + } + } + if (nextStage == 1000) { + intermediaryApi.updateAutomationCompositionElementState( + instanceId, elementId, + DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated"); + } else { + intermediaryApi.updateAutomationCompositionElementStage( + instanceId, elementId, + StateChangeResult.NO_ERROR, nextStage, "stage " + stage + " Migrated"); + } + } else { + intermediaryApi.updateAutomationCompositionElementState( + instanceId, elementId, + DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Migrate failed!"); + } + } + + /** + * Handle a Migrate Precheck on a automation composition element. + * + * @param instanceId the instanceId + * @param elementId the elementId + */ + public void migratePrecheck(UUID instanceId, UUID elementId) { + if (!execution(config.getMigratePrecheckTimerMs(), + "Current Thread migrate precheck is Interrupted during execution {}", elementId)) { + return; + } + + if (config.isMigratePrecheck()) { intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, - DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated"); + DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migration precheck completed"); } else { intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, - DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Migrate failed!"); + DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Migration precheck failed"); + } + } + + /** + * Handle a Prepare on a automation composition element. + * + * @param instanceId the instanceId + * @param elementId the elementId + */ + public void prepare(UUID instanceId, UUID elementId) { + if (!execution(config.getPrepareTimerMs(), + "Current Thread prepare is Interrupted during execution {}", elementId)) { + return; + } + + if (config.isPrepare()) { + intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, + DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Prepare completed"); + } else { + intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, + DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Prepare failed"); + } + } + + /** + * Handle a Review on a automation composition element. + * + * @param instanceId the instanceId + * @param elementId the elementId + */ + public void review(UUID instanceId, UUID elementId) { + if (!execution(config.getReviewTimerMs(), + "Current Thread review is Interrupted during execution {}", elementId)) { + return; + } + + if (config.isReview()) { + intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, + DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Review completed"); + } else { + intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, + DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Review failed"); } } } diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/model/SimConfig.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/model/SimConfig.java index f4d4c6e2e..f38f3079b 100644 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/model/SimConfig.java +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/model/SimConfig.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation. + * Copyright (C) 2023-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. @@ -38,6 +38,12 @@ public class SimConfig { private boolean migrateSuccess = true; + private boolean migratePrecheck = true; + + private boolean prepare = true; + + private boolean review = true; + private boolean primeSuccess = true; private boolean deprimeSuccess = true; @@ -54,6 +60,12 @@ public class SimConfig { private int migrateTimerMs = 100; + private int migratePrecheckTimerMs = 100; + + private int prepareTimerMs = 100; + + private int reviewTimerMs = 100; + private int deleteTimerMs = 100; private int primeTimerMs = 100; diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/parameters/ParticipantSimParameters.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/parameters/ParticipantSimParameters.java index 4c7845143..4157bfd88 100644 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/parameters/ParticipantSimParameters.java +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/parameters/ParticipantSimParameters.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation. + * Copyright (C) 2023-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. @@ -41,5 +41,5 @@ public class ParticipantSimParameters implements ParticipantParameters { @NotNull @Valid - private ParticipantIntermediaryParameters intermediaryParameters; + private ParticipantIntermediaryParameters intermediaryParameters = new ParticipantIntermediaryParameters(); } diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/comm/CommonTestData.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/comm/CommonTestData.java index 5499931a2..f73f75970 100644 --- a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/comm/CommonTestData.java +++ b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/comm/CommonTestData.java @@ -26,6 +26,7 @@ import java.util.Map; import java.util.TreeMap; import java.util.UUID; import org.onap.policy.clamp.acm.participant.intermediary.parameters.Topics; +import org.onap.policy.clamp.acm.participant.sim.model.SimConfig; import org.onap.policy.clamp.acm.participant.sim.parameters.ParticipantSimParameters; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; @@ -102,7 +103,7 @@ public class CommonTestData { * @return topic parameters */ private static TopicParameters getSinkTopicParams() { - final TopicParameters topicParams = new TopicParameters(); + final var topicParams = new TopicParameters(); topicParams.setTopic("policy-acruntime-participant"); topicParams.setTopicCommInfrastructure("NOOP"); topicParams.setServers(List.of("localhost")); @@ -115,7 +116,7 @@ public class CommonTestData { * @return topic parameters */ private static TopicParameters getSyncTopicParams() { - final TopicParameters topicParams = new TopicParameters(); + final var topicParams = new TopicParameters(); topicParams.setTopic("acm-ppnt-sync"); topicParams.setTopicCommInfrastructure("NOOP"); topicParams.setServers(List.of("localhost")); @@ -135,8 +136,6 @@ public class CommonTestData { * Returns a Map of ToscaConceptIdentifier and AutomationComposition for test cases. * * @return automationCompositionMap - * - * @throws CoderException if there is an error with .json file. */ public static Map<UUID, AutomationComposition> getTestAutomationCompositionMap() { var automationComposition = getTestAutomationComposition(); @@ -147,8 +146,6 @@ public class CommonTestData { * Returns List of AutomationComposition for test cases. * * @return AutomationCompositions - * - * @throws CoderException if there is an error with .json file. */ public static AutomationComposition getTestAutomationComposition() { var automationComposition = new AutomationComposition(); @@ -158,4 +155,26 @@ public class CommonTestData { automationComposition.setElements(Map.of(element.getId(), element)); return automationComposition; } + + /** + * Create a new SimConfig. + * + * @return a new SimConfig + */ + public static SimConfig createSimConfig() { + var config = new SimConfig(); + config.setPrepareTimerMs(1); + config.setDeployTimerMs(1); + config.setReviewTimerMs(1); + config.setUndeployTimerMs(1); + config.setLockTimerMs(1); + config.setUnlockTimerMs(1); + config.setUpdateTimerMs(1); + config.setDeleteTimerMs(1); + config.setPrimeTimerMs(1); + config.setDeprimeTimerMs(1); + config.setMigrateTimerMs(1); + config.setMigratePrecheckTimerMs(1); + return config; + } } diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV1Test.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV1Test.java index 300caa52c..d78b851d4 100644 --- a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV1Test.java +++ b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV1Test.java @@ -28,194 +28,178 @@ import java.util.Map; import java.util.UUID; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.acm.participant.sim.model.SimConfig; +import org.onap.policy.clamp.acm.participant.sim.comm.CommonTestData; import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; 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.models.base.PfModelException; class AutomationCompositionElementHandlerV1Test { + private static final UUID COMPOSITION_ID = UUID.randomUUID(); + private static final UUID INSTANCE_ID = UUID.randomUUID(); + private static final UUID ELEMENT_ID = UUID.randomUUID(); + + private AcElementDeploy createAcElementDeploy() { + var element = new AcElementDeploy(); + element.setId(ELEMENT_ID); + return element; + } + @Test - void testDeploy() throws PfModelException { - var config = new SimConfig(); - config.setDeployTimerMs(1); + void testDeploy() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV1(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var instanceId = UUID.randomUUID(); - var element = new AcElementDeploy(); - element.setId(UUID.randomUUID()); - acElementHandler.deploy(instanceId, element, Map.of()); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(), + var element = createAcElementDeploy(); + acElementHandler.deploy(INSTANCE_ID, element, Map.of()); + verify(intermediaryApi).updateAutomationCompositionElementState(INSTANCE_ID, element.getId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed"); config.setDeploySuccess(false); - acElementHandler.deploy(instanceId, element, Map.of()); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(), + acElementHandler.deploy(INSTANCE_ID, element, Map.of()); + verify(intermediaryApi).updateAutomationCompositionElementState(INSTANCE_ID, element.getId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Deploy failed!"); } @Test - void testUndeploy() throws PfModelException { - var config = new SimConfig(); - config.setUndeployTimerMs(1); + void testUndeploy() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV1(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var instanceId = UUID.randomUUID(); - var elementId = UUID.randomUUID(); - acElementHandler.undeploy(instanceId, elementId); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, DeployState.UNDEPLOYED, + acElementHandler.undeploy(INSTANCE_ID, ELEMENT_ID); + verify(intermediaryApi).updateAutomationCompositionElementState(INSTANCE_ID, ELEMENT_ID, DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed"); config.setUndeploySuccess(false); - acElementHandler.undeploy(instanceId, elementId); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, DeployState.DEPLOYED, + acElementHandler.undeploy(INSTANCE_ID, ELEMENT_ID); + verify(intermediaryApi).updateAutomationCompositionElementState(INSTANCE_ID, ELEMENT_ID, DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Undeploy failed!"); } @Test - void testLock() throws PfModelException { - var config = new SimConfig(); - config.setLockTimerMs(1); + void testLock() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV1(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var instanceId = UUID.randomUUID(); - var elementId = UUID.randomUUID(); - acElementHandler.lock(instanceId, elementId); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, null, LockState.LOCKED, - StateChangeResult.NO_ERROR, "Locked"); + acElementHandler.lock(INSTANCE_ID, ELEMENT_ID); + verify(intermediaryApi).updateAutomationCompositionElementState(INSTANCE_ID, ELEMENT_ID, + null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked"); config.setLockSuccess(false); - acElementHandler.lock(instanceId, elementId); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, null, LockState.UNLOCKED, - StateChangeResult.FAILED, "Lock failed!"); + acElementHandler.lock(INSTANCE_ID, ELEMENT_ID); + verify(intermediaryApi).updateAutomationCompositionElementState(INSTANCE_ID, ELEMENT_ID, + null, LockState.UNLOCKED, StateChangeResult.FAILED, "Lock failed!"); } @Test - void testUnlock() throws PfModelException { - var config = new SimConfig(); - config.setUnlockTimerMs(1); + void testUnlock() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV1(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var instanceId = UUID.randomUUID(); - var elementId = UUID.randomUUID(); - acElementHandler.unlock(instanceId, elementId); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, null, LockState.UNLOCKED, - StateChangeResult.NO_ERROR, "Unlocked"); + acElementHandler.unlock(INSTANCE_ID, ELEMENT_ID); + verify(intermediaryApi).updateAutomationCompositionElementState(INSTANCE_ID, ELEMENT_ID, + null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked"); config.setUnlockSuccess(false); - acElementHandler.unlock(instanceId, elementId); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, null, LockState.LOCKED, - StateChangeResult.FAILED, "Unlock failed!"); + acElementHandler.unlock(INSTANCE_ID, ELEMENT_ID); + verify(intermediaryApi).updateAutomationCompositionElementState(INSTANCE_ID, ELEMENT_ID, + null, LockState.LOCKED, StateChangeResult.FAILED, "Unlock failed!"); } @Test - void testUpdate() throws PfModelException { - var config = new SimConfig(); - config.setUpdateTimerMs(1); + void testUpdate() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV1(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var instanceId = UUID.randomUUID(); - var element = new AcElementDeploy(); - element.setId(UUID.randomUUID()); - acElementHandler.update(instanceId, element, Map.of()); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(), + var element = createAcElementDeploy(); + acElementHandler.update(INSTANCE_ID, element, Map.of()); + verify(intermediaryApi).updateAutomationCompositionElementState(INSTANCE_ID, element.getId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Updated"); config.setUpdateSuccess(false); - acElementHandler.update(instanceId, element, Map.of()); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(), + acElementHandler.update(INSTANCE_ID, element, Map.of()); + verify(intermediaryApi).updateAutomationCompositionElementState(INSTANCE_ID, element.getId(), DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Update failed!"); } @Test - void testDelete() throws PfModelException { - var config = new SimConfig(); - config.setDeleteTimerMs(1); + void testDelete() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV1(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var instanceId = UUID.randomUUID(); - var elementId = UUID.randomUUID(); - acElementHandler.delete(instanceId, elementId); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, DeployState.DELETED, + acElementHandler.delete(INSTANCE_ID, ELEMENT_ID); + verify(intermediaryApi).updateAutomationCompositionElementState(INSTANCE_ID, ELEMENT_ID, DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted"); config.setDeleteSuccess(false); - acElementHandler.delete(instanceId, elementId); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, DeployState.UNDEPLOYED, + acElementHandler.delete(INSTANCE_ID, ELEMENT_ID); + verify(intermediaryApi).updateAutomationCompositionElementState(INSTANCE_ID, ELEMENT_ID, DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Delete failed!"); } @Test - void testPrime() throws PfModelException { - var config = new SimConfig(); - config.setPrimeTimerMs(1); + void testPrime() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV1(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var compositionId = UUID.randomUUID(); - acElementHandler.prime(compositionId, List.of()); - verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, + acElementHandler.prime(COMPOSITION_ID, List.of()); + verify(intermediaryApi).updateCompositionState(COMPOSITION_ID, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Primed"); config.setPrimeSuccess(false); - acElementHandler.prime(compositionId, List.of()); - verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.COMMISSIONED, + acElementHandler.prime(COMPOSITION_ID, List.of()); + verify(intermediaryApi).updateCompositionState(COMPOSITION_ID, AcTypeState.COMMISSIONED, StateChangeResult.FAILED, "Prime failed!"); } @Test - void testDeprime() throws PfModelException { - var config = new SimConfig(); - config.setDeprimeTimerMs(1); + void testDeprime() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV1(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var compositionId = UUID.randomUUID(); - acElementHandler.deprime(compositionId); - verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.COMMISSIONED, + acElementHandler.deprime(COMPOSITION_ID); + verify(intermediaryApi).updateCompositionState(COMPOSITION_ID, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR, "Deprimed"); config.setDeprimeSuccess(false); - acElementHandler.deprime(compositionId); - verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.FAILED, + acElementHandler.deprime(COMPOSITION_ID); + verify(intermediaryApi).updateCompositionState(COMPOSITION_ID, AcTypeState.PRIMED, StateChangeResult.FAILED, "Deprime failed!"); } @Test - void testMigrate() throws PfModelException { - var config = new SimConfig(); - config.setUpdateTimerMs(1); + void testMigrate() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV1(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var instanceId = UUID.randomUUID(); - var element = new AcElementDeploy(); - element.setId(UUID.randomUUID()); - acElementHandler.migrate(instanceId, element, UUID.randomUUID(), Map.of()); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(), + var element = createAcElementDeploy(); + acElementHandler.migrate(INSTANCE_ID, element, COMPOSITION_ID, Map.of()); + verify(intermediaryApi).updateAutomationCompositionElementState(INSTANCE_ID, element.getId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated"); config.setMigrateSuccess(false); - acElementHandler.migrate(instanceId, element, UUID.randomUUID(), Map.of()); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(), + acElementHandler.migrate(INSTANCE_ID, element, COMPOSITION_ID, Map.of()); + verify(intermediaryApi).updateAutomationCompositionElementState(INSTANCE_ID, element.getId(), DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Migrate failed!"); } } diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2Test.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2Test.java index 51e39067f..f3a1839f0 100644 --- a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2Test.java +++ b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2Test.java @@ -28,227 +28,312 @@ import java.util.UUID; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState; import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.acm.participant.sim.model.SimConfig; -import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; +import org.onap.policy.clamp.acm.participant.sim.comm.CommonTestData; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; 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.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; class AutomationCompositionElementHandlerV2Test { + private static final CompositionElementDto COMPOSITION_ELEMENT = + new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of()); + private static final InstanceElementDto INSTANCE_ELEMENT = + new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); + private static final CompositionDto COMPOSITION = new CompositionDto(UUID.randomUUID(), Map.of(), Map.of()); + @Test - void testDeploy() throws PfModelException { - var config = new SimConfig(); - config.setDeployTimerMs(1); + void testDeploy() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of()); - var instanceId = UUID.randomUUID(); - var elementId = UUID.randomUUID(); - var instanceElement = new InstanceElementDto(instanceId, elementId, null, Map.of(), Map.of()); - acElementHandler.deploy(compositionElement, instanceElement); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, DeployState.DEPLOYED, + acElementHandler.deploy(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed"); config.setDeploySuccess(false); - acElementHandler.deploy(compositionElement, instanceElement); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, DeployState.UNDEPLOYED, + acElementHandler.deploy(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Deploy failed!"); } @Test - void testUndeploy() throws PfModelException { - var config = new SimConfig(); - config.setUndeployTimerMs(1); + void testUndeploy() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of()); - var instanceId = UUID.randomUUID(); - var elementId = UUID.randomUUID(); - var instanceElement = new InstanceElementDto(instanceId, elementId, null, Map.of(), Map.of()); - acElementHandler.undeploy(compositionElement, instanceElement); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, DeployState.UNDEPLOYED, + acElementHandler.undeploy(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed"); config.setUndeploySuccess(false); - acElementHandler.undeploy(compositionElement, instanceElement); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, DeployState.DEPLOYED, + acElementHandler.undeploy(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Undeploy failed!"); } @Test - void testLock() throws PfModelException { - var config = new SimConfig(); - config.setLockTimerMs(1); + void testLock() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of()); - var instanceId = UUID.randomUUID(); - var elementId = UUID.randomUUID(); - var instanceElement = new InstanceElementDto(instanceId, elementId, null, Map.of(), Map.of()); - acElementHandler.lock(compositionElement, instanceElement); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, null, LockState.LOCKED, + acElementHandler.lock(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked"); config.setLockSuccess(false); - acElementHandler.lock(compositionElement, instanceElement); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, null, LockState.UNLOCKED, + acElementHandler.lock(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, LockState.UNLOCKED, StateChangeResult.FAILED, "Lock failed!"); } @Test - void testUnlock() throws PfModelException { - var config = new SimConfig(); - config.setUnlockTimerMs(1); + void testUnlock() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of()); - var instanceId = UUID.randomUUID(); - var elementId = UUID.randomUUID(); - var instanceElement = new InstanceElementDto(instanceId, elementId, null, Map.of(), Map.of()); - acElementHandler.unlock(compositionElement, instanceElement); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, null, LockState.UNLOCKED, + acElementHandler.unlock(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked"); config.setUnlockSuccess(false); - acElementHandler.unlock(compositionElement, instanceElement); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, null, LockState.LOCKED, + acElementHandler.unlock(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, LockState.LOCKED, StateChangeResult.FAILED, "Unlock failed!"); } @Test - void testUpdate() throws PfModelException { - var config = new SimConfig(); - config.setUpdateTimerMs(1); + void testUpdate() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of()); - var instanceId = UUID.randomUUID(); - var element = new AcElementDeploy(); - element.setId(UUID.randomUUID()); - var instanceElement = new InstanceElementDto(instanceId, element.getId(), null, Map.of(), Map.of()); - var instanceElementUpdated = new InstanceElementDto(instanceId, element.getId(), null, + var instanceElementUpdated = new InstanceElementDto( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, Map.of("key", "value"), Map.of()); - acElementHandler.update(compositionElement, instanceElement, instanceElementUpdated); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(), + acElementHandler.update(COMPOSITION_ELEMENT, INSTANCE_ELEMENT, instanceElementUpdated); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Updated"); config.setUpdateSuccess(false); - acElementHandler.update(compositionElement, instanceElement, instanceElementUpdated); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(), + acElementHandler.update(COMPOSITION_ELEMENT, INSTANCE_ELEMENT, instanceElementUpdated); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Update failed!"); } @Test - void testDelete() throws PfModelException { - var config = new SimConfig(); - config.setDeleteTimerMs(1); + void testDelete() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of()); - var instanceId = UUID.randomUUID(); - var elementId = UUID.randomUUID(); - var instanceElement = new InstanceElementDto(instanceId, elementId, null, Map.of(), Map.of()); - acElementHandler.delete(compositionElement, instanceElement); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, DeployState.DELETED, + acElementHandler.delete(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted"); config.setDeleteSuccess(false); - acElementHandler.delete(compositionElement, instanceElement); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId, DeployState.UNDEPLOYED, + acElementHandler.delete(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Delete failed!"); } @Test - void testPrime() throws PfModelException { - var config = new SimConfig(); - config.setPrimeTimerMs(1); + void testPrime() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var compositionId = UUID.randomUUID(); - var composition = new CompositionDto(compositionId, Map.of(), Map.of()); - acElementHandler.prime(composition); - verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, - "Primed"); + acElementHandler.prime(COMPOSITION); + verify(intermediaryApi).updateCompositionState( + COMPOSITION.compositionId(), AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Primed"); config.setPrimeSuccess(false); - acElementHandler.prime(composition); - verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.COMMISSIONED, - StateChangeResult.FAILED, "Prime failed!"); + acElementHandler.prime(COMPOSITION); + verify(intermediaryApi).updateCompositionState( + COMPOSITION.compositionId(), AcTypeState.COMMISSIONED, StateChangeResult.FAILED, "Prime failed!"); } @Test - void testDeprime() throws PfModelException { - var config = new SimConfig(); - config.setDeprimeTimerMs(1); + void testDeprime() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var compositionId = UUID.randomUUID(); - var composition = new CompositionDto(compositionId, Map.of(), Map.of()); - acElementHandler.deprime(composition); - verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.COMMISSIONED, - StateChangeResult.NO_ERROR, "Deprimed"); + acElementHandler.deprime(COMPOSITION); + verify(intermediaryApi).updateCompositionState( + COMPOSITION.compositionId(), AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR, "Deprimed"); config.setDeprimeSuccess(false); - acElementHandler.deprime(composition); - verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.FAILED, - "Deprime failed!"); + acElementHandler.deprime(COMPOSITION); + verify(intermediaryApi).updateCompositionState( + COMPOSITION.compositionId(), AcTypeState.PRIMED, StateChangeResult.FAILED, "Deprime failed!"); } @Test - void testMigrate() throws PfModelException { - var config = new SimConfig(); - config.setUpdateTimerMs(1); + void testMigrate() { + var config = CommonTestData.createSimConfig(); var intermediaryApi = mock(ParticipantIntermediaryApi.class); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + var compositionElementTarget = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of()); - var compositionElementTraget = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of()); - var instanceId = UUID.randomUUID(); - var element = new AcElementDeploy(); - element.setId(UUID.randomUUID()); - var instanceElement = new InstanceElementDto(instanceId, element.getId(), null, Map.of(), Map.of()); - var instanceElementMigrated = new InstanceElementDto(instanceId, element.getId(), + var instanceElementMigrated = new InstanceElementDto( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, Map.of("key", "value"), Map.of()); acElementHandler - .migrate(compositionElement, compositionElementTraget, instanceElement, instanceElementMigrated); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(), + .migrate(COMPOSITION_ELEMENT, compositionElementTarget, INSTANCE_ELEMENT, instanceElementMigrated); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated"); config.setMigrateSuccess(false); acElementHandler - .migrate(compositionElement, compositionElementTraget, instanceElement, instanceElementMigrated); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(), + .migrate(COMPOSITION_ELEMENT, compositionElementTarget, INSTANCE_ELEMENT, instanceElementMigrated); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Migrate failed!"); } + + @Test + void testMigrateAdd() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + + var compositionElement = new CompositionElementDto( + UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of(), ElementState.NOT_PRESENT); + + var instanceElement = new InstanceElementDto( + UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of(), ElementState.NOT_PRESENT); + + var compoElTargetAdd = new CompositionElementDto( + UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of(), ElementState.NEW); + var inElMigratedAdd = new InstanceElementDto( + instanceElement.instanceId(), instanceElement.elementId(), null, Map.of(), Map.of(), ElementState.NEW); + acElementHandler + .migrate(compositionElement, compoElTargetAdd, instanceElement, inElMigratedAdd); + verify(intermediaryApi).updateAutomationCompositionElementState( + instanceElement.instanceId(), instanceElement.elementId(), + DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated"); + } + + @Test + void testMigrateRemove() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + + var compoElTargetRemove = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of(), ElementState.REMOVED); + var inElMigratedRemove = new InstanceElementDto( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + null, Map.of("key", "value"), Map.of(), ElementState.REMOVED); + acElementHandler + .migrate(COMPOSITION_ELEMENT, compoElTargetRemove, INSTANCE_ELEMENT, inElMigratedRemove); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed"); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted"); + } + + @Test + void testMigratePrecheck() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + var compositionElementTarget = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElementMigrated = new InstanceElementDto( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + null, Map.of("key", "value"), Map.of()); + acElementHandler.migratePrecheck(COMPOSITION_ELEMENT, compositionElementTarget, + INSTANCE_ELEMENT, instanceElementMigrated); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Migration precheck completed"); + + config.setMigratePrecheck(false); + acElementHandler.migratePrecheck(COMPOSITION_ELEMENT, compositionElementTarget, + INSTANCE_ELEMENT, instanceElementMigrated); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + DeployState.DEPLOYED, null, + StateChangeResult.FAILED, "Migration precheck failed"); + } + + @Test + void testPrepare() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + acElementHandler.prepare(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED, + null, StateChangeResult.NO_ERROR, "Prepare completed"); + + config.setPrepare(false); + acElementHandler.prepare(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED, + null, StateChangeResult.FAILED, "Prepare failed"); + } + + @Test + void testReview() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + acElementHandler.review(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED, + null, StateChangeResult.NO_ERROR, "Review completed"); + + config.setReview(false); + acElementHandler.review(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED, + null, StateChangeResult.FAILED, "Review failed"); + } } diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV3Test.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV3Test.java new file mode 100644 index 000000000..d2d3d5c7e --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV3Test.java @@ -0,0 +1,358 @@ +/*- + * ============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.acm.participant.sim.main.handler; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState; +import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.acm.participant.sim.comm.CommonTestData; +import org.onap.policy.clamp.models.acm.concepts.AcTypeState; +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.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +class AutomationCompositionElementHandlerV3Test { + + private static final CompositionElementDto COMPOSITION_ELEMENT = + new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of()); + private static final InstanceElementDto INSTANCE_ELEMENT = + new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); + private static final CompositionDto COMPOSITION = new CompositionDto(UUID.randomUUID(), Map.of(), Map.of()); + + @Test + void testDeploy() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + acElementHandler.deploy(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED, + null, StateChangeResult.NO_ERROR, "Deployed"); + + config.setDeploySuccess(false); + acElementHandler.deploy(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED, + null, StateChangeResult.FAILED, "Deploy failed!"); + } + + @Test + void testUndeploy() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + acElementHandler.undeploy(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED, + null, StateChangeResult.NO_ERROR, "Undeployed"); + + config.setUndeploySuccess(false); + acElementHandler.undeploy(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED, + null, StateChangeResult.FAILED, "Undeploy failed!"); + } + + @Test + void testLock() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + acElementHandler.lock(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, LockState.LOCKED, + StateChangeResult.NO_ERROR, "Locked"); + + config.setLockSuccess(false); + acElementHandler.lock(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, LockState.UNLOCKED, + StateChangeResult.FAILED, "Lock failed!"); + } + + @Test + void testUnlock() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + acElementHandler.unlock(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, LockState.UNLOCKED, + StateChangeResult.NO_ERROR, "Unlocked"); + + config.setUnlockSuccess(false); + acElementHandler.unlock(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, LockState.LOCKED, + StateChangeResult.FAILED, "Unlock failed!"); + } + + @Test + void testUpdate() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + var instanceElementUpdated = new InstanceElementDto( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), null, + Map.of("key", "value"), Map.of()); + acElementHandler.update(COMPOSITION_ELEMENT, INSTANCE_ELEMENT, instanceElementUpdated); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Updated"); + + config.setUpdateSuccess(false); + acElementHandler.update(COMPOSITION_ELEMENT, INSTANCE_ELEMENT, instanceElementUpdated); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Update failed!"); + } + + @Test + void testDelete() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + acElementHandler.delete(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DELETED, + null, StateChangeResult.NO_ERROR, "Deleted"); + + config.setDeleteSuccess(false); + acElementHandler.delete(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED, + null, StateChangeResult.FAILED, "Delete failed!"); + } + + @Test + void testPrime() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + acElementHandler.prime(COMPOSITION); + verify(intermediaryApi).updateCompositionState( + COMPOSITION.compositionId(), AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Primed"); + + config.setPrimeSuccess(false); + acElementHandler.prime(COMPOSITION); + verify(intermediaryApi).updateCompositionState( + COMPOSITION.compositionId(), AcTypeState.COMMISSIONED, StateChangeResult.FAILED, "Prime failed!"); + } + + @Test + void testDeprime() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + acElementHandler.deprime(COMPOSITION); + verify(intermediaryApi).updateCompositionState( + COMPOSITION.compositionId(), AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR, "Deprimed"); + + config.setDeprimeSuccess(false); + acElementHandler.deprime(COMPOSITION); + verify(intermediaryApi).updateCompositionState( + COMPOSITION.compositionId(), AcTypeState.PRIMED, StateChangeResult.FAILED, "Deprime failed!"); + } + + @Test + void testMigrate() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + var compositionElementTarget = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElementMigrated = new InstanceElementDto( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + null, Map.of("key", "value"), new HashMap<>()); + acElementHandler + .migrate(COMPOSITION_ELEMENT, compositionElementTarget, INSTANCE_ELEMENT, instanceElementMigrated, 0); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated"); + + config.setMigrateSuccess(false); + acElementHandler + .migrate(COMPOSITION_ELEMENT, compositionElementTarget, INSTANCE_ELEMENT, instanceElementMigrated, 0); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Migrate failed!"); + } + + @Test + void testMigrateStage() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + var compositionElementTarget = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of("stage", List.of(1, 2)), Map.of()); + var instanceElementMigrated = new InstanceElementDto(INSTANCE_ELEMENT.instanceId(), + INSTANCE_ELEMENT.elementId(), null, Map.of(), new HashMap<>()); + acElementHandler + .migrate(COMPOSITION_ELEMENT, compositionElementTarget, INSTANCE_ELEMENT, instanceElementMigrated, 1); + verify(intermediaryApi).updateAutomationCompositionElementStage( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + StateChangeResult.NO_ERROR, 2, "stage 1 Migrated"); + } + + @Test + void testMigrateAdd() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + var compositionElement = new CompositionElementDto( + UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of(), ElementState.NOT_PRESENT); + + var instanceElement = new InstanceElementDto( + UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of(), ElementState.NOT_PRESENT); + + var compoElTargetAdd = new CompositionElementDto( + UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of(), ElementState.NEW); + var inElMigratedAdd = new InstanceElementDto(instanceElement.instanceId(), instanceElement.elementId(), + null, Map.of(), new HashMap<>(), ElementState.NEW); + acElementHandler + .migrate(compositionElement, compoElTargetAdd, instanceElement, inElMigratedAdd, 0); + verify(intermediaryApi).updateAutomationCompositionElementState( + instanceElement.instanceId(), instanceElement.elementId(), + DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated"); + } + + @Test + void testMigrateRemove() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + + var compoElTargetRemove = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of(), ElementState.REMOVED); + var inElMigratedRemove = new InstanceElementDto( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + null, Map.of("key", "value"), Map.of(), ElementState.REMOVED); + acElementHandler + .migrate(COMPOSITION_ELEMENT, compoElTargetRemove, INSTANCE_ELEMENT, inElMigratedRemove, 0); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed"); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted"); + } + + @Test + void testMigratePrecheck() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + var compositionElementTarget = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElementMigrated = new InstanceElementDto( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + null, Map.of("key", "value"), Map.of()); + acElementHandler.migratePrecheck(COMPOSITION_ELEMENT, compositionElementTarget, + INSTANCE_ELEMENT, instanceElementMigrated); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Migration precheck completed"); + + config.setMigratePrecheck(false); + acElementHandler.migratePrecheck(COMPOSITION_ELEMENT, compositionElementTarget, + INSTANCE_ELEMENT, instanceElementMigrated); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + DeployState.DEPLOYED, null, + StateChangeResult.FAILED, "Migration precheck failed"); + } + + @Test + void testPrepare() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + acElementHandler.prepare(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED, + null, StateChangeResult.NO_ERROR, "Prepare completed"); + + config.setPrepare(false); + acElementHandler.prepare(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.UNDEPLOYED, + null, StateChangeResult.FAILED, "Prepare failed"); + } + + @Test + void testReview() { + var config = CommonTestData.createSimConfig(); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var simulatorService = new SimulatorService(intermediaryApi); + var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); + simulatorService.setConfig(config); + acElementHandler.review(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED, + null, StateChangeResult.NO_ERROR, "Review completed"); + + config.setReview(false); + acElementHandler.review(COMPOSITION_ELEMENT, INSTANCE_ELEMENT); + verify(intermediaryApi).updateAutomationCompositionElementState( + INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), DeployState.DEPLOYED, + null, StateChangeResult.FAILED, "Review failed"); + } +} diff --git a/participant/participant-impl/pom.xml b/participant/participant-impl/pom.xml index 5961b90cd..3ee6db78e 100644 --- a/participant/participant-impl/pom.xml +++ b/participant/participant-impl/pom.xml @@ -27,7 +27,7 @@ <parent> <groupId>org.onap.policy.clamp.participant</groupId> <artifactId>policy-clamp-participant</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>policy-clamp-participant-impl</artifactId> diff --git a/participant/participant-intermediary/pom.xml b/participant/participant-intermediary/pom.xml index 97c98f6dd..d16e17a86 100644 --- a/participant/participant-intermediary/pom.xml +++ b/participant/participant-intermediary/pom.xml @@ -25,7 +25,7 @@ <parent> <groupId>org.onap.policy.clamp.participant</groupId> <artifactId>policy-clamp-participant</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>policy-clamp-participant-intermediary</artifactId> diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java index 505f515d7..5994328d5 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java @@ -20,9 +20,6 @@ package org.onap.policy.clamp.acm.participant.intermediary.api; -import org.onap.policy.clamp.models.acm.concepts.AcTypeState; -import org.onap.policy.clamp.models.acm.concepts.DeployState; -import org.onap.policy.clamp.models.acm.concepts.LockState; import org.onap.policy.models.base.PfModelException; /** @@ -89,20 +86,26 @@ public interface AutomationCompositionElementListener { void deprime(CompositionDto composition) throws PfModelException; - void handleRestartComposition(CompositionDto composition, AcTypeState state) throws PfModelException; - - void handleRestartInstance(CompositionElementDto compositionElement, InstanceElementDto instanceElement, - DeployState deployState, LockState lockState) throws PfModelException; - /** * Handle an update on a automation composition element. * - * @param compositionElement the information of the Automation Composition Definition Element + * @param compositionElement the information of the Automation Composition Definition Element * @param compositionElementTarget the information of the Automation Composition Definition Element Target - * @param instanceElement the information of the Automation Composition Instance Element - * @param instanceElementMigrate the information of the Automation Composition Instance Element updated + * @param instanceElement the information of the Automation Composition Instance Element + * @param instanceElementMigrate the information of the Automation Composition Instance Element updated + * @param nextStage the next stage * @throws PfModelException from Policy framework */ void migrate(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, + InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate, + int nextStage) throws PfModelException; + + void migratePrecheck(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate) throws PfModelException; + + void review(CompositionElementDto compositionElement, InstanceElementDto instanceElement) + throws PfModelException; + + void prepare(CompositionElementDto compositionElement, InstanceElementDto instanceElement) + throws PfModelException; } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/CompositionDto.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/CompositionDto.java index 88f080bc7..4902a9efb 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/CompositionDto.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/CompositionDto.java @@ -20,10 +20,8 @@ package org.onap.policy.clamp.acm.participant.intermediary.api; -import java.util.List; import java.util.Map; import java.util.UUID; -import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; public record CompositionDto(UUID compositionId, diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/CompositionElementDto.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/CompositionElementDto.java index d203f90cb..50699e22c 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/CompositionElementDto.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/CompositionElementDto.java @@ -25,5 +25,12 @@ import java.util.UUID; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; public record CompositionElementDto(UUID compositionId, ToscaConceptIdentifier elementDefinitionId, - Map<String, Object> inProperties, Map<String, Object> outProperties) { + Map<String, Object> inProperties, Map<String, Object> outProperties, + ElementState state) { + + public CompositionElementDto(UUID compositionId, ToscaConceptIdentifier elementDefinitionId, + Map<String, Object> inProperties, Map<String, Object> outProperties) { + this(compositionId, elementDefinitionId, inProperties, outProperties, ElementState.PRESENT); + + } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ElementState.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ElementState.java new file mode 100644 index 000000000..afb01d014 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ElementState.java @@ -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.acm.participant.intermediary.api; + +public enum ElementState { + PRESENT, + NOT_PRESENT, + REMOVED, + NEW +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/InstanceElementDto.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/InstanceElementDto.java index 197d7e46d..b4fdefbf3 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/InstanceElementDto.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/InstanceElementDto.java @@ -22,10 +22,14 @@ package org.onap.policy.clamp.acm.participant.intermediary.api; import java.util.Map; import java.util.UUID; -import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; -import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; public record InstanceElementDto(UUID instanceId, UUID elementId, ToscaServiceTemplate toscaServiceTemplateFragment, - Map<String, Object> inProperties, Map<String, Object> outProperties) { + Map<String, Object> inProperties, Map<String, Object> outProperties, + ElementState state) { + + public InstanceElementDto(UUID instanceId, UUID elementId, ToscaServiceTemplate toscaServiceTemplateFragment, + Map<String, Object> inProperties, Map<String, Object> outProperties) { + this(instanceId, elementId, toscaServiceTemplateFragment, inProperties, outProperties, ElementState.PRESENT); + } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java index 9b3279232..c06ffe62e 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java @@ -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. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -38,41 +38,52 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; public interface ParticipantIntermediaryApi { /** - * Update the state of a automation composition element. + * Update the state of a AutomationComposition Instance Element. * - * @param automationCompositionId the ID of the automation composition to update the state on - * @param elementId the ID of the automation composition element to update the state on - * @param deployState the Deploy State of the automation composition element - * @param lockState the Lock State of the automation composition element + * @param instance the ID of the AutomationComposition Instance to update the state on + * @param elementId the ID of the AutomationComposition Instance element to update the state on + * @param deployState the Deploy State of the AutomationComposition Instance element + * @param lockState the Lock State of the AutomationComposition Instance element * @param stateChangeResult the indicator if error occurs * @param message the message */ - void updateAutomationCompositionElementState(UUID automationCompositionId, UUID elementId, DeployState deployState, + void updateAutomationCompositionElementState(UUID instance, UUID elementId, DeployState deployState, LockState lockState, StateChangeResult stateChangeResult, String message); /** - * Get a copy of all AutomationCompositions. + * Update the stage of a AutomationComposition Instance Element. * - * @return get all AutomationCompositions + * @param instance the ID of the AutomationComposition Instance to update the state on + * @param elementId the ID of the AutomationComposition Instance Element to update the state on + * @param stateChangeResult the indicator if error occurs + * @param message the message + */ + void updateAutomationCompositionElementStage(UUID instance, UUID elementId, StateChangeResult stateChangeResult, + int stage, String message); + + /** + * Get a copy of all AutomationComposition Instances. + * + * @return get all AutomationComposition Instances */ Map<UUID, AutomationComposition> getAutomationCompositions(); /** - * Get a copy of the AutomationComposition by automationCompositionId. + * Get a copy of the AutomationComposition Instance by AutomationComposition Instance Id. * - * @param automationCompositionId the ID of the automation composition to update the state on - * @return get the AutomationComposition + * @param instanceId the ID of the AutomationComposition Instance to update the state on + * @return get the AutomationComposition Instance */ - AutomationComposition getAutomationComposition(UUID automationCompositionId); + AutomationComposition getAutomationComposition(UUID instanceId); /** - * Get a copy of the AutomationCompositionElement by automationCompositionId and elementId. + * Get a copy of the AutomationCompositionElement by AutomationComposition Instance Id and elementId. * - * @param automationCompositionId the ID of the automation composition to update the state on - * @param elementId the ID of the automation composition element to update the state on + * @param instanceId the ID of the AutomationComposition Instance to update the state on + * @param elementId the ID of the AutomationComposition Instance Element to update the state on * @return get the AutomationCompositionElement */ - AutomationCompositionElement getAutomationCompositionElement(UUID automationCompositionId, UUID elementId); + AutomationCompositionElement getAutomationCompositionElement(UUID instanceId, UUID elementId); /** * Get a copy of all AutomationCompositionElementDefinition from all primed compositions. @@ -99,15 +110,15 @@ public interface ParticipantIntermediaryApi { AutomationCompositionElementDefinition getAcElementDefinition(UUID compositionId, ToscaConceptIdentifier elementId); /** - * Send Automation Composition Element update Info to AC-runtime. + * Send AutomationComposition Instance Element update Info to AC-runtime. * - * @param automationCompositionId the ID of the automation composition to update the states - * @param elementId the ID of the automation composition element to update the states + * @param instanceId the ID of the AutomationComposition Instance to update the states + * @param elementId the ID of the AutomationComposition Instance Element to update the states * @param useState the use State * @param operationalState the operational State * @param outProperties the output Properties Map */ - void sendAcElementInfo(UUID automationCompositionId, UUID elementId, String useState, String operationalState, + void sendAcElementInfo(UUID instanceId, UUID elementId, String useState, String operationalState, Map<String, Object> outProperties); /** diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV1.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV1.java index 5d4e1fe7c..34bdc349b 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV1.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV1.java @@ -20,6 +20,7 @@ package org.onap.policy.clamp.acm.participant.intermediary.api.impl; +import jakarta.ws.rs.core.Response; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -44,9 +45,12 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; * Wrapper of AutomationCompositionElementListener. * Valid since 7.1.0 release. */ -public abstract class AcElementListenerV1 implements AutomationCompositionElementListener { +public abstract class AcElementListenerV1 + implements AutomationCompositionElementListener, AutomationCompositionElementListenerV1 { protected final ParticipantIntermediaryApi intermediaryApi; + private static final String NOT_SUPPORTED = "not supported!"; + protected AcElementListenerV1(ParticipantIntermediaryApi intermediaryApi) { this.intermediaryApi = intermediaryApi; } @@ -64,23 +68,19 @@ public abstract class AcElementListenerV1 implements AutomationCompositionElemen deploy(instanceElement.instanceId(), element, properties); } - public abstract void deploy(UUID instanceId, AcElementDeploy element, Map<String, Object> properties) - throws PfModelException; - @Override public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException { undeploy(instanceElement.instanceId(), instanceElement.elementId()); } - public abstract void undeploy(UUID instanceId, UUID elementId) throws PfModelException; - @Override public void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException { lock(instanceElement.instanceId(), instanceElement.elementId()); } + @Override public void lock(UUID instanceId, UUID elementId) throws PfModelException { intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked"); @@ -92,6 +92,7 @@ public abstract class AcElementListenerV1 implements AutomationCompositionElemen unlock(instanceElement.instanceId(), instanceElement.elementId()); } + @Override public void unlock(UUID instanceId, UUID elementId) throws PfModelException { intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked"); @@ -103,6 +104,7 @@ public abstract class AcElementListenerV1 implements AutomationCompositionElemen delete(instanceElement.instanceId(), instanceElement.elementId()); } + @Override public void delete(UUID instanceId, UUID elementId) throws PfModelException { intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted"); @@ -150,6 +152,7 @@ public abstract class AcElementListenerV1 implements AutomationCompositionElemen prime(composition.compositionId(), createAcElementDefinitionList(composition)); } + @Override public void prime(UUID compositionId, List<AutomationCompositionElementDefinition> elementDefinitionList) throws PfModelException { intermediaryApi.updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Primed"); @@ -160,14 +163,14 @@ public abstract class AcElementListenerV1 implements AutomationCompositionElemen deprime(composition.compositionId()); } + @Override public void deprime(UUID compositionId) throws PfModelException { intermediaryApi.updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR, "Deprimed"); } - @Override public void handleRestartComposition(CompositionDto composition, AcTypeState state) throws PfModelException { - handleRestartComposition(composition.compositionId(), createAcElementDefinitionList(composition), state); + throw new PfModelException(Response.Status.BAD_REQUEST, NOT_SUPPORTED); } /** @@ -180,24 +183,12 @@ public abstract class AcElementListenerV1 implements AutomationCompositionElemen */ public void handleRestartComposition(UUID compositionId, List<AutomationCompositionElementDefinition> elementDefinitionList, AcTypeState state) throws PfModelException { - switch (state) { - case PRIMING -> prime(compositionId, elementDefinitionList); - case DEPRIMING -> deprime(compositionId); - default -> - intermediaryApi.updateCompositionState(compositionId, state, StateChangeResult.NO_ERROR, "Restarted"); - } + throw new PfModelException(Response.Status.BAD_REQUEST, NOT_SUPPORTED); } - @Override public void handleRestartInstance(CompositionElementDto compositionElement, InstanceElementDto instanceElement, DeployState deployState, LockState lockState) throws PfModelException { - var element = new AcElementDeploy(); - element.setId(instanceElement.elementId()); - element.setDefinition(compositionElement.elementDefinitionId()); - element.setProperties(instanceElement.inProperties()); - Map<String, Object> properties = new HashMap<>(instanceElement.inProperties()); - properties.putAll(compositionElement.inProperties()); - handleRestartInstance(instanceElement.instanceId(), element, properties, deployState, lockState); + throw new PfModelException(Response.Status.BAD_REQUEST, NOT_SUPPORTED); } /** @@ -212,38 +203,14 @@ public abstract class AcElementListenerV1 implements AutomationCompositionElemen */ public void handleRestartInstance(UUID instanceId, AcElementDeploy element, Map<String, Object> properties, DeployState deployState, LockState lockState) throws PfModelException { + throw new PfModelException(Response.Status.BAD_REQUEST, NOT_SUPPORTED); - if (DeployState.DEPLOYING.equals(deployState)) { - deploy(instanceId, element, properties); - return; - } - if (DeployState.UNDEPLOYING.equals(deployState)) { - undeploy(instanceId, element.getId()); - return; - } - if (DeployState.UPDATING.equals(deployState)) { - update(instanceId, element, properties); - return; - } - if (DeployState.DELETING.equals(deployState)) { - delete(instanceId, element.getId()); - return; - } - if (LockState.LOCKING.equals(lockState)) { - lock(instanceId, element.getId()); - return; - } - if (LockState.UNLOCKING.equals(lockState)) { - unlock(instanceId, element.getId()); - return; - } - intermediaryApi.updateAutomationCompositionElementState(instanceId, element.getId(), - deployState, lockState, StateChangeResult.NO_ERROR, "Restarted"); } @Override public void migrate(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, - InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate) throws PfModelException { + InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate, + int stage) throws PfModelException { var element = new AcElementDeploy(); element.setId(instanceElementMigrate.elementId()); element.setDefinition(compositionElementTarget.elementDefinitionId()); @@ -252,9 +219,35 @@ public abstract class AcElementListenerV1 implements AutomationCompositionElemen element.getProperties()); } + @Override public void migrate(UUID instanceId, AcElementDeploy element, UUID compositionTargetId, Map<String, Object> properties) throws PfModelException { intermediaryApi.updateAutomationCompositionElementState(instanceId, element.getId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated"); } + + @Override + public void migratePrecheck(CompositionElementDto compositionElement, + CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, + InstanceElementDto instanceElementMigrate) throws PfModelException { + intermediaryApi.updateAutomationCompositionElementState(instanceElementMigrate.instanceId(), + instanceElementMigrate.elementId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Migration Precheck completed"); + } + + @Override + public void review(CompositionElementDto compositionElement, InstanceElementDto instanceElement) + throws PfModelException { + intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Review completed"); + } + + @Override + public void prepare(CompositionElementDto compositionElement, InstanceElementDto instanceElement) + throws PfModelException { + intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.UNDEPLOYED, null, + StateChangeResult.NO_ERROR, "Prepare completed"); + } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV2.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV2.java index daf9d6e71..7db220095 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV2.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV2.java @@ -20,6 +20,7 @@ package org.onap.policy.clamp.acm.participant.intermediary.api.impl; +import jakarta.ws.rs.core.Response; import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; @@ -35,9 +36,12 @@ import org.onap.policy.models.base.PfModelException; * Wrapper of AutomationCompositionElementListener. * Valid since 7.1.1 release. */ -public abstract class AcElementListenerV2 implements AutomationCompositionElementListener { +public abstract class AcElementListenerV2 + implements AutomationCompositionElementListener, AutomationCompositionElementListenerV2 { protected final ParticipantIntermediaryApi intermediaryApi; + private static final String NOT_SUPPORTED = "not supported!"; + protected AcElementListenerV2(ParticipantIntermediaryApi intermediaryApi) { this.intermediaryApi = intermediaryApi; } @@ -84,46 +88,20 @@ public abstract class AcElementListenerV2 implements AutomationCompositionElemen StateChangeResult.NO_ERROR, "Deprimed"); } - @Override public void handleRestartComposition(CompositionDto composition, AcTypeState state) throws PfModelException { - switch (state) { - case PRIMING -> prime(composition); - case DEPRIMING -> deprime(composition); - default -> intermediaryApi - .updateCompositionState(composition.compositionId(), state, StateChangeResult.NO_ERROR, "Restarted"); - } + throw new PfModelException(Response.Status.BAD_REQUEST, NOT_SUPPORTED); } - @Override public void handleRestartInstance(CompositionElementDto compositionElement, InstanceElementDto instanceElement, DeployState deployState, LockState lockState) throws PfModelException { + throw new PfModelException(Response.Status.BAD_REQUEST, NOT_SUPPORTED); + } - if (DeployState.DEPLOYING.equals(deployState)) { - deploy(compositionElement, instanceElement); - return; - } - if (DeployState.UNDEPLOYING.equals(deployState)) { - undeploy(compositionElement, instanceElement); - return; - } - if (DeployState.UPDATING.equals(deployState)) { - update(compositionElement, instanceElement, instanceElement); - return; - } - if (DeployState.DELETING.equals(deployState)) { - delete(compositionElement, instanceElement); - return; - } - if (LockState.LOCKING.equals(lockState)) { - lock(compositionElement, instanceElement); - return; - } - if (LockState.UNLOCKING.equals(lockState)) { - unlock(compositionElement, instanceElement); - return; - } - intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), - instanceElement.elementId(), deployState, lockState, StateChangeResult.NO_ERROR, "Restarted"); + @Override + public void migrate(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, + InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate, int stage) + throws PfModelException { + migrate(compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate); } @Override @@ -133,4 +111,29 @@ public abstract class AcElementListenerV2 implements AutomationCompositionElemen intermediaryApi.updateAutomationCompositionElementState(instanceElementMigrate.instanceId(), instanceElementMigrate.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated"); } + + @Override + public void migratePrecheck(CompositionElementDto compositionElement, + CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, + InstanceElementDto instanceElementMigrate) throws PfModelException { + intermediaryApi.updateAutomationCompositionElementState(instanceElementMigrate.instanceId(), + instanceElementMigrate.elementId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Migration Precheck completed"); + } + + @Override + public void review(CompositionElementDto compositionElement, InstanceElementDto instanceElement) + throws PfModelException { + intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Review completed"); + } + + @Override + public void prepare(CompositionElementDto compositionElement, InstanceElementDto instanceElement) + throws PfModelException { + intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.UNDEPLOYED, null, + StateChangeResult.NO_ERROR, "Prepare completed"); + } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV3.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV3.java new file mode 100644 index 000000000..d63323d1a --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV3.java @@ -0,0 +1,119 @@ +/*-
+ * ============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.acm.participant.intermediary.api.impl;
+
+import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener;
+import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto;
+import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto;
+import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto;
+import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
+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.models.base.PfModelException;
+
+/**
+ * Wrapper of AutomationCompositionElementListener.
+ * Valid since 8.0.1 release.
+ */
+public abstract class AcElementListenerV3 implements AutomationCompositionElementListener {
+ protected final ParticipantIntermediaryApi intermediaryApi;
+
+ protected AcElementListenerV3(ParticipantIntermediaryApi intermediaryApi) {
+ this.intermediaryApi = intermediaryApi;
+ }
+
+ @Override
+ public void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
+ throws PfModelException {
+ intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
+ instanceElement.elementId(), null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked");
+ }
+
+ @Override
+ public void unlock(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
+ throws PfModelException {
+ intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
+ instanceElement.elementId(), null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked");
+ }
+
+ @Override
+ public void delete(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
+ throws PfModelException {
+ intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
+ instanceElement.elementId(), DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted");
+ }
+
+ @Override
+ public void update(CompositionElementDto compositionElement, InstanceElementDto instanceElement,
+ InstanceElementDto instanceElementUpdated) throws PfModelException {
+ intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
+ instanceElement.elementId(), DeployState.DEPLOYED, null,
+ StateChangeResult.NO_ERROR, "Update not supported");
+
+ }
+
+ @Override
+ public void prime(CompositionDto composition) throws PfModelException {
+ intermediaryApi.updateCompositionState(composition.compositionId(), AcTypeState.PRIMED,
+ StateChangeResult.NO_ERROR, "Primed");
+ }
+
+ @Override
+ public void deprime(CompositionDto composition) throws PfModelException {
+ intermediaryApi.updateCompositionState(composition.compositionId(), AcTypeState.COMMISSIONED,
+ StateChangeResult.NO_ERROR, "Deprimed");
+ }
+
+ @Override
+ public void migrate(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget,
+ InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate, int stage)
+ throws PfModelException {
+ intermediaryApi.updateAutomationCompositionElementState(instanceElementMigrate.instanceId(),
+ instanceElementMigrate.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated");
+ }
+
+ @Override
+ public void migratePrecheck(CompositionElementDto compositionElement,
+ CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement,
+ InstanceElementDto instanceElementMigrate) throws PfModelException {
+ intermediaryApi.updateAutomationCompositionElementState(instanceElementMigrate.instanceId(),
+ instanceElementMigrate.elementId(), DeployState.DEPLOYED, null,
+ StateChangeResult.NO_ERROR, "Migration Precheck completed");
+ }
+
+ @Override
+ public void review(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
+ throws PfModelException {
+ intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
+ instanceElement.elementId(), DeployState.DEPLOYED, null,
+ StateChangeResult.NO_ERROR, "Review completed");
+ }
+
+ @Override
+ public void prepare(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
+ throws PfModelException {
+ intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
+ instanceElement.elementId(), DeployState.UNDEPLOYED, null,
+ StateChangeResult.NO_ERROR, "Prepare completed");
+ }
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AutomationCompositionElementListenerV1.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AutomationCompositionElementListenerV1.java new file mode 100644 index 000000000..007ba3d80 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AutomationCompositionElementListenerV1.java @@ -0,0 +1,53 @@ +/*- + * ============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.acm.participant.intermediary.api.impl; + +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; +import org.onap.policy.models.base.PfModelException; + +public interface AutomationCompositionElementListenerV1 { + + void undeploy(UUID automationCompositionId, UUID automationCompositionElementId) throws PfModelException; + + void deploy(UUID automationCompositionId, AcElementDeploy element, Map<String, Object> properties) + throws PfModelException; + + void lock(UUID automationCompositionId, UUID automationCompositionElementId) throws PfModelException; + + void unlock(UUID automationCompositionId, UUID automationCompositionElementId) throws PfModelException; + + void delete(UUID automationCompositionId, UUID automationCompositionElementId) throws PfModelException; + + void update(UUID automationCompositionId, AcElementDeploy element, Map<String, Object> properties) + throws PfModelException; + + void prime(UUID compositionId, List<AutomationCompositionElementDefinition> elementDefinitionList) + throws PfModelException; + + void deprime(UUID compositionId) throws PfModelException; + + void migrate(UUID instanceId, AcElementDeploy element, UUID compositionTargetId, + Map<String, Object> properties) throws PfModelException; +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AutomationCompositionElementListenerV2.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AutomationCompositionElementListenerV2.java new file mode 100644 index 000000000..721caa88e --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AutomationCompositionElementListenerV2.java @@ -0,0 +1,58 @@ +/*- + * ============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.acm.participant.intermediary.api.impl; + +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; +import org.onap.policy.models.base.PfModelException; + +public interface AutomationCompositionElementListenerV2 { + + void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException; + + void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException; + + void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException; + + void unlock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException; + + void delete(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException; + + void update(CompositionElementDto compositionElement, InstanceElementDto instanceElement, + InstanceElementDto instanceElementUpdated) throws PfModelException; + + void prime(CompositionDto composition) throws PfModelException; + + void deprime(CompositionDto composition) throws PfModelException; + + void migrate(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, + InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate) throws PfModelException; + + void migratePrecheck(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, + InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate) throws PfModelException; + + void review(CompositionElementDto compositionElement, InstanceElementDto instanceElement) + throws PfModelException; + + void prepare(CompositionElementDto compositionElement, InstanceElementDto instanceElement) + throws PfModelException; +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java index 5cdbacab6..233b55926 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java @@ -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. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -50,16 +50,23 @@ public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryAp private final CacheProvider cacheProvider; @Override - public void updateAutomationCompositionElementState(UUID automationCompositionId, UUID id, DeployState newState, + public void updateAutomationCompositionElementState(UUID instance, UUID elementId, DeployState deployState, LockState lockState, StateChangeResult stateChangeResult, String message) { - automationCompositionHandler.updateAutomationCompositionElementState(automationCompositionId, id, newState, - lockState, stateChangeResult, message); + automationCompositionHandler.updateAutomationCompositionElementState(instance, elementId, deployState, + lockState, stateChangeResult, message); } @Override - public void sendAcElementInfo(UUID automationCompositionId, UUID elementId, String useState, + public void updateAutomationCompositionElementStage(UUID instance, UUID elementId, + StateChangeResult stateChangeResult, int stage, String message) { + automationCompositionHandler.updateAutomationCompositionElementStage(instance, elementId, stateChangeResult, + stage, message); + } + + @Override + public void sendAcElementInfo(UUID instance, UUID elementId, String useState, String operationalState, Map<String, Object> outProperties) { - automationCompositionHandler.sendAcElementInfo(automationCompositionId, elementId, useState, operationalState, + automationCompositionHandler.sendAcElementInfo(instance, elementId, useState, operationalState, outProperties); } @@ -75,8 +82,8 @@ public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryAp } @Override - public AutomationCompositionElement getAutomationCompositionElement(UUID automationCompositionId, UUID elementId) { - var automationComposition = cacheProvider.getAutomationCompositions().get(automationCompositionId); + public AutomationCompositionElement getAutomationCompositionElement(UUID instanceId, UUID elementId) { + var automationComposition = cacheProvider.getAutomationCompositions().get(instanceId); if (automationComposition == null) { return null; } @@ -91,8 +98,8 @@ public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryAp } @Override - public AutomationComposition getAutomationComposition(UUID automationCompositionId) { - var automationComposition = cacheProvider.getAutomationCompositions().get(automationCompositionId); + public AutomationComposition getAutomationComposition(UUID instanceId) { + var automationComposition = cacheProvider.getAutomationCompositions().get(instanceId); return automationComposition != null ? new AutomationComposition(automationComposition) : null; } @@ -107,7 +114,7 @@ public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryAp UUID compositionId) { var acElementDefinitions = cacheProvider.getAcElementsDefinitions().get(compositionId); if (acElementDefinitions == null) { - return null; + return Map.of(); } return PfUtils.mapMap(acElementDefinitions, AutomationCompositionElementDefinition::new); } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantRestartListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AcPrepareListener.java index fd59b02ee..0f6d2c09f 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantRestartListener.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AcPrepareListener.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023-2024 Nordix Foundation. + * 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. @@ -21,24 +21,26 @@ package org.onap.policy.clamp.acm.participant.intermediary.comm; import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionPrepare; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMessageType; -import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRestart; import org.springframework.stereotype.Component; @Component -public class ParticipantRestartListener extends ParticipantListener<ParticipantRestart> { +public class AcPrepareListener extends ParticipantListener<AutomationCompositionPrepare> { /** * Constructs the object. * * @param participantHandler the handler for managing the state of the participant */ - public ParticipantRestartListener(ParticipantHandler participantHandler) { - super(ParticipantRestart.class, participantHandler, participantHandler::handleParticipantRestart); + public AcPrepareListener(final ParticipantHandler participantHandler) { + super(AutomationCompositionPrepare.class, participantHandler, + participantHandler::handleAutomationCompositionPrepare); } + @Override public String getType() { - return ParticipantMessageType.PARTICIPANT_RESTART.name(); + return ParticipantMessageType.AUTOMATION_COMPOSITION_PREPARE.name(); } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantRegisterAckListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantRegisterAckListener.java index 544e66fe4..8b8192e3a 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantRegisterAckListener.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantRegisterAckListener.java @@ -45,4 +45,9 @@ public class ParticipantRegisterAckListener extends ParticipantAckListener<Parti public String getType() { return ParticipantMessageType.PARTICIPANT_REGISTER_ACK.name(); } + + @Override + public boolean isDefaultTopic() { + return false; + } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantStatusReqListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantStatusReqListener.java index ec3e568e3..12ff57217 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantStatusReqListener.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantStatusReqListener.java @@ -44,4 +44,9 @@ public class ParticipantStatusReqListener extends ParticipantListener<Participan public String getType() { return ParticipantMessageType.PARTICIPANT_STATUS_REQ.name(); } + + @Override + public boolean isDefaultTopic() { + return false; + } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcDefinitionHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcDefinitionHandler.java index d3ad4cf3e..b38df515a 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcDefinitionHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcDefinitionHandler.java @@ -34,7 +34,7 @@ import org.onap.policy.clamp.models.acm.concepts.ParticipantState; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrime; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrimeAck; -import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRestart; +import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantSync; import org.springframework.stereotype.Component; @Component @@ -107,32 +107,33 @@ public class AcDefinitionHandler { } /** - * Handle a ParticipantRestart message. + * Handle a Participant Sync message. * - * @param participantRestartMsg the participantRestart message + * @param participantSyncMsg the participantRestart message */ - public void handleParticipantRestart(ParticipantRestart participantRestartMsg) { - List<AutomationCompositionElementDefinition> list = new ArrayList<>(); - for (var participantDefinition : participantRestartMsg.getParticipantDefinitionUpdates()) { - list.addAll(participantDefinition.getAutomationCompositionElementDefinitionList()); + public void handleParticipantSync(ParticipantSync participantSyncMsg) { + + if (participantSyncMsg.isDelete()) { + if (AcTypeState.COMMISSIONED.equals(participantSyncMsg.getState())) { + cacheProvider.removeElementDefinition(participantSyncMsg.getCompositionId()); + } + for (var automationcomposition : participantSyncMsg.getAutomationcompositionList()) { + cacheProvider.removeAutomationComposition(automationcomposition.getAutomationCompositionId()); + } + return; } - if (!AcTypeState.COMMISSIONED.equals(participantRestartMsg.getState())) { - cacheProvider.addElementDefinition(participantRestartMsg.getCompositionId(), list); + + if (!participantSyncMsg.getParticipantDefinitionUpdates().isEmpty()) { + List<AutomationCompositionElementDefinition> list = new ArrayList<>(); + for (var participantDefinition : participantSyncMsg.getParticipantDefinitionUpdates()) { + list.addAll(participantDefinition.getAutomationCompositionElementDefinitionList()); + } + cacheProvider.addElementDefinition(participantSyncMsg.getCompositionId(), list); } - for (var automationcomposition : participantRestartMsg.getAutomationcompositionList()) { + for (var automationcomposition : participantSyncMsg.getAutomationcompositionList()) { cacheProvider - .initializeAutomationComposition(participantRestartMsg.getCompositionId(), automationcomposition); + .initializeAutomationComposition(participantSyncMsg.getCompositionId(), automationcomposition); } - var inPropertiesMap = list.stream().collect(Collectors.toMap( - AutomationCompositionElementDefinition::getAcElementDefinitionId, - el -> el.getAutomationCompositionElementToscaNodeTemplate().getProperties())); - var outPropertiesMap = list.stream().collect(Collectors.toMap( - AutomationCompositionElementDefinition::getAcElementDefinitionId, - AutomationCompositionElementDefinition::getOutProperties)); - var composition = - new CompositionDto(participantRestartMsg.getCompositionId(), inPropertiesMap, outPropertiesMap); - listener.restarted(participantRestartMsg.getMessageId(), composition, participantRestartMsg.getState(), - participantRestartMsg.getAutomationcompositionList()); } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java index ddf465a2d..95613cc9e 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java @@ -27,6 +27,7 @@ import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.LockState; import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; +import org.onap.policy.clamp.models.acm.concepts.SubState; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionStateChange; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -70,16 +71,20 @@ public class AcLockHandler { private void handleLockState(UUID messageId, final AutomationComposition automationComposition, Integer startPhaseMsg) { + automationComposition.setLockState(LockState.LOCKING); + var serviceTemplateFragment = cacheProvider + .getServiceTemplateFragmentMap().get(automationComposition.getCompositionId()); for (var element : automationComposition.getElements().values()) { var compositionInProperties = cacheProvider .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition()); int startPhase = ParticipantUtils.findStartPhase(compositionInProperties); if (startPhaseMsg.equals(startPhase)) { element.setLockState(LockState.LOCKING); + element.setSubState(SubState.NONE); var compositionElement = cacheProvider.createCompositionElementDto( automationComposition.getCompositionId(), element, compositionInProperties); var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(), - null, element.getProperties(), element.getOutProperties()); + serviceTemplateFragment, element.getProperties(), element.getOutProperties()); listener.lock(messageId, compositionElement, instanceElement); } } @@ -87,16 +92,20 @@ public class AcLockHandler { private void handleUnlockState(UUID messageId, final AutomationComposition automationComposition, Integer startPhaseMsg) { + automationComposition.setLockState(LockState.UNLOCKING); + var serviceTemplateFragment = cacheProvider + .getServiceTemplateFragmentMap().get(automationComposition.getCompositionId()); for (var element : automationComposition.getElements().values()) { var compositionInProperties = cacheProvider .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition()); int startPhase = ParticipantUtils.findStartPhase(compositionInProperties); if (startPhaseMsg.equals(startPhase)) { element.setLockState(LockState.UNLOCKING); + element.setSubState(SubState.NONE); var compositionElement = cacheProvider.createCompositionElementDto( automationComposition.getCompositionId(), element, compositionInProperties); var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(), - null, element.getProperties(), element.getOutProperties()); + serviceTemplateFragment, element.getProperties(), element.getOutProperties()); listener.unlock(messageId, compositionElement, instanceElement); } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandler.java new file mode 100644 index 000000000..1dbf2c935 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandler.java @@ -0,0 +1,197 @@ +/*- + * ============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.acm.participant.intermediary.handler; + +import java.util.List; +import java.util.Map; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState; +import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; +import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +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.SubState; +import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration; +import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionPrepare; +import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class AcSubStateHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(AcSubStateHandler.class); + + private final CacheProvider cacheProvider; + private final ThreadHandler listener; + + /** + * Handles AutomationComposition Migration Precheck. + * + * @param migrationMsg the AutomationCompositionMigration + */ + public void handleAcMigrationPrecheck(AutomationCompositionMigration migrationMsg) { + if (migrationMsg.getAutomationCompositionId() == null || migrationMsg.getCompositionTargetId() == null) { + return; + } + + var automationComposition = cacheProvider.getAutomationComposition(migrationMsg.getAutomationCompositionId()); + if (automationComposition == null) { + LOGGER.debug("Automation composition {} does not use this participant", + migrationMsg.getAutomationCompositionId()); + return; + } + automationComposition.setSubState(SubState.MIGRATION_PRECHECKING); + for (var participantDeploy : migrationMsg.getParticipantUpdatesList()) { + if (cacheProvider.getParticipantId().equals(participantDeploy.getParticipantId())) { + + callParticipantMigratePrecheck(migrationMsg.getMessageId(), participantDeploy.getAcElementList(), + automationComposition, migrationMsg.getCompositionTargetId()); + } + } + } + + private void callParticipantMigratePrecheck(UUID messageId, List<AcElementDeploy> acElements, + AutomationComposition automationComposition, UUID compositionTargetId) { + var compositionElementMap = cacheProvider.getCompositionElementDtoMap(automationComposition); + var instanceElementMap = cacheProvider.getInstanceElementDtoMap(automationComposition); + var acElementList = automationComposition.getElements(); + for (var acElement : acElements) { + var element = acElementList.get(acElement.getId()); + if (element != null) { + element.setSubState(SubState.MIGRATION_PRECHECKING); + } + } + var acCopyMigrateTo = new AutomationComposition(automationComposition); + var acElementCopyList = acCopyMigrateTo.getElements(); + for (var acElement : acElements) { + var element = acElementCopyList.get(acElement.getId()); + if (element != null) { + AcmUtils.recursiveMerge(element.getProperties(), acElement.getProperties()); + element.setDefinition(acElement.getDefinition()); + } else { + element = CacheProvider.createAutomationCompositionElement(acElement); + element.setSubState(SubState.MIGRATION_PRECHECKING); + acElementCopyList.put(element.getId(), element); + } + } + var toDelete = acElementCopyList.values().stream() + .filter(el -> !SubState.MIGRATION_PRECHECKING.equals(el.getSubState())) + .map(AutomationCompositionElement::getId) + .toList(); + toDelete.forEach(acElementCopyList::remove); + + var compositionElementTargetMap = cacheProvider.getCompositionElementDtoMap(acCopyMigrateTo, + compositionTargetId); + var instanceElementMigrateMap = cacheProvider.getInstanceElementDtoMap(acCopyMigrateTo); + + for (var acElement : acElements) { + var compositionElement = compositionElementMap.get(acElement.getId()); + var compositionElementTarget = compositionElementTargetMap.get(acElement.getId()); + var instanceElement = instanceElementMap.get(acElement.getId()); + var instanceElementMigrate = instanceElementMigrateMap.get(acElement.getId()); + + if (instanceElement == null) { + // new element scenario + compositionElement = new CompositionElementDto(automationComposition.getCompositionId(), + acElement.getDefinition(), Map.of(), Map.of(), ElementState.NOT_PRESENT); + instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), acElement.getId(), + new ToscaServiceTemplate(), Map.of(), Map.of(), ElementState.NOT_PRESENT); + compositionElementTarget = CacheProvider.changeStateToNew(compositionElementTarget); + instanceElementMigrate = CacheProvider.changeStateToNew(instanceElementMigrate); + } + + listener.migratePrecheck(messageId, compositionElement, compositionElementTarget, + instanceElement, instanceElementMigrate); + } + + for (var elementId : toDelete) { + var compositionDtoTarget = + new CompositionElementDto(compositionTargetId, + automationComposition.getElements().get(elementId).getDefinition(), + Map.of(), Map.of(), ElementState.REMOVED); + var instanceDtoTarget = + new InstanceElementDto(automationComposition.getInstanceId(), elementId, + null, Map.of(), Map.of(), ElementState.REMOVED); + + listener.migratePrecheck(messageId, compositionElementMap.get(elementId), compositionDtoTarget, + instanceElementMap.get(elementId), instanceDtoTarget); + } + } + + /** + * Handle AutomationComposition Prepare message. + * + * @param acPrepareMsg the AutomationCompositionPrepare message + */ + public void handleAcPrepare(AutomationCompositionPrepare acPrepareMsg) { + if (acPrepareMsg.isPreDeploy()) { + for (var participantPrepare : acPrepareMsg.getParticipantList()) { + if (cacheProvider.getParticipantId().equals(participantPrepare.getParticipantId())) { + cacheProvider.initializeAutomationComposition(acPrepareMsg.getCompositionId(), + acPrepareMsg.getAutomationCompositionId(), participantPrepare, DeployState.UNDEPLOYED, + SubState.PREPARING); + callParticipanPrepare(acPrepareMsg.getMessageId(), participantPrepare.getAcElementList(), + acPrepareMsg.getAutomationCompositionId()); + } + } + } else { + var automationComposition = + cacheProvider.getAutomationComposition(acPrepareMsg.getAutomationCompositionId()); + automationComposition.setSubState(SubState.REVIEWING); + callParticipanReview(acPrepareMsg.getMessageId(), automationComposition); + } + } + + private void callParticipanPrepare(UUID messageId, List<AcElementDeploy> acElementList, UUID instanceId) { + var automationComposition = cacheProvider.getAutomationComposition(instanceId); + for (var elementDeploy : acElementList) { + var element = automationComposition.getElements().get(elementDeploy.getId()); + var compositionInProperties = cacheProvider + .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition()); + var compositionElement = cacheProvider.createCompositionElementDto(automationComposition.getCompositionId(), + element, compositionInProperties); + var instanceElement = new InstanceElementDto(instanceId, elementDeploy.getId(), + elementDeploy.getToscaServiceTemplateFragment(), + elementDeploy.getProperties(), element.getOutProperties()); + listener.prepare(messageId, compositionElement, instanceElement); + } + } + + private void callParticipanReview(UUID messageId, AutomationComposition automationComposition) { + for (var element : automationComposition.getElements().values()) { + var compositionInProperties = cacheProvider + .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition()); + element.setSubState(SubState.REVIEWING); + var compositionElement = cacheProvider.createCompositionElementDto(automationComposition.getCompositionId(), + element, compositionInProperties); + var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(), + null, element.getProperties(), element.getOutProperties()); + listener.review(messageId, compositionElement, instanceElement); + } + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java index a3eafd844..6d94efb0f 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java @@ -21,20 +21,24 @@ package org.onap.policy.clamp.acm.participant.intermediary.handler; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState; import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher; import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +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.ParticipantDeploy; import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; 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.messages.kafka.participant.AutomationCompositionDeploy; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeployAck; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration; @@ -59,7 +63,6 @@ public class AutomationCompositionHandler { private final ParticipantMessagePublisher publisher; private final ThreadHandler listener; - /** * Handle a automation composition state change message. * @@ -116,11 +119,11 @@ public class AutomationCompositionHandler { for (var participantDeploy : updateMsg.getParticipantUpdatesList()) { if (cacheProvider.getParticipantId().equals(participantDeploy.getParticipantId())) { - - var acCopy = new AutomationComposition(cacheProvider.getAutomationComposition( - updateMsg.getAutomationCompositionId())); - updateExistingElementsOnThisParticipant(updateMsg.getAutomationCompositionId(), participantDeploy, - DeployState.UPDATING); + var automationComposition = cacheProvider.getAutomationComposition( + updateMsg.getAutomationCompositionId()); + automationComposition.setDeployState(DeployState.UPDATING); + var acCopy = new AutomationComposition(automationComposition); + updateExistingElementsOnThisParticipant(updateMsg.getAutomationCompositionId(), participantDeploy); callParticipantUpdateProperty(updateMsg.getMessageId(), participantDeploy.getAcElementList(), acCopy); } @@ -154,6 +157,7 @@ public class AutomationCompositionHandler { private void callParticipanDeploy(UUID messageId, List<AcElementDeploy> acElementDeployList, Integer startPhaseMsg, UUID instanceId) { var automationComposition = cacheProvider.getAutomationComposition(instanceId); + automationComposition.setDeployState(DeployState.DEPLOYING); for (var elementDeploy : acElementDeployList) { var element = automationComposition.getElements().get(elementDeploy.getId()); var compositionInProperties = cacheProvider @@ -170,55 +174,70 @@ public class AutomationCompositionHandler { } } - private Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition, - UUID compositionId) { - Map<UUID, CompositionElementDto> map = new HashMap<>(); - for (var element : automationComposition.getElements().values()) { - var compositionInProperties = cacheProvider.getCommonProperties(compositionId, element.getDefinition()); - var compositionElement = cacheProvider - .createCompositionElementDto(compositionId, element, compositionInProperties); - map.put(element.getId(), compositionElement); - } - return map; - } - - private Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition) { - return getCompositionElementDtoMap(automationComposition, automationComposition.getCompositionId()); - } - - private Map<UUID, InstanceElementDto> getInstanceElementDtoMap(AutomationComposition automationComposition) { - Map<UUID, InstanceElementDto> map = new HashMap<>(); - for (var element : automationComposition.getElements().values()) { - var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(), - null, element.getProperties(), element.getOutProperties()); - map.put(element.getId(), instanceElement); - } - return map; - } - private void callParticipantUpdateProperty(UUID messageId, List<AcElementDeploy> acElements, AutomationComposition acCopy) { - var instanceElementDtoMap = getInstanceElementDtoMap(acCopy); - var instanceElementDtoMapUpdated = getInstanceElementDtoMap( + var instanceElementDtoMap = cacheProvider.getInstanceElementDtoMap(acCopy); + var instanceElementDtoMapUpdated = cacheProvider.getInstanceElementDtoMap( cacheProvider.getAutomationComposition(acCopy.getInstanceId())); - var compositionElementDtoMap = getCompositionElementDtoMap(acCopy); + var compositionElementDtoMap = cacheProvider.getCompositionElementDtoMap(acCopy); for (var acElement : acElements) { listener.update(messageId, compositionElementDtoMap.get(acElement.getId()), instanceElementDtoMap.get(acElement.getId()), instanceElementDtoMapUpdated.get(acElement.getId())); } } - private void updateExistingElementsOnThisParticipant(UUID instanceId, ParticipantDeploy participantDeploy, - DeployState deployState) { + private void migrateExistingElementsOnThisParticipant(UUID instanceId, UUID compositionTargetId, + ParticipantDeploy participantDeploy, int stage) { + var automationComposition = cacheProvider.getAutomationComposition(instanceId); + var acElementList = automationComposition.getElements(); + for (var element : participantDeploy.getAcElementList()) { + var compositionInProperties = + cacheProvider.getCommonProperties(compositionTargetId, element.getDefinition()); + var stageSet = ParticipantUtils.findStageSet(compositionInProperties); + if (stageSet.contains(stage)) { + var acElement = acElementList.get(element.getId()); + if (acElement == null) { + var newElement = CacheProvider.createAutomationCompositionElement(element); + newElement.setParticipantId(participantDeploy.getParticipantId()); + newElement.setDeployState(DeployState.MIGRATING); + newElement.setLockState(LockState.LOCKED); + newElement.setStage(stage); + + acElementList.put(element.getId(), newElement); + LOGGER.info("New Ac Element with id {} is added in Migration", element.getId()); + } else { + AcmUtils.recursiveMerge(acElement.getProperties(), element.getProperties()); + acElement.setDeployState(DeployState.MIGRATING); + acElement.setStage(stage); + acElement.setDefinition(element.getDefinition()); + } + } + } + // Check for missing elements and remove them from cache + var elementsToRemove = findElementsToRemove(participantDeploy.getAcElementList(), acElementList); + for (var key : elementsToRemove) { + acElementList.remove(key); + LOGGER.info("Element with id {} is removed in Migration", key); + } + } + + private void updateExistingElementsOnThisParticipant(UUID instanceId, ParticipantDeploy participantDeploy) { var acElementList = cacheProvider.getAutomationComposition(instanceId).getElements(); for (var element : participantDeploy.getAcElementList()) { var acElement = acElementList.get(element.getId()); AcmUtils.recursiveMerge(acElement.getProperties(), element.getProperties()); - acElement.setDeployState(deployState); + acElement.setDeployState(DeployState.UPDATING); + acElement.setSubState(SubState.NONE); acElement.setDefinition(element.getDefinition()); } } + private List<UUID> findElementsToRemove(List<AcElementDeploy> acElementDeployList, Map<UUID, + AutomationCompositionElement> acElementList) { + var acElementDeploySet = acElementDeployList.stream().map(AcElementDeploy::getId).collect(Collectors.toSet()); + return acElementList.keySet().stream().filter(id -> !acElementDeploySet.contains(id)).toList(); + } + /** * Method to handle when the new state from participant is UNINITIALISED state. * @@ -229,6 +248,9 @@ public class AutomationCompositionHandler { private void handleUndeployState(UUID messageId, final AutomationComposition automationComposition, Integer startPhaseMsg) { automationComposition.setCompositionTargetId(null); + automationComposition.setDeployState(DeployState.UNDEPLOYING); + var serviceTemplateFragment = cacheProvider + .getServiceTemplateFragmentMap().get(automationComposition.getCompositionId()); for (var element : automationComposition.getElements().values()) { var compositionInProperties = cacheProvider .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition()); @@ -238,7 +260,7 @@ public class AutomationCompositionHandler { var compositionElement = cacheProvider.createCompositionElementDto( automationComposition.getCompositionId(), element, compositionInProperties); var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(), - null, element.getProperties(), element.getOutProperties()); + serviceTemplateFragment, element.getProperties(), element.getOutProperties()); listener.undeploy(messageId, compositionElement, instanceElement); } } @@ -246,16 +268,20 @@ public class AutomationCompositionHandler { private void handleDeleteState(UUID messageId, final AutomationComposition automationComposition, Integer startPhaseMsg) { + automationComposition.setDeployState(DeployState.DELETING); + var serviceTemplateFragment = cacheProvider + .getServiceTemplateFragmentMap().get(automationComposition.getCompositionId()); for (var element : automationComposition.getElements().values()) { var compositionInProperties = cacheProvider .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition()); int startPhase = ParticipantUtils.findStartPhase(compositionInProperties); if (startPhaseMsg.equals(startPhase)) { element.setDeployState(DeployState.DELETING); + element.setSubState(SubState.NONE); var compositionElement = cacheProvider.createCompositionElementDto( automationComposition.getCompositionId(), element, compositionInProperties); var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(), - null, element.getProperties(), element.getOutProperties()); + serviceTemplateFragment, element.getProperties(), element.getOutProperties()); listener.delete(messageId, compositionElement, instanceElement); } } @@ -279,30 +305,70 @@ public class AutomationCompositionHandler { } var acCopy = new AutomationComposition(automationComposition); automationComposition.setCompositionTargetId(migrationMsg.getCompositionTargetId()); + automationComposition.setDeployState(DeployState.MIGRATING); for (var participantDeploy : migrationMsg.getParticipantUpdatesList()) { if (cacheProvider.getParticipantId().equals(participantDeploy.getParticipantId())) { - updateExistingElementsOnThisParticipant(migrationMsg.getAutomationCompositionId(), participantDeploy, - DeployState.MIGRATING); + migrateExistingElementsOnThisParticipant(migrationMsg.getAutomationCompositionId(), + migrationMsg.getCompositionTargetId(), participantDeploy, migrationMsg.getStage()); callParticipantMigrate(migrationMsg.getMessageId(), participantDeploy.getAcElementList(), - acCopy, migrationMsg.getCompositionTargetId()); + acCopy, migrationMsg.getCompositionTargetId(), migrationMsg.getStage()); } } } private void callParticipantMigrate(UUID messageId, List<AcElementDeploy> acElements, - AutomationComposition acCopy, UUID compositionTargetId) { - var compositionElementMap = getCompositionElementDtoMap(acCopy); - var instanceElementMap = getInstanceElementDtoMap(acCopy); + AutomationComposition acCopy, UUID compositionTargetId, int stage) { + var compositionElementMap = cacheProvider.getCompositionElementDtoMap(acCopy); + var instanceElementMap = cacheProvider.getInstanceElementDtoMap(acCopy); var automationComposition = cacheProvider.getAutomationComposition(acCopy.getInstanceId()); - var compositionElementTargetMap = getCompositionElementDtoMap(automationComposition, compositionTargetId); - var instanceElementMigrateMap = getInstanceElementDtoMap(automationComposition); + var compositionElementTargetMap = cacheProvider.getCompositionElementDtoMap(automationComposition, + compositionTargetId); + var instanceElementMigrateMap = cacheProvider.getInstanceElementDtoMap(automationComposition); + // Call migrate for newly added and updated elements for (var acElement : acElements) { - listener.migrate(messageId, compositionElementMap.get(acElement.getId()), - compositionElementTargetMap.get(acElement.getId()), - instanceElementMap.get(acElement.getId()), instanceElementMigrateMap.get(acElement.getId())); + var compositionInProperties = cacheProvider + .getCommonProperties(compositionTargetId, acElement.getDefinition()); + var stageSet = ParticipantUtils.findStageSet(compositionInProperties); + if (stageSet.contains(stage)) { + if (instanceElementMap.get(acElement.getId()) == null) { + var compositionElementDto = + new CompositionElementDto(acCopy.getCompositionId(), acElement.getDefinition(), + Map.of(), Map.of(), ElementState.NOT_PRESENT); + var instanceElementDto = new InstanceElementDto(acCopy.getInstanceId(), acElement.getId(), + null, Map.of(), Map.of(), ElementState.NOT_PRESENT); + var compositionElementTargetDto = CacheProvider.changeStateToNew( + compositionElementTargetMap.get(acElement.getId())); + var instanceElementMigrateDto = CacheProvider + .changeStateToNew(instanceElementMigrateMap.get(acElement.getId())); + + listener.migrate(messageId, compositionElementDto, compositionElementTargetDto, instanceElementDto, + instanceElementMigrateDto, stage); + } else { + listener.migrate(messageId, compositionElementMap.get(acElement.getId()), + compositionElementTargetMap.get(acElement.getId()), + instanceElementMap.get(acElement.getId()), instanceElementMigrateMap.get(acElement.getId()), + stage); + } + } + } + if (stage == 0) { + // Call migrate for removed elements + List<UUID> removedElements = findElementsToRemove(acElements, acCopy.getElements()); + for (var elementId : removedElements) { + var compositionDtoTarget = + new CompositionElementDto(compositionTargetId, + acCopy.getElements().get(elementId).getDefinition(), + Map.of(), Map.of(), ElementState.REMOVED); + var instanceDtoTarget = + new InstanceElementDto(acCopy.getInstanceId(), elementId, null, Map.of(), + Map.of(), ElementState.REMOVED); + + listener.migrate(messageId, compositionElementMap.get(elementId), compositionDtoTarget, + instanceElementMap.get(elementId), instanceDtoTarget, 0); + } } } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java index 1f4c036e7..7cf83db9d 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java @@ -37,10 +37,12 @@ import org.onap.policy.clamp.models.acm.concepts.LockState; import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; import org.onap.policy.clamp.models.acm.concepts.ParticipantState; 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.messages.kafka.participant.AutomationCompositionDeployAck; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMessageType; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrimeAck; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantStatus; +import org.onap.policy.clamp.models.acm.utils.AcmUtils; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,27 +57,94 @@ public class AutomationCompositionOutHandler { private final CacheProvider cacheProvider; /** + * Handle a automation composition element stage change message. + * + * @param instance the automationComposition Id + * @param elementId the automationComposition Element Id + * @param stage the next stage + * @param message the message + * @param stateChangeResult the indicator if error occurs + */ + public void updateAutomationCompositionElementStage(UUID instance, UUID elementId, + StateChangeResult stateChangeResult, int stage, String message) { + if (!validateData(instance, elementId, stateChangeResult)) { + return; + } + + var automationComposition = cacheProvider.getAutomationComposition(instance); + if (automationComposition == null) { + LOGGER.error("Cannot update Automation composition element stage, Automation composition id {} not present", + instance); + return; + } + + var element = automationComposition.getElements().get(elementId); + if (element == null) { + var msg = "Cannot update Automation composition element stage, AC Element id {} not present"; + LOGGER.error(msg, elementId); + return; + } + + var automationCompositionStateChangeAck = + new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK); + automationCompositionStateChangeAck.setParticipantId(cacheProvider.getParticipantId()); + automationCompositionStateChangeAck.setMessage(AcmUtils.validatedMessage(message)); + automationCompositionStateChangeAck.setResponseTo(cacheProvider.getMsgIdentification().get(element.getId())); + automationCompositionStateChangeAck.setStateChangeResult(stateChangeResult); + automationCompositionStateChangeAck.setStage(stage); + automationCompositionStateChangeAck.setAutomationCompositionId(instance); + automationCompositionStateChangeAck.getAutomationCompositionResultMap().put(element.getId(), + new AcElementDeployAck(element.getDeployState(), element.getLockState(), element.getOperationalState(), + element.getUseState(), element.getOutProperties(), true, message)); + LOGGER.debug("Automation composition element {} stage changed to {}", elementId, stage); + automationCompositionStateChangeAck.setResult(true); + publisher.sendAutomationCompositionAck(automationCompositionStateChangeAck); + cacheProvider.getMsgIdentification().remove(element.getId()); + } + + private boolean validateData(UUID instance, UUID elementId, StateChangeResult stateChangeResult) { + if (instance == null || elementId == null) { + LOGGER.error("Not valid Ac instance, id is null"); + return false; + } + if (stateChangeResult == null) { + LOGGER.error("Not valid Ac instance, stateChangeResult is null"); + return false; + } + if (!StateChangeResult.NO_ERROR.equals(stateChangeResult) + && !StateChangeResult.FAILED.equals(stateChangeResult)) { + LOGGER.error("Not valid Ac instance, stateChangeResult is not valid"); + return false; + } + return true; + } + + /** * Handle a automation composition element state change message. * - * @param automationCompositionId the automationComposition Id + * @param instance the automationComposition Id * @param elementId the automationComposition Element Id * @param deployState the DeployState state * @param lockState the LockState state * @param message the message * @param stateChangeResult the indicator if error occurs */ - public void updateAutomationCompositionElementState(UUID automationCompositionId, UUID elementId, + public void updateAutomationCompositionElementState(UUID instance, UUID elementId, DeployState deployState, LockState lockState, StateChangeResult stateChangeResult, String message) { + if (!validateData(instance, elementId, stateChangeResult)) { + return; + } - if (automationCompositionId == null || elementId == null) { - LOGGER.error("Cannot update Automation composition element state, id is null"); + if ((deployState != null && lockState != null) || (deployState == null && lockState == null) + || AcmUtils.isInTransitionalState(deployState, lockState, SubState.NONE)) { + LOGGER.error("state error {} and {} cannot be handled", deployState, lockState); return; } - var automationComposition = cacheProvider.getAutomationComposition(automationCompositionId); + var automationComposition = cacheProvider.getAutomationComposition(instance); if (automationComposition == null) { LOGGER.error("Cannot update Automation composition element state, Automation composition id {} not present", - automationCompositionId); + instance); return; } @@ -86,14 +155,13 @@ public class AutomationCompositionOutHandler { return; } - if ((element.getRestarting() == null) - && ((deployState != null && lockState != null) || (deployState == null && lockState == null))) { - LOGGER.error("state error {} and {} cannot be handled", deployState, lockState); - return; - } - element.setRestarting(null); - - if (deployState != null) { + if (deployState != null && !SubState.NONE.equals(element.getSubState())) { + handleSubState(automationComposition, element); + if (!StateChangeResult.NO_ERROR.equals(stateChangeResult)) { + stateChangeResult = StateChangeResult.NO_ERROR; + LOGGER.warn("SubState has always NO_ERROR result!"); + } + } else if (deployState != null) { handleDeployState(automationComposition, element, deployState); } if (lockState != null) { @@ -104,10 +172,10 @@ public class AutomationCompositionOutHandler { new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK); automationCompositionStateChangeAck.setParticipantId(cacheProvider.getParticipantId()); automationCompositionStateChangeAck.setReplicaId(cacheProvider.getReplicaId()); - automationCompositionStateChangeAck.setMessage(message); + automationCompositionStateChangeAck.setMessage(AcmUtils.validatedMessage(message)); automationCompositionStateChangeAck.setResponseTo(cacheProvider.getMsgIdentification().get(element.getId())); automationCompositionStateChangeAck.setStateChangeResult(stateChangeResult); - automationCompositionStateChangeAck.setAutomationCompositionId(automationCompositionId); + automationCompositionStateChangeAck.setAutomationCompositionId(instance); automationCompositionStateChangeAck.getAutomationCompositionResultMap().put(element.getId(), new AcElementDeployAck(element.getDeployState(), element.getLockState(), element.getOperationalState(), element.getUseState(), element.getOutProperties(), true, message)); @@ -132,6 +200,7 @@ public class AutomationCompositionOutHandler { } automationComposition.setDeployState(deployState); automationComposition.setLockState(element.getLockState()); + automationComposition.setSubState(SubState.NONE); if (DeployState.DELETED.equals(deployState)) { cacheProvider.removeAutomationComposition(automationComposition.getInstanceId()); @@ -146,6 +215,16 @@ public class AutomationCompositionOutHandler { .filter(acElement -> !lockState.equals(acElement.getLockState())).findAny(); if (checkOpt.isEmpty()) { automationComposition.setLockState(lockState); + automationComposition.setSubState(SubState.NONE); + } + } + + private void handleSubState(AutomationComposition automationComposition, AutomationCompositionElement element) { + element.setSubState(SubState.NONE); + var checkOpt = automationComposition.getElements().values().stream() + .filter(acElement -> !SubState.NONE.equals(acElement.getSubState())).findAny(); + if (checkOpt.isEmpty()) { + automationComposition.setSubState(SubState.NONE); } } @@ -221,9 +300,29 @@ public class AutomationCompositionOutHandler { */ public void updateCompositionState(UUID compositionId, AcTypeState state, StateChangeResult stateChangeResult, String message) { + if (compositionId == null) { + LOGGER.error("Cannot update Automation composition definition state, id is null"); + return; + } + + if (stateChangeResult == null) { + LOGGER.error("Cannot update Automation composition definition state, stateChangeResult is null"); + return; + } + if (!StateChangeResult.NO_ERROR.equals(stateChangeResult) + && !StateChangeResult.FAILED.equals(stateChangeResult)) { + LOGGER.error("Cannot update Automation composition definition state, stateChangeResult is not valid"); + return; + } + + if ((state == null) || AcTypeState.PRIMING.equals(state) || AcTypeState.DEPRIMING.equals(state)) { + LOGGER.error("state invalid {} cannot be handled", state); + return; + } + var participantPrimeAck = new ParticipantPrimeAck(); participantPrimeAck.setCompositionId(compositionId); - participantPrimeAck.setMessage(message); + participantPrimeAck.setMessage(AcmUtils.validatedMessage(message)); participantPrimeAck.setResult(true); participantPrimeAck.setResponseTo(cacheProvider.getMsgIdentification().get(compositionId)); participantPrimeAck.setCompositionState(state); diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java index b85a3c35a..65ad627d1 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java @@ -30,7 +30,10 @@ import lombok.Getter; import lombok.NonNull; import lombok.Setter; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState; +import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters; +import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; @@ -39,8 +42,10 @@ import org.onap.policy.clamp.models.acm.concepts.LockState; import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy; import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc; import org.onap.policy.clamp.models.acm.concepts.ParticipantSupportedElementType; +import org.onap.policy.clamp.models.acm.concepts.SubState; import org.onap.policy.models.base.PfUtils; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.springframework.stereotype.Component; @Component @@ -68,6 +73,9 @@ public class CacheProvider { @Getter private final Map<UUID, UUID> msgIdentification = new ConcurrentHashMap<>(); + @Getter + private final Map<UUID, ToscaServiceTemplate> serviceTemplateFragmentMap = new ConcurrentHashMap<>(); + /** * Constructor. * @@ -118,6 +126,7 @@ public class CacheProvider { public void removeElementDefinition(@NonNull UUID compositionId) { acElementsDefinitions.remove(compositionId); + serviceTemplateFragmentMap.remove(compositionId); } /** @@ -156,21 +165,36 @@ public class CacheProvider { */ public void initializeAutomationComposition(@NonNull UUID compositionId, @NonNull UUID instanceId, ParticipantDeploy participantDeploy) { + initializeAutomationComposition(compositionId, instanceId, participantDeploy, + DeployState.DEPLOYING, SubState.NONE); + } + + /** + * Initialize an AutomationComposition from a ParticipantDeploy. + * + * @param compositionId the composition Id + * @param instanceId the Automation Composition Id + * @param participantDeploy the ParticipantDeploy + * @param deployState the DeployState + * @param subState the SubState + */ + public void initializeAutomationComposition(@NonNull UUID compositionId, @NonNull UUID instanceId, + ParticipantDeploy participantDeploy, DeployState deployState, SubState subState) { var acLast = automationCompositions.get(instanceId); Map<UUID, AutomationCompositionElement> acElementMap = new LinkedHashMap<>(); for (var element : participantDeploy.getAcElementList()) { - var acElement = new AutomationCompositionElement(); - acElement.setId(element.getId()); + var acElement = createAutomationCompositionElement(element); acElement.setParticipantId(getParticipantId()); - acElement.setDefinition(element.getDefinition()); - acElement.setDeployState(DeployState.DEPLOYING); - acElement.setLockState(LockState.NONE); - acElement.setProperties(element.getProperties()); + acElement.setDeployState(deployState); + acElement.setSubState(subState); var acElementLast = acLast != null ? acLast.getElements().get(element.getId()) : null; if (acElementLast != null) { acElement.setOutProperties(acElementLast.getOutProperties()); acElement.setOperationalState(acElementLast.getOperationalState()); acElement.setUseState(acElementLast.getUseState()); + if (element.getToscaServiceTemplateFragment() != null) { + serviceTemplateFragmentMap.put(compositionId, element.getToscaServiceTemplateFragment()); + } } acElementMap.put(element.getId(), acElement); } @@ -178,6 +202,8 @@ public class CacheProvider { automationComposition.setCompositionId(compositionId); automationComposition.setInstanceId(instanceId); automationComposition.setElements(acElementMap); + automationComposition.setDeployState(deployState); + automationComposition.setSubState(subState); automationCompositions.put(instanceId, automationComposition); } @@ -191,28 +217,52 @@ public class CacheProvider { ParticipantRestartAc participantRestartAc) { Map<UUID, AutomationCompositionElement> acElementMap = new LinkedHashMap<>(); for (var element : participantRestartAc.getAcElementList()) { + if (!getParticipantId().equals(element.getParticipantId())) { + continue; + } var acElement = new AutomationCompositionElement(); acElement.setId(element.getId()); acElement.setParticipantId(getParticipantId()); acElement.setDefinition(element.getDefinition()); acElement.setDeployState(element.getDeployState()); acElement.setLockState(element.getLockState()); + acElement.setSubState(SubState.NONE); acElement.setOperationalState(element.getOperationalState()); acElement.setUseState(element.getUseState()); acElement.setProperties(element.getProperties()); acElement.setOutProperties(element.getOutProperties()); - acElement.setRestarting(true); acElementMap.put(element.getId(), acElement); + if (element.getToscaServiceTemplateFragment() != null) { + serviceTemplateFragmentMap.put(compositionId, element.getToscaServiceTemplateFragment()); + } } var automationComposition = new AutomationComposition(); automationComposition.setCompositionId(compositionId); + automationComposition.setDeployState(participantRestartAc.getDeployState()); + automationComposition.setLockState(participantRestartAc.getLockState()); automationComposition.setInstanceId(participantRestartAc.getAutomationCompositionId()); automationComposition.setElements(acElementMap); automationCompositions.put(automationComposition.getInstanceId(), automationComposition); } /** + * Create AutomationCompositionElement to save in memory. + * + * @param element AcElementDeploy + * @return a new AutomationCompositionElement + */ + public static AutomationCompositionElement createAutomationCompositionElement(AcElementDeploy element) { + var acElement = new AutomationCompositionElement(); + acElement.setId(element.getId()); + acElement.setDefinition(element.getDefinition()); + acElement.setProperties(element.getProperties()); + acElement.setSubState(SubState.NONE); + acElement.setLockState(LockState.LOCKED); + return acElement; + } + + /** * Create CompositionElementDto. * * @param compositionId the composition Id @@ -221,10 +271,78 @@ public class CacheProvider { * @return the CompositionElementDto */ public CompositionElementDto createCompositionElementDto(UUID compositionId, AutomationCompositionElement element, - Map<String, Object> compositionInProperties) { + Map<String, Object> compositionInProperties) { var compositionOutProperties = getAcElementsDefinitions() .get(compositionId).get(element.getDefinition()).getOutProperties(); return new CompositionElementDto(compositionId, element.getDefinition(), compositionInProperties, compositionOutProperties); } + + /** + * Get a Map of CompositionElementDto by elementId from the elements of an AutomationComposition. + * + * @param automationComposition the AutomationComposition + * @param compositionId the compositionId + * @return the Map of CompositionElementDto + */ + public Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition, + UUID compositionId) { + var definitions = acElementsDefinitions.get(compositionId); + Map<UUID, CompositionElementDto> map = new HashMap<>(); + for (var element : automationComposition.getElements().values()) { + var definition = definitions.get(element.getDefinition()); + var compositionElement = (definition != null) + ? new CompositionElementDto(compositionId, element.getDefinition(), + definition.getAutomationCompositionElementToscaNodeTemplate().getProperties(), + definition.getOutProperties()) : + new CompositionElementDto(compositionId, element.getDefinition(), + Map.of(), Map.of(), ElementState.NOT_PRESENT); + map.put(element.getId(), compositionElement); + } + return map; + } + + public Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition) { + return getCompositionElementDtoMap(automationComposition, automationComposition.getCompositionId()); + } + + /** + * Get a Map of InstanceElementDto by elementId from the elements of an AutomationComposition. + * + * @param automationComposition the AutomationComposition + * @return the Map of InstanceElementDto + */ + public Map<UUID, InstanceElementDto> getInstanceElementDtoMap(AutomationComposition automationComposition) { + Map<UUID, InstanceElementDto> map = new HashMap<>(); + var serviceTemplateFragment = serviceTemplateFragmentMap.get(automationComposition.getCompositionId()); + for (var element : automationComposition.getElements().values()) { + var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(), + serviceTemplateFragment, element.getProperties(), element.getOutProperties()); + map.put(element.getId(), instanceElement); + } + return map; + } + + /** + * Create a new InstanceElementDto record with state New. + * + * @param instanceElement the InstanceElementDto + * @return a new InstanceElementDto + */ + public static InstanceElementDto changeStateToNew(InstanceElementDto instanceElement) { + return new InstanceElementDto(instanceElement.instanceId(), instanceElement.elementId(), + instanceElement.toscaServiceTemplateFragment(), + instanceElement.inProperties(), instanceElement.outProperties(), ElementState.NEW); + } + + /** + * Create a new CompositionElementDto record with state New. + * + * @param compositionElement the CompositionElementDto + * @return a new CompositionElementDto + */ + public static CompositionElementDto changeStateToNew(CompositionElementDto compositionElement) { + return new CompositionElementDto(compositionElement.compositionId(), compositionElement.elementDefinitionId(), + compositionElement.inProperties(), compositionElement.outProperties(), ElementState.NEW); + } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java index 7ac58ae6c..6615ae102 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java @@ -28,6 +28,7 @@ import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessag import org.onap.policy.clamp.models.acm.concepts.ParticipantState; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeploy; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration; +import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionPrepare; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionStateChange; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantAckMessage; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantDeregister; @@ -36,7 +37,6 @@ import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMe import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrime; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRegister; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRegisterAck; -import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRestart; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantStatus; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantStatusReq; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantSync; @@ -56,6 +56,7 @@ public class ParticipantHandler { private final AutomationCompositionHandler automationCompositionHandler; private final AcLockHandler acLockHandler; + private final AcSubStateHandler acSubStateHandler; private final AcDefinitionHandler acDefinitionHandler; private final ParticipantMessagePublisher publisher; private final CacheProvider cacheProvider; @@ -107,7 +108,11 @@ public class ParticipantHandler { value = "listener.automation_composition_migration", description = "AUTOMATION_COMPOSITION_MIGRATION messages received") public void handleAutomationCompositionMigration(AutomationCompositionMigration migrationMsg) { - automationCompositionHandler.handleAutomationCompositionMigration(migrationMsg); + if (Boolean.TRUE.equals(migrationMsg.getPrecheck())) { + acSubStateHandler.handleAcMigrationPrecheck(migrationMsg); + } else { + automationCompositionHandler.handleAutomationCompositionMigration(migrationMsg); + } } /** @@ -120,6 +125,11 @@ public class ParticipantHandler { automationCompositionHandler.handleAcPropertyUpdate(propertyUpdateMsg); } + @Timed(value = "listener.prepare", description = "AUTOMATION_COMPOSITION_PREPARE message received") + public void handleAutomationCompositionPrepare(AutomationCompositionPrepare acPrepareMsg) { + acSubStateHandler.handleAcPrepare(acPrepareMsg); + } + /** * Check if a participant message applies to this participant handler. * @@ -198,27 +208,18 @@ public class ParticipantHandler { } /** - * Handle a ParticipantRestart message. - * - * @param participantRestartMsg the participantRestart message - */ - @Timed(value = "listener.participant_restart", description = "PARTICIPANT_RESTART messages received") - public void handleParticipantRestart(ParticipantRestart participantRestartMsg) { - LOGGER.debug("ParticipantRestart message received for participantId {}", - participantRestartMsg.getParticipantId()); - acDefinitionHandler.handleParticipantRestart(participantRestartMsg); - } - - /** * Handle a ParticipantSync message. * * @param participantSyncMsg the participantSync message */ @Timed(value = "listener.participant_sync_msg", description = "PARTICIPANT_SYNC messages received") public void handleParticipantSync(ParticipantSync participantSyncMsg) { - LOGGER.debug("ParticipantSync message received for participantId {}", - participantSyncMsg.getParticipantId()); - acDefinitionHandler.handleParticipantRestart(participantSyncMsg); + if (participantSyncMsg.getExcludeReplicas().contains(cacheProvider.getReplicaId())) { + LOGGER.debug("Ignore ParticipantSync message {}", participantSyncMsg.getMessageId()); + return; + } + LOGGER.debug("ParticipantSync message received for participantId {}", participantSyncMsg.getParticipantId()); + acDefinitionHandler.handleParticipantSync(participantSyncMsg); } /** diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java index 9f3e16777..9a43bf4c3 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java @@ -23,7 +23,6 @@ package org.onap.policy.clamp.acm.participant.intermediary.handler; import io.opentelemetry.context.Context; import java.io.Closeable; import java.io.IOException; -import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -39,7 +38,6 @@ import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantInterme import org.onap.policy.clamp.models.acm.concepts.AcTypeState; 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.ParticipantRestartAc; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.models.base.PfModelException; import org.slf4j.Logger; @@ -55,7 +53,7 @@ public class ThreadHandler implements Closeable { private final ParticipantIntermediaryApi intermediaryApi; private final CacheProvider cacheProvider; - private final Map<UUID, Future> executionMap = new ConcurrentHashMap<>(); + private final Map<UUID, Future<?>> executionMap = new ConcurrentHashMap<>(); private final ExecutorService executor = Context.taskWrapping(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())); @@ -278,55 +276,6 @@ public class ThreadHandler implements Closeable { } /** - * Handles restarted scenario. - * - * @param messageId the messageId - * @param composition the composition - * @param state the state of the composition - * @param automationCompositionList list of ParticipantRestartAc - */ - public void restarted(UUID messageId, CompositionDto composition, - AcTypeState state, List<ParticipantRestartAc> automationCompositionList) { - try { - listener.handleRestartComposition(composition, state); - } catch (PfModelException e) { - LOGGER.error("Composition Defintion restarted failed {} {}", composition.compositionId(), e.getMessage()); - intermediaryApi.updateCompositionState(composition.compositionId(), state, StateChangeResult.FAILED, - "Composition Defintion restarted failed"); - } - - for (var automationComposition : automationCompositionList) { - for (var element : automationComposition.getAcElementList()) { - var compositionElement = new CompositionElementDto(composition.compositionId(), - element.getDefinition(), composition.inPropertiesMap().get(element.getDefinition()), - composition.outPropertiesMap().get(element.getDefinition())); - var instanceElementDto = new InstanceElementDto(automationComposition.getAutomationCompositionId(), - element.getId(), element.getToscaServiceTemplateFragment(), - element.getProperties(), element.getOutProperties()); - cleanExecution(element.getId(), messageId); - var result = executor.submit(() -> - this.restartedInstanceProcess(compositionElement, instanceElementDto, - element.getDeployState(), element.getLockState())); - executionMap.put(element.getId(), result); - } - } - } - - private void restartedInstanceProcess(CompositionElementDto compositionElement, - InstanceElementDto instanceElementDto, DeployState deployState, LockState lockState) { - try { - listener.handleRestartInstance(compositionElement, instanceElementDto, deployState, lockState); - executionMap.remove(instanceElementDto.elementId()); - } catch (PfModelException e) { - LOGGER.error("Automation composition element deploy failed {} {}", - instanceElementDto.elementId(), e.getMessage()); - intermediaryApi.updateAutomationCompositionElementState(instanceElementDto.instanceId(), - instanceElementDto.elementId(), deployState, lockState, StateChangeResult.FAILED, - "Automation composition element restart failed"); - } - } - - /** * Closes this stream and releases any system resources associated * with it. If the stream is already closed then invoking this * method has no effect. @@ -346,21 +295,24 @@ public class ThreadHandler implements Closeable { * @param compositionElementTarget the information of the Automation Composition Definition Element Target * @param instanceElement the information of the Automation Composition Instance Element * @param instanceElementMigrate the information of the Automation Composition Instance Element updated + * @param stage the stage */ public void migrate(UUID messageId, CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, - InstanceElementDto instanceElementMigrate) { + InstanceElementDto instanceElementMigrate, int stage) { cleanExecution(instanceElement.elementId(), messageId); var result = executor.submit(() -> - this.migrateProcess(compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate)); + this.migrateProcess(compositionElement, compositionElementTarget, + instanceElement, instanceElementMigrate, stage)); executionMap.put(instanceElement.elementId(), result); } private void migrateProcess(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, - InstanceElementDto instanceElementMigrate) { + InstanceElementDto instanceElementMigrate, int stage) { try { - listener.migrate(compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate); + listener.migrate(compositionElement, compositionElementTarget, + instanceElement, instanceElementMigrate, stage); } catch (PfModelException e) { LOGGER.error("Automation composition element migrate failed {} {}", instanceElement.elementId(), e.getMessage()); @@ -370,4 +322,93 @@ public class ThreadHandler implements Closeable { } executionMap.remove(instanceElement.elementId()); } + + /** + * Handles AutomationComposition Migration Precheck. + * + * @param messageId the messageId + * @param compositionElement the information of the Automation Composition Definition Element + * @param compositionElementTarget the information of the Automation Composition Definition Element Target + * @param instanceElement the information of the Automation Composition Instance Element + * @param instanceElementMigrate the information of the Automation Composition Instance Element updated + */ + public void migratePrecheck(UUID messageId, CompositionElementDto compositionElement, + CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, + InstanceElementDto instanceElementMigrate) { + cleanExecution(instanceElement.elementId(), messageId); + var result = executor.submit(() -> + this.migratePrecheckProcess(compositionElement, compositionElementTarget, instanceElement, + instanceElementMigrate)); + executionMap.put(instanceElement.elementId(), result); + } + + private void migratePrecheckProcess(CompositionElementDto compositionElement, + CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, + InstanceElementDto instanceElementMigrate) { + try { + listener.migratePrecheck(compositionElement, compositionElementTarget, instanceElement, + instanceElementMigrate); + } catch (PfModelException e) { + LOGGER.error("Automation composition element migrate precheck failed {} {}", + instanceElement.elementId(), e.getMessage()); + intermediaryApi.updateAutomationCompositionElementState( + instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED, + null, StateChangeResult.FAILED, "Automation composition element migrate precheck failed"); + } + executionMap.remove(instanceElement.elementId()); + } + + /** + * Handles AutomationComposition Prepare Post Deploy. + * + * @param messageId the messageId + * @param compositionElement the information of the Automation Composition Definition Element + * @param instanceElement the information of the Automation Composition Instance Element + */ + public void review(UUID messageId, CompositionElementDto compositionElement, + InstanceElementDto instanceElement) { + cleanExecution(instanceElement.elementId(), messageId); + var result = executor.submit(() -> this.reviewProcess(compositionElement, instanceElement)); + executionMap.put(instanceElement.elementId(), result); + } + + private void reviewProcess(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + try { + listener.review(compositionElement, instanceElement); + } catch (PfModelException e) { + LOGGER.error("Automation composition element Review failed {} {}", + instanceElement.elementId(), e.getMessage()); + intermediaryApi.updateAutomationCompositionElementState( + instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED, + null, StateChangeResult.FAILED, "Automation composition element Review failed"); + } + executionMap.remove(instanceElement.elementId()); + } + + /** + * Handles AutomationComposition Prepare Pre Deploy. + * + * @param messageId the messageId + * @param compositionElement the information of the Automation Composition Definition Element + * @param instanceElement the information of the Automation Composition Instance Element + */ + public void prepare(UUID messageId, CompositionElementDto compositionElement, + InstanceElementDto instanceElement) { + cleanExecution(instanceElement.elementId(), messageId); + var result = executor.submit(() -> this.prepareProcess(compositionElement, instanceElement)); + executionMap.put(instanceElement.elementId(), result); + } + + private void prepareProcess(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + try { + listener.prepare(compositionElement, instanceElement); + } catch (PfModelException e) { + LOGGER.error("Automation composition element prepare Pre Deploy failed {} {}", + instanceElement.elementId(), e.getMessage()); + intermediaryApi.updateAutomationCompositionElementState( + instanceElement.instanceId(), instanceElement.elementId(), DeployState.UNDEPLOYED, + null, StateChangeResult.FAILED, "Automation composition element prepare Pre Deploy failed"); + } + executionMap.remove(instanceElement.elementId()); + } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/ParticipantIntermediaryParameters.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/ParticipantIntermediaryParameters.java index 1c36ad17f..47fa7754e 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/ParticipantIntermediaryParameters.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/ParticipantIntermediaryParameters.java @@ -62,6 +62,6 @@ public class ParticipantIntermediaryParameters { @NotNull @Valid - private Topics topics; + private Topics topics = new Topics(); } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/Topics.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/Topics.java index ddf72052f..7a93255b0 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/Topics.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/Topics.java @@ -24,6 +24,7 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; /** @@ -32,6 +33,7 @@ import lombok.Setter; @Getter @Setter @AllArgsConstructor +@NoArgsConstructor public class Topics { @NotNull diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV1Test.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV1Test.java index a60e1b8cd..12acdbbb6 100755..100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV1Test.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV1Test.java @@ -20,8 +20,8 @@ package org.onap.policy.clamp.acm.participant.intermediary.api.impl; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -51,11 +51,6 @@ class AcElementListenerV1Test { var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); acElementListenerV1.deploy(compositionElement, instanceElement); verify(acElementListenerV1).deploy(any(), any(), any()); - - clearInvocations(acElementListenerV1); - acElementListenerV1.handleRestartInstance(compositionElement, instanceElement, - DeployState.DEPLOYING, LockState.NONE); - verify(acElementListenerV1).deploy(any(), any(), any()); } @Test @@ -66,11 +61,6 @@ class AcElementListenerV1Test { var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); acElementListenerV1.undeploy(compositionElement, instanceElement); verify(acElementListenerV1).undeploy(instanceElement.instanceId(), instanceElement.elementId()); - - clearInvocations(acElementListenerV1); - acElementListenerV1.handleRestartInstance(compositionElement, instanceElement, - DeployState.UNDEPLOYING, LockState.NONE); - verify(acElementListenerV1).undeploy(instanceElement.instanceId(), instanceElement.elementId()); } @Test @@ -147,92 +137,81 @@ class AcElementListenerV1Test { } @Test - void handleRestartComposition() throws PfModelException { - var intermediaryApi = mock(ParticipantIntermediaryApi.class); - var acElementListenerV1 = createAcElementListenerV1(intermediaryApi); - var compositionId = UUID.randomUUID(); - var toscaConceptIdentifier = new ToscaConceptIdentifier(); - var composition = new CompositionDto(compositionId, Map.of(toscaConceptIdentifier, Map.of()), Map.of()); - - acElementListenerV1.handleRestartComposition(composition, AcTypeState.PRIMED); - verify(intermediaryApi) - .updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Restarted"); - - clearInvocations(intermediaryApi); - acElementListenerV1.handleRestartComposition(composition, AcTypeState.PRIMING); - verify(intermediaryApi) - .updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Primed"); + void handleRestartComposition() { + var acElementListenerV1 = createAcElementListenerV1(mock(ParticipantIntermediaryApi.class)); + assertThatThrownBy(() -> acElementListenerV1.handleRestartComposition(null, null)) + .isInstanceOf(PfModelException.class); + } - clearInvocations(intermediaryApi); - acElementListenerV1.handleRestartComposition(composition, AcTypeState.DEPRIMING); - verify(intermediaryApi) - .updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR, "Deprimed"); + @Test + void handleRestartInstance() { + var acElementListenerV1 = createAcElementListenerV1(mock(ParticipantIntermediaryApi.class)); + assertThatThrownBy(() -> acElementListenerV1.handleRestartInstance(null, null, + null, null)).isInstanceOf(PfModelException.class); } @Test - void handleRestartInstance() throws PfModelException { + void migrateTest() throws PfModelException { var intermediaryApi = mock(ParticipantIntermediaryApi.class); var acElementListenerV1 = createAcElementListenerV1(intermediaryApi); var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of()); var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); - - acElementListenerV1.handleRestartInstance(compositionElement, instanceElement, - DeployState.DEPLOYED, LockState.LOCKED); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), - instanceElement.elementId(), DeployState.DEPLOYED, LockState.LOCKED, - StateChangeResult.NO_ERROR, "Restarted"); - - clearInvocations(intermediaryApi); - acElementListenerV1.handleRestartInstance(compositionElement, instanceElement, - DeployState.DEPLOYED, LockState.LOCKING); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), - instanceElement.elementId(), null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked"); - - clearInvocations(intermediaryApi); - acElementListenerV1.handleRestartInstance(compositionElement, instanceElement, - DeployState.DEPLOYED, LockState.UNLOCKING); + acElementListenerV1.migrate(compositionElement, compositionElement, instanceElement, instanceElement, 0); verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), - instanceElement.elementId(), null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked"); + instanceElement.elementId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Migrated"); + } - clearInvocations(intermediaryApi); - acElementListenerV1.handleRestartInstance(compositionElement, instanceElement, - DeployState.UPDATING, LockState.LOCKED); + @Test + void migratePrecheckTest() throws PfModelException { + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var acElementListenerV1 = createAcElementListenerV1(intermediaryApi); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); + acElementListenerV1.migratePrecheck(compositionElement, compositionElement, instanceElement, instanceElement); verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), - instanceElement.elementId(), DeployState.DEPLOYED, null, - StateChangeResult.NO_ERROR, "Update not supported"); + instanceElement.elementId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Migration Precheck completed"); + } - clearInvocations(intermediaryApi); - acElementListenerV1.handleRestartInstance(compositionElement, instanceElement, - DeployState.DELETING, LockState.NONE); + @Test + void reviewTest() throws PfModelException { + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var acElementListenerV1 = createAcElementListenerV1(intermediaryApi); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); + acElementListenerV1.review(compositionElement, instanceElement); verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), - instanceElement.elementId(), DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted"); + instanceElement.elementId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Review completed"); } @Test - void migrateTest() throws PfModelException { + void prepareTest() throws PfModelException { var intermediaryApi = mock(ParticipantIntermediaryApi.class); var acElementListenerV1 = createAcElementListenerV1(intermediaryApi); var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of()); + Map.of(), Map.of()); var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); - acElementListenerV1.migrate(compositionElement, compositionElement, instanceElement, instanceElement); + acElementListenerV1.prepare(compositionElement, instanceElement); verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), - instanceElement.elementId(), DeployState.DEPLOYED, null, - StateChangeResult.NO_ERROR, "Migrated"); + instanceElement.elementId(), DeployState.UNDEPLOYED, null, + StateChangeResult.NO_ERROR, "Prepare completed"); } private AcElementListenerV1 createAcElementListenerV1(ParticipantIntermediaryApi intermediaryApi) { return new AcElementListenerV1(intermediaryApi) { @Override - public void deploy(UUID instanceId, AcElementDeploy element, Map<String, Object> properties) - throws PfModelException { - + public void deploy(UUID instanceId, AcElementDeploy element, Map<String, Object> properties) { + // dummy implementation } @Override - public void undeploy(UUID instanceId, UUID elementId) throws PfModelException { - + public void undeploy(UUID instanceId, UUID elementId) { + // dummy implementation } }; } diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV2Test.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV2Test.java index c36e11dbc..a6cb7b005 100755..100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV2Test.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV2Test.java @@ -20,14 +20,13 @@ package org.onap.policy.clamp.acm.participant.intermediary.api.impl; -import static org.mockito.Mockito.clearInvocations; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import java.util.Map; import java.util.UUID; import org.junit.jupiter.api.Test; -import org.mockito.Answers; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; @@ -42,28 +41,6 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; class AcElementListenerV2Test { @Test - void deployTest() throws PfModelException { - var acElementListenerV2 = mock(AcElementListenerV2.class, Answers.CALLS_REAL_METHODS); - var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of()); - var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); - acElementListenerV2.handleRestartInstance(compositionElement, instanceElement, - DeployState.DEPLOYING, LockState.NONE); - verify(acElementListenerV2).deploy(compositionElement, instanceElement); - } - - @Test - void undeployTest() throws PfModelException { - var acElementListenerV2 = mock(AcElementListenerV2.class, Answers.CALLS_REAL_METHODS); - var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of()); - var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); - acElementListenerV2.handleRestartInstance(compositionElement, instanceElement, - DeployState.UNDEPLOYING, LockState.NONE); - verify(acElementListenerV2).undeploy(compositionElement, instanceElement); - } - - @Test void lockTest() throws PfModelException { var intermediaryApi = mock(ParticipantIntermediaryApi.class); var acElementListenerV2 = createAcElementListenerV2(intermediaryApi); @@ -137,91 +114,81 @@ class AcElementListenerV2Test { } @Test - void handleRestartComposition() throws PfModelException { - var intermediaryApi = mock(ParticipantIntermediaryApi.class); - var acElementListenerV2 = createAcElementListenerV2(intermediaryApi); - var compositionId = UUID.randomUUID(); - var toscaConceptIdentifier = new ToscaConceptIdentifier(); - var composition = new CompositionDto(compositionId, Map.of(toscaConceptIdentifier, Map.of()), Map.of()); - - acElementListenerV2.handleRestartComposition(composition, AcTypeState.PRIMED); - verify(intermediaryApi) - .updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Restarted"); - - clearInvocations(intermediaryApi); - acElementListenerV2.handleRestartComposition(composition, AcTypeState.PRIMING); - verify(intermediaryApi) - .updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Primed"); + void handleRestartComposition() { + var acElementListenerV2 = createAcElementListenerV2(mock(ParticipantIntermediaryApi.class)); + assertThatThrownBy(() -> acElementListenerV2.handleRestartComposition(null, null)) + .isInstanceOf(PfModelException.class); + } - clearInvocations(intermediaryApi); - acElementListenerV2.handleRestartComposition(composition, AcTypeState.DEPRIMING); - verify(intermediaryApi) - .updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR, "Deprimed"); + @Test + void handleRestartInstance() { + var acElementListenerV2 = createAcElementListenerV2(mock(ParticipantIntermediaryApi.class)); + assertThatThrownBy(() -> acElementListenerV2.handleRestartInstance(null, null, + null, null)).isInstanceOf(PfModelException.class); } @Test - void handleRestartInstance() throws PfModelException { + void migrateTest() throws PfModelException { var intermediaryApi = mock(ParticipantIntermediaryApi.class); var acElementListenerV2 = createAcElementListenerV2(intermediaryApi); var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of()); var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); - - acElementListenerV2.handleRestartInstance(compositionElement, instanceElement, - DeployState.DEPLOYED, LockState.LOCKED); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), - instanceElement.elementId(), DeployState.DEPLOYED, LockState.LOCKED, - StateChangeResult.NO_ERROR, "Restarted"); - - clearInvocations(intermediaryApi); - acElementListenerV2.handleRestartInstance(compositionElement, instanceElement, - DeployState.DEPLOYED, LockState.LOCKING); + acElementListenerV2.migrate(compositionElement, compositionElement, instanceElement, instanceElement, 0); verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), - instanceElement.elementId(), null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked"); - - clearInvocations(intermediaryApi); - acElementListenerV2.handleRestartInstance(compositionElement, instanceElement, - DeployState.DEPLOYED, LockState.UNLOCKING); - verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), - instanceElement.elementId(), null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked"); + instanceElement.elementId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Migrated"); + } - clearInvocations(intermediaryApi); - acElementListenerV2.handleRestartInstance(compositionElement, instanceElement, - DeployState.UPDATING, LockState.LOCKED); + @Test + void migratePrecheckTest() throws PfModelException { + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var acElementListenerV1 = createAcElementListenerV2(intermediaryApi); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); + acElementListenerV1.migratePrecheck(compositionElement, compositionElement, instanceElement, instanceElement); verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), - instanceElement.elementId(), DeployState.DEPLOYED, null, - StateChangeResult.NO_ERROR, "Update not supported"); + instanceElement.elementId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Migration Precheck completed"); + } - clearInvocations(intermediaryApi); - acElementListenerV2.handleRestartInstance(compositionElement, instanceElement, - DeployState.DELETING, LockState.NONE); + @Test + void reviewTest() throws PfModelException { + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var acElementListenerV1 = createAcElementListenerV2(intermediaryApi); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); + acElementListenerV1.review(compositionElement, instanceElement); verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), - instanceElement.elementId(), DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted"); + instanceElement.elementId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Review completed"); } @Test - void migrateTest() throws PfModelException { + void prepareTest() throws PfModelException { var intermediaryApi = mock(ParticipantIntermediaryApi.class); - var acElementListenerV2 = createAcElementListenerV2(intermediaryApi); + var acElementListenerV1 = createAcElementListenerV2(intermediaryApi); var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of()); + Map.of(), Map.of()); var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); - acElementListenerV2.migrate(compositionElement, compositionElement, instanceElement, instanceElement); + acElementListenerV1.prepare(compositionElement, instanceElement); verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), - instanceElement.elementId(), DeployState.DEPLOYED, null, - StateChangeResult.NO_ERROR, "Migrated"); + instanceElement.elementId(), DeployState.UNDEPLOYED, null, + StateChangeResult.NO_ERROR, "Prepare completed"); } private AcElementListenerV2 createAcElementListenerV2(ParticipantIntermediaryApi intermediaryApi) { return new AcElementListenerV2(intermediaryApi) { @Override - public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) - throws PfModelException { + public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + // dummy implementation } @Override - public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) - throws PfModelException { + public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + // dummy implementation } }; } diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV3Test.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV3Test.java new file mode 100644 index 000000000..1385f439a --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV3Test.java @@ -0,0 +1,180 @@ +/*- + * ============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.acm.participant.intermediary.api.impl; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.util.Map; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.models.acm.concepts.AcTypeState; +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.models.base.PfModelException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +class AcElementListenerV3Test { + + @Test + void lockTest() throws PfModelException { + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var acElementListenerV2 = createAcElementListenerV3(intermediaryApi); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); + acElementListenerV2.lock(compositionElement, instanceElement); + verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked"); + } + + @Test + void deleteTest() throws PfModelException { + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var acElementListenerV2 = createAcElementListenerV3(intermediaryApi); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); + acElementListenerV2.delete(compositionElement, instanceElement); + verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted"); + } + + @Test + void updateTest() throws PfModelException { + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var acElementListenerV2 = createAcElementListenerV3(intermediaryApi); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); + acElementListenerV2.update(compositionElement, instanceElement, instanceElement); + verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Update not supported"); + } + + @Test + void unlockTest() throws PfModelException { + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var acElementListenerV2 = createAcElementListenerV3(intermediaryApi); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); + acElementListenerV2.unlock(compositionElement, instanceElement); + verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked"); + } + + @Test + void primeTest() throws PfModelException { + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var acElementListenerV2 = createAcElementListenerV3(intermediaryApi); + var compositionId = UUID.randomUUID(); + var toscaConceptIdentifier = new ToscaConceptIdentifier(); + var composition = new CompositionDto(compositionId, Map.of(toscaConceptIdentifier, Map.of()), Map.of()); + acElementListenerV2.prime(composition); + verify(intermediaryApi) + .updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Primed"); + } + + @Test + void deprimeTest() throws PfModelException { + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var acElementListenerV2 = createAcElementListenerV3(intermediaryApi); + var compositionId = UUID.randomUUID(); + var toscaConceptIdentifier = new ToscaConceptIdentifier(); + var composition = new CompositionDto(compositionId, Map.of(toscaConceptIdentifier, Map.of()), Map.of()); + acElementListenerV2.deprime(composition); + verify(intermediaryApi) + .updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR, "Deprimed"); + } + + @Test + void migrateTest() throws PfModelException { + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var acElementListenerV2 = createAcElementListenerV3(intermediaryApi); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); + acElementListenerV2.migrate(compositionElement, compositionElement, instanceElement, instanceElement, 0); + verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Migrated"); + } + + @Test + void migratePrecheckTest() throws PfModelException { + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var acElementListenerV1 = createAcElementListenerV3(intermediaryApi); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); + acElementListenerV1.migratePrecheck(compositionElement, compositionElement, instanceElement, instanceElement); + verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Migration Precheck completed"); + } + + @Test + void reviewTest() throws PfModelException { + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var acElementListenerV1 = createAcElementListenerV3(intermediaryApi); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); + acElementListenerV1.review(compositionElement, instanceElement); + verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Review completed"); + } + + @Test + void prepareTest() throws PfModelException { + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var acElementListenerV1 = createAcElementListenerV3(intermediaryApi); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + Map.of(), Map.of()); + var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); + acElementListenerV1.prepare(compositionElement, instanceElement); + verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), + instanceElement.elementId(), DeployState.UNDEPLOYED, null, + StateChangeResult.NO_ERROR, "Prepare completed"); + } + + private AcElementListenerV3 createAcElementListenerV3(ParticipantIntermediaryApi intermediaryApi) { + return new AcElementListenerV3(intermediaryApi) { + @Override + public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + // dummy implementation + } + + @Override + public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { + // dummy implementation + } + }; + } +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AutomationCompositionElementListenerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AutomationCompositionElementListenerTest.java deleted file mode 100644 index b01065d09..000000000 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AutomationCompositionElementListenerTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2023-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.acm.participant.intermediary.api.impl; - -import static org.assertj.core.api.Assertions.assertThatCode; - -import java.util.Map; -import java.util.UUID; -import org.junit.jupiter.api.Test; -import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; -import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; -import org.onap.policy.clamp.acm.participant.intermediary.handler.DummyAcElementListener; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; - -class AutomationCompositionElementListenerTest { - - @Test - void defaultTest() { - var listener = new DummyAcElementListener(); - var compositionElementDto = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of()); - var instanceElementDto = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, - Map.of(), Map.of()); - assertThatCode(() -> listener.lock(compositionElementDto, instanceElementDto)).doesNotThrowAnyException(); - assertThatCode(() -> listener.unlock(compositionElementDto, instanceElementDto)).doesNotThrowAnyException(); - } -} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java index 22929a237..71af77fbf 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation. + * Copyright (C) 2021-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. @@ -84,7 +84,7 @@ class ParticipantIntermediaryApiImplTest { var automationComposiitonHandler = mock(AutomationCompositionOutHandler.class); var apiImpl = new ParticipantIntermediaryApiImpl(automationComposiitonHandler, mock(CacheProvider.class)); apiImpl.sendAcDefinitionInfo(COMPOSITION_ID, DEFINITION_ELEMENT_ID, MAP); - verify(automationComposiitonHandler).sendAcDefinitionInfo(COMPOSITION_ID, DEFINITION_ELEMENT_ID, MAP);; + verify(automationComposiitonHandler).sendAcDefinitionInfo(COMPOSITION_ID, DEFINITION_ELEMENT_ID, MAP); } @Test @@ -134,7 +134,7 @@ class ParticipantIntermediaryApiImplTest { assertEquals(map, mapResult); var result = apiImpl.getAcElementsDefinitions(UUID.randomUUID()); - assertThat(result).isNull(); + assertThat(result).isEmpty(); result = apiImpl.getAcElementsDefinitions(COMPOSITION_ID); assertEquals(elementsDefinitions, result); diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantCommTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantCommTest.java index d7c97bd00..39e51f576 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantCommTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantCommTest.java @@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import java.util.Collections; @@ -42,23 +43,24 @@ import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRe import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantStatus; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantStatusReq; import org.onap.policy.common.endpoints.event.comm.TopicSink; -import org.onap.policy.common.utils.coder.CoderException; class ParticipantCommTest { @Test - void participantListenerTest() throws CoderException { + void participantListenerTest() { var participantHandler = mock(ParticipantHandler.class); var participantRegisterAckListener = new ParticipantRegisterAckListener(participantHandler); participantRegisterAckListener.onTopicEvent(null, null, null, new ParticipantRegisterAck()); assertEquals(ParticipantMessageType.PARTICIPANT_REGISTER_ACK.name(), participantRegisterAckListener.getType()); + assertFalse(participantRegisterAckListener.isDefaultTopic()); assertEquals(participantRegisterAckListener, participantRegisterAckListener.getScoListener()); var participantStatusReqListener = new ParticipantStatusReqListener(participantHandler); participantStatusReqListener.onTopicEvent(null, null, null, new ParticipantStatusReq()); assertEquals(ParticipantMessageType.PARTICIPANT_STATUS_REQ.name(), participantStatusReqListener.getType()); assertEquals(participantStatusReqListener, participantStatusReqListener.getScoListener()); + assertFalse(participantStatusReqListener.isDefaultTopic()); var participantDeregisterAckListener = new ParticipantDeregisterAckListener(participantHandler); assertEquals(ParticipantMessageType.PARTICIPANT_DEREGISTER_ACK.name(), @@ -66,6 +68,7 @@ class ParticipantCommTest { var participantPrimeListener = new ParticipantPrimeListener(participantHandler); assertEquals(ParticipantMessageType.PARTICIPANT_PRIME.name(), participantPrimeListener.getType()); + assertTrue(participantPrimeListener.isDefaultTopic()); var acPropertyUpdateListener = new AcPropertyUpdateListener(participantHandler); assertEquals(ParticipantMessageType.PROPERTIES_UPDATE.name(), acPropertyUpdateListener.getType()); @@ -78,16 +81,16 @@ class ParticipantCommTest { assertEquals(ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE.name(), automationCompositionStateChangeListener.getType()); - var participantRestartListener = new ParticipantRestartListener(participantHandler); - assertEquals(ParticipantMessageType.PARTICIPANT_RESTART.name(), - participantRestartListener.getType()); - var participantSyncListener = new ParticipantSyncListener(participantHandler); assertEquals(ParticipantMessageType.PARTICIPANT_SYNC_MSG.name(), participantSyncListener.getType()); + assertFalse(participantSyncListener.isDefaultTopic()); var acMigrationListener = new AutomationCompositionMigrationListener(participantHandler); assertEquals(ParticipantMessageType.AUTOMATION_COMPOSITION_MIGRATION.name(), acMigrationListener.getType()); + + var acPrepareListener = new AcPrepareListener(participantHandler); + assertEquals(ParticipantMessageType.AUTOMATION_COMPOSITION_PREPARE.name(), acPrepareListener.getType()); } @Test @@ -137,7 +140,7 @@ class ParticipantCommTest { } @Test - void messageSenderTest() throws CoderException { + void messageSenderTest() { var participantHandler = mock(ParticipantHandler.class); var participantParameters = CommonTestData.getParticipantParameters(); var messageSender = new MessageSender(participantHandler, participantParameters); diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcDefinitionHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcDefinitionHandlerTest.java index 3bbdc3dbf..c6259a28f 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcDefinitionHandlerTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcDefinitionHandlerTest.java @@ -37,10 +37,10 @@ import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrime; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrimeAck; -import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRestart; +import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantSync; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -public class AcDefinitionHandlerTest { +class AcDefinitionHandlerTest { @Test void handleComposiotPrimeTest() { @@ -94,18 +94,36 @@ public class AcDefinitionHandlerTest { } @Test - void restartedTest() { - var participantRestartMsg = new ParticipantRestart(); - participantRestartMsg.setState(AcTypeState.PRIMED); - participantRestartMsg.setCompositionId(UUID.randomUUID()); - participantRestartMsg.getParticipantDefinitionUpdates().add(createParticipantDefinition()); - participantRestartMsg.setAutomationcompositionList(List.of(CommonTestData.createParticipantRestartAc())); + void syncTest() { + var participantSyncMsg = new ParticipantSync(); + participantSyncMsg.setState(AcTypeState.PRIMED); + participantSyncMsg.setCompositionId(UUID.randomUUID()); + participantSyncMsg.getParticipantDefinitionUpdates().add(createParticipantDefinition()); + participantSyncMsg.setAutomationcompositionList(List.of(CommonTestData.createParticipantRestartAc())); var cacheProvider = mock(CacheProvider.class); var listener = mock(ThreadHandler.class); var ach = new AcDefinitionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), listener); - ach.handleParticipantRestart(participantRestartMsg); + ach.handleParticipantSync(participantSyncMsg); verify(cacheProvider).initializeAutomationComposition(any(UUID.class), any()); verify(cacheProvider).addElementDefinition(any(), any()); } + + @Test + void syncDeleteTest() { + var participantSyncMsg = new ParticipantSync(); + participantSyncMsg.setState(AcTypeState.COMMISSIONED); + participantSyncMsg.setDelete(true); + participantSyncMsg.setCompositionId(UUID.randomUUID()); + participantSyncMsg.getParticipantDefinitionUpdates().add(createParticipantDefinition()); + var restartAc = CommonTestData.createParticipantRestartAc(); + participantSyncMsg.setAutomationcompositionList(List.of(restartAc)); + + var cacheProvider = mock(CacheProvider.class); + var listener = mock(ThreadHandler.class); + var ach = new AcDefinitionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), listener); + ach.handleParticipantSync(participantSyncMsg); + verify(cacheProvider).removeElementDefinition(participantSyncMsg.getCompositionId()); + verify(cacheProvider).removeAutomationComposition(restartAc.getAutomationCompositionId()); + } } diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandlerTest.java new file mode 100644 index 000000000..8fad1d22b --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandlerTest.java @@ -0,0 +1,199 @@ +/*- + * ============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.acm.participant.intermediary.handler; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData; +import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; +import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy; +import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration; +import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionPrepare; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +class AcSubStateHandlerTest { + + @Test + void handleAcStateChangeNullTest() { + var cacheProvider = mock(CacheProvider.class); + var ach = new AcSubStateHandler(cacheProvider, mock(ThreadHandler.class)); + + var acMigration = new AutomationCompositionMigration(); + acMigration.setPrecheck(true); + assertDoesNotThrow(() -> ach.handleAcMigrationPrecheck(acMigration)); + + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + acMigration.setAutomationCompositionId(automationComposition.getInstanceId()); + acMigration.setCompositionTargetId(UUID.randomUUID()); + assertDoesNotThrow(() -> ach.handleAcMigrationPrecheck(acMigration)); + + var acPrepare = new AutomationCompositionPrepare(); + assertDoesNotThrow(() -> ach.handleAcPrepare(acPrepare)); + + acPrepare.setAutomationCompositionId(automationComposition.getInstanceId()); + assertDoesNotThrow(() -> ach.handleAcPrepare(acPrepare)); + } + + @Test + void handleAcMigrationPrecheckTest() { + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + automationComposition.setCompositionId(UUID.randomUUID()); + automationComposition.setInstanceId(UUID.randomUUID()); + automationComposition.setCompositionTargetId(UUID.randomUUID()); + var cacheProvider = new CacheProvider(CommonTestData.getParticipantParameters()); + var definitions = + CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); + cacheProvider.addElementDefinition(automationComposition.getCompositionId(), definitions); + cacheProvider.addElementDefinition(automationComposition.getCompositionTargetId(), definitions); + var participantDeploy = + CommonTestData.createparticipantDeploy(cacheProvider.getParticipantId(), automationComposition); + cacheProvider.initializeAutomationComposition(automationComposition.getCompositionId(), + automationComposition.getInstanceId(), participantDeploy); + var migrationMsg = new AutomationCompositionMigration(); + migrationMsg.setStage(0); + migrationMsg.setCompositionId(automationComposition.getCompositionId()); + migrationMsg.setAutomationCompositionId(automationComposition.getInstanceId()); + migrationMsg.setCompositionTargetId(automationComposition.getCompositionTargetId()); + migrationMsg.setParticipantUpdatesList(List.of(participantDeploy)); + migrationMsg.setPrecheck(true); + var listener = mock(ThreadHandler.class); + var ach = new AcSubStateHandler(cacheProvider, listener); + ach.handleAcMigrationPrecheck(migrationMsg); + verify(listener, times(automationComposition.getElements().size())) + .migratePrecheck(any(), any(), any(), any(), any()); + } + + @Test + void handleAcMigrationPrecheckAddRemoveTest() { + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + automationComposition.setCompositionId(UUID.randomUUID()); + automationComposition.setInstanceId(UUID.randomUUID()); + var cacheProvider = new CacheProvider(CommonTestData.getParticipantParameters()); + var definitions = + CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); + cacheProvider.addElementDefinition(automationComposition.getCompositionId(), definitions); + var participantDeploy = + CommonTestData.createparticipantDeploy(cacheProvider.getParticipantId(), automationComposition); + cacheProvider.initializeAutomationComposition(automationComposition.getCompositionId(), + automationComposition.getInstanceId(), participantDeploy); + + var acMigrate = new AutomationComposition(automationComposition); + acMigrate.setCompositionTargetId(UUID.randomUUID()); + + // replacing first element with new one + var element = acMigrate.getElements().values().iterator().next(); + element.setDefinition(new ToscaConceptIdentifier("policy.clamp.new.element", "1.0.0")); + element.setId(UUID.randomUUID()); + + var migrateDefinitions = + CommonTestData.createAutomationCompositionElementDefinitionList(acMigrate); + cacheProvider.addElementDefinition(acMigrate.getCompositionTargetId(), migrateDefinitions); + + var migrationMsg = new AutomationCompositionMigration(); + migrationMsg.setStage(0); + migrationMsg.setCompositionId(acMigrate.getCompositionId()); + migrationMsg.setAutomationCompositionId(acMigrate.getInstanceId()); + migrationMsg.setCompositionTargetId(acMigrate.getCompositionTargetId()); + var participantMigrate = CommonTestData.createparticipantDeploy(cacheProvider.getParticipantId(), acMigrate); + migrationMsg.setParticipantUpdatesList(List.of(participantMigrate)); + var listener = mock(ThreadHandler.class); + var ach = new AcSubStateHandler(cacheProvider, listener); + ach.handleAcMigrationPrecheck(migrationMsg); + verify(listener, times(acMigrate.getElements().size() + 1)) + .migratePrecheck(any(), any(), any(), any(), any()); + } + + @Test + void handlePrepareTest() { + var listener = mock(ThreadHandler.class); + var cacheProvider = mock(CacheProvider.class); + var ach = new AcSubStateHandler(cacheProvider, listener); + + var acPrepareMsg = new AutomationCompositionPrepare(); + acPrepareMsg.setPreDeploy(true); + assertDoesNotThrow(() -> ach.handleAcPrepare(acPrepareMsg)); + + acPrepareMsg.setParticipantId(CommonTestData.getParticipantId()); + when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); + var participantDeploy = new ParticipantDeploy(); + participantDeploy.setParticipantId(CommonTestData.getParticipantId()); + acPrepareMsg.getParticipantList().add(participantDeploy); + + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + acPrepareMsg.setAutomationCompositionId(automationComposition.getInstanceId()); + when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) + .thenReturn(automationComposition); + Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map = new HashMap<>(); + for (var element : automationComposition.getElements().values()) { + var acElementDeploy = new AcElementDeploy(); + acElementDeploy.setProperties(Map.of()); + acElementDeploy.setId(element.getId()); + participantDeploy.getAcElementList().add(acElementDeploy); + map.put(element.getDefinition(), new AutomationCompositionElementDefinition()); + } + when(cacheProvider.getAcElementsDefinitions()) + .thenReturn(Map.of(automationComposition.getCompositionId(), map)); + + ach.handleAcPrepare(acPrepareMsg); + verify(listener, times(automationComposition.getElements().size())).prepare(any(), any(), any()); + } + + @Test + void handleReviewTest() { + var cacheProvider = mock(CacheProvider.class); + when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); + + var acPrepareMsg = new AutomationCompositionPrepare(); + acPrepareMsg.setPreDeploy(false); + acPrepareMsg.setParticipantId(CommonTestData.getParticipantId()); + + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + acPrepareMsg.setAutomationCompositionId(automationComposition.getInstanceId()); + when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) + .thenReturn(automationComposition); + Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map = new HashMap<>(); + for (var element : automationComposition.getElements().values()) { + var acElementDeploy = new AcElementDeploy(); + acElementDeploy.setProperties(Map.of()); + acElementDeploy.setId(element.getId()); + map.put(element.getDefinition(), new AutomationCompositionElementDefinition()); + } + when(cacheProvider.getAcElementsDefinitions()) + .thenReturn(Map.of(automationComposition.getCompositionId(), map)); + + var listener = mock(ThreadHandler.class); + var ach = new AcSubStateHandler(cacheProvider, listener); + ach.handleAcPrepare(acPrepareMsg); + verify(listener, times(automationComposition.getElements().size())).review(any(), any(), any()); + } +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java index 40e3b1eec..ec61f886e 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java @@ -23,18 +23,22 @@ package org.onap.policy.clamp.acm.participant.intermediary.handler; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher; import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData; import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; import org.onap.policy.clamp.models.acm.concepts.DeployState; import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy; @@ -196,36 +200,145 @@ class AutomationCompositionHandlerTest { } @Test - void handleAutomationCompositionMigrationTest() { - var listener = mock(ThreadHandler.class); - var cacheProvider = mock(CacheProvider.class); - var ach = new AutomationCompositionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), listener); + void handleMigrationNullTest() { + var ach = new AutomationCompositionHandler( + mock(CacheProvider.class), mock(ParticipantMessagePublisher.class), mock(ThreadHandler.class)); var migrationMsg = new AutomationCompositionMigration(); + migrationMsg.setStage(0); assertDoesNotThrow(() -> ach.handleAutomationCompositionMigration(migrationMsg)); - var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + migrationMsg.setAutomationCompositionId(UUID.randomUUID()); migrationMsg.setCompositionTargetId(UUID.randomUUID()); - migrationMsg.setAutomationCompositionId(automationComposition.getInstanceId()); assertDoesNotThrow(() -> ach.handleAutomationCompositionMigration(migrationMsg)); - when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) - .thenReturn(automationComposition); - var participantDeploy = new ParticipantDeploy(); - participantDeploy.setParticipantId(CommonTestData.getParticipantId()); - when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); - migrationMsg.getParticipantUpdatesList().add(participantDeploy); - Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map = new HashMap<>(); - for (var element : automationComposition.getElements().values()) { - var acElementDeploy = new AcElementDeploy(); - acElementDeploy.setProperties(Map.of()); - acElementDeploy.setId(element.getId()); - acElementDeploy.setDefinition(element.getDefinition()); - participantDeploy.getAcElementList().add(acElementDeploy); - map.put(element.getDefinition(), new AutomationCompositionElementDefinition()); - } - when(cacheProvider.getAcElementsDefinitions()) - .thenReturn(Map.of(automationComposition.getCompositionId(), map, - migrationMsg.getCompositionTargetId(), map)); + } + + @Test + void handleAutomationCompositionMigrationTest() { + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + automationComposition.setCompositionId(UUID.randomUUID()); + automationComposition.setInstanceId(UUID.randomUUID()); + automationComposition.setCompositionTargetId(UUID.randomUUID()); + var definitions = + CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); + var participantDeploy = + CommonTestData.createparticipantDeploy(CommonTestData.getParticipantId(), automationComposition); + + var cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(), + automationComposition.getInstanceId(), definitions, + automationComposition.getCompositionTargetId(), definitions); + + testMigration(cacheProvider, automationComposition, 0, automationComposition.getElements().size()); + } + + @Test + void handleMigrationAddRemoveTest() { + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + automationComposition.setCompositionId(UUID.randomUUID()); + automationComposition.setInstanceId(UUID.randomUUID()); + var acMigrate = new AutomationComposition(automationComposition); + acMigrate.setCompositionTargetId(UUID.randomUUID()); + + // replacing first element with new one + var element = acMigrate.getElements().values().iterator().next(); + element.setDefinition(new ToscaConceptIdentifier("policy.clamp.new.element", "1.0.0")); + element.setId(UUID.randomUUID()); + + var migrateDefinitions = + CommonTestData.createAutomationCompositionElementDefinitionList(acMigrate); + + var participantDeploy = + CommonTestData.createparticipantDeploy(CommonTestData.getParticipantId(), automationComposition); + var definitions = + CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); + var cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(), + automationComposition.getInstanceId(), definitions, + acMigrate.getCompositionTargetId(), migrateDefinitions); + + testMigration(cacheProvider, acMigrate, 0, acMigrate.getElements().size() + 1); + } + + @Test + void handleAcMigrationStageTest() { + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + automationComposition.setCompositionId(UUID.randomUUID()); + automationComposition.setInstanceId(UUID.randomUUID()); + + var acMigrate = new AutomationComposition(automationComposition); + acMigrate.setCompositionTargetId(UUID.randomUUID()); + + // replacing first element with new one + var element = acMigrate.getElements().values().iterator().next(); + element.setDefinition(new ToscaConceptIdentifier("policy.clamp.new.element", "1.2.4")); + element.setId(UUID.randomUUID()); + + // replacing definition version + acMigrate.getElements().values().forEach(el -> el.setDefinition( + new ToscaConceptIdentifier(el.getDefinition().getName(), "1.2.4"))); + + var migrateDefinitions = + CommonTestData.createAutomationCompositionElementDefinitionList(acMigrate); + + migrateDefinitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate() + .setProperties(Map.of("stage", List.of(0, 1)))); + + var participantDeploy = + CommonTestData.createparticipantDeploy(CommonTestData.getParticipantId(), automationComposition); + var definitions = + CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); + var cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(), + automationComposition.getInstanceId(), definitions, + acMigrate.getCompositionTargetId(), migrateDefinitions); + + // scenario 1,2 + migrateDefinitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate() + .setProperties(Map.of("stage", List.of(1, 2)))); + + // expected the element deleted + testMigration(cacheProvider, acMigrate, 0, 1); + + // expected 4 elements from stage 1 + testMigration(cacheProvider, acMigrate, 1, 4); + + // scenario 0,2 + cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(), + automationComposition.getInstanceId(), definitions, + acMigrate.getCompositionTargetId(), migrateDefinitions); + + migrateDefinitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate() + .setProperties(Map.of("stage", List.of(0, 2)))); + + // expected the element deleted + 4 elements from stage 0 + testMigration(cacheProvider, acMigrate, 0, 5); + + // expected 0 elements + testMigration(cacheProvider, acMigrate, 1, 0); + } + + private CacheProvider createCacheProvider(ParticipantDeploy participantDeploy, + UUID compositionId, UUID instanceId, List<AutomationCompositionElementDefinition> definitions, + UUID compositionTargetId, List<AutomationCompositionElementDefinition> migrateDefinitions) { + var cacheProvider = new CacheProvider(CommonTestData.getParticipantParameters()); + cacheProvider.addElementDefinition(compositionId, definitions); + cacheProvider.initializeAutomationComposition(compositionId, instanceId, participantDeploy); + cacheProvider.addElementDefinition(compositionTargetId, migrateDefinitions); + return cacheProvider; + } + + private void testMigration(CacheProvider cacheProvider, AutomationComposition acMigrate, + int stage, int expectedMigrated) { + var migrationMsg = new AutomationCompositionMigration(); + migrationMsg.setStage(stage); + migrationMsg.setCompositionId(acMigrate.getCompositionId()); + migrationMsg.setAutomationCompositionId(acMigrate.getInstanceId()); + migrationMsg.setCompositionTargetId(acMigrate.getCompositionTargetId()); + var participantMigrate = CommonTestData.createparticipantDeploy(cacheProvider.getParticipantId(), acMigrate); + migrationMsg.setParticipantUpdatesList(List.of(participantMigrate)); + var listener = mock(ThreadHandler.class); + + clearInvocations(); + var ach = new AutomationCompositionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), listener); ach.handleAutomationCompositionMigration(migrationMsg); - verify(listener, times(automationComposition.getElements().size())).migrate(any(), any(), any(), any(), any()); + verify(listener, times(expectedMigrated)).migrate(any(), any(), any(), any(), any(), anyInt()); } + } diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java index eed5319f8..202f25c6f 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java @@ -20,7 +20,6 @@ package org.onap.policy.clamp.acm.participant.intermediary.handler; -import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; @@ -39,6 +38,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDef 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.messages.kafka.participant.AutomationCompositionDeployAck; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrimeAck; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantStatus; @@ -49,45 +49,77 @@ class AutomationCompositionOutHandlerTest { @Test void updateAutomationCompositionElementStateNullTest() { var cacheProvider = mock(CacheProvider.class); - var acOutHandler = new AutomationCompositionOutHandler(mock(ParticipantMessagePublisher.class), cacheProvider); + var publisher = mock(ParticipantMessagePublisher.class); + var acOutHandler = new AutomationCompositionOutHandler(publisher, cacheProvider); assertDoesNotThrow( () -> acOutHandler.updateAutomationCompositionElementState(null, null, null, null, null, null)); + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementState(null, + UUID.randomUUID(), null, null, null, null)); + + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementState(UUID.randomUUID(), + null, null, null, null, null)); + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementState(UUID.randomUUID(), UUID.randomUUID(), null, null, null, null)); assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementState(UUID.randomUUID(), + UUID.randomUUID(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, null)); + + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementState(UUID.randomUUID(), UUID.randomUUID(), DeployState.DEPLOYED, null, null, null)); var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) .thenReturn(automationComposition); assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementState( - automationComposition.getInstanceId(), UUID.randomUUID(), DeployState.DEPLOYED, null, null, null)); + automationComposition.getInstanceId(), UUID.randomUUID(), DeployState.DEPLOYED, + null, StateChangeResult.NO_ERROR, null)); var elementId = automationComposition.getElements().values().iterator().next().getId(); assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementState( - automationComposition.getInstanceId(), elementId, null, null, null, null)); + automationComposition.getInstanceId(), elementId, null, null, + StateChangeResult.NO_ERROR, null)); + + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementStage( + elementId, null, StateChangeResult.NO_ERROR, 0, null)); + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementStage( + null, elementId, StateChangeResult.NO_ERROR, 0, null)); + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementStage( + UUID.randomUUID(), elementId, StateChangeResult.NO_ERROR, 0, null)); + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementStage( + automationComposition.getInstanceId(), UUID.randomUUID(), + StateChangeResult.NO_ERROR, 0, null)); + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementState( + automationComposition.getInstanceId(), elementId, DeployState.DEPLOYED, LockState.LOCKED, + StateChangeResult.NO_ERROR, null)); + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementState( + automationComposition.getInstanceId(), elementId, DeployState.DEPLOYING, null, + StateChangeResult.NO_ERROR, "")); + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementState( + automationComposition.getInstanceId(), elementId, DeployState.DEPLOYED, null, + StateChangeResult.TIMEOUT, "")); + + verify(publisher, times(0)).sendAutomationCompositionAck(any()); } @Test - void updateAutomationCompositionElementStateDeployedTest() { + void updateAutomationCompositionElementStageTest() { var publisher = mock(ParticipantMessagePublisher.class); var cacheProvider = mock(CacheProvider.class); var acOutHandler = new AutomationCompositionOutHandler(publisher, cacheProvider); - var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) .thenReturn(automationComposition); var elementId = automationComposition.getElements().values().iterator().next().getId(); - acOutHandler.updateAutomationCompositionElementState(automationComposition.getInstanceId(), elementId, - DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed"); + acOutHandler.updateAutomationCompositionElementStage( + automationComposition.getInstanceId(), elementId, StateChangeResult.NO_ERROR, 0, "OK"); verify(publisher).sendAutomationCompositionAck(any(AutomationCompositionDeployAck.class)); } @Test - void updateAutomationCompositionElementStateLockTest() { + void updateAutomationCompositionElementStateDeployedTest() { var publisher = mock(ParticipantMessagePublisher.class); var cacheProvider = mock(CacheProvider.class); var acOutHandler = new AutomationCompositionOutHandler(publisher, cacheProvider); @@ -96,13 +128,30 @@ class AutomationCompositionOutHandlerTest { when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) .thenReturn(automationComposition); var elementId = automationComposition.getElements().values().iterator().next().getId(); - acOutHandler.updateAutomationCompositionElementState(automationComposition.getInstanceId(), elementId, null, - LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked"); + acOutHandler.updateAutomationCompositionElementState(automationComposition.getInstanceId(), elementId, + DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed"); + verify(publisher).sendAutomationCompositionAck(any(AutomationCompositionDeployAck.class)); + } + + @Test + void updateAutomationCompositionElementStatePrepareTest() { + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + automationComposition.setSubState(SubState.PREPARING); + var cacheProvider = mock(CacheProvider.class); + when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) + .thenReturn(automationComposition); + var element = automationComposition.getElements().values().iterator().next(); + element.setSubState(SubState.PREPARING); + var elementId = element.getId(); + var publisher = mock(ParticipantMessagePublisher.class); + var acOutHandler = new AutomationCompositionOutHandler(publisher, cacheProvider); + acOutHandler.updateAutomationCompositionElementState(automationComposition.getInstanceId(), elementId, + DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Prepare completed"); verify(publisher).sendAutomationCompositionAck(any(AutomationCompositionDeployAck.class)); } @Test - void updateAutomationCompositionElementStateRestartedTest() { + void updateAutomationCompositionElementStateLockTest() { var publisher = mock(ParticipantMessagePublisher.class); var cacheProvider = mock(CacheProvider.class); var acOutHandler = new AutomationCompositionOutHandler(publisher, cacheProvider); @@ -110,12 +159,10 @@ class AutomationCompositionOutHandlerTest { var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) .thenReturn(automationComposition); - var element = automationComposition.getElements().values().iterator().next(); - element.setRestarting(true); - acOutHandler.updateAutomationCompositionElementState(automationComposition.getInstanceId(), element.getId(), - DeployState.DEPLOYED, LockState.LOCKED, StateChangeResult.NO_ERROR, "Restarted"); + var elementId = automationComposition.getElements().values().iterator().next().getId(); + acOutHandler.updateAutomationCompositionElementState(automationComposition.getInstanceId(), elementId, null, + LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked"); verify(publisher).sendAutomationCompositionAck(any(AutomationCompositionDeployAck.class)); - assertThat(element.getRestarting()).isNull(); } @Test @@ -169,6 +216,28 @@ class AutomationCompositionOutHandlerTest { } @Test + void updateCompositionStateNullTest() { + var publisher = mock(ParticipantMessagePublisher.class); + var cacheProvider = mock(CacheProvider.class); + var acOutHandler = new AutomationCompositionOutHandler(publisher, cacheProvider); + + assertDoesNotThrow( + () -> acOutHandler.updateCompositionState(null, null, null, null)); + assertDoesNotThrow(() -> acOutHandler.updateCompositionState(UUID.randomUUID(), null, + StateChangeResult.NO_ERROR, null)); + assertDoesNotThrow( + () -> acOutHandler.updateCompositionState(UUID.randomUUID(), AcTypeState.PRIMED, null, null)); + assertDoesNotThrow(() -> acOutHandler.updateCompositionState(UUID.randomUUID(), AcTypeState.PRIMING, + StateChangeResult.NO_ERROR, null)); + assertDoesNotThrow(() -> acOutHandler.updateCompositionState(UUID.randomUUID(), AcTypeState.DEPRIMING, + StateChangeResult.NO_ERROR, null)); + assertDoesNotThrow(() -> acOutHandler.updateCompositionState(UUID.randomUUID(), AcTypeState.PRIMED, + StateChangeResult.TIMEOUT, null)); + + verify(publisher, times(0)).sendParticipantPrimeAck(any()); + } + + @Test void updateCompositionStatePrimedTest() { var cacheProvider = mock(CacheProvider.class); when(cacheProvider.getParticipantId()).thenReturn(UUID.randomUUID()); diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java index 9451f0138..ced2d81e8 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java @@ -186,4 +186,36 @@ class CacheProviderTest { assertEquals(element.getDefinition(), result.elementDefinitionId()); } } + + @Test + void testGetCompositionElementDtoMap() { + var parameter = CommonTestData.getParticipantParameters(); + var cacheProvider = new CacheProvider(parameter); + var compositionId = UUID.randomUUID(); + var automationComposition = + CommonTestData.getTestAutomationCompositions().getAutomationCompositionList().get(0); + automationComposition.setCompositionId(compositionId); + cacheProvider.addElementDefinition(compositionId, + CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition)); + var result = cacheProvider.getCompositionElementDtoMap(automationComposition); + for (var element : automationComposition.getElements().values()) { + var compositionElementDto = result.get(element.getId()); + assertEquals(element.getDefinition(), compositionElementDto.elementDefinitionId()); + } + } + + @Test + void testGetInstanceElementDtoMap() { + var parameter = CommonTestData.getParticipantParameters(); + var cacheProvider = new CacheProvider(parameter); + var compositionId = UUID.randomUUID(); + var automationComposition = + CommonTestData.getTestAutomationCompositions().getAutomationCompositionList().get(0); + automationComposition.setCompositionId(compositionId); + var result = cacheProvider.getInstanceElementDtoMap(automationComposition); + for (var element : automationComposition.getElements().values()) { + var compositionElementDto = result.get(element.getId()); + assertEquals(element.getId(), compositionElementDto.elementId()); + } + } } diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/DummyAcElementListener.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/DummyAcElementListener.java deleted file mode 100644 index 24935c1c9..000000000 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/DummyAcElementListener.java +++ /dev/null @@ -1,90 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2023-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.acm.participant.intermediary.handler; - -import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener; -import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; -import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; -import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; -import org.onap.policy.clamp.models.acm.concepts.AcTypeState; -import org.onap.policy.clamp.models.acm.concepts.DeployState; -import org.onap.policy.clamp.models.acm.concepts.LockState; -import org.onap.policy.models.base.PfModelException; - -public class DummyAcElementListener implements AutomationCompositionElementListener { - @Override - public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) - throws PfModelException { - - } - - @Override - public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) - throws PfModelException { - - } - - @Override - public void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) - throws PfModelException { - - } - - @Override - public void unlock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) - throws PfModelException { - - } - - @Override - public void delete(CompositionElementDto compositionElement, InstanceElementDto instanceElement) - throws PfModelException { - } - - @Override - public void update(CompositionElementDto compositionElement, InstanceElementDto instanceElement, - InstanceElementDto instanceElementUpdated) - throws PfModelException { - } - - @Override - public void prime(CompositionDto composition) throws PfModelException { - } - - @Override - public void deprime(CompositionDto composition) throws PfModelException { - } - - @Override - public void handleRestartComposition(CompositionDto composition, AcTypeState state) throws PfModelException { - } - - @Override - public void handleRestartInstance(CompositionElementDto compositionElement, InstanceElementDto instanceElement, - DeployState deployState, LockState lockState) throws PfModelException { - } - - @Override - public void migrate(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, - InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate) - throws PfModelException { - } -} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/IntermediaryActivatorTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/IntermediaryActivatorTest.java index 8868c733a..89bafa196 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/IntermediaryActivatorTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/IntermediaryActivatorTest.java @@ -34,10 +34,8 @@ import static org.mockito.Mockito.when; import java.util.List; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantStatusReqListener; -import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantSyncListener; import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantStatusReq; -import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantSync; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.common.utils.coder.StandardCoderObject; diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java index eb1db475b..1fb72812b 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java @@ -47,9 +47,9 @@ import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMe import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrime; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRegister; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRegisterAck; -import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRestart; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantStatus; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantStatusReq; +import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantSync; import org.onap.policy.clamp.models.acm.messages.kafka.participant.PropertiesUpdate; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder; @@ -62,7 +62,8 @@ class ParticipantHandlerTest { when(publisher.isActive()).thenReturn(true); var cacheProvider = mock(CacheProvider.class); var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), - mock(AcLockHandler.class), mock(AcDefinitionHandler.class), publisher, cacheProvider); + mock(AcLockHandler.class), mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class), + publisher, cacheProvider); participantHandler.handleParticipantStatusReq(new ParticipantStatusReq()); verify(publisher).sendParticipantRegister(any(ParticipantRegister.class)); @@ -76,7 +77,8 @@ class ParticipantHandlerTest { void handleAutomationCompositionDeployTest() { var acHandler = mock(AutomationCompositionHandler.class); var participantHandler = new ParticipantHandler(acHandler, mock(AcLockHandler.class), - mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); + mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), + mock(CacheProvider.class)); var automationCompositionDeploy = new AutomationCompositionDeploy(); participantHandler.handleAutomationCompositionDeploy(automationCompositionDeploy); verify(acHandler).handleAutomationCompositionDeploy(automationCompositionDeploy); @@ -86,8 +88,8 @@ class ParticipantHandlerTest { void handleAutomationCompositionStateChangeTest() { var acHandler = mock(AutomationCompositionHandler.class); var acLockHandler = mock(AcLockHandler.class); - var participantHandler = new ParticipantHandler(acHandler, acLockHandler, mock(AcDefinitionHandler.class), - mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); + var participantHandler = new ParticipantHandler(acHandler, acLockHandler, mock(AcSubStateHandler.class), + mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); var acStateChange = new AutomationCompositionStateChange(); acStateChange.setDeployOrderedState(DeployOrder.DEPLOY); @@ -104,18 +106,25 @@ class ParticipantHandlerTest { @Test void handleAutomationCompositionMigrationTest() { var acHandler = mock(AutomationCompositionHandler.class); + var acSubStateHandler = mock(AcSubStateHandler.class); var participantHandler = new ParticipantHandler(acHandler, mock(AcLockHandler.class), - mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); + acSubStateHandler, mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), + mock(CacheProvider.class)); var migrationMsg = new AutomationCompositionMigration(); participantHandler.handleAutomationCompositionMigration(migrationMsg); verify(acHandler).handleAutomationCompositionMigration(migrationMsg); + + migrationMsg.setPrecheck(true); + participantHandler.handleAutomationCompositionMigration(migrationMsg); + verify(acSubStateHandler).handleAcMigrationPrecheck(migrationMsg); } @Test void handleAcPropertyUpdateTest() { var acHandler = mock(AutomationCompositionHandler.class); var participantHandler = new ParticipantHandler(acHandler, mock(AcLockHandler.class), - mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); + mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), + mock(CacheProvider.class)); var propertyUpdateMsg = new PropertiesUpdate(); participantHandler.handleAcPropertyUpdate(propertyUpdateMsg); verify(acHandler).handleAcPropertyUpdate(propertyUpdateMsg); @@ -127,8 +136,8 @@ class ParticipantHandlerTest { when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); when(cacheProvider.getReplicaId()).thenReturn(CommonTestData.getReplicaId()); var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), - mock(AcLockHandler.class), mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), - cacheProvider); + mock(AcLockHandler.class), mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class), + mock(ParticipantMessagePublisher.class), cacheProvider); var participantAckMsg = new ParticipantAckMessage(ParticipantMessageType.AUTOMATION_COMPOSITION_DEPLOY); assertTrue(participantHandler.appliesTo(participantAckMsg)); @@ -147,7 +156,8 @@ class ParticipantHandlerTest { when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); when(cacheProvider.getSupportedAcElementTypes()).thenReturn(List.of(new ParticipantSupportedElementType())); var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), - mock(AcLockHandler.class), mock(AcDefinitionHandler.class), publisher, cacheProvider); + mock(AcLockHandler.class), mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class), publisher, + cacheProvider); participantHandler.sendParticipantRegister(); verify(publisher).sendParticipantRegister(any(ParticipantRegister.class)); @@ -159,7 +169,8 @@ class ParticipantHandlerTest { var cacheProvider = mock(CacheProvider.class); when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), - mock(AcLockHandler.class), mock(AcDefinitionHandler.class), publisher, cacheProvider); + mock(AcLockHandler.class), mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class), publisher, + cacheProvider); participantHandler.handleParticipantRegisterAck(new ParticipantRegisterAck()); verify(publisher).sendParticipantStatus(any(ParticipantStatus.class)); @@ -171,7 +182,8 @@ class ParticipantHandlerTest { var cacheProvider = mock(CacheProvider.class); when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), - mock(AcLockHandler.class), mock(AcDefinitionHandler.class), publisher, cacheProvider); + mock(AcLockHandler.class), mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class), publisher, + cacheProvider); participantHandler.sendParticipantDeregister(); verify(publisher).sendParticipantDeregister(any(ParticipantDeregister.class)); @@ -180,8 +192,8 @@ class ParticipantHandlerTest { @Test void handleParticipantDeregisterAckTest() { var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), - mock(AcLockHandler.class), mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), - mock(CacheProvider.class)); + mock(AcLockHandler.class), mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class), + mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); var participantDeregisterAck = new ParticipantDeregisterAck(); assertDoesNotThrow(() -> participantHandler.handleParticipantDeregisterAck(participantDeregisterAck)); } @@ -194,8 +206,8 @@ class ParticipantHandlerTest { var acHandler = mock(AcDefinitionHandler.class); var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), - mock(AcLockHandler.class), acHandler, mock(ParticipantMessagePublisher.class), - mock(CacheProvider.class)); + mock(AcLockHandler.class), mock(AcSubStateHandler.class), acHandler, + mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); participantHandler.handleParticipantPrime(participantPrime); verify(acHandler).handlePrime(participantPrime); @@ -203,18 +215,20 @@ class ParticipantHandlerTest { @Test void handleParticipantRestartTest() { - var participantRestartMsg = new ParticipantRestart(); - participantRestartMsg.setState(AcTypeState.PRIMED); - participantRestartMsg.setCompositionId(UUID.randomUUID()); + var participantSyncMsg = new ParticipantSync(); + participantSyncMsg.setState(AcTypeState.PRIMED); + participantSyncMsg.setCompositionId(UUID.randomUUID()); + participantSyncMsg.setReplicaId(CommonTestData.getReplicaId()); var cacheProvider = mock(CacheProvider.class); + when(cacheProvider.getReplicaId()).thenReturn(CommonTestData.getReplicaId()); var publisher = mock(ParticipantMessagePublisher.class); var acHandler = mock(AcDefinitionHandler.class); var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), - mock(AcLockHandler.class), acHandler, publisher, cacheProvider); + mock(AcLockHandler.class), mock(AcSubStateHandler.class), acHandler, publisher, cacheProvider); - participantHandler.handleParticipantRestart(participantRestartMsg); - verify(acHandler).handleParticipantRestart(participantRestartMsg); + participantHandler.handleParticipantSync(participantSyncMsg); + verify(acHandler).handleParticipantSync(participantSyncMsg); } @Test @@ -227,7 +241,7 @@ class ParticipantHandlerTest { when(publisher.isActive()).thenReturn(true); var acHandler = mock(AcDefinitionHandler.class); var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), - mock(AcLockHandler.class), acHandler, publisher, cacheProvider); + mock(AcLockHandler.class), mock(AcSubStateHandler.class), acHandler, publisher, cacheProvider); participantHandler.sendHeartbeat(); verify(publisher).sendParticipantRegister(any(ParticipantRegister.class)); diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java index e4c34845e..d05471901 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java @@ -20,7 +20,6 @@ package org.onap.policy.clamp.acm.participant.intermediary.handler; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; @@ -29,7 +28,6 @@ import static org.mockito.Mockito.verify; import jakarta.ws.rs.core.Response.Status; import java.io.IOException; -import java.util.List; import java.util.Map; import java.util.UUID; import org.junit.jupiter.api.Test; @@ -39,11 +37,9 @@ import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElement import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; -import org.onap.policy.clamp.models.acm.concepts.AcElementRestart; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; 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.ParticipantRestartAc; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; @@ -53,7 +49,7 @@ class ThreadHandlerTest { private static final int TIMEOUT = 400; @Test - void test() throws PfModelException, IOException { + void testPrime() throws PfModelException, IOException { var listener = mock(AutomationCompositionElementListener.class); var intermediaryApi = mock(ParticipantIntermediaryApi.class); try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) { @@ -65,11 +61,45 @@ class ThreadHandlerTest { verify(listener, timeout(TIMEOUT)).prime(composition); clearInvocations(listener); + threadHandler.deprime(messageId, composition); + verify(listener, timeout(TIMEOUT)).deprime(composition); + } + } + + @Test + void testPrimeException() throws PfModelException, IOException { + var listener = mock(AutomationCompositionElementListener.class); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) { + + var compositionId = UUID.randomUUID(); + var composition = new CompositionDto(compositionId, Map.of(), Map.of()); + doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).prime(composition); + var messageId = UUID.randomUUID(); + threadHandler.prime(messageId, composition); + verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.COMMISSIONED, + StateChangeResult.FAILED, "Composition Defintion prime failed"); + + clearInvocations(listener); + doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).deprime(composition); + threadHandler.deprime(messageId, composition); + verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.PRIMED, + StateChangeResult.FAILED, "Composition Defintion deprime failed"); + } + } + + @Test + void testDeploy() throws PfModelException, IOException { + var listener = mock(AutomationCompositionElementListener.class); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) { + Map<String, Object> properties = Map.of("key", "value"); var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), properties, properties); var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), - null, properties, properties); + null, properties, properties); + var messageId = UUID.randomUUID(); threadHandler.deploy(messageId, compositionElement, instanceElement); verify(listener, timeout(TIMEOUT)).deploy(compositionElement, instanceElement); @@ -87,17 +117,9 @@ class ThreadHandlerTest { var compositionElementTarget = new CompositionElementDto(compositionTargetId, new ToscaConceptIdentifier(), properties, properties); threadHandler.migrate(messageId, compositionElement, compositionElementTarget, - instanceElement, instanceElementUpdated); + instanceElement, instanceElementUpdated, 0); verify(listener, timeout(TIMEOUT)).migrate(compositionElement, compositionElementTarget, - instanceElement, instanceElementUpdated); - - clearInvocations(listener); - threadHandler.lock(messageId, compositionElement, instanceElement); - verify(listener, timeout(TIMEOUT)).lock(compositionElement, instanceElement); - - clearInvocations(listener); - threadHandler.unlock(messageId, compositionElement, instanceElement); - verify(listener, timeout(TIMEOUT)).unlock(compositionElement, instanceElement); + instanceElement, instanceElementUpdated, 0); clearInvocations(listener); threadHandler.undeploy(messageId, compositionElement, instanceElement); @@ -106,29 +128,15 @@ class ThreadHandlerTest { clearInvocations(listener); threadHandler.delete(messageId, compositionElement, instanceElement); verify(listener, timeout(TIMEOUT)).delete(compositionElement, instanceElement); - - clearInvocations(listener); - threadHandler.deprime(messageId, composition); - verify(listener, timeout(TIMEOUT)).deprime(composition); } } @Test - void testException() throws PfModelException, IOException { + void testDeployException() throws PfModelException, IOException { var listener = mock(AutomationCompositionElementListener.class); var intermediaryApi = mock(ParticipantIntermediaryApi.class); try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) { - var compositionId = UUID.randomUUID(); - var composition = new CompositionDto(compositionId, Map.of(), Map.of()); - doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener) - .prime(composition); - var messageId = UUID.randomUUID(); - threadHandler.prime(messageId, composition); - verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.COMMISSIONED, - StateChangeResult.FAILED, "Composition Defintion prime failed"); - - clearInvocations(intermediaryApi); Map<String, Object> properties = Map.of("key", "value"); var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), properties, properties); @@ -139,9 +147,10 @@ class ThreadHandlerTest { element.setId(elementId); doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener) .deploy(compositionElement, instanceElement); + var messageId = UUID.randomUUID(); threadHandler.deploy(messageId, compositionElement, instanceElement); verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId, - DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, + DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Automation composition element deploy failed"); clearInvocations(listener); @@ -151,30 +160,28 @@ class ThreadHandlerTest { .update(compositionElement, instanceElement, instanceElementUpdated); threadHandler.update(messageId, compositionElement, instanceElement, instanceElementUpdated); verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId, - DeployState.DEPLOYED, null, StateChangeResult.FAILED, - "Automation composition element update failed"); - - clearInvocations(listener); - doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener) - .lock(compositionElement, instanceElement); - threadHandler.lock(messageId, compositionElement, instanceElement); - verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId, - null, LockState.UNLOCKED, StateChangeResult.FAILED, "Automation composition element lock failed"); + DeployState.DEPLOYED, null, StateChangeResult.FAILED, + "Automation composition element update failed"); clearInvocations(listener); + var compositionTargetId = UUID.randomUUID(); + var compositionElementTarget = new CompositionElementDto(compositionTargetId, new ToscaConceptIdentifier(), + properties, properties); doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener) - .unlock(compositionElement, instanceElement); - threadHandler.unlock(messageId, compositionElement, instanceElement); + .migrate(compositionElement, compositionElementTarget, instanceElement, instanceElementUpdated, 0); + threadHandler.migrate(messageId, compositionElement, compositionElementTarget, + instanceElement, instanceElementUpdated, 0); verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId, - null, LockState.LOCKED, StateChangeResult.FAILED, "Automation composition element unlock failed"); + DeployState.DEPLOYED, null, StateChangeResult.FAILED, + "Automation composition element migrate failed"); clearInvocations(listener); doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener) .undeploy(compositionElement, instanceElement); threadHandler.undeploy(messageId, compositionElement, instanceElement); verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId, - DeployState.DEPLOYED, null, StateChangeResult.FAILED, - "Automation composition element undeploy failed"); + DeployState.DEPLOYED, null, StateChangeResult.FAILED, + "Automation composition element undeploy failed"); clearInvocations(listener); doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener) @@ -183,36 +190,139 @@ class ThreadHandlerTest { verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId, DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Automation composition element delete failed"); + } + } + + @Test + void testLock() throws PfModelException, IOException { + var listener = mock(AutomationCompositionElementListener.class); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) { + + Map<String, Object> properties = Map.of("key", "value"); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + properties, properties); + var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), + null, properties, properties); + var messageId = UUID.randomUUID(); + threadHandler.lock(messageId, compositionElement, instanceElement); + verify(listener, timeout(TIMEOUT)).lock(compositionElement, instanceElement); clearInvocations(listener); - doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).deprime(composition); - threadHandler.deprime(messageId, composition); - verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.PRIMED, - StateChangeResult.FAILED, "Composition Defintion deprime failed"); + threadHandler.unlock(messageId, compositionElement, instanceElement); + verify(listener, timeout(TIMEOUT)).unlock(compositionElement, instanceElement); + + clearInvocations(listener); + threadHandler.undeploy(messageId, compositionElement, instanceElement); + verify(listener, timeout(TIMEOUT)).undeploy(compositionElement, instanceElement); + } + } + + @Test + void testLockException() throws PfModelException, IOException { + var listener = mock(AutomationCompositionElementListener.class); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) { + + Map<String, Object> properties = Map.of("key", "value"); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + properties, properties); + var instanceId = UUID.randomUUID(); + var elementId = UUID.randomUUID(); + var instanceElement = new InstanceElementDto(instanceId, elementId, null, properties, properties); + var element = new AcElementDeploy(); + element.setId(elementId); + var messageId = UUID.randomUUID(); + doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener) + .lock(compositionElement, instanceElement); + threadHandler.lock(messageId, compositionElement, instanceElement); + verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId, + null, LockState.UNLOCKED, StateChangeResult.FAILED, "Automation composition element lock failed"); clearInvocations(listener); doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener) - .handleRestartComposition(composition, AcTypeState.PRIMING); - threadHandler.restarted(messageId, composition, AcTypeState.PRIMING, List.of()); - verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.FAILED, - "Composition Defintion deprime failed"); + .unlock(compositionElement, instanceElement); + threadHandler.unlock(messageId, compositionElement, instanceElement); + verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId, + null, LockState.LOCKED, StateChangeResult.FAILED, "Automation composition element unlock failed"); } } @Test - void testRestarted() throws IOException, PfModelException { + void testSubState() throws PfModelException, IOException { var listener = mock(AutomationCompositionElementListener.class); var intermediaryApi = mock(ParticipantIntermediaryApi.class); - var cacheProvider = mock(CacheProvider.class); - try (var threadHandler = new ThreadHandler(listener, intermediaryApi, cacheProvider)) { + try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) { + + Map<String, Object> properties = Map.of("key", "value"); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + properties, properties); + var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), + null, properties, properties); var messageId = UUID.randomUUID(); - var compositionId = UUID.randomUUID(); - var participantRestartAc = new ParticipantRestartAc(); - participantRestartAc.setAutomationCompositionId(UUID.randomUUID()); - participantRestartAc.getAcElementList().add(new AcElementRestart()); - var composition = new CompositionDto(compositionId, Map.of(), Map.of()); - threadHandler.restarted(messageId, composition, AcTypeState.PRIMED, List.of(participantRestartAc)); - verify(listener, timeout(TIMEOUT)).handleRestartInstance(any(), any(), any(), any()); + threadHandler.prepare(messageId, compositionElement, instanceElement); + verify(listener, timeout(TIMEOUT)).prepare(compositionElement, instanceElement); + + clearInvocations(listener); + threadHandler.review(messageId, compositionElement, instanceElement); + verify(listener, timeout(TIMEOUT)).review(compositionElement, instanceElement); + + clearInvocations(listener); + var instanceElementMigrate = new InstanceElementDto(instanceElement.instanceId(), + instanceElement.elementId(), null, properties, properties); + var compositionTargetId = UUID.randomUUID(); + var compositionElementTarget = new CompositionElementDto(compositionTargetId, new ToscaConceptIdentifier(), + properties, properties); + threadHandler.migratePrecheck(messageId, compositionElement, compositionElementTarget, + instanceElement, instanceElementMigrate); + verify(listener, timeout(TIMEOUT)).migratePrecheck(compositionElement, compositionElementTarget, + instanceElement, instanceElementMigrate); + } + } + + @Test + void testSubStateException() throws PfModelException, IOException { + var listener = mock(AutomationCompositionElementListener.class); + var intermediaryApi = mock(ParticipantIntermediaryApi.class); + try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) { + + Map<String, Object> properties = Map.of("key", "value"); + var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + properties, properties); + var instanceId = UUID.randomUUID(); + var elementId = UUID.randomUUID(); + var instanceElement = new InstanceElementDto(instanceId, elementId, null, properties, properties); + var element = new AcElementDeploy(); + element.setId(elementId); + doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener) + .prepare(compositionElement, instanceElement); + var messageId = UUID.randomUUID(); + threadHandler.prepare(messageId, compositionElement, instanceElement); + verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId, + DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, + "Automation composition element prepare Pre Deploy failed"); + + clearInvocations(listener); + doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener) + .review(compositionElement, instanceElement); + threadHandler.review(messageId, compositionElement, instanceElement); + verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId, + DeployState.DEPLOYED, null, StateChangeResult.FAILED, + "Automation composition element Review failed"); + + clearInvocations(listener); + var compositionTargetId = UUID.randomUUID(); + var compositionElementTarget = new CompositionElementDto(compositionTargetId, new ToscaConceptIdentifier(), + properties, properties); + var instanceElementMigrate = new InstanceElementDto(instanceElement.instanceId(), + instanceElement.elementId(), null, properties, properties); + doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener) + .migratePrecheck(compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate); + threadHandler.migratePrecheck(messageId, compositionElement, compositionElementTarget, + instanceElement, instanceElementMigrate); + verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId, + DeployState.DEPLOYED, null, StateChangeResult.FAILED, + "Automation composition element migrate precheck failed"); } } } diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java index e8cafa96f..a116f1299 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java @@ -50,6 +50,7 @@ import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; /** * Class to hold/create all parameters for test cases. @@ -184,10 +185,6 @@ public class CommonTestData { return REPLICA_ID; } - public static UUID getRndParticipantId() { - return UUID.randomUUID(); - } - public static ToscaConceptIdentifier getDefinition() { return new ToscaConceptIdentifier("org.onap.domain.pmsh.PMSH_DCAEMicroservice", "1.2.3"); } @@ -196,8 +193,6 @@ public class CommonTestData { * Returns a Map of ToscaConceptIdentifier and AutomationComposition for test cases. * * @return automationCompositionMap - * - * @throws CoderException if there is an error with .json file. */ public static Map<UUID, AutomationComposition> getTestAutomationCompositionMap() { var automationCompositions = getTestAutomationCompositions(); @@ -211,8 +206,6 @@ public class CommonTestData { * Returns List of AutomationComposition for test cases. * * @return AutomationCompositions - * - * @throws CoderException if there is an error with .json file. */ public static AutomationCompositions getTestAutomationCompositions() { try { @@ -257,14 +250,18 @@ public class CommonTestData { public static ParticipantRestartAc createParticipantRestartAc() { var participantRestartAc = new ParticipantRestartAc(); participantRestartAc.setAutomationCompositionId(AC_ID_0); + participantRestartAc.setDeployState(DeployState.DEPLOYED); + participantRestartAc.setLockState(LockState.LOCKED); var acElementRestart = new AcElementRestart(); acElementRestart.setDefinition(getDefinition()); + acElementRestart.setParticipantId(PARTCICIPANT_ID); acElementRestart.setDeployState(DeployState.DEPLOYED); acElementRestart.setLockState(LockState.LOCKED); acElementRestart.setOperationalState("OperationalState"); acElementRestart.setUseState("UseState"); acElementRestart.setProperties(Map.of("key", "value")); acElementRestart.setOutProperties(Map.of("keyOut", "valueOut")); + acElementRestart.setToscaServiceTemplateFragment(new ToscaServiceTemplate()); acElementRestart.setId(UUID.randomUUID()); participantRestartAc.getAcElementList().add(acElementRestart); return participantRestartAc; @@ -286,6 +283,7 @@ public class CommonTestData { acElement.setId(element.getId()); acElement.setDefinition(element.getDefinition()); acElement.setProperties(element.getProperties()); + acElement.setToscaServiceTemplateFragment(new ToscaServiceTemplate()); participantDeploy.getAcElementList().add(acElement); } return participantDeploy; diff --git a/participant/pom.xml b/participant/pom.xml index 63c4826a4..fdbd154b8 100644 --- a/participant/pom.xml +++ b/participant/pom.xml @@ -26,7 +26,7 @@ <parent> <groupId>org.onap.policy.clamp</groupId> <artifactId>policy-clamp</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <groupId>org.onap.policy.clamp.participant</groupId> @@ -23,12 +23,12 @@ <parent> <groupId>org.onap.policy.parent</groupId> <artifactId>integration</artifactId> - <version>5.0.0-SNAPSHOT</version> + <version>5.0.1-SNAPSHOT</version> <relativePath /> </parent> <groupId>org.onap.policy.clamp</groupId> <artifactId>policy-clamp</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> <name>${project.artifactId}</name> <packaging>pom</packaging> <description> @@ -50,8 +50,8 @@ o policy-clamp-participant-impl-kserve: A standard participant for Kserve </description> <properties> - <policy.common.version>3.0.0-SNAPSHOT</policy.common.version> - <policy.models.version>4.0.0-SNAPSHOT</policy.models.version> + <policy.common.version>3.0.1-SNAPSHOT</policy.common.version> + <policy.models.version>4.0.1-SNAPSHOT</policy.models.version> </properties> <modules> <module>common</module> diff --git a/releases/8.0.0-container.yaml b/releases/8.0.0-container.yaml new file mode 100644 index 000000000..3a16df393 --- /dev/null +++ b/releases/8.0.0-container.yaml @@ -0,0 +1,22 @@ +distribution_type: 'container' +container_release_tag: '8.0.0' +project: 'policy-clamp' +log_dir: 'policy-clamp-maven-docker-stage-master/878' +ref: e197a0b95b5df5c0a37f7f420be8851920ca204b +containers: + - name: 'policy-clamp-ac-pf-ppnt' + version: '8.0.0-20240712T1140' + - name: 'policy-clamp-ac-k8s-ppnt' + version: '8.0.0-20240712T1140' + - name: 'policy-clamp-ac-http-ppnt' + version: '8.0.0-20240712T1140' + - name: 'policy-clamp-ac-a1pms-ppnt' + version: '8.0.0-20240712T1140' + - name: 'policy-clamp-runtime-acm' + version: '8.0.0-20240712T1140' + - name: 'policy-clamp-acm-element-impl' + version: '8.0.0-20240712T1140' + - name: 'policy-clamp-ac-kserve-ppnt' + version: '8.0.0-20240712T1140' + - name: 'policy-clamp-ac-sim-ppnt' + version: '8.0.0-20240712T1140' diff --git a/releases/8.0.0.yaml b/releases/8.0.0.yaml new file mode 100644 index 000000000..0573c08eb --- /dev/null +++ b/releases/8.0.0.yaml @@ -0,0 +1,5 @@ +distribution_type: 'maven' +version: '8.0.0' +project: 'policy-clamp' +tag_release: false +log_dir: 'policy-clamp-maven-stage-master/884/' diff --git a/runtime-acm/pom.xml b/runtime-acm/pom.xml index 1110b3a6c..82283eaf7 100644 --- a/runtime-acm/pom.xml +++ b/runtime-acm/pom.xml @@ -26,7 +26,7 @@ <parent> <groupId>org.onap.policy.clamp</groupId> <artifactId>policy-clamp</artifactId> - <version>8.0.0-SNAPSHOT</version> + <version>8.0.1-SNAPSHOT</version> </parent> <artifactId>policy-clamp-runtime-acm</artifactId> @@ -139,7 +139,6 @@ <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> - <version>${version.jupiter}</version> <scope>test</scope> </dependency> <dependency> diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java index 74ccb9cc6..48b139495 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java @@ -29,7 +29,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import lombok.RequiredArgsConstructor; import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; -import org.onap.policy.clamp.acm.runtime.participants.AcmParticipantProvider; import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantPrimePublisher; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; @@ -39,6 +38,7 @@ import org.onap.policy.clamp.models.acm.messages.rest.commissioning.Commissionin import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.AcTypeStateResolver; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; +import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider; import org.onap.policy.clamp.models.acm.utils.TimestampHelper; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; @@ -56,7 +56,7 @@ public class CommissioningProvider { private final AcDefinitionProvider acDefinitionProvider; private final AutomationCompositionProvider acProvider; - private final AcmParticipantProvider acmParticipantProvider; + private final ParticipantProvider participantProvider; private final AcTypeStateResolver acTypeStateResolver; private final ParticipantPrimePublisher participantPrimePublisher; private final AcRuntimeParameterGroup acRuntimeParameterGroup; @@ -188,10 +188,6 @@ public class CommissioningProvider { throw new PfModelRuntimeException(Status.BAD_REQUEST, "There are instances, Priming/Depriming not allowed"); } var acmDefinition = acDefinitionProvider.getAcDefinition(compositionId); - if (acmDefinition.getRestarting() != null) { - throw new PfModelRuntimeException(Status.BAD_REQUEST, - "There is a restarting process, Priming/Depriming not allowed"); - } var stateOrdered = acTypeStateResolver.resolve(acTypeStateUpdate.getPrimeOrder(), acmDefinition.getState(), acmDefinition.getStateChangeResult()); switch (stateOrdered) { @@ -229,7 +225,7 @@ public class CommissioningProvider { } } if (!participantIds.isEmpty()) { - acmParticipantProvider.verifyParticipantState(participantIds); + participantProvider.verifyParticipantState(participantIds); } acmDefinition.setState(AcTypeState.DEPRIMING); acmDefinition.setLastMsg(TimestampHelper.now()); diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/MetricsConfiguration.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/MetricsConfiguration.java index 084f7c774..f5c8368e2 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/MetricsConfiguration.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/MetricsConfiguration.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 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. @@ -23,6 +23,7 @@ package org.onap.policy.clamp.acm.runtime.config; import io.micrometer.core.aop.TimedAspect; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,8 +35,9 @@ public class MetricsConfiguration { * Load up the metrics registry. */ @Bean - public InitializingBean forcePrometheusPostProcessor(BeanPostProcessor meterRegistryPostProcessor, - MeterRegistry registry) { + public InitializingBean forcePrometheusPostProcessor(@Qualifier("meterRegistryPostProcessor") + BeanPostProcessor meterRegistryPostProcessor, + MeterRegistry registry) { return () -> meterRegistryPostProcessor.postProcessAfterInitialization(registry, ""); } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/OpenTelConfiguration.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/OpenTelConfiguration.java index 3727333a4..05d47d4f7 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/OpenTelConfiguration.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/OpenTelConfiguration.java @@ -35,7 +35,7 @@ import org.springframework.context.annotation.Configuration; public class OpenTelConfiguration { @Bean - @ConditionalOnProperty(prefix = "tracing", name = "enabled", havingValue = "true", matchIfMissing = false) + @ConditionalOnProperty(prefix = "tracing", name = "enabled", havingValue = "true") @ConditionalOnExpression("'http'.equals('${tracing.exporter.protocol}')") OtlpHttpSpanExporter otlpHttpSpanExporter(@Value("${tracing.exporter.endpoint:http://jaeger:4318/v1/traces}") String url) { return OtlpHttpSpanExporter.builder() @@ -44,7 +44,7 @@ public class OpenTelConfiguration { } @Bean - @ConditionalOnProperty(prefix = "tracing", name = "enabled", havingValue = "true", matchIfMissing = false) + @ConditionalOnProperty(prefix = "tracing", name = "enabled", havingValue = "true") @ConditionalOnExpression("'grpc'.equals('${tracing.exporter.protocol}')") OtlpGrpcSpanExporter otlpGrpcSpanExporter(@Value("${tracing.exporter.endpoint:http://jaeger:4317}") String url) { return OtlpGrpcSpanExporter.builder() @@ -53,7 +53,7 @@ public class OpenTelConfiguration { } @Bean - @ConditionalOnProperty(prefix = "tracing", name = "enabled", havingValue = "true", matchIfMissing = false) + @ConditionalOnProperty(prefix = "tracing", name = "enabled", havingValue = "true") JaegerRemoteSampler jaegerRemoteSampler( @Value("${tracing.sampler.jaeger-remote.endpoint:http://jaeger:14250}") String url, @Value("${SERVICE_ID:unknown_service}") String serviceId) { diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/SecurityConfig.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/SecurityConfig.java index 2e75db12e..9d50fc739 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/SecurityConfig.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/SecurityConfig.java @@ -45,16 +45,16 @@ public class SecurityConfig { */ @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - http - .httpBasic(Customizer.withDefaults()) - .authorizeHttpRequests(authorize -> { - if (useBasicAuth) { - authorize.anyRequest().authenticated(); - } else { - authorize.anyRequest().permitAll(); - } - }) - .csrf(AbstractHttpConfigurer::disable); + if (useBasicAuth) { + http + .httpBasic(Customizer.withDefaults()) + .authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated()); + } else { + http + .authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll()); + } + + http.csrf(AbstractHttpConfigurer::disable); return http.build(); } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/messaging/MessageDispatcherActivator.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/messaging/MessageDispatcherActivator.java index a3e55c3f7..ff1f60b69 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/messaging/MessageDispatcherActivator.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/messaging/MessageDispatcherActivator.java @@ -22,7 +22,6 @@ package org.onap.policy.clamp.acm.runtime.config.messaging; import java.io.Closeable; -import java.io.IOException; import java.util.List; import java.util.function.UnaryOperator; import java.util.stream.Collectors; @@ -139,7 +138,7 @@ public class MessageDispatcherActivator extends ServiceManagerContainer implemen } @Override - public void close() throws IOException { + public void close() { if (isAlive()) { super.shutdown(); } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/messaging/Publisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/messaging/Publisher.java index a76a09d99..63957c685 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/messaging/Publisher.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/config/messaging/Publisher.java @@ -20,8 +20,6 @@ package org.onap.policy.clamp.acm.runtime.config.messaging; -import java.util.List; -import org.onap.policy.clamp.acm.runtime.main.parameters.Topics; import org.onap.policy.common.endpoints.event.comm.TopicSink; /** diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java index 220636b9d..42af70596 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java @@ -22,14 +22,13 @@ package org.onap.policy.clamp.acm.runtime.instantiation; import jakarta.validation.Valid; -import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; +import java.util.List; import java.util.UUID; import java.util.stream.Collectors; import lombok.NonNull; import lombok.RequiredArgsConstructor; import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; -import org.onap.policy.clamp.acm.runtime.participants.AcmParticipantProvider; import org.onap.policy.clamp.acm.runtime.supervision.SupervisionAcHandler; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; @@ -38,15 +37,21 @@ 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.NodeTemplateState; 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.messages.rest.instantiation.AcInstanceStateUpdate; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.SubOrder; import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.AcInstanceStateResolver; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; +import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider; import org.onap.policy.clamp.models.acm.utils.AcmUtils; import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.common.parameters.ObjectValidationResult; import org.onap.policy.common.parameters.ValidationStatus; +import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfKey; import org.onap.policy.models.base.PfModelRuntimeException; import org.slf4j.Logger; @@ -62,6 +67,7 @@ import org.springframework.transaction.annotation.Transactional; @RequiredArgsConstructor public class AutomationCompositionInstantiationProvider { private static final String DO_NOT_MATCH = " do not match with "; + private static final String ELEMENT_ID_NOT_PRESENT = "Element id not present "; private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionInstantiationProvider.class); @@ -69,7 +75,7 @@ public class AutomationCompositionInstantiationProvider { private final AcDefinitionProvider acDefinitionProvider; private final AcInstanceStateResolver acInstanceStateResolver; private final SupervisionAcHandler supervisionAcHandler; - private final AcmParticipantProvider acmParticipantProvider; + private final ParticipantProvider participantProvider; private final AcRuntimeParameterGroup acRuntimeParameterGroup; /** @@ -82,19 +88,19 @@ public class AutomationCompositionInstantiationProvider { public InstantiationResponse createAutomationComposition(UUID compositionId, AutomationComposition automationComposition) { if (!compositionId.equals(automationComposition.getCompositionId())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); } var checkAutomationCompositionOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getKey().asIdentifier()); if (checkAutomationCompositionOpt.isPresent()) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, automationComposition.getKey().asIdentifier() + " already defined"); } var validationResult = validateAutomationComposition(automationComposition); if (!validationResult.isValid()) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult()); + throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); } automationComposition = automationCompositionProvider.createAutomationComposition(automationComposition); @@ -120,7 +126,7 @@ public class AutomationCompositionInstantiationProvider { var instanceId = automationComposition.getInstanceId(); var acToUpdate = automationCompositionProvider.getAutomationComposition(instanceId); if (!compositionId.equals(acToUpdate.getCompositionId())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); } if (DeployState.UNDEPLOYED.equals(acToUpdate.getDeployState())) { @@ -131,22 +137,38 @@ public class AutomationCompositionInstantiationProvider { acToUpdate.setDerivedFrom(automationComposition.getDerivedFrom()); var validationResult = validateAutomationComposition(acToUpdate); if (!validationResult.isValid()) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult()); + throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); } automationComposition = automationCompositionProvider.updateAutomationComposition(acToUpdate); return createInstantiationResponse(automationComposition); - } else if ((DeployState.DEPLOYED.equals(acToUpdate.getDeployState()) - || DeployState.UPDATING.equals(acToUpdate.getDeployState())) - && LockState.LOCKED.equals(acToUpdate.getLockState())) { - if (automationComposition.getCompositionTargetId() != null) { - return migrateAutomationComposition(automationComposition, acToUpdate); + } + + var deployOrder = DeployOrder.UPDATE; + var subOrder = SubOrder.NONE; + + if (automationComposition.getCompositionTargetId() != null) { + + if (Boolean.TRUE.equals(automationComposition.getPrecheck())) { + subOrder = SubOrder.MIGRATE_PRECHECK; + deployOrder = DeployOrder.NONE; } else { - return updateDeployedAutomationComposition(automationComposition, acToUpdate); + deployOrder = DeployOrder.MIGRATE; } } - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, - "Not allowed to update in the state " + acToUpdate.getDeployState()); + var result = acInstanceStateResolver.resolve(deployOrder, LockOrder.NONE, subOrder, + acToUpdate.getDeployState(), acToUpdate.getLockState(), acToUpdate.getSubState(), + acToUpdate.getStateChangeResult()); + return switch (result) { + case "UPDATE" -> updateDeployedAutomationComposition(automationComposition, acToUpdate); + + case "MIGRATE" -> migrateAutomationComposition(automationComposition, acToUpdate); + + case "MIGRATE_PRECHECK" -> migratePrecheckAc(automationComposition, acToUpdate); + + default -> throw new PfModelRuntimeException(Status.BAD_REQUEST, + "Not allowed to " + deployOrder + " in the state " + acToUpdate.getDeployState()); + }; } /** @@ -164,17 +186,14 @@ public class AutomationCompositionInstantiationProvider { var elementId = element.getKey(); var dbAcElement = acToBeUpdated.getElements().get(elementId); if (dbAcElement == null) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, "Element id not present " + elementId); + throw new PfModelRuntimeException(Status.BAD_REQUEST, ELEMENT_ID_NOT_PRESENT + elementId); } AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties()); } - if (automationComposition.getRestarting() != null) { - throw new PfModelRuntimeException(Status.BAD_REQUEST, "There is a restarting process, Update not allowed"); - } var validationResult = validateAutomationComposition(acToBeUpdated); if (!validationResult.isValid()) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult()); + throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); } // Publish property update event to the participants supervisionAcHandler.update(acToBeUpdated); @@ -187,47 +206,104 @@ public class AutomationCompositionInstantiationProvider { AutomationComposition automationComposition, AutomationComposition acToBeUpdated) { if (!DeployState.DEPLOYED.equals(acToBeUpdated.getDeployState())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, "Not allowed to migrate in the state " + acToBeUpdated.getDeployState()); } - if (automationComposition.getRestarting() != null) { - throw new PfModelRuntimeException(Status.BAD_REQUEST, "There is a restarting process, Migrate not allowed"); - } // Iterate and update the element property values for (var element : automationComposition.getElements().entrySet()) { var elementId = element.getKey(); var dbAcElement = acToBeUpdated.getElements().get(elementId); + // Add additional elements if present for migration if (dbAcElement == null) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, "Element id not present " + elementId); - } - AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties()); - var newDefinition = element.getValue().getDefinition(); - var compatibility = - newDefinition.asConceptKey().getCompatibility(dbAcElement.getDefinition().asConceptKey()); - if (PfKey.Compatibility.DIFFERENT.equals(compatibility)) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, - dbAcElement.getDefinition() + " is not compatible with " + newDefinition); - } - if (PfKey.Compatibility.MAJOR.equals(compatibility) || PfKey.Compatibility.MINOR.equals(compatibility)) { - LOGGER.warn("Migrate {}: Version {} has {} compatibility with {} ", - automationComposition.getInstanceId(), newDefinition, compatibility, dbAcElement.getDefinition()); + LOGGER.info("New Ac element {} added in Migration", elementId); + acToBeUpdated.getElements().put(elementId, element.getValue()); + } else { + AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties()); + var newDefinition = element.getValue().getDefinition().asConceptKey(); + var dbElementDefinition = dbAcElement.getDefinition().asConceptKey(); + checkCompatibility(newDefinition, dbElementDefinition, automationComposition.getInstanceId()); + dbAcElement.setDefinition(element.getValue().getDefinition()); } - dbAcElement.setDefinition(element.getValue().getDefinition()); } + // Remove element which is not present in the new Ac instance + var elementsRemoved = getElementRemoved(acToBeUpdated, automationComposition); + elementsRemoved.forEach(uuid -> acToBeUpdated.getElements().remove(uuid)); var validationResult = - validateAutomationComposition(acToBeUpdated, automationComposition.getCompositionTargetId()); + validateAutomationComposition(acToBeUpdated, automationComposition.getCompositionTargetId()); if (!validationResult.isValid()) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult()); + throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); } acToBeUpdated.setCompositionTargetId(automationComposition.getCompositionTargetId()); + var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionTargetId()); + // Publish migrate event to the participants + supervisionAcHandler.migrate(acToBeUpdated, acDefinition.getServiceTemplate()); + + var ac = automationCompositionProvider.updateAutomationComposition(acToBeUpdated); + elementsRemoved.forEach(automationCompositionProvider::deleteAutomationCompositionElement); + return createInstantiationResponse(ac); + } + + private List<UUID> getElementRemoved(AutomationComposition acFromDb, AutomationComposition acFromMigration) { + return acFromDb.getElements().keySet().stream() + .filter(id -> acFromMigration.getElements().get(id) == null).toList(); + } + + void checkCompatibility(PfConceptKey newDefinition, PfConceptKey dbElementDefinition, + UUID instanceId) { + var compatibility = newDefinition.getCompatibility(dbElementDefinition); + if (PfKey.Compatibility.DIFFERENT.equals(compatibility)) { + throw new PfModelRuntimeException(Status.BAD_REQUEST, + dbElementDefinition + " is not compatible with " + newDefinition); + } + if (PfKey.Compatibility.MAJOR.equals(compatibility) || PfKey.Compatibility.MINOR + .equals(compatibility)) { + LOGGER.warn("Migrate {}: Version {} has {} compatibility with {} ", instanceId, newDefinition, + compatibility, dbElementDefinition); + } + } + + private InstantiationResponse migratePrecheckAc( + AutomationComposition automationComposition, AutomationComposition acToBeUpdated) { + + acToBeUpdated.setPrecheck(true); + var copyAc = new AutomationComposition(acToBeUpdated); + // Iterate and update the element property values + for (var element : automationComposition.getElements().entrySet()) { + var elementId = element.getKey(); + var copyElement = copyAc.getElements().get(elementId); + // Add additional elements if present for migration + if (copyElement == null) { + LOGGER.info("New Ac element {} added in Migration", elementId); + copyAc.getElements().put(elementId, element.getValue()); + } else { + AcmUtils.recursiveMerge(copyElement.getProperties(), element.getValue().getProperties()); + var newDefinition = element.getValue().getDefinition().asConceptKey(); + var copyElementDefinition = copyElement.getDefinition().asConceptKey(); + checkCompatibility(newDefinition, copyElementDefinition, automationComposition.getInstanceId()); + copyElement.setDefinition(element.getValue().getDefinition()); + } + } + // Remove element which is not present in the new Ac instance + var elementsRemoved = getElementRemoved(copyAc, automationComposition); + elementsRemoved.forEach(uuid -> copyAc.getElements().remove(uuid)); + + var validationResult = + validateAutomationComposition(copyAc, automationComposition.getCompositionTargetId()); + if (!validationResult.isValid()) { + throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); + } + copyAc.setCompositionTargetId(automationComposition.getCompositionTargetId()); // Publish migrate event to the participants - supervisionAcHandler.migrate(acToBeUpdated, automationComposition.getCompositionTargetId()); + supervisionAcHandler.migratePrecheck(copyAc); - automationComposition = automationCompositionProvider.updateAutomationComposition(acToBeUpdated); - return createInstantiationResponse(automationComposition); + AcmUtils.setCascadedState(acToBeUpdated, DeployState.DEPLOYED, LockState.LOCKED, + SubState.MIGRATION_PRECHECKING); + acToBeUpdated.setStateChangeResult(StateChangeResult.NO_ERROR); + + return createInstantiationResponse(automationCompositionProvider.updateAutomationComposition(acToBeUpdated)); } private BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition) { @@ -256,16 +332,10 @@ public class AutomationCompositionInstantiationProvider { ValidationStatus.INVALID, "Commissioned automation composition definition not primed")); return result; } - if (acDefinitionOpt.get().getRestarting() != null) { - result.addResult( - new ObjectValidationResult("ServiceTemplate.restarting", acDefinitionOpt.get().getRestarting(), - ValidationStatus.INVALID, "There is a restarting process in composition")); - return result; - } var participantIds = acDefinitionOpt.get().getElementStateMap().values().stream() .map(NodeTemplateState::getParticipantId).collect(Collectors.toSet()); - acmParticipantProvider.verifyParticipantState(participantIds); + participantProvider.verifyParticipantState(participantIds); result.addResult(AcmUtils.validateAutomationComposition(automationComposition, acDefinitionOpt.get().getServiceTemplate(), @@ -296,7 +366,7 @@ public class AutomationCompositionInstantiationProvider { var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId); if (!compositionId.equals(automationComposition.getCompositionId()) && !compositionId.equals(automationComposition.getCompositionTargetId())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); } return automationComposition; @@ -312,26 +382,23 @@ public class AutomationCompositionInstantiationProvider { public InstantiationResponse deleteAutomationComposition(UUID compositionId, UUID instanceId) { var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId); if (!compositionId.equals(automationComposition.getCompositionId())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); } if (!DeployState.UNDEPLOYED.equals(automationComposition.getDeployState()) && !DeployState.DELETING.equals(automationComposition.getDeployState())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, "Automation composition state is still " + automationComposition.getDeployState()); } if (DeployState.DELETING.equals(automationComposition.getDeployState()) && StateChangeResult.NO_ERROR.equals(automationComposition.getStateChangeResult())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, "Automation composition state is still " + automationComposition.getDeployState()); } - if (automationComposition.getRestarting() != null) { - throw new PfModelRuntimeException(Status.BAD_REQUEST, "There is a restarting process, Delete not allowed"); - } var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId()); var participantIds = acDefinition.getElementStateMap().values().stream() .map(NodeTemplateState::getParticipantId).collect(Collectors.toSet()); - acmParticipantProvider.verifyParticipantState(participantIds); + participantProvider.verifyParticipantState(participantIds); supervisionAcHandler.delete(automationComposition, acDefinition); var response = new InstantiationResponse(); response.setInstanceId(automationComposition.getInstanceId()); @@ -366,7 +433,7 @@ public class AutomationCompositionInstantiationProvider { @Valid AcInstanceStateUpdate acInstanceStateUpdate) { var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId); if (!compositionId.equals(automationComposition.getCompositionId())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); } var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId()); @@ -374,10 +441,11 @@ public class AutomationCompositionInstantiationProvider { var participantIds = acDefinition.getElementStateMap().values().stream() .map(NodeTemplateState::getParticipantId).collect(Collectors.toSet()); - acmParticipantProvider.verifyParticipantState(participantIds); + participantProvider.verifyParticipantState(participantIds); var result = acInstanceStateResolver.resolve(acInstanceStateUpdate.getDeployOrder(), - acInstanceStateUpdate.getLockOrder(), automationComposition.getDeployState(), - automationComposition.getLockState(), automationComposition.getStateChangeResult()); + acInstanceStateUpdate.getLockOrder(), acInstanceStateUpdate.getSubOrder(), + automationComposition.getDeployState(), automationComposition.getLockState(), + automationComposition.getSubState(), automationComposition.getStateChangeResult()); switch (result) { case "DEPLOY": supervisionAcHandler.deploy(automationComposition, acDefinition); @@ -395,6 +463,14 @@ public class AutomationCompositionInstantiationProvider { supervisionAcHandler.unlock(automationComposition, acDefinition); break; + case "PREPARE": + supervisionAcHandler.prepare(automationComposition); + break; + + case "REVIEW": + supervisionAcHandler.review(automationComposition); + break; + default: throw new PfModelRuntimeException(Status.BAD_REQUEST, "Not valid " + acInstanceStateUpdate); } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/parameters/AcRuntimeParameterGroup.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/parameters/AcRuntimeParameterGroup.java index a0b6fe13e..e6ce61438 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/parameters/AcRuntimeParameterGroup.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/parameters/AcRuntimeParameterGroup.java @@ -53,5 +53,5 @@ public class AcRuntimeParameterGroup { @Valid @NotNull - private Topics topics; + private Topics topics = new Topics(); } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/parameters/Topics.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/parameters/Topics.java index d485a24ba..6e230d3df 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/parameters/Topics.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/parameters/Topics.java @@ -20,6 +20,7 @@ package org.onap.policy.clamp.acm.runtime.main.parameters; import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; import org.springframework.validation.annotation.Validated; @@ -27,6 +28,7 @@ import org.springframework.validation.annotation.Validated; @Setter @Validated @AllArgsConstructor +@NoArgsConstructor public class Topics { private String operationTopic; diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/ParticipantController.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/ParticipantController.java index 855681e69..1136dcb16 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/ParticipantController.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/ParticipantController.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation. + * Copyright (C) 2023-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. @@ -41,8 +41,7 @@ public class ParticipantController extends AbstractRestController implements Par @Override public ResponseEntity<ParticipantInformation> getParticipant(UUID participantId, UUID requestId) { - ParticipantInformation participantInformation = acmParticipantProvider - .getParticipantById(participantId); + var participantInformation = acmParticipantProvider.getParticipantById(participantId); return ResponseEntity.ok().body(participantInformation); } @@ -61,7 +60,7 @@ public class ParticipantController extends AbstractRestController implements Par @Override public ResponseEntity<List<ParticipantInformation>> queryParticipants(String name, String version, UUID requestId) { - List<ParticipantInformation> participantInformationList = acmParticipantProvider.getAllParticipants(); + var participantInformationList = acmParticipantProvider.getAllParticipants(); return ResponseEntity.ok().body(participantInformationList); } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/participants/AcmParticipantProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/participants/AcmParticipantProvider.java index 13382e0fb..62ba7b017 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/participants/AcmParticipantProvider.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/participants/AcmParticipantProvider.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation. + * Copyright (C) 2023-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. @@ -20,12 +20,10 @@ package org.onap.policy.clamp.acm.runtime.participants; -import jakarta.ws.rs.core.Response; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.UUID; import lombok.RequiredArgsConstructor; import org.apache.commons.collections4.MapUtils; @@ -33,9 +31,7 @@ import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantStatusReqPu import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState; import org.onap.policy.clamp.models.acm.concepts.ParticipantInformation; -import org.onap.policy.clamp.models.acm.concepts.ParticipantState; import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider; -import org.onap.policy.models.base.PfModelRuntimeException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @@ -94,12 +90,11 @@ public class AcmParticipantProvider { * @param participantId The UUID of the participant to send request to */ public void sendParticipantStatusRequest(UUID participantId) { - var participant = this.participantProvider.getParticipantById(participantId); + // check if participant is present + this.participantProvider.getParticipantById(participantId); LOGGER.debug("Requesting Participant Status Now ParticipantStatusReq"); participantStatusReqPublisher.send(participantId); - participant.setParticipantState(ParticipantState.OFF_LINE); - participantProvider.updateParticipant(participant); } /** @@ -110,22 +105,6 @@ public class AcmParticipantProvider { this.participantStatusReqPublisher.send((UUID) null); } - /** - * Verify Participant state. - * - * @param participantIds The list of UUIDs of the participants to get - * @throws PfModelRuntimeException in case the participant is offline - */ - public void verifyParticipantState(Set<UUID> participantIds) { - for (UUID participantId : participantIds) { - var participant = this.participantProvider.getParticipantById(participantId); - if (! participant.getParticipantState().equals(ParticipantState.ON_LINE)) { - throw new PfModelRuntimeException(Response.Status.CONFLICT, - "Participant: " + participantId + " is OFFLINE"); - } - } - } - private Map<UUID, AutomationCompositionElement> getAutomationCompositionElementsForParticipant(UUID participantId) { var automationCompositionElements = participantProvider .getAutomationCompositionElements(participantId); diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java index 802c6603b..6a56a2c2b 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java @@ -23,27 +23,30 @@ package org.onap.policy.clamp.acm.runtime.supervision; import io.micrometer.core.annotation.Timed; import io.opentelemetry.context.Context; import java.util.Map; -import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import lombok.AllArgsConstructor; import org.onap.policy.clamp.acm.runtime.supervision.comm.AcElementPropertiesPublisher; +import org.onap.policy.clamp.acm.runtime.supervision.comm.AcPreparePublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionDeployPublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionMigrationPublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher; +import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher; import org.onap.policy.clamp.models.acm.concepts.AcElementDeployAck; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; -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.ParticipantUtils; 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.messages.kafka.participant.AutomationCompositionDeployAck; +import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -58,12 +61,15 @@ public class SupervisionAcHandler { private static final Logger LOGGER = LoggerFactory.getLogger(SupervisionAcHandler.class); private final AutomationCompositionProvider automationCompositionProvider; + private final AcDefinitionProvider acDefinitionProvider; // Publishers for participant communication private final AutomationCompositionDeployPublisher automationCompositionDeployPublisher; private final AutomationCompositionStateChangePublisher automationCompositionStateChangePublisher; private final AcElementPropertiesPublisher acElementPropertiesPublisher; private final AutomationCompositionMigrationPublisher acCompositionMigrationPublisher; + private final ParticipantSyncPublisher participantSyncPublisher; + private final AcPreparePublisher acPreparePublisher; private final ExecutorService executor = Context.taskWrapping(Executors.newFixedThreadPool(1)); @@ -146,6 +152,30 @@ public class SupervisionAcHandler { } /** + * Handle prepare Pre Deploy an AutomationComposition instance. + * + * @param automationComposition the AutomationComposition + */ + public void prepare(AutomationComposition automationComposition) { + AcmUtils.setCascadedState(automationComposition, DeployState.UNDEPLOYED, LockState.NONE, SubState.PREPARING); + automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); + automationCompositionProvider.updateAutomationComposition(automationComposition); + executor.execute(() -> acPreparePublisher.sendPrepare(automationComposition)); + } + + /** + * Handle prepare Post Deploy an AutomationComposition instance. + * + * @param automationComposition the AutomationComposition + */ + public void review(AutomationComposition automationComposition) { + AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKED, SubState.REVIEWING); + automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); + automationCompositionProvider.updateAutomationComposition(automationComposition); + executor.execute(() -> acPreparePublisher.sendRevew(automationComposition)); + } + + /** * Handle Lock an AutomationComposition instance. * * @param automationComposition the AutomationComposition @@ -227,10 +257,14 @@ public class SupervisionAcHandler { } private void setAcElementStateInDb(AutomationCompositionDeployAck automationCompositionAckMessage) { + if (!validateMessage(automationCompositionAckMessage)) { + return; + } + var automationCompositionOpt = automationCompositionProvider .findAutomationComposition(automationCompositionAckMessage.getAutomationCompositionId()); if (automationCompositionOpt.isEmpty()) { - LOGGER.warn("AutomationComposition not found in database {}", + LOGGER.error("AutomationComposition not found in database {}", automationCompositionAckMessage.getAutomationCompositionId()); return; } @@ -239,14 +273,7 @@ public class SupervisionAcHandler { if (automationCompositionAckMessage.getAutomationCompositionResultMap() == null || automationCompositionAckMessage.getAutomationCompositionResultMap().isEmpty()) { if (DeployState.DELETING.equals(automationComposition.getDeployState())) { - // scenario when Automation Composition instance has never been deployed - for (var element : automationComposition.getElements().values()) { - if (element.getParticipantId().equals(automationCompositionAckMessage.getParticipantId())) { - element.setDeployState(DeployState.DELETED); - automationCompositionProvider.updateAutomationCompositionElement(element, - automationComposition.getInstanceId()); - } - } + deleteAcInstance(automationComposition, automationCompositionAckMessage.getParticipantId()); } else { LOGGER.warn("Empty AutomationCompositionResultMap {} {}", automationCompositionAckMessage.getAutomationCompositionId(), @@ -257,15 +284,51 @@ public class SupervisionAcHandler { var updated = updateState(automationComposition, automationCompositionAckMessage.getAutomationCompositionResultMap().entrySet(), - automationCompositionAckMessage.getStateChangeResult()); + automationCompositionAckMessage.getStateChangeResult(), automationCompositionAckMessage.getStage()); if (updated) { - automationCompositionProvider.updateAutomationComposition(automationComposition); + automationComposition = automationCompositionProvider.updateAcState(automationComposition); + var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId()); + participantSyncPublisher.sendSync(acDefinition.getServiceTemplate(), automationComposition); + } + } + + private boolean validateMessage(AutomationCompositionDeployAck acAckMessage) { + if (acAckMessage.getAutomationCompositionId() == null + || acAckMessage.getStateChangeResult() == null) { + LOGGER.error("Not valid AutomationCompositionDeployAck message"); + return false; + } + if (!StateChangeResult.NO_ERROR.equals(acAckMessage.getStateChangeResult()) + && !StateChangeResult.FAILED.equals(acAckMessage.getStateChangeResult())) { + LOGGER.error("Not valid AutomationCompositionDeployAck message, stateChangeResult is not valid {} ", + acAckMessage.getStateChangeResult()); + return false; + } + + if (acAckMessage.getStage() == null) { + for (var el : acAckMessage.getAutomationCompositionResultMap().values()) { + if (AcmUtils.isInTransitionalState(el.getDeployState(), el.getLockState(), SubState.NONE)) { + LOGGER.error("Not valid AutomationCompositionDeployAck message, states are not valid"); + return false; + } + } + } + return true; + } + + private void deleteAcInstance(AutomationComposition automationComposition, UUID participantId) { + // scenario when Automation Composition instance has never been deployed + for (var element : automationComposition.getElements().values()) { + if (element.getParticipantId().equals(participantId)) { + element.setDeployState(DeployState.DELETED); + automationCompositionProvider.updateAutomationCompositionElement(element); + } } } private boolean updateState(AutomationComposition automationComposition, Set<Map.Entry<UUID, AcElementDeployAck>> automationCompositionResultSet, - StateChangeResult stateChangeResult) { + StateChangeResult stateChangeResult, Integer stage) { var updated = false; boolean inProgress = !StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult()); if (inProgress && !stateChangeResult.equals(automationComposition.getStateChangeResult())) { @@ -276,24 +339,17 @@ public class SupervisionAcHandler { for (var acElementAck : automationCompositionResultSet) { var element = automationComposition.getElements().get(acElementAck.getKey()); if (element != null) { - element.setMessage(acElementAck.getValue().getMessage()); + element.setMessage(AcmUtils.validatedMessage(acElementAck.getValue().getMessage())); element.setOutProperties(acElementAck.getValue().getOutProperties()); element.setOperationalState(acElementAck.getValue().getOperationalState()); element.setUseState(acElementAck.getValue().getUseState()); + if (stage == null) { + element.setSubState(SubState.NONE); + } element.setDeployState(acElementAck.getValue().getDeployState()); element.setLockState(acElementAck.getValue().getLockState()); - element.setRestarting(null); - automationCompositionProvider.updateAutomationCompositionElement(element, - automationComposition.getInstanceId()); - } - } - - if (automationComposition.getRestarting() != null) { - var restarting = automationComposition.getElements().values().stream() - .map(AutomationCompositionElement::getRestarting).filter(Objects::nonNull).findAny(); - if (restarting.isEmpty()) { - automationComposition.setRestarting(null); - updated = true; + element.setStage(stage); + automationCompositionProvider.updateAutomationCompositionElement(element); } } @@ -304,12 +360,22 @@ public class SupervisionAcHandler { * Handle Migration of an AutomationComposition instance to other ACM Definition. * * @param automationComposition the AutomationComposition - * @param compositionTargetId the ACM Definition Id + * @param serviceTemplate the ServiceTemplate */ - public void migrate(AutomationComposition automationComposition, UUID compositionTargetId) { + public void migrate(AutomationComposition automationComposition, ToscaServiceTemplate serviceTemplate) { AcmUtils.setCascadedState(automationComposition, DeployState.MIGRATING, LockState.LOCKED); + var stage = ParticipantUtils.getFirstStage(automationComposition, serviceTemplate); automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); - executor.execute( - () -> acCompositionMigrationPublisher.send(automationComposition, compositionTargetId)); + automationComposition.setPhase(stage); + executor.execute(() -> acCompositionMigrationPublisher.send(automationComposition, stage)); + } + + /** + * Handle Migration precheck of an AutomationComposition instance to other ACM Definition. + * + * @param automationComposition the AutomationComposition + */ + public void migratePrecheck(AutomationComposition automationComposition) { + executor.execute(() -> acCompositionMigrationPublisher.send(automationComposition, 0)); } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspect.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspect.java index 8f3a4c2eb..9ef979f8e 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspect.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspect.java @@ -41,9 +41,9 @@ public class SupervisionAspect implements Closeable { private static final Logger LOGGER = LoggerFactory.getLogger(SupervisionAspect.class); private final SupervisionScanner supervisionScanner; - private final SupervisionPartecipantScanner partecipantScanner; + private final SupervisionParticipantScanner participantScanner; - private ThreadPoolExecutor executor = + private final ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); @Scheduled( @@ -56,7 +56,7 @@ public class SupervisionAspect implements Closeable { private void executeScan() { supervisionScanner.run(); - partecipantScanner.run(); + participantScanner.run(); } /** diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java index 963e4830e..f13f5da2c 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java @@ -23,12 +23,14 @@ package org.onap.policy.clamp.acm.runtime.supervision; import io.micrometer.core.annotation.Timed; import lombok.AllArgsConstructor; -import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; +import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; +import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrimeAck; import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; +import org.onap.policy.clamp.models.acm.utils.AcmUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -43,7 +45,7 @@ public class SupervisionHandler { private static final Logger LOGGER = LoggerFactory.getLogger(SupervisionHandler.class); private final AcDefinitionProvider acDefinitionProvider; - private final AcRuntimeParameterGroup acRuntimeParameterGroup; + private final ParticipantSyncPublisher participantSyncPublisher; /** * Handle a ParticipantPrimeAck message from a participant. @@ -52,6 +54,22 @@ public class SupervisionHandler { */ @Timed(value = "listener.participant_prime_ack", description = "PARTICIPANT_PRIME_ACK messages received") public void handleParticipantMessage(ParticipantPrimeAck participantPrimeAckMessage) { + if (participantPrimeAckMessage.getCompositionId() == null + || participantPrimeAckMessage.getCompositionState() == null + || participantPrimeAckMessage.getStateChangeResult() == null) { + LOGGER.error("Not valid ParticipantPrimeAck message"); + return; + } + if (AcTypeState.PRIMING.equals(participantPrimeAckMessage.getCompositionState()) + || AcTypeState.DEPRIMING.equals(participantPrimeAckMessage.getCompositionState())) { + LOGGER.error("Not valid state {}", participantPrimeAckMessage.getCompositionState()); + return; + } + if (!StateChangeResult.NO_ERROR.equals(participantPrimeAckMessage.getStateChangeResult()) + && !StateChangeResult.FAILED.equals(participantPrimeAckMessage.getStateChangeResult())) { + LOGGER.error("Vot valid stateChangeResult {} ", participantPrimeAckMessage.getStateChangeResult()); + return; + } var acDefinitionOpt = acDefinitionProvider.findAcDefinition(participantPrimeAckMessage.getCompositionId()); if (acDefinitionOpt.isEmpty()) { LOGGER.warn("AC Definition not found in database {}", participantPrimeAckMessage.getCompositionId()); @@ -59,7 +77,7 @@ public class SupervisionHandler { } var acDefinition = acDefinitionOpt.get(); if (!AcTypeState.PRIMING.equals(acDefinition.getState()) - && !AcTypeState.DEPRIMING.equals(acDefinition.getState()) && acDefinition.getRestarting() == null) { + && !AcTypeState.DEPRIMING.equals(acDefinition.getState())) { LOGGER.error("AC Definition {} already primed/deprimed with participant {}", participantPrimeAckMessage.getCompositionId(), participantPrimeAckMessage.getParticipantId()); return; @@ -80,20 +98,11 @@ public class SupervisionHandler { } boolean completed = true; - boolean restarting = false; for (var element : acDefinition.getElementStateMap().values()) { - if (participantPrimeAckMessage.getParticipantId().equals(element.getParticipantId())) { - element.setMessage(participantPrimeAckMessage.getMessage()); - element.setState(participantPrimeAckMessage.getCompositionState()); - element.setRestarting(null); - acDefinitionProvider.updateAcDefinitionElement(element, acDefinition.getCompositionId()); - } + handlePrimeAckElement(participantPrimeAckMessage, element); if (!finalState.equals(element.getState())) { completed = false; } - if (element.getRestarting() != null) { - restarting = true; - } } if (inProgress && !msgInErrors && completed) { @@ -103,13 +112,20 @@ public class SupervisionHandler { acDefinition.setStateChangeResult(StateChangeResult.NO_ERROR); } } - if (!restarting && acDefinition.getRestarting() != null) { - toUpdate = true; - acDefinition.setRestarting(null); - } if (toUpdate) { acDefinitionProvider.updateAcDefinitionState(acDefinition.getCompositionId(), acDefinition.getState(), - acDefinition.getStateChangeResult(), acDefinition.getRestarting()); + acDefinition.getStateChangeResult()); + if (!participantPrimeAckMessage.getParticipantId().equals(participantPrimeAckMessage.getReplicaId())) { + participantSyncPublisher.sendSync(acDefinition, participantPrimeAckMessage.getReplicaId()); + } + } + } + + private void handlePrimeAckElement(ParticipantPrimeAck participantPrimeAckMessage, NodeTemplateState element) { + if (participantPrimeAckMessage.getParticipantId().equals(element.getParticipantId())) { + element.setMessage(AcmUtils.validatedMessage(participantPrimeAckMessage.getMessage())); + element.setState(participantPrimeAckMessage.getCompositionState()); + acDefinitionProvider.updateAcDefinitionElement(element, participantPrimeAckMessage.getCompositionId()); } } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java index d1efb6ac0..ea3ef0ff7 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java @@ -21,7 +21,6 @@ package org.onap.policy.clamp.acm.runtime.supervision; import io.micrometer.core.annotation.Timed; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -31,15 +30,15 @@ import org.apache.commons.collections4.MapUtils; import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantDeregisterAckPublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantRegisterAckPublisher; -import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantRestartPublisher; +import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; import org.onap.policy.clamp.models.acm.concepts.Participant; import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; +import org.onap.policy.clamp.models.acm.concepts.ParticipantReplica; import org.onap.policy.clamp.models.acm.concepts.ParticipantState; import org.onap.policy.clamp.models.acm.concepts.ParticipantSupportedElementType; -import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantDeregister; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRegister; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantStatus; @@ -64,7 +63,7 @@ public class SupervisionParticipantHandler { private final ParticipantDeregisterAckPublisher participantDeregisterAckPublisher; private final AutomationCompositionProvider automationCompositionProvider; private final AcDefinitionProvider acDefinitionProvider; - private final ParticipantRestartPublisher participantRestartPublisher; + private final ParticipantSyncPublisher participantSyncPublisher; private final AcRuntimeParameterGroup acRuntimeParameterGroup; /** @@ -72,24 +71,14 @@ public class SupervisionParticipantHandler { * * @param participantRegisterMsg the ParticipantRegister message received from a participant */ - @MessageIntercept @Timed(value = "listener.participant_register", description = "PARTICIPANT_REGISTER messages received") public void handleParticipantMessage(ParticipantRegister participantRegisterMsg) { - var participantOpt = participantProvider.findParticipant(participantRegisterMsg.getParticipantId()); - - if (participantOpt.isPresent()) { - var participant = participantOpt.get(); - checkOnline(participant); - handleRestart(participant.getParticipantId()); - } else { - var participant = createParticipant(participantRegisterMsg.getParticipantId(), - listToMap(participantRegisterMsg.getParticipantSupportedElementType())); - participantProvider.saveParticipant(participant); - - } + saveIfNotPresent(participantRegisterMsg.getReplicaId(), + participantRegisterMsg.getParticipantId(), + participantRegisterMsg.getParticipantSupportedElementType(), true); participantRegisterAckPublisher.send(participantRegisterMsg.getMessageId(), - participantRegisterMsg.getParticipantId()); + participantRegisterMsg.getParticipantId(), participantRegisterMsg.getReplicaId()); } /** @@ -97,15 +86,13 @@ public class SupervisionParticipantHandler { * * @param participantDeregisterMsg the ParticipantDeregister message received from a participant */ - @MessageIntercept @Timed(value = "listener.participant_deregister", description = "PARTICIPANT_DEREGISTER messages received") public void handleParticipantMessage(ParticipantDeregister participantDeregisterMsg) { - var participantOpt = participantProvider.findParticipant(participantDeregisterMsg.getParticipantId()); - - if (participantOpt.isPresent()) { - var participant = participantOpt.get(); - participant.setParticipantState(ParticipantState.OFF_LINE); - participantProvider.updateParticipant(participant); + var replicaId = participantDeregisterMsg.getReplicaId() != null + ? participantDeregisterMsg.getReplicaId() : participantDeregisterMsg.getParticipantId(); + var replicaOpt = participantProvider.findParticipantReplica(replicaId); + if (replicaOpt.isPresent()) { + participantProvider.deleteParticipantReplica(replicaId); } participantDeregisterAckPublisher.send(participantDeregisterMsg.getMessageId()); @@ -116,32 +103,57 @@ public class SupervisionParticipantHandler { * * @param participantStatusMsg the ParticipantStatus message received from a participant */ - @MessageIntercept @Timed(value = "listener.participant_status", description = "PARTICIPANT_STATUS messages received") public void handleParticipantMessage(ParticipantStatus participantStatusMsg) { + saveIfNotPresent(participantStatusMsg.getReplicaId(), participantStatusMsg.getParticipantId(), + participantStatusMsg.getParticipantSupportedElementType(), false); - var participantOpt = participantProvider.findParticipant(participantStatusMsg.getParticipantId()); - if (participantOpt.isEmpty()) { - var participant = createParticipant(participantStatusMsg.getParticipantId(), - listToMap(participantStatusMsg.getParticipantSupportedElementType())); - participantProvider.saveParticipant(participant); - } else { - checkOnline(participantOpt.get()); - } if (!participantStatusMsg.getAutomationCompositionInfoList().isEmpty()) { automationCompositionProvider.upgradeStates(participantStatusMsg.getAutomationCompositionInfoList()); } if (!participantStatusMsg.getParticipantDefinitionUpdates().isEmpty() && participantStatusMsg.getCompositionId() != null) { updateAcDefinitionOutProperties(participantStatusMsg.getCompositionId(), - participantStatusMsg.getParticipantDefinitionUpdates()); + participantStatusMsg.getReplicaId(), participantStatusMsg.getParticipantDefinitionUpdates()); + } + } + + private void saveIfNotPresent(UUID msgReplicaId, UUID participantId, + List<ParticipantSupportedElementType> participantSupportedElementType, boolean registration) { + var replicaId = msgReplicaId != null ? msgReplicaId : participantId; + var replicaOpt = participantProvider.findParticipantReplica(replicaId); + if (replicaOpt.isPresent()) { + var replica = replicaOpt.get(); + checkOnline(replica); + } else { + var participant = getParticipant(participantId, listToMap(participantSupportedElementType)); + participant.getReplicas().put(replicaId, createReplica(replicaId)); + participantProvider.saveParticipant(participant); + } + if (registration) { + handleRestart(participantId, replicaId); } } - private void updateAcDefinitionOutProperties(UUID composotionId, List<ParticipantDefinition> list) { - var acDefinitionOpt = acDefinitionProvider.findAcDefinition(composotionId); + private Participant getParticipant(UUID participantId, + Map<UUID, ParticipantSupportedElementType> participantSupportedElementType) { + var participantOpt = participantProvider.findParticipant(participantId); + return participantOpt.orElseGet(() -> createParticipant(participantId, participantSupportedElementType)); + } + + private ParticipantReplica createReplica(UUID replicaId) { + var replica = new ParticipantReplica(); + replica.setReplicaId(replicaId); + replica.setParticipantState(ParticipantState.ON_LINE); + replica.setLastMsg(TimestampHelper.now()); + return replica; + + } + + private void updateAcDefinitionOutProperties(UUID compositionId, UUID replicaId, List<ParticipantDefinition> list) { + var acDefinitionOpt = acDefinitionProvider.findAcDefinition(compositionId); if (acDefinitionOpt.isEmpty()) { - LOGGER.error("Ac Definition with id {} not found", composotionId); + LOGGER.error("Ac Definition with id {} not found", compositionId); return; } var acDefinition = acDefinitionOpt.get(); @@ -155,71 +167,47 @@ public class SupervisionParticipantHandler { } acDefinitionProvider.updateAcDefinition(acDefinition, acRuntimeParameterGroup.getAcmParameters().getToscaCompositionName()); + participantSyncPublisher.sendSync(acDefinition, replicaId); } - private void checkOnline(Participant participant) { - if (ParticipantState.OFF_LINE.equals(participant.getParticipantState())) { - participant.setParticipantState(ParticipantState.ON_LINE); + private void checkOnline(ParticipantReplica replica) { + if (ParticipantState.OFF_LINE.equals(replica.getParticipantState())) { + replica.setParticipantState(ParticipantState.ON_LINE); } - participant.setLastMsg(TimestampHelper.now()); - participantProvider.saveParticipant(participant); + replica.setLastMsg(TimestampHelper.now()); + participantProvider.saveParticipantReplica(replica); } - private void handleRestart(UUID participantId) { + private void handleRestart(UUID participantId, UUID replicaId) { var compositionIds = participantProvider.getCompositionIds(participantId); for (var compositionId : compositionIds) { var acDefinition = acDefinitionProvider.getAcDefinition(compositionId); LOGGER.debug("Scan Composition {} for restart", acDefinition.getCompositionId()); - handleRestart(participantId, acDefinition); + handleSyncRestart(participantId, replicaId, acDefinition); } } - private void handleRestart(UUID participantId, AutomationCompositionDefinition acDefinition) { + private void handleSyncRestart(final UUID participantId, UUID replicaId, + AutomationCompositionDefinition acDefinition) { if (AcTypeState.COMMISSIONED.equals(acDefinition.getState())) { LOGGER.debug("Composition {} COMMISSIONED", acDefinition.getCompositionId()); return; } LOGGER.debug("Composition to be send in Restart message {}", acDefinition.getCompositionId()); - for (var elementState : acDefinition.getElementStateMap().values()) { - if (participantId.equals(elementState.getParticipantId())) { - elementState.setRestarting(true); - } - } var automationCompositionList = automationCompositionProvider.getAcInstancesByCompositionId(acDefinition.getCompositionId()); - List<AutomationComposition> automationCompositions = new ArrayList<>(); - for (var automationComposition : automationCompositionList) { - if (isAcToBeRestarted(participantId, automationComposition)) { - automationCompositions.add(automationComposition); - } - } - // expected final state - if (StateChangeResult.TIMEOUT.equals(acDefinition.getStateChangeResult())) { - acDefinition.setStateChangeResult(StateChangeResult.NO_ERROR); - } - acDefinition.setRestarting(true); - acDefinitionProvider.updateAcDefinition(acDefinition, - acRuntimeParameterGroup.getAcmParameters().getToscaCompositionName()); - participantRestartPublisher.send(participantId, acDefinition, automationCompositions); + var automationCompositions = automationCompositionList.stream() + .filter(ac -> isAcToBeSyncRestarted(participantId, ac)).toList(); + participantSyncPublisher.sendRestartMsg(participantId, replicaId, acDefinition, automationCompositions); } - private boolean isAcToBeRestarted(UUID participantId, AutomationComposition automationComposition) { - boolean toAdd = false; + private boolean isAcToBeSyncRestarted(UUID participantId, AutomationComposition automationComposition) { for (var element : automationComposition.getElements().values()) { if (participantId.equals(element.getParticipantId())) { - element.setRestarting(true); - toAdd = true; - } - } - if (toAdd) { - automationComposition.setRestarting(true); - // expected final state - if (StateChangeResult.TIMEOUT.equals(automationComposition.getStateChangeResult())) { - automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); + return true; } - automationCompositionProvider.updateAutomationComposition(automationComposition); } - return toAdd; + return false; } private Participant createParticipant(UUID participantId, @@ -227,8 +215,6 @@ public class SupervisionParticipantHandler { var participant = new Participant(); participant.setParticipantId(participantId); participant.setParticipantSupportedElementTypes(participantSupportedElementType); - participant.setParticipantState(ParticipantState.ON_LINE); - participant.setLastMsg(TimestampHelper.now()); return participant; } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionPartecipantScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantScanner.java index 4d2a22f26..4ada199b6 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionPartecipantScanner.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantScanner.java @@ -21,8 +21,7 @@ package org.onap.policy.clamp.acm.runtime.supervision; import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; -import org.onap.policy.clamp.models.acm.concepts.Participant; -import org.onap.policy.clamp.models.acm.concepts.ParticipantState; +import org.onap.policy.clamp.models.acm.concepts.ParticipantReplica; import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider; import org.onap.policy.clamp.models.acm.utils.TimestampHelper; import org.slf4j.Logger; @@ -33,20 +32,20 @@ import org.springframework.stereotype.Component; * This class is used to scan the automation compositions in the database and check if they are in the correct state. */ @Component -public class SupervisionPartecipantScanner { - private static final Logger LOGGER = LoggerFactory.getLogger(SupervisionPartecipantScanner.class); +public class SupervisionParticipantScanner { + private static final Logger LOGGER = LoggerFactory.getLogger(SupervisionParticipantScanner.class); private final long maxWaitMs; private final ParticipantProvider participantProvider; /** - * Constructor for instantiating SupervisionPartecipantScanner. + * Constructor for instantiating SupervisionParticipantScanner. * * @param participantProvider the Participant Provider * @param acRuntimeParameterGroup the parameters for the automation composition runtime */ - public SupervisionPartecipantScanner(final ParticipantProvider participantProvider, + public SupervisionParticipantScanner(final ParticipantProvider participantProvider, final AcRuntimeParameterGroup acRuntimeParameterGroup) { this.participantProvider = participantProvider; this.maxWaitMs = acRuntimeParameterGroup.getParticipantParameters().getMaxStatusWaitMs(); @@ -56,27 +55,17 @@ public class SupervisionPartecipantScanner { * Run Scanning. */ public void run() { - LOGGER.debug("Scanning participans in the database . . ."); - - for (var participant : participantProvider.getParticipants()) { - scanParticipantStatus(participant); - } - - LOGGER.debug("Participans scan complete . . ."); + LOGGER.debug("Scanning participants in the database . . ."); + participantProvider.findReplicasOnLine().forEach(this::scanParticipantReplicaStatus); + LOGGER.debug("Participants scan complete . . ."); } - private void scanParticipantStatus(Participant participant) { - var id = participant.getParticipantId(); - if (ParticipantState.OFF_LINE.equals(participant.getParticipantState())) { - LOGGER.debug("report Participant is still OFF_LINE {}", id); - return; - } + private void scanParticipantReplicaStatus(ParticipantReplica replica) { var now = TimestampHelper.nowEpochMilli(); - var lastMsg = TimestampHelper.toEpochMilli(participant.getLastMsg()); + var lastMsg = TimestampHelper.toEpochMilli(replica.getLastMsg()); if ((now - lastMsg) > maxWaitMs) { - LOGGER.debug("report Participant OFF_LINE {}", id); - participant.setParticipantState(ParticipantState.OFF_LINE); - participantProvider.updateParticipant(participant); + LOGGER.debug("Participant OFF_LINE {}", replica.getReplicaId()); + participantProvider.deleteParticipantReplica(replica.getReplicaId()); } } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java index 06d464671..c4cebb430 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java @@ -22,17 +22,21 @@ package org.onap.policy.clamp.acm.runtime.supervision; +import java.util.Comparator; import java.util.HashMap; import java.util.UUID; import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionDeployPublisher; +import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionMigrationPublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher; +import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; import org.onap.policy.clamp.models.acm.concepts.DeployState; import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; 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.persistence.provider.AcDefinitionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; import org.onap.policy.clamp.models.acm.utils.AcmUtils; @@ -55,6 +59,8 @@ public class SupervisionScanner { private final AcDefinitionProvider acDefinitionProvider; private final AutomationCompositionStateChangePublisher automationCompositionStateChangePublisher; private final AutomationCompositionDeployPublisher automationCompositionDeployPublisher; + private final ParticipantSyncPublisher participantSyncPublisher; + private final AutomationCompositionMigrationPublisher automationCompositionMigrationPublisher; /** * Constructor for instantiating SupervisionScanner. @@ -69,11 +75,15 @@ public class SupervisionScanner { final AcDefinitionProvider acDefinitionProvider, final AutomationCompositionStateChangePublisher automationCompositionStateChangePublisher, final AutomationCompositionDeployPublisher automationCompositionDeployPublisher, + final ParticipantSyncPublisher participantSyncPublisher, + final AutomationCompositionMigrationPublisher automationCompositionMigrationPublisher, final AcRuntimeParameterGroup acRuntimeParameterGroup) { this.automationCompositionProvider = automationCompositionProvider; this.acDefinitionProvider = acDefinitionProvider; this.automationCompositionStateChangePublisher = automationCompositionStateChangePublisher; this.automationCompositionDeployPublisher = automationCompositionDeployPublisher; + this.participantSyncPublisher = participantSyncPublisher; + this.automationCompositionMigrationPublisher = automationCompositionMigrationPublisher; this.maxStatusWaitMs = acRuntimeParameterGroup.getParticipantParameters().getMaxStatusWaitMs(); } @@ -91,11 +101,9 @@ public class SupervisionScanner { var acList = automationCompositionProvider.getAcInstancesInTransition(); HashMap<UUID, AutomationCompositionDefinition> acDefinitionMap = new HashMap<>(); for (var automationComposition : acList) { - var acDefinition = acDefinitionMap.get(automationComposition.getCompositionId()); - if (acDefinition == null) { - acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId()); - acDefinitionMap.put(acDefinition.getCompositionId(), acDefinition); - } + var compositionId = automationComposition.getCompositionTargetId() != null + ? automationComposition.getCompositionTargetId() : automationComposition.getCompositionId(); + var acDefinition = acDefinitionMap.computeIfAbsent(compositionId, acDefinitionProvider::getAcDefinition); scanAutomationComposition(automationComposition, acDefinition.getServiceTemplate()); } LOGGER.debug("Automation composition scan complete . . ."); @@ -113,11 +121,13 @@ public class SupervisionScanner { for (var element : acDefinition.getElementStateMap().values()) { if (!finalState.equals(element.getState())) { completed = false; + break; } } if (completed) { acDefinitionProvider.updateAcDefinitionState(acDefinition.getCompositionId(), finalState, - StateChangeResult.NO_ERROR, null); + StateChangeResult.NO_ERROR); + participantSyncPublisher.sendSync(acDefinition, null); } else { handleTimeout(acDefinition); } @@ -128,14 +138,33 @@ public class SupervisionScanner { LOGGER.debug("scanning automation composition {} . . .", automationComposition.getInstanceId()); if (!AcmUtils.isInTransitionalState(automationComposition.getDeployState(), - automationComposition.getLockState()) + automationComposition.getLockState(), automationComposition.getSubState()) || StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())) { LOGGER.debug("automation composition {} scanned, OK", automationComposition.getInstanceId()); - // Clear Timeout on automation composition return; } + if (DeployState.MIGRATING.equals(automationComposition.getDeployState())) { + scanStage(automationComposition, serviceTemplate); + } else if (DeployState.UPDATING.equals(automationComposition.getDeployState()) + || SubState.PREPARING.equals(automationComposition.getSubState()) + || SubState.REVIEWING.equals(automationComposition.getSubState()) + || SubState.MIGRATION_PRECHECKING.equals(automationComposition.getSubState())) { + simpleScan(automationComposition, serviceTemplate); + } else { + scanWithPhase(automationComposition, serviceTemplate); + } + } + + /** + * Scan with startPhase: DEPLOY, UNDEPLOY, LOCK and UNLOCK. + * + * @param automationComposition the AutomationComposition + * @param serviceTemplate the ToscaServiceTemplate + */ + private void scanWithPhase(final AutomationComposition automationComposition, + ToscaServiceTemplate serviceTemplate) { var completed = true; var minSpNotCompleted = 1000; // min startPhase not completed var maxSpNotCompleted = 0; // max startPhase not completed @@ -147,7 +176,8 @@ public class SupervisionScanner { int startPhase = ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties()); defaultMin = Math.min(defaultMin, startPhase); defaultMax = Math.max(defaultMax, startPhase); - if (AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState())) { + if (AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState(), + element.getSubState())) { completed = false; minSpNotCompleted = Math.min(minSpNotCompleted, startPhase); maxSpNotCompleted = Math.max(maxSpNotCompleted, startPhase); @@ -155,35 +185,86 @@ public class SupervisionScanner { } if (completed) { - LOGGER.debug("automation composition scan: transition state {} {} completed", - automationComposition.getDeployState(), automationComposition.getLockState()); - - complete(automationComposition); + complete(automationComposition, serviceTemplate); } else { LOGGER.debug("automation composition scan: transition state {} {} not completed", automationComposition.getDeployState(), automationComposition.getLockState()); - if (DeployState.UPDATING.equals(automationComposition.getDeployState()) - || DeployState.MIGRATING.equals(automationComposition.getDeployState())) { - // UPDATING do not need phases - handleTimeoutUpdate(automationComposition); - return; - } - var isForward = AcmUtils.isForward(automationComposition.getDeployState(), automationComposition.getLockState()); var nextSpNotCompleted = isForward ? minSpNotCompleted : maxSpNotCompleted; if (nextSpNotCompleted != automationComposition.getPhase()) { - sendAutomationCompositionMsg(automationComposition, serviceTemplate, nextSpNotCompleted, false); + sendAutomationCompositionMsg(automationComposition, serviceTemplate, nextSpNotCompleted); } else { - handleTimeoutWithPhase(automationComposition, serviceTemplate); + handleTimeout(automationComposition); } } } - private void complete(final AutomationComposition automationComposition) { + /** + * Simple scan: UPDATE, PREPARE, REVIEW, MIGRATE_PRECHECKING. + * + * @param automationComposition the AutomationComposition + * @param serviceTemplate the ToscaServiceTemplate + */ + private void simpleScan(final AutomationComposition automationComposition, ToscaServiceTemplate serviceTemplate) { + var completed = automationComposition.getElements().values().stream() + .filter(element -> AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState(), + element.getSubState())).findFirst().isEmpty(); + + if (completed) { + complete(automationComposition, serviceTemplate); + } else { + handleTimeout(automationComposition); + } + } + + /** + * Scan with stage: MIGRATE. + * + * @param automationComposition the AutomationComposition + * @param serviceTemplate the ToscaServiceTemplate + */ + private void scanStage(final AutomationComposition automationComposition, ToscaServiceTemplate serviceTemplate) { + var completed = true; + var minStageNotCompleted = 1000; // min stage not completed + for (var element : automationComposition.getElements().values()) { + if (AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState(), + element.getSubState())) { + var toscaNodeTemplate = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates() + .get(element.getDefinition().getName()); + var stageSet = ParticipantUtils.findStageSet(toscaNodeTemplate.getProperties()); + var minStage = stageSet.stream().min(Comparator.comparing(Integer::valueOf)).orElse(0); + int stage = element.getStage() != null ? element.getStage() : minStage; + minStageNotCompleted = Math.min(minStageNotCompleted, stage); + completed = false; + } + } + + if (completed) { + complete(automationComposition, serviceTemplate); + } else { + LOGGER.debug("automation composition scan: transition from state {} to {} not completed", + automationComposition.getDeployState(), automationComposition.getLockState()); + + if (minStageNotCompleted != automationComposition.getPhase()) { + savePahese(automationComposition, minStageNotCompleted); + LOGGER.debug("retry message AutomationCompositionMigration"); + automationCompositionMigrationPublisher.send(automationComposition, minStageNotCompleted); + } else { + handleTimeout(automationComposition); + } + } + } + + private void complete(final AutomationComposition automationComposition, + ToscaServiceTemplate serviceTemplate) { + LOGGER.debug("automation composition scan: transition state {} {} {} completed", + automationComposition.getDeployState(), automationComposition.getLockState(), + automationComposition.getSubState()); + var deployState = automationComposition.getDeployState(); if (DeployState.MIGRATING.equals(automationComposition.getDeployState())) { // migration scenario @@ -193,14 +274,18 @@ public class SupervisionScanner { automationComposition.setDeployState(AcmUtils.deployCompleted(deployState)); automationComposition.setLockState(AcmUtils.lockCompleted(deployState, automationComposition.getLockState())); automationComposition.setPhase(null); + automationComposition.setSubState(SubState.NONE); + automationComposition.setPrecheck(null); if (StateChangeResult.TIMEOUT.equals(automationComposition.getStateChangeResult())) { automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); } + var acToUpdate = automationComposition; if (DeployState.DELETED.equals(automationComposition.getDeployState())) { automationCompositionProvider.deleteAutomationComposition(automationComposition.getInstanceId()); } else { - automationCompositionProvider.updateAutomationComposition(automationComposition); + acToUpdate = automationCompositionProvider.updateAcState(acToUpdate); } + participantSyncPublisher.sendSync(serviceTemplate, acToUpdate); } private void handleTimeout(AutomationCompositionDefinition acDefinition) { @@ -214,71 +299,45 @@ public class SupervisionScanner { LOGGER.debug("Report timeout for the ac definition {}", acDefinition.getCompositionId()); acDefinition.setStateChangeResult(StateChangeResult.TIMEOUT); acDefinitionProvider.updateAcDefinitionState(acDefinition.getCompositionId(), - acDefinition.getState(), acDefinition.getStateChangeResult(), acDefinition.getRestarting()); + acDefinition.getState(), acDefinition.getStateChangeResult()); } } - private void handleTimeoutUpdate(AutomationComposition automationComposition) { - if (StateChangeResult.TIMEOUT.equals(automationComposition.getStateChangeResult())) { - LOGGER.debug("The ac instance is in timeout {}", automationComposition.getInstanceId()); - return; - } - var now = TimestampHelper.nowEpochMilli(); - var lastMsg = TimestampHelper.toEpochMilli(automationComposition.getLastMsg()); - for (var element : automationComposition.getElements().values()) { - if (!AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState())) { - continue; - } - if ((now - lastMsg) > maxStatusWaitMs) { - LOGGER.debug("Report timeout for the ac instance {}", automationComposition.getInstanceId()); - automationComposition.setStateChangeResult(StateChangeResult.TIMEOUT); - automationCompositionProvider.updateAutomationComposition(automationComposition); - break; - } - } - } + private void handleTimeout(AutomationComposition automationComposition) { + LOGGER.debug("automation composition scan: transition from state {} to {} {} not completed", + automationComposition.getDeployState(), automationComposition.getLockState(), + automationComposition.getSubState()); - private void handleTimeoutWithPhase(AutomationComposition automationComposition, - ToscaServiceTemplate serviceTemplate) { if (StateChangeResult.TIMEOUT.equals(automationComposition.getStateChangeResult())) { LOGGER.debug("The ac instance is in timeout {}", automationComposition.getInstanceId()); return; } - int currentPhase = automationComposition.getPhase(); var now = TimestampHelper.nowEpochMilli(); var lastMsg = TimestampHelper.toEpochMilli(automationComposition.getLastMsg()); - for (var element : automationComposition.getElements().values()) { - if (!AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState())) { - continue; - } - var toscaNodeTemplate = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates() - .get(element.getDefinition().getName()); - int startPhase = ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties()); - if (currentPhase != startPhase) { - continue; - } - if ((now - lastMsg) > maxStatusWaitMs) { - LOGGER.debug("Report timeout for the ac instance {}", automationComposition.getInstanceId()); - automationComposition.setStateChangeResult(StateChangeResult.TIMEOUT); - automationCompositionProvider.updateAutomationComposition(automationComposition); - break; - } + if ((now - lastMsg) > maxStatusWaitMs) { + LOGGER.debug("Report timeout for the ac instance {}", automationComposition.getInstanceId()); + automationComposition.setStateChangeResult(StateChangeResult.TIMEOUT); + automationCompositionProvider.updateAcState(automationComposition); } } - private void sendAutomationCompositionMsg(AutomationComposition automationComposition, - ToscaServiceTemplate serviceTemplate, int startPhase, boolean firstStartPhase) { + private void savePahese(AutomationComposition automationComposition, int startPhase) { automationComposition.setLastMsg(TimestampHelper.now()); automationComposition.setPhase(startPhase); - automationCompositionProvider.updateAutomationComposition(automationComposition); + automationCompositionProvider.updateAcState(automationComposition); + } + + private void sendAutomationCompositionMsg(AutomationComposition automationComposition, + ToscaServiceTemplate serviceTemplate, int startPhase) { + savePahese(automationComposition, startPhase); if (DeployState.DEPLOYING.equals(automationComposition.getDeployState())) { - LOGGER.debug("retry message AutomationCompositionUpdate"); + LOGGER.debug("retry message AutomationCompositionDeploy"); automationCompositionDeployPublisher.send(automationComposition, serviceTemplate, startPhase, - firstStartPhase); + false); } else { LOGGER.debug("retry message AutomationCompositionStateChange"); - automationCompositionStateChangePublisher.send(automationComposition, startPhase, firstStartPhase); + automationCompositionStateChangePublisher.send(automationComposition, startPhase, false); } } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AbstractParticipantAckPublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AbstractParticipantAckPublisher.java index 5014f7dc3..1e8ff7072 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AbstractParticipantAckPublisher.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AbstractParticipantAckPublisher.java @@ -21,10 +21,7 @@ package org.onap.policy.clamp.acm.runtime.supervision.comm; import jakarta.ws.rs.core.Response.Status; -import java.util.List; -import java.util.Optional; import org.onap.policy.clamp.acm.runtime.config.messaging.Publisher; -import org.onap.policy.clamp.acm.runtime.main.parameters.Topics; import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantAckMessage; import org.onap.policy.common.endpoints.event.comm.TopicSink; diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AbstractParticipantPublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AbstractParticipantPublisher.java index 5afb7eba4..0619f05d0 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AbstractParticipantPublisher.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AbstractParticipantPublisher.java @@ -21,10 +21,7 @@ package org.onap.policy.clamp.acm.runtime.supervision.comm; import jakarta.ws.rs.core.Response.Status; -import java.util.List; -import java.util.Optional; import org.onap.policy.clamp.acm.runtime.config.messaging.Publisher; -import org.onap.policy.clamp.acm.runtime.main.parameters.Topics; import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMessage; import org.onap.policy.common.endpoints.event.comm.TopicSink; diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcElementPropertiesPublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcElementPropertiesPublisher.java index 338f2960d..cc5d1461f 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcElementPropertiesPublisher.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcElementPropertiesPublisher.java @@ -56,7 +56,7 @@ public class AcElementPropertiesPublisher extends AbstractParticipantPublisher<P propertiesUpdate.setParticipantUpdatesList( AcmUtils.createParticipantDeployList(automationComposition, DeployOrder.UPDATE)); - LOGGER.debug("AC Element properties update sent {}", propertiesUpdate); + LOGGER.debug("AC Element properties update sent {}", propertiesUpdate.getMessageId()); super.send(propertiesUpdate); } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcPreparePublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcPreparePublisher.java new file mode 100644 index 000000000..acf403595 --- /dev/null +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcPreparePublisher.java @@ -0,0 +1,78 @@ +/*- + * ============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.acm.runtime.supervision.comm; + +import io.micrometer.core.annotation.Timed; +import java.time.Instant; +import java.util.UUID; +import lombok.AllArgsConstructor; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionPrepare; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; +import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +@AllArgsConstructor +public class AcPreparePublisher extends AbstractParticipantPublisher<AutomationCompositionPrepare> { + + private static final Logger LOGGER = LoggerFactory.getLogger(AcPreparePublisher.class); + + /** + * Send AutomationCompositionPrepare Prepare message to Participant. + * + * @param automationComposition the AutomationComposition + */ + @Timed(value = "publisher.prepare", description = "AC Prepare Pre Deploy published") + public void sendPrepare(AutomationComposition automationComposition) { + var acPrepare = createAutomationCompositionPrepare(automationComposition.getCompositionId(), + automationComposition.getInstanceId()); + acPrepare.setParticipantList( + AcmUtils.createParticipantDeployList(automationComposition, DeployOrder.NONE)); + LOGGER.debug("AC Prepare sent {}", acPrepare); + super.send(acPrepare); + } + + /** + * Send AutomationCompositionPrepare Review message to Participant. + * + * @param automationComposition the AutomationComposition + */ + @Timed(value = "publisher.review", description = "AC Review Post Deploy published") + public void sendRevew(AutomationComposition automationComposition) { + var acPrepare = createAutomationCompositionPrepare(automationComposition.getCompositionId(), + automationComposition.getInstanceId()); + acPrepare.setPreDeploy(false); + LOGGER.debug("AC Review sent {}", acPrepare); + super.send(acPrepare); + } + + private AutomationCompositionPrepare createAutomationCompositionPrepare(UUID compositionId, UUID instanceId) { + var acPrepare = new AutomationCompositionPrepare(); + acPrepare.setCompositionId(compositionId); + acPrepare.setAutomationCompositionId(instanceId); + acPrepare.setMessageId(UUID.randomUUID()); + acPrepare.setTimestamp(Instant.now()); + return acPrepare; + } +} diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionDeployPublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionDeployPublisher.java index 2b6435e67..7fe63a7c5 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionDeployPublisher.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionDeployPublisher.java @@ -87,7 +87,7 @@ public class AutomationCompositionDeployPublisher extends AbstractParticipantPub acDeployMsg.setTimestamp(Instant.now()); acDeployMsg.setParticipantUpdatesList(participantDeploys); - LOGGER.debug("AutomationCompositionDeploy message sent {}", acDeployMsg); + LOGGER.debug("AutomationCompositionDeploy message sent {}", acDeployMsg.getMessageId()); super.send(acDeployMsg); } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionMigrationPublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionMigrationPublisher.java index e26a5403b..572f7b1fe 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionMigrationPublisher.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionMigrationPublisher.java @@ -36,20 +36,22 @@ public class AutomationCompositionMigrationPublisher * Send AutomationCompositionMigration message to Participant. * * @param automationComposition the AutomationComposition - * @param compositionTargetId the Composition Definition Target + * @param stage the stage to execute */ @Timed( value = "publisher.automation_composition_migration", description = "AUTOMATION_COMPOSITION_MIGRATION messages published") - public void send(AutomationComposition automationComposition, UUID compositionTargetId) { - var acsc = new AutomationCompositionMigration(); - acsc.setCompositionId(automationComposition.getCompositionId()); - acsc.setAutomationCompositionId(automationComposition.getInstanceId()); - acsc.setMessageId(UUID.randomUUID()); - acsc.setCompositionTargetId(compositionTargetId); - acsc.setParticipantUpdatesList( + public void send(AutomationComposition automationComposition, int stage) { + var acMigration = new AutomationCompositionMigration(); + acMigration.setPrecheck(Boolean.TRUE.equals(automationComposition.getPrecheck())); + acMigration.setCompositionId(automationComposition.getCompositionId()); + acMigration.setAutomationCompositionId(automationComposition.getInstanceId()); + acMigration.setMessageId(UUID.randomUUID()); + acMigration.setCompositionTargetId(automationComposition.getCompositionTargetId()); + acMigration.setStage(stage); + acMigration.setParticipantUpdatesList( AcmUtils.createParticipantDeployList(automationComposition, DeployOrder.MIGRATE)); - super.send(acsc); + super.send(acMigration); } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantPrimePublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantPrimePublisher.java index 89763a2b6..360e526cc 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantPrimePublisher.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantPrimePublisher.java @@ -31,7 +31,6 @@ import java.util.Map; import java.util.UUID; import lombok.AllArgsConstructor; import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; -import org.onap.policy.clamp.acm.runtime.participants.AcmParticipantProvider; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; @@ -55,7 +54,6 @@ public class ParticipantPrimePublisher extends AbstractParticipantPublisher<Part private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantPrimePublisher.class); private final ParticipantProvider participantProvider; - private final AcmParticipantProvider acmParticipantProvider; private final AcRuntimeParameterGroup acRuntimeParameterGroup; /** @@ -74,7 +72,7 @@ public class ParticipantPrimePublisher extends AbstractParticipantPublisher<Part message.setParticipantId(participantId); message.setTimestamp(Instant.now()); message.setParticipantDefinitionUpdates(participantDefinitions); - LOGGER.debug("Participant Update sent {}", message); + LOGGER.debug("Participant Update sent {}", message.getMessageId()); super.send(message); } @@ -99,9 +97,7 @@ public class ParticipantPrimePublisher extends AbstractParticipantPublisher<Part var elementState = acmDefinition.getElementStateMap().get(elementEntry.getKey()); elementState.setState(AcTypeState.PRIMING); participantIds.add(elementState.getParticipantId()); - var type = new ToscaConceptIdentifier(elementEntry.getValue().getType(), - elementEntry.getValue().getTypeVersion()); - supportedElementMap.put(type, elementState.getParticipantId()); + supportedElementMap.put(AcmUtils.getType(elementEntry.getValue()), elementState.getParticipantId()); } } else { // scenario Prime participants not assigned yet @@ -109,16 +105,14 @@ public class ParticipantPrimePublisher extends AbstractParticipantPublisher<Part for (var elementEntry : acElements) { var elementState = acmDefinition.getElementStateMap().get(elementEntry.getKey()); elementState.setState(AcTypeState.PRIMING); - var type = new ToscaConceptIdentifier(elementEntry.getValue().getType(), - elementEntry.getValue().getTypeVersion()); - var participantId = supportedElementMap.get(type); + var participantId = supportedElementMap.get(AcmUtils.getType(elementEntry.getValue())); if (participantId != null) { elementState.setParticipantId(participantId); participantIds.add(participantId); } } } - acmParticipantProvider.verifyParticipantState(participantIds); + participantProvider.verifyParticipantState(participantIds); return AcmUtils.prepareParticipantPriming(acElements, supportedElementMap); } @@ -133,7 +127,7 @@ public class ParticipantPrimePublisher extends AbstractParticipantPublisher<Part // DeCommission the automation composition but deleting participantdefinitions on participants message.setParticipantDefinitionUpdates(null); - LOGGER.debug("Participant Update sent {}", message); + LOGGER.debug("Participant Update sent {}", message.getMessageId()); super.send(message); } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantRegisterAckPublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantRegisterAckPublisher.java index d021c57a4..5e073080b 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantRegisterAckPublisher.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantRegisterAckPublisher.java @@ -36,14 +36,21 @@ public class ParticipantRegisterAckPublisher extends AbstractParticipantAckPubli * * @param responseTo the original request id in the request. * @param participantId the participant Id + * @param replicaId the participant replica Id */ @Timed(value = "publisher.participant_register_ack", description = "PARTICIPANT_REGISTER_ACK messages published") - public void send(UUID responseTo, UUID participantId) { + public void send(UUID responseTo, UUID participantId, UUID replicaId) { var message = new ParticipantRegisterAck(); message.setParticipantId(participantId); + message.setReplicaId(replicaId); message.setResponseTo(responseTo); message.setMessage("Participant Register Ack"); message.setResult(true); super.send(message); } + + @Override + public boolean isDefaultTopic() { + return false; + } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantRestartPublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantRestartPublisher.java deleted file mode 100644 index 4f28eab8e..000000000 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantRestartPublisher.java +++ /dev/null @@ -1,117 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2023-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.acm.runtime.supervision.comm; - -import io.micrometer.core.annotation.Timed; -import java.time.Instant; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.UUID; -import lombok.AllArgsConstructor; -import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; -import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; -import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; -import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; -import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc; -import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRestart; -import org.onap.policy.clamp.models.acm.utils.AcmUtils; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -@Component -@AllArgsConstructor -public class ParticipantRestartPublisher extends AbstractParticipantPublisher<ParticipantRestart> { - - private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantRestartPublisher.class); - private final AcRuntimeParameterGroup acRuntimeParameterGroup; - - /** - * Send Restart to Participant. - * - * @param participantId the ParticipantId - * @param acmDefinition the AutomationComposition Definition - * @param automationCompositions the list of automationCompositions - */ - @Timed(value = "publisher.participant_restart", description = "Participant Restart published") - public void send(UUID participantId, AutomationCompositionDefinition acmDefinition, - List<AutomationComposition> automationCompositions) { - - var message = new ParticipantRestart(); - message.setParticipantId(participantId); - message.setCompositionId(acmDefinition.getCompositionId()); - message.setMessageId(UUID.randomUUID()); - message.setTimestamp(Instant.now()); - message.setState(acmDefinition.getState()); - message.setParticipantDefinitionUpdates(prepareParticipantRestarting(participantId, acmDefinition)); - var toscaServiceTemplateFragment = AcmUtils.getToscaServiceTemplateFragment(acmDefinition.getServiceTemplate()); - - for (var automationComposition : automationCompositions) { - var restartAc = new ParticipantRestartAc(); - restartAc.setAutomationCompositionId(automationComposition.getInstanceId()); - for (var element : automationComposition.getElements().values()) { - if (participantId.equals(element.getParticipantId())) { - var acElementRestart = AcmUtils.createAcElementRestart(element); - acElementRestart.setToscaServiceTemplateFragment(toscaServiceTemplateFragment); - restartAc.getAcElementList().add(acElementRestart); - } - } - message.getAutomationcompositionList().add(restartAc); - } - - LOGGER.debug("Participant Restart sent {}", message); - super.send(message); - } - - protected List<ParticipantDefinition> prepareParticipantRestarting(UUID participantId, - AutomationCompositionDefinition acmDefinition) { - var acElements = AcmUtils.extractAcElementsFromServiceTemplate(acmDefinition.getServiceTemplate(), - acRuntimeParameterGroup.getAcmParameters().getToscaElementName()); - - // list of entry filtered by participantId - List<Entry<String, ToscaNodeTemplate>> elementList = new ArrayList<>(); - Map<ToscaConceptIdentifier, UUID> supportedElementMap = new HashMap<>(); - for (var elementEntry : acElements) { - var elementState = acmDefinition.getElementStateMap().get(elementEntry.getKey()); - if (participantId.equals(elementState.getParticipantId())) { - var type = new ToscaConceptIdentifier(elementEntry.getValue().getType(), - elementEntry.getValue().getTypeVersion()); - supportedElementMap.put(type, participantId); - elementList.add(elementEntry); - } - } - var list = AcmUtils.prepareParticipantPriming(elementList, supportedElementMap); - for (var participantDefinition : list) { - for (var elementDe : participantDefinition.getAutomationCompositionElementDefinitionList()) { - var state = acmDefinition.getElementStateMap().get(elementDe.getAcElementDefinitionId().getName()); - if (state != null) { - elementDe.setOutProperties(state.getOutProperties()); - } - } - } - return list; - } -} diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantStatusReqPublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantStatusReqPublisher.java index 76feee72f..96abac494 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantStatusReqPublisher.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantStatusReqPublisher.java @@ -40,11 +40,16 @@ public class ParticipantStatusReqPublisher extends AbstractParticipantPublisher< */ @Timed(value = "publisher.participant_status_req", description = "PARTICIPANT_STATUS_REQ messages published") public void send(UUID participantId) { - ParticipantStatusReq message = new ParticipantStatusReq(); + var message = new ParticipantStatusReq(); message.setParticipantId(participantId); message.setTimestamp(Instant.now()); - LOGGER.debug("Participant StatusReq sent {}", message); + LOGGER.debug("Participant StatusReq sent {}", message.getMessageId()); super.send(message); } + + @Override + public boolean isDefaultTopic() { + return false; + } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantSyncPublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantSyncPublisher.java index ae7eda1ee..eb1db6f0e 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantSyncPublisher.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantSyncPublisher.java @@ -23,69 +23,58 @@ package org.onap.policy.clamp.acm.runtime.supervision.comm; import io.micrometer.core.annotation.Timed; import java.time.Instant; import java.util.List; -import java.util.Optional; import java.util.UUID; +import lombok.AllArgsConstructor; import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; -import org.onap.policy.clamp.acm.runtime.main.parameters.Topics; +import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; +import org.onap.policy.clamp.models.acm.concepts.DeployState; import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantSync; import org.onap.policy.clamp.models.acm.utils.AcmUtils; -import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; - @Component -public class ParticipantSyncPublisher extends ParticipantRestartPublisher { +@AllArgsConstructor +public class ParticipantSyncPublisher extends AbstractParticipantPublisher<ParticipantSync> { private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantSyncPublisher.class); - private final AcRuntimeParameterGroup acRuntimeParameterGroup; - public ParticipantSyncPublisher(AcRuntimeParameterGroup acRuntimeParameterGroup) { - super(acRuntimeParameterGroup); - this.acRuntimeParameterGroup = acRuntimeParameterGroup; - } - - /** - * Send sync msg to Participant. + * Send Restart sync msg to Participant by participantId. * - * @param participantId the ParticipantId + * @param participantId the participantId + * @param replicaId the replicaId * @param acmDefinition the AutomationComposition Definition * @param automationCompositions the list of automationCompositions */ - @Override @Timed(value = "publisher.participant_sync_msg", description = "Participant Sync published") - public void send(UUID participantId, AutomationCompositionDefinition acmDefinition, + public void sendRestartMsg(UUID participantId, UUID replicaId, AutomationCompositionDefinition acmDefinition, List<AutomationComposition> automationCompositions) { var message = new ParticipantSync(); message.setParticipantId(participantId); + message.setReplicaId(replicaId); + message.setRestarting(true); message.setCompositionId(acmDefinition.getCompositionId()); message.setMessageId(UUID.randomUUID()); message.setTimestamp(Instant.now()); message.setState(acmDefinition.getState()); - message.setParticipantDefinitionUpdates(prepareParticipantRestarting(participantId, acmDefinition)); + message.setParticipantDefinitionUpdates(AcmUtils.prepareParticipantRestarting(participantId, acmDefinition, + acRuntimeParameterGroup.getAcmParameters().getToscaElementName())); var toscaServiceTemplateFragment = AcmUtils.getToscaServiceTemplateFragment(acmDefinition.getServiceTemplate()); for (var automationComposition : automationCompositions) { - var syncAc = new ParticipantRestartAc(); - syncAc.setAutomationCompositionId(automationComposition.getInstanceId()); - for (var element : automationComposition.getElements().values()) { - if (participantId.equals(element.getParticipantId())) { - var acElementSync = AcmUtils.createAcElementRestart(element); - acElementSync.setToscaServiceTemplateFragment(toscaServiceTemplateFragment); - syncAc.getAcElementList().add(acElementSync); - } - } + var syncAc = AcmUtils.createAcRestart(automationComposition, participantId, toscaServiceTemplateFragment); message.getAutomationcompositionList().add(syncAc); } - LOGGER.debug("Participant Sync sent {}", message); + LOGGER.debug("Participant Restarting Sync sent {}", message); super.send(message); } @@ -98,4 +87,64 @@ public class ParticipantSyncPublisher extends ParticipantRestartPublisher { return false; } + /** + * Send AutomationCompositionDefinition sync msg to all Participants. + * + * @param acDefinition the AutomationComposition Definition + * @param excludeReplicaId the replica to be excluded + */ + @Timed(value = "publisher.participant_sync_msg", description = "Participant Sync published") + public void sendSync(AutomationCompositionDefinition acDefinition, UUID excludeReplicaId) { + var message = new ParticipantSync(); + message.setCompositionId(acDefinition.getCompositionId()); + if (excludeReplicaId != null) { + message.getExcludeReplicas().add(excludeReplicaId); + } + message.setState(acDefinition.getState()); + message.setMessageId(UUID.randomUUID()); + message.setTimestamp(Instant.now()); + if (AcTypeState.COMMISSIONED.equals(acDefinition.getState())) { + message.setDelete(true); + } else { + message.setParticipantDefinitionUpdates(AcmUtils.prepareParticipantRestarting(null, acDefinition, + acRuntimeParameterGroup.getAcmParameters().getToscaElementName())); + } + LOGGER.debug("Participant AutomationCompositionDefinition Sync sent {}", message); + super.send(message); + } + + /** + * Send AutomationComposition sync msg to all Participants. + * + * @param serviceTemplate the ServiceTemplate + * @param automationComposition the automationComposition + */ + @Timed(value = "publisher.participant_sync_msg", description = "Participant Sync published") + public void sendSync(ToscaServiceTemplate serviceTemplate, AutomationComposition automationComposition) { + var message = new ParticipantSync(); + message.setCompositionId(automationComposition.getCompositionId()); + message.setAutomationCompositionId(automationComposition.getInstanceId()); + message.setState(AcTypeState.PRIMED); + message.setMessageId(UUID.randomUUID()); + message.setTimestamp(Instant.now()); + var syncAc = new ParticipantRestartAc(); + syncAc.setAutomationCompositionId(automationComposition.getInstanceId()); + syncAc.setDeployState(automationComposition.getDeployState()); + syncAc.setLockState(automationComposition.getLockState()); + if (DeployState.DELETED.equals(automationComposition.getDeployState())) { + message.setDelete(true); + } else { + var toscaServiceTemplateFragment = AcmUtils.getToscaServiceTemplateFragment(serviceTemplate); + for (var element : automationComposition.getElements().values()) { + var acElementSync = AcmUtils.createAcElementRestart(element); + acElementSync.setToscaServiceTemplateFragment(toscaServiceTemplateFragment); + syncAc.getAcElementList().add(acElementSync); + + } + } + message.getAutomationcompositionList().add(syncAc); + + LOGGER.debug("Participant AutomationComposition Sync sent {}", message.getMessageId()); + super.send(message); + } } diff --git a/runtime-acm/src/main/resources/application.yaml b/runtime-acm/src/main/resources/application.yaml index 0e2585dba..bca01ace8 100644 --- a/runtime-acm/src/main/resources/application.yaml +++ b/runtime-acm/src/main/resources/application.yaml @@ -44,21 +44,18 @@ runtime: maxStatusWaitMs: 200000 topicParameterGroup: topicSources: - - - topic: ${runtime.topics.operationTopic} + - topic: ${runtime.topics.operationTopic} servers: - ${topicServer:kafka:9092} topicCommInfrastructure: NOOP fetchTimeout: 15000 topicSinks: - - - topic: ${runtime.topics.operationTopic} + - topic: ${runtime.topics.operationTopic} servers: - ${topicServer:kafka:9092} topicCommInfrastructure: NOOP - - - topic: ${runtime.topics.syncTopic} + - topic: ${runtime.topics.syncTopic} servers: - ${topicServer:kafka:9092} topicCommInfrastructure: NOOP diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java index 5c26ea3bd..8c76baef7 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java @@ -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. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,6 +23,7 @@ package org.onap.policy.clamp.acm.runtime.commissioning; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; @@ -36,7 +37,6 @@ import java.util.UUID; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils; import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; -import org.onap.policy.clamp.acm.runtime.participants.AcmParticipantProvider; import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantPrimePublisher; import org.onap.policy.clamp.acm.runtime.util.CommonTestData; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; @@ -47,14 +47,13 @@ import org.onap.policy.clamp.models.acm.messages.rest.commissioning.PrimeOrder; import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.AcTypeStateResolver; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; +import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; class CommissioningProviderTest { /** * Test the fetching of automation composition definitions (ToscaServiceTemplates). - * - * @throws Exception . */ @Test void testGetAutomationCompositionDefinitions() { @@ -63,7 +62,7 @@ class CommissioningProviderTest { var acRuntimeParameterGroup = mock(AcRuntimeParameterGroup.class); var provider = new CommissioningProvider(acDefinitionProvider, acProvider, null, null, null, - acRuntimeParameterGroup); + acRuntimeParameterGroup); var serviceTemplates = provider.getAutomationCompositionDefinitions(null, null); assertThat(serviceTemplates.getServiceTemplates()).isEmpty(); @@ -75,12 +74,11 @@ class CommissioningProviderTest { /** * Test the creation of automation composition definitions (ToscaServiceTemplates). - * - * @throws Exception . */ @Test void testCreateAutomationCompositionDefinitions() { var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); + assertNotNull(serviceTemplate); serviceTemplate.setName("Name"); serviceTemplate.setVersion("1.0.0"); var acmDefinition = new AutomationCompositionDefinition(); @@ -88,15 +86,15 @@ class CommissioningProviderTest { acmDefinition.setServiceTemplate(serviceTemplate); var acDefinitionProvider = mock(AcDefinitionProvider.class); when(acDefinitionProvider.createAutomationCompositionDefinition(serviceTemplate, - CommonTestData.TOSCA_ELEMENT_NAME, CommonTestData.TOSCA_COMP_NAME)).thenReturn(acmDefinition); + CommonTestData.TOSCA_ELEMENT_NAME, CommonTestData.TOSCA_COMP_NAME)).thenReturn(acmDefinition); var acProvider = mock(AutomationCompositionProvider.class); var provider = new CommissioningProvider(acDefinitionProvider, acProvider, null, null, null, - CommonTestData.getTestParamaterGroup()); + CommonTestData.getTestParamaterGroup()); var affectedDefinitions = provider.createAutomationCompositionDefinition(serviceTemplate) - .getAffectedAutomationCompositionDefinitions(); + .getAffectedAutomationCompositionDefinitions(); verify(acDefinitionProvider).createAutomationCompositionDefinition(serviceTemplate, - CommonTestData.TOSCA_ELEMENT_NAME, CommonTestData.TOSCA_COMP_NAME); + CommonTestData.TOSCA_ELEMENT_NAME, CommonTestData.TOSCA_COMP_NAME); // Response should return the number of node templates present in the service template assertThat(affectedDefinitions).hasSize(7); } @@ -104,7 +102,6 @@ class CommissioningProviderTest { /** * Test the fetching of a full ToscaServiceTemplate object - as opposed to the reduced template that is being * tested in the testGetToscaServiceTemplateReduced() test. - * */ @Test void testGetToscaServiceTemplateList() { @@ -113,6 +110,7 @@ class CommissioningProviderTest { var provider = new CommissioningProvider(acDefinitionProvider, acProvider, null, null, null, null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); + assertNotNull(serviceTemplate); when(acDefinitionProvider.getServiceTemplateList(null, null)).thenReturn(List.of(serviceTemplate)); var returnedServiceTemplate = provider.getAutomationCompositionDefinitions(null, null); @@ -121,7 +119,7 @@ class CommissioningProviderTest { } @Test - void testDeletecDefinitionDabRequest() { + void testDeleteAcDefinitionDabRequest() { var acDefinitionProvider = mock(AcDefinitionProvider.class); var acProvider = mock(AutomationCompositionProvider.class); @@ -131,7 +129,7 @@ class CommissioningProviderTest { var provider = new CommissioningProvider(acDefinitionProvider, acProvider, null, null, null, null); assertThatThrownBy(() -> provider.deleteAutomationCompositionDefinition(compositionId)) - .hasMessageMatching("Delete instances, to commission automation composition definitions"); + .hasMessageMatching("Delete instances, to commission automation composition definitions"); } @Test @@ -139,6 +137,7 @@ class CommissioningProviderTest { var acDefinitionProvider = mock(AcDefinitionProvider.class); var compositionId = UUID.randomUUID(); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); + assertNotNull(serviceTemplate); when(acDefinitionProvider.deleteAcDefintion(compositionId)).thenReturn(serviceTemplate); var acmDefinition = new AutomationCompositionDefinition(); @@ -159,14 +158,14 @@ class CommissioningProviderTest { void testPriming() { var acDefinitionProvider = mock(AcDefinitionProvider.class); var acmDefinition = CommonTestData.createAcDefinition( - InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.COMMISSIONED); + InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.COMMISSIONED); var compositionId = acmDefinition.getCompositionId(); when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acmDefinition); var participantPrimePublisher = mock(ParticipantPrimePublisher.class); var provider = new CommissioningProvider(acDefinitionProvider, mock(AutomationCompositionProvider.class), - mock(AcmParticipantProvider.class), new AcTypeStateResolver(), participantPrimePublisher, - CommonTestData.getTestParamaterGroup()); + mock(ParticipantProvider.class), new AcTypeStateResolver(), participantPrimePublisher, + CommonTestData.getTestParamaterGroup()); var acTypeStateUpdate = new AcTypeStateUpdate(); acTypeStateUpdate.setPrimeOrder(PrimeOrder.PRIME); @@ -179,20 +178,20 @@ class CommissioningProviderTest { void testDepriming() { var acDefinitionProvider = mock(AcDefinitionProvider.class); var acmDefinition = CommonTestData.createAcDefinition( - InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.PRIMED); + InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.PRIMED); var compositionId = acmDefinition.getCompositionId(); when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acmDefinition); var participantPrimePublisher = mock(ParticipantPrimePublisher.class); - var acmParticipantProvider = mock(AcmParticipantProvider.class); + var participantProvider = mock(ParticipantProvider.class); var provider = new CommissioningProvider(acDefinitionProvider, mock(AutomationCompositionProvider.class), - acmParticipantProvider, new AcTypeStateResolver(), participantPrimePublisher, - CommonTestData.getTestParamaterGroup()); + participantProvider, new AcTypeStateResolver(), participantPrimePublisher, + CommonTestData.getTestParamaterGroup()); var acTypeStateUpdate = new AcTypeStateUpdate(); acTypeStateUpdate.setPrimeOrder(PrimeOrder.DEPRIME); - doNothing().when(acmParticipantProvider).verifyParticipantState(any()); + doNothing().when(participantProvider).verifyParticipantState(any()); provider.compositionDefinitionPriming(compositionId, acTypeStateUpdate); verify(participantPrimePublisher, timeout(1000).times(1)).sendDepriming(compositionId); } @@ -201,19 +200,19 @@ class CommissioningProviderTest { void testBadRequest() { var acProvider = mock(AutomationCompositionProvider.class); var provider = new CommissioningProvider(mock(AcDefinitionProvider.class), acProvider, - mock(AcmParticipantProvider.class), new AcTypeStateResolver(), mock(ParticipantPrimePublisher.class), - mock(AcRuntimeParameterGroup.class)); + mock(ParticipantProvider.class), new AcTypeStateResolver(), mock(ParticipantPrimePublisher.class), + mock(AcRuntimeParameterGroup.class)); var compositionId = UUID.randomUUID(); when(acProvider.getAcInstancesByCompositionId(compositionId)).thenReturn(List.of(new AutomationComposition())); var toscaServiceTemplate = new ToscaServiceTemplate(); assertThatThrownBy(() -> provider.updateCompositionDefinition(compositionId, toscaServiceTemplate)) - .hasMessageMatching("There are ACM instances, Update of ACM Definition not allowed"); + .hasMessageMatching("There are ACM instances, Update of ACM Definition not allowed"); var acTypeStateUpdate = new AcTypeStateUpdate(); assertThatThrownBy(() -> provider.compositionDefinitionPriming(compositionId, acTypeStateUpdate)) - .hasMessageMatching("There are instances, Priming/Depriming not allowed"); + .hasMessageMatching("There are instances, Priming/Depriming not allowed"); } @Test @@ -225,31 +224,13 @@ class CommissioningProviderTest { when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acmDefinition); var provider = new CommissioningProvider(acDefinitionProvider, mock(AutomationCompositionProvider.class), - mock(AcmParticipantProvider.class), new AcTypeStateResolver(), mock(ParticipantPrimePublisher.class), - mock(AcRuntimeParameterGroup.class)); + mock(ParticipantProvider.class), new AcTypeStateResolver(), mock(ParticipantPrimePublisher.class), + mock(AcRuntimeParameterGroup.class)); assertThatThrownBy(() -> provider.updateCompositionDefinition(compositionId, toscaServiceTemplate)) - .hasMessageMatching("ACM not in COMMISSIONED state, Update of ACM Definition not allowed"); + .hasMessageMatching("ACM not in COMMISSIONED state, Update of ACM Definition not allowed"); assertThatThrownBy(() -> provider.deleteAutomationCompositionDefinition(compositionId)) - .hasMessageMatching("ACM not in COMMISSIONED state, Delete of ACM Definition not allowed"); - } - - @Test - void testPrimingBadRequest() { - var acDefinitionProvider = mock(AcDefinitionProvider.class); - var toscaServiceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); - var acmDefinition = CommonTestData.createAcDefinition(toscaServiceTemplate, AcTypeState.PRIMED); - acmDefinition.setRestarting(true); - var compositionId = acmDefinition.getCompositionId(); - when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acmDefinition); - - var provider = new CommissioningProvider(acDefinitionProvider, mock(AutomationCompositionProvider.class), - mock(AcmParticipantProvider.class), new AcTypeStateResolver(), mock(ParticipantPrimePublisher.class), - mock(AcRuntimeParameterGroup.class)); - - var acTypeStateUpdate = new AcTypeStateUpdate(); - assertThatThrownBy(() -> provider.compositionDefinitionPriming(compositionId, acTypeStateUpdate)) - .hasMessageMatching("There is a restarting process, Priming/Depriming not allowed"); + .hasMessageMatching("ACM not in COMMISSIONED state, Delete of ACM Definition not allowed"); } } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/rest/CommissioningControllerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/rest/CommissioningControllerTest.java index ed8badf8b..16de37e7f 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/rest/CommissioningControllerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/rest/CommissioningControllerTest.java @@ -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. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -34,6 +34,7 @@ import jakarta.ws.rs.core.Response; import java.util.HashMap; import java.util.Map; import java.util.UUID; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -61,7 +62,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -@ActiveProfiles({ "test", "default" }) +@ActiveProfiles({"test", "default"}) class CommissioningControllerTest extends CommonRestController { private static final String COMMISSIONING_ENDPOINT = "compositions"; @@ -72,6 +73,7 @@ class CommissioningControllerTest extends CommonRestController { @Autowired private ParticipantProvider participantProvider; + @LocalServerPort private int randomServerPort; @@ -88,6 +90,11 @@ class CommissioningControllerTest extends CommonRestController { super.setHttpPrefix(randomServerPort); } + @AfterEach + void after() { + super.client.close(); + } + @Test void testSwagger() { super.testSwagger(COMMISSIONING_ENDPOINT); @@ -111,15 +118,16 @@ class CommissioningControllerTest extends CommonRestController { @Test void testCreateBadRequest() { var invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT); - var resp = invocationBuilder.post(Entity.json("NotToscaServiceTempalte")); + var resp = invocationBuilder.post(Entity.json("NotToscaServiceTemplate")); assertThat(Response.Status.BAD_REQUEST.getStatusCode()).isEqualTo(resp.getStatus()); var commissioningResponse = resp.readEntity(CommissioningResponse.class); assertThat(commissioningResponse.getErrorDetails()) .isEqualTo("org.springframework.http.converter.HttpMessageNotReadableException " - + "Bad Request Could not read JSON: java.lang.IllegalStateException: " + + "Could not read JSON: java.lang.IllegalStateException: " + "Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $"); assertThat(commissioningResponse.getAffectedAutomationCompositionDefinitions()).isNull(); + resp.close(); } @Test @@ -132,7 +140,7 @@ class CommissioningControllerTest extends CommonRestController { var commissioningResponse = createServiceTemplate(serviceTemplateCreate, Response.Status.INTERNAL_SERVER_ERROR); assertThat(commissioningResponse.getErrorDetails()) - .isEqualTo("java.lang.IllegalArgumentException Internal Server Error parameter " + .isEqualTo("java.lang.IllegalArgumentException parameter " + "\"version\": value \"1.0.wrong\", does not match regular expression \"" + PfKey.VERSION_REGEXP + "\""); assertThat(commissioningResponse.getAffectedAutomationCompositionDefinitions()).isNull(); @@ -149,7 +157,7 @@ class CommissioningControllerTest extends CommonRestController { assertThat(commissioningResponse.getAffectedAutomationCompositionDefinitions()).hasSize(7); for (var nodeTemplateName : serviceTemplateCreate.getToscaTopologyTemplate().getNodeTemplates().keySet()) { assertTrue(commissioningResponse.getAffectedAutomationCompositionDefinitions().stream() - .anyMatch(ac -> ac.getName().equals(nodeTemplateName))); + .anyMatch(ac -> ac.getName().equals(nodeTemplateName))); } } @@ -161,6 +169,7 @@ class CommissioningControllerTest extends CommonRestController { assertNull(commissioningResponse.getErrorDetails()); // Response should return the number of node templates present in the service template assertThat(commissioningResponse.getAffectedAutomationCompositionDefinitions()).hasSize(11); + assertNotNull(serviceTemplateCreate); for (var nodeTemplateName : serviceTemplateCreate.getToscaTopologyTemplate().getNodeTemplates().keySet()) { assertTrue(commissioningResponse.getAffectedAutomationCompositionDefinitions().stream() .anyMatch(ac -> ac.getName().equals(nodeTemplateName))); @@ -168,7 +177,7 @@ class CommissioningControllerTest extends CommonRestController { } private CommissioningResponse createServiceTemplate(ToscaServiceTemplate serviceTemplateCreate, - Response.Status statusExpected) { + Response.Status statusExpected) { var invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT); try (var resp = invocationBuilder.post(Entity.json(serviceTemplateCreate))) { assertEquals(statusExpected.getStatusCode(), resp.getStatus()); @@ -199,17 +208,17 @@ class CommissioningControllerTest extends CommonRestController { assertThat(commissioningResponse.getAffectedAutomationCompositionDefinitions()).hasSize(7); for (var nodeTemplateName : serviceTemplateUpdate.getToscaTopologyTemplate().getNodeTemplates().keySet()) { assertTrue(commissioningResponse.getAffectedAutomationCompositionDefinitions().stream() - .anyMatch(ac -> ac.getName().equals(nodeTemplateName))); + .anyMatch(ac -> ac.getName().equals(nodeTemplateName))); } - var entity = getServiceTemplate(COMMISSIONING_ENDPOINT + "/" + compositionId, Response.Status.OK); + var entity = getServiceTemplate(COMMISSIONING_ENDPOINT + "/" + compositionId); assertThat(entity.getServiceTemplate().getDataTypes()).containsKey(toscaDataType.getName()); } - private AutomationCompositionDefinition getServiceTemplate(String url, Response.Status statusExpected) { + private AutomationCompositionDefinition getServiceTemplate(String url) { var invocationBuilder = super.sendRequest(url); try (var resp = invocationBuilder.buildGet().invoke()) { - assertEquals(statusExpected.getStatusCode(), resp.getStatus()); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); return resp.readEntity(AutomationCompositionDefinition.class); } } @@ -221,6 +230,7 @@ class CommissioningControllerTest extends CommonRestController { assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); var entityList = rawresp.readEntity(ToscaServiceTemplate.class); assertThat(entityList.getNodeTypes()).isNull(); + rawresp.close(); } @Test @@ -232,6 +242,7 @@ class CommissioningControllerTest extends CommonRestController { assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); var entityList = rawresp.readEntity(ToscaServiceTemplate.class); assertNotNull(entityList); + rawresp.close(); } @Test @@ -264,14 +275,15 @@ class CommissioningControllerTest extends CommonRestController { body.setPrimeOrder(PrimeOrder.PRIME); var resp = invocationBuilder.put(Entity.json(body)); assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus()); + resp.close(); } private UUID createEntryInDB(String name) { var serviceTemplateCreate = new ToscaServiceTemplate(serviceTemplate); serviceTemplateCreate.setName(name); var acmDefinition = acDefinitionProvider - .createAutomationCompositionDefinition(serviceTemplateCreate, CommonTestData.TOSCA_ELEMENT_NAME, - CommonTestData.TOSCA_COMP_NAME); + .createAutomationCompositionDefinition(serviceTemplateCreate, CommonTestData.TOSCA_ELEMENT_NAME, + CommonTestData.TOSCA_COMP_NAME); return acmDefinition.getCompositionId(); } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/config/TestOpenTelemetry.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/config/TestOpenTelemetry.java new file mode 100644 index 000000000..8996d77cd --- /dev/null +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/config/TestOpenTelemetry.java @@ -0,0 +1,47 @@ +/*- + * ============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.acm.runtime.config; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.ActiveProfiles; + +@ActiveProfiles("tracing") +@SpringBootTest(classes = OpenTelConfiguration.class) +class TestOpenTelemetry { + + @Autowired + ApplicationContext context; + + @Test + void testOpenTelemetry() { + assertThat(context).isNotNull(); + assertTrue(context.containsBean("otlpGrpcSpanExporter")); + assertTrue(context.containsBean("jaegerRemoteSampler")); + assertFalse(context.containsBean("otlpHttpSpanExporter")); + } +} diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/config/messaging/MessageDispatcherActivatorTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/config/messaging/MessageDispatcherActivatorTest.java index 66595c89a..7e79c6e03 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/config/messaging/MessageDispatcherActivatorTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/config/messaging/MessageDispatcherActivatorTest.java @@ -25,7 +25,6 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java index fbd8330fc..21ad2f616 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java @@ -23,6 +23,7 @@ package org.onap.policy.clamp.acm.runtime.instantiation; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; @@ -32,27 +33,34 @@ import static org.onap.policy.clamp.acm.runtime.util.CommonTestData.TOSCA_SERVIC import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.UUID; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; -import org.onap.policy.clamp.acm.runtime.participants.AcmParticipantProvider; import org.onap.policy.clamp.acm.runtime.supervision.SupervisionAcHandler; import org.onap.policy.clamp.acm.runtime.util.CommonTestData; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; +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.StateChangeResult; +import org.onap.policy.clamp.models.acm.concepts.SubState; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.SubOrder; import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.AcInstanceStateResolver; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; +import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider; import org.onap.policy.clamp.models.acm.persistence.provider.ProviderUtils; +import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; @@ -64,6 +72,7 @@ class AutomationCompositionInstantiationProviderTest { private static final String AC_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/acm/AutomationComposition.json"; private static final String AC_INSTANTIATION_UPDATE_JSON = "src/test/resources/rest/acm/AutomationCompositionUpdate.json"; + private static final String AC_MIGRATE_JSON = "src/test/resources/rest/acm/AutomationCompositionMigrate.json"; private static final String AC_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON = "src/test/resources/rest/acm/AutomationCompositionElementsNotFound.json"; @@ -71,15 +80,17 @@ class AutomationCompositionInstantiationProviderTest { "src/test/resources/rest/acm/AutomationCompositionNotFound.json"; private static final String DELETE_BAD_REQUEST = "Automation composition state is still %s"; - private static final String AC_ELEMENT_NAME_NOT_FOUND = - "\"AutomationComposition\" INVALID, item has status INVALID\n" - + " \"entry PMSHInstance0AcElementNotFound\" INVALID, item has status INVALID\n" - + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not found\n" - + " \"entry org.onap.domain.pmsh.PMSH_MonitoringPolicyAutomationCompositionElement\"" - + " INVALID, Not found\n"; - private static final String AC_DEFINITION_NOT_FOUND = "\"AutomationComposition\" INVALID, item has status INVALID\n" - + " item \"ServiceTemplate\" value \"%s\" INVALID," - + " Commissioned automation composition definition not found\n"; + private static final String AC_ELEMENT_NAME_NOT_FOUND = """ + "AutomationComposition" INVALID, item has status INVALID + "entry PMSHInstance0AcElementNotFound" INVALID, item has status INVALID + "entry org.onap.domain.pmsh.DCAEMicroservice" INVALID, Not found + "entry org.onap.domain.pmsh.PMSH_MonitoringPolicyAutomationCompositionElement" INVALID, Not found + """; + private static final String AC_DEFINITION_NOT_FOUND = """ + "AutomationComposition" INVALID, item has status INVALID + item "ServiceTemplate" value "%s" INVALID, Commissioned automation composition definition not found + """; + private static final String DO_NOT_MATCH = " do not match with "; private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate(); @@ -101,9 +112,9 @@ class AutomationCompositionInstantiationProviderTest { when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition); var acProvider = mock(AutomationCompositionProvider.class); var supervisionAcHandler = mock(SupervisionAcHandler.class); - var acmParticipantProvider = mock(AcmParticipantProvider.class); + var participantProvider = mock(ParticipantProvider.class); var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, - null, supervisionAcHandler, acmParticipantProvider, + null, supervisionAcHandler, participantProvider, CommonTestData.getTestParamaterGroup()); var automationCompositionCreate = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud"); @@ -141,7 +152,7 @@ class AutomationCompositionInstantiationProviderTest { when(acProvider.deleteAutomationComposition(automationCompositionUpdate.getInstanceId())) .thenReturn(automationCompositionUpdate); - doNothing().when(acmParticipantProvider).verifyParticipantState(any()); + doNothing().when(participantProvider).verifyParticipantState(any()); instantiationProvider.deleteAutomationComposition(automationCompositionCreate.getCompositionId(), automationCompositionCreate.getInstanceId()); @@ -167,9 +178,9 @@ class AutomationCompositionInstantiationProviderTest { when(acProvider.updateAutomationComposition(acmFromDb)).thenReturn(acmFromDb); var supervisionAcHandler = mock(SupervisionAcHandler.class); - var acmParticipantProvider = mock(AcmParticipantProvider.class); + var participantProvider = mock(ParticipantProvider.class); var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, - null, supervisionAcHandler, acmParticipantProvider, + new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, CommonTestData.getTestParamaterGroup()); var instantiationResponse = instantiationProvider.updateAutomationComposition( automationCompositionUpdate.getCompositionId(), automationCompositionUpdate); @@ -200,15 +211,15 @@ class AutomationCompositionInstantiationProviderTest { .thenReturn(automationCompositionUpdate); var instantiationProvider = - new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class), null, - mock(SupervisionAcHandler.class), mock(AcmParticipantProvider.class), - mock(AcRuntimeParameterGroup.class)); + new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class), + new AcInstanceStateResolver(), mock(SupervisionAcHandler.class), mock(ParticipantProvider.class), + mock(AcRuntimeParameterGroup.class)); var compositionId = automationCompositionUpdate.getCompositionId(); assertThatThrownBy( () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate)) .hasMessageMatching( - "Not allowed to update in the state " + automationCompositionUpdate.getDeployState()); + "Not allowed to UPDATE in the state " + automationCompositionUpdate.getDeployState()); automationCompositionUpdate.setDeployState(DeployState.UPDATING); automationCompositionUpdate.setLockState(LockState.LOCKED); @@ -216,72 +227,103 @@ class AutomationCompositionInstantiationProviderTest { assertThatThrownBy( () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate)) .hasMessageMatching( - "Not allowed to migrate in the state " + automationCompositionUpdate.getDeployState()); + "Not allowed to MIGRATE in the state " + automationCompositionUpdate.getDeployState()); } @Test - void testUpdateRestartedBadRequest() { - var automationCompositionUpdate = - InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); - automationCompositionUpdate.setDeployState(DeployState.DEPLOYED); - automationCompositionUpdate.setLockState(LockState.LOCKED); - automationCompositionUpdate.setRestarting(true); + void testMigrationAddRemoveElements() { + var acDefinitionProvider = mock(AcDefinitionProvider.class); + var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); + var compositionId = acDefinition.getCompositionId(); + when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition)); + var instanceId = UUID.randomUUID(); + + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_MIGRATE_JSON, "Crud"); + automationComposition.setCompositionId(compositionId); + automationComposition.setInstanceId(instanceId); + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.LOCKED); var acProvider = mock(AutomationCompositionProvider.class); - when(acProvider.getAutomationComposition(automationCompositionUpdate.getInstanceId())) - .thenReturn(automationCompositionUpdate); + when(acProvider.getAutomationComposition(automationComposition.getInstanceId())) + .thenReturn(automationComposition); - var instantiationProvider = - new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class), null, - mock(SupervisionAcHandler.class), mock(AcmParticipantProvider.class), - mock(AcRuntimeParameterGroup.class)); + var automationCompositionTarget = new AutomationComposition(automationComposition); + automationCompositionTarget.setInstanceId(instanceId); + automationCompositionTarget.setCompositionId(compositionId); + // Add a new element + var uuid = UUID.randomUUID(); + var newElement = new AutomationCompositionElement(); + newElement.setId(uuid); + newElement.setDefinition(new ToscaConceptIdentifier( + "org.onap.domain.pmsh.PMSH_OperationalPolicyAutomationCompositionElement", "1.2.3")); + newElement.setProperties(Map.of("testVar", "1", "testVar2", "2")); + automationCompositionTarget.getElements().put(uuid, newElement); + + //Remove an existing element + var elementIdToRemove = UUID.randomUUID(); + for (var element : automationCompositionTarget.getElements().values()) { + if (element.getDefinition().getName() + .equals("org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement")) { + elementIdToRemove = element.getId(); + } + } + automationCompositionTarget.getElements().remove(elementIdToRemove); - var compositionId = automationCompositionUpdate.getCompositionId(); - assertThatThrownBy( - () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate)) - .hasMessageMatching("There is a restarting process, Update not allowed"); + var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); + var compositionTargetId = acDefinitionTarget.getCompositionId(); + automationCompositionTarget.setCompositionTargetId(compositionTargetId); + when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget)); + when(acDefinitionProvider.getAcDefinition(compositionTargetId)).thenReturn(acDefinitionTarget); + when(acProvider.updateAutomationComposition(any())).thenReturn(automationCompositionTarget); - automationCompositionUpdate.setCompositionTargetId(UUID.randomUUID()); - assertThatThrownBy( - () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate)) - .hasMessageMatching("There is a restarting process, Migrate not allowed"); + var supervisionAcHandler = mock(SupervisionAcHandler.class); + var participantProvider = mock(ParticipantProvider.class); + var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, + new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, + new AcRuntimeParameterGroup()); - automationCompositionUpdate.setDeployState(DeployState.UNDEPLOYED); - automationCompositionUpdate.setLockState(LockState.NONE); + automationCompositionTarget.setPrecheck(true); + var preCheckResponse = instantiationProvider.updateAutomationComposition(compositionId, + automationCompositionTarget); + verify(supervisionAcHandler).migratePrecheck(any()); + InstantiationUtils.assertInstantiationResponse(preCheckResponse, automationCompositionTarget); + + automationCompositionTarget.setPrecheck(false); + AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKED, + SubState.NONE); + var instantiationResponse = instantiationProvider.updateAutomationComposition(compositionId, + automationCompositionTarget); + + verify(supervisionAcHandler).migrate(any(), any()); + InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationCompositionTarget); - var instanceId = automationCompositionUpdate.getInstanceId(); - assertThatThrownBy(() -> instantiationProvider.deleteAutomationComposition(compositionId, instanceId)) - .hasMessageMatching("There is a restarting process, Delete not allowed"); } @Test - void testUpdateCompositionRestartedBadRequest() { - var acDefinitionProvider = mock(AcDefinitionProvider.class); - var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); - acDefinition.setRestarting(true); - var compositionId = acDefinition.getCompositionId(); - when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition)); - - var automationCompositionUpdate = - InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); - automationCompositionUpdate.setCompositionId(compositionId); - automationCompositionUpdate.setDeployState(DeployState.DEPLOYED); - automationCompositionUpdate.setLockState(LockState.LOCKED); + void testVersionCompatibility() { var acProvider = mock(AutomationCompositionProvider.class); - when(acProvider.getAutomationComposition(automationCompositionUpdate.getInstanceId())) - .thenReturn(automationCompositionUpdate); - when(acProvider.updateAutomationComposition(automationCompositionUpdate)) - .thenReturn(automationCompositionUpdate); - + var acDefinitionProvider = mock(AcDefinitionProvider.class); var supervisionAcHandler = mock(SupervisionAcHandler.class); - var acmParticipantProvider = mock(AcmParticipantProvider.class); + var participantProvider = mock(ParticipantProvider.class); + var newDefinition = new PfConceptKey("policy.clamp.element", "1.2.3"); + var oldDefinition = new PfConceptKey("policy.clamp.element", "2.2.3"); + var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, - null, supervisionAcHandler, acmParticipantProvider, - mock(AcRuntimeParameterGroup.class)); - assertThatThrownBy( - () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate)) - .hasMessageMatching("\"AutomationComposition\" INVALID, item has status INVALID\n" - + " item \"ServiceTemplate.restarting\" value \"true\" INVALID," - + " There is a restarting process in composition\n"); + new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, + new AcRuntimeParameterGroup()); + var instanceId = UUID.randomUUID(); + assertDoesNotThrow(() -> { + instantiationProvider.checkCompatibility(newDefinition, oldDefinition, instanceId); + }, "No exception for major version update"); + + // Not compatible + newDefinition.setName("policy.clamp.newElement"); + newDefinition.setVersion("2.2.4"); + + assertThatThrownBy(() -> instantiationProvider + .checkCompatibility(newDefinition, oldDefinition, instanceId)) + .hasMessageContaining("is not compatible"); } @Test @@ -303,9 +345,9 @@ class AutomationCompositionInstantiationProviderTest { when(acProvider.updateAutomationComposition(automationComposition)).thenReturn(automationComposition); var supervisionAcHandler = mock(SupervisionAcHandler.class); - var acmParticipantProvider = mock(AcmParticipantProvider.class); + var participantProvider = mock(ParticipantProvider.class); var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, - null, supervisionAcHandler, acmParticipantProvider, new AcRuntimeParameterGroup()); + new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup()); assertThatThrownBy(() -> instantiationProvider .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition)) @@ -315,6 +357,7 @@ class AutomationCompositionInstantiationProviderTest { var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var compositionTargetId = acDefinitionTarget.getCompositionId(); when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget)); + when(acDefinitionProvider.getAcDefinition(compositionTargetId)).thenReturn(acDefinitionTarget); automationComposition.setCompositionTargetId(compositionTargetId); @@ -327,6 +370,49 @@ class AutomationCompositionInstantiationProviderTest { } @Test + void testInstantiationMigrationPrecheck() { + var acDefinitionProvider = mock(AcDefinitionProvider.class); + var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); + var compositionId = acDefinition.getCompositionId(); + when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition)); + + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); + automationComposition.setCompositionId(compositionId); + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.LOCKED); + automationComposition.setCompositionTargetId(UUID.randomUUID()); + automationComposition.setPrecheck(true); + var acProvider = mock(AutomationCompositionProvider.class); + when(acProvider.getAutomationComposition(automationComposition.getInstanceId())) + .thenReturn(automationComposition); + when(acProvider.updateAutomationComposition(automationComposition)).thenReturn(automationComposition); + + var supervisionAcHandler = mock(SupervisionAcHandler.class); + var acmParticipantProvider = mock(ParticipantProvider.class); + var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, + new AcInstanceStateResolver(), supervisionAcHandler, acmParticipantProvider, new AcRuntimeParameterGroup()); + + assertThatThrownBy(() -> instantiationProvider + .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition)) + .hasMessageMatching( + String.format(AC_DEFINITION_NOT_FOUND, automationComposition.getCompositionTargetId())); + + var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); + var compositionTargetId = acDefinitionTarget.getCompositionId(); + when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget)); + + automationComposition.setCompositionTargetId(compositionTargetId); + + var instantiationResponse = instantiationProvider + .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition); + + verify(supervisionAcHandler).migratePrecheck(any()); + verify(acProvider).updateAutomationComposition(automationComposition); + InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationComposition); + } + + @Test void testMigrateBadRequest() { var acDefinitionProvider = mock(AcDefinitionProvider.class); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); @@ -349,16 +435,55 @@ class AutomationCompositionInstantiationProviderTest { var acMigrate = new AutomationComposition(automationComposition); acMigrate.setCompositionTargetId(compositionTargetId); - automationComposition.getElements().clear(); + automationComposition.setDeployState(DeployState.DEPLOYING); var supervisionAcHandler = mock(SupervisionAcHandler.class); - var acmParticipantProvider = mock(AcmParticipantProvider.class); + var participantProvider = mock(ParticipantProvider.class); var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, - null, supervisionAcHandler, acmParticipantProvider, new AcRuntimeParameterGroup()); + new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, + new AcRuntimeParameterGroup()); assertThatThrownBy(() -> instantiationProvider .updateAutomationComposition(automationComposition.getCompositionId(), acMigrate)) - .hasMessageStartingWith("Element id not present"); + .hasMessageStartingWith("Not allowed to MIGRATE in the state DEPLOYING"); + } + + @Test + void testMigratePrecheckBadRequest() { + var acDefinitionProvider = mock(AcDefinitionProvider.class); + var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); + var compositionId = acDefinition.getCompositionId(); + when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition)); + + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); + automationComposition.setCompositionId(compositionId); + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.LOCKED); + automationComposition.setPrecheck(true); + var acProvider = mock(AutomationCompositionProvider.class); + when(acProvider.getAutomationComposition(automationComposition.getInstanceId())) + .thenReturn(automationComposition); + when(acProvider.updateAutomationComposition(automationComposition)).thenReturn(automationComposition); + + var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); + var compositionTargetId = acDefinitionTarget.getCompositionId(); + when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget)); + + var acMigrate = new AutomationComposition(automationComposition); + acMigrate.setCompositionTargetId(compositionTargetId); + automationComposition.setDeployState(DeployState.DEPLOYING); + automationComposition.setPrecheck(true); + + var supervisionAcHandler = mock(SupervisionAcHandler.class); + var participantProvider = mock(ParticipantProvider.class); + var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, + new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, + new AcRuntimeParameterGroup()); + + assertThatThrownBy(() -> instantiationProvider + .updateAutomationComposition(automationComposition.getCompositionId(), acMigrate)) + .hasMessageStartingWith("Not allowed to NONE in the state DEPLOYING"); } @Test @@ -373,11 +498,11 @@ class AutomationCompositionInstantiationProviderTest { when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition); automationComposition.setCompositionId(compositionId); var supervisionAcHandler = mock(SupervisionAcHandler.class); - var acmParticipantProvider = mock(AcmParticipantProvider.class); + var participantProvider = mock(ParticipantProvider.class); var acRuntimeParameterGroup = mock(AcRuntimeParameterGroup.class); var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, - null, supervisionAcHandler, acmParticipantProvider, acRuntimeParameterGroup); + null, supervisionAcHandler, participantProvider, acRuntimeParameterGroup); when(acProvider.getAutomationComposition(automationComposition.getInstanceId())) .thenReturn(automationComposition); @@ -436,10 +561,10 @@ class AutomationCompositionInstantiationProviderTest { var acProvider = mock(AutomationCompositionProvider.class); when(acProvider.createAutomationComposition(automationCompositionCreate)) .thenReturn(automationCompositionCreate); - var acmParticipantProvider = mock(AcmParticipantProvider.class); + var participantProvider = mock(ParticipantProvider.class); var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, - null, null, acmParticipantProvider, + null, null, participantProvider, CommonTestData.getTestParamaterGroup()); var instantiationResponse = instantiationProvider.createAutomationComposition( @@ -457,7 +582,7 @@ class AutomationCompositionInstantiationProviderTest { @Test void testCreateAutomationCompositions_CommissionedAcElementNotFound() { var acDefinitionProvider = mock(AcDefinitionProvider.class); - var acmParticipantProvider = mock(AcmParticipantProvider.class); + var participantProvider = mock(ParticipantProvider.class); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var compositionId = acDefinition.getCompositionId(); when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition)); @@ -467,7 +592,7 @@ class AutomationCompositionInstantiationProviderTest { var acProvider = mock(AutomationCompositionProvider.class); var provider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, null, null, - acmParticipantProvider, CommonTestData.getTestParamaterGroup()); + participantProvider, CommonTestData.getTestParamaterGroup()); assertThatThrownBy(() -> provider.createAutomationComposition(compositionId, automationComposition)) .hasMessageMatching(AC_ELEMENT_NAME_NOT_FOUND); @@ -550,10 +675,14 @@ class AutomationCompositionInstantiationProviderTest { var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud"); automationComposition.setCompositionId(compositionId); + var message = """ + "AutomationComposition" INVALID, item has status INVALID + item "ServiceTemplate.state" value "COMMISSIONED" INVALID, Commissioned automation composition \ + definition not primed + """; + assertThatThrownBy(() -> provider.createAutomationComposition(compositionId, automationComposition)) - .hasMessageMatching("\"AutomationComposition\" INVALID, item has status INVALID\n" - + " item \"ServiceTemplate.state\" value \"COMMISSIONED\" INVALID," - + " Commissioned automation composition definition not primed\n"); + .hasMessageMatching(message); } @Test @@ -572,9 +701,9 @@ class AutomationCompositionInstantiationProviderTest { when(acProvider.getAutomationComposition(instanceId)).thenReturn(automationComposition); var supervisionAcHandler = mock(SupervisionAcHandler.class); - var acmParticipantProvider = mock(AcmParticipantProvider.class); + var participantProvider = mock(ParticipantProvider.class); var provider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, - new AcInstanceStateResolver(), supervisionAcHandler, acmParticipantProvider, + new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, mock(AcRuntimeParameterGroup.class)); var acInstanceStateUpdate = new AcInstanceStateUpdate(); @@ -605,5 +734,21 @@ class AutomationCompositionInstantiationProviderTest { acInstanceStateUpdate.setLockOrder(LockOrder.LOCK); provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate); verify(supervisionAcHandler).lock(any(AutomationComposition.class), any(AutomationCompositionDefinition.class)); + + automationComposition.setDeployState(DeployState.UNDEPLOYED); + automationComposition.setLockState(LockState.NONE); + acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE); + acInstanceStateUpdate.setLockOrder(LockOrder.NONE); + acInstanceStateUpdate.setSubOrder(SubOrder.PREPARE); + provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate); + verify(supervisionAcHandler).prepare(any(AutomationComposition.class)); + + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.LOCKED); + acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE); + acInstanceStateUpdate.setLockOrder(LockOrder.NONE); + acInstanceStateUpdate.setSubOrder(SubOrder.REVIEW); + provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate); + verify(supervisionAcHandler).review(any(AutomationComposition.class)); } } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/InstantiationUtils.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/InstantiationUtils.java index 8639dffcd..564723b7c 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/InstantiationUtils.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/InstantiationUtils.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation. + * Copyright (C) 2021-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. @@ -34,7 +34,6 @@ import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.common.utils.coder.StandardYamlCoder; import org.onap.policy.common.utils.resources.ResourceUtils; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; /** diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java index bcfdea1dd..ca58fad51 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java @@ -374,6 +374,9 @@ class InstantiationControllerTest extends CommonRestController { } private void saveDummyParticipantInDb() { - participantProvider.saveParticipant(CommonTestData.createParticipant(CommonTestData.getParticipantId())); + var participant = CommonTestData.createParticipant(CommonTestData.getParticipantId()); + var replica = CommonTestData.createParticipantReplica(CommonTestData.getReplicaId()); + participant.getReplicas().put(replica.getReplicaId(), replica); + participantProvider.saveParticipant(participant); } } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/rest/ActuatorControllerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/rest/ActuatorControllerTest.java index bdfaedc04..18911f461 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/rest/ActuatorControllerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/rest/ActuatorControllerTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation. + * Copyright (C) 2021-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. @@ -20,84 +20,62 @@ package org.onap.policy.clamp.acm.runtime.main.rest; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.http.MediaType.TEXT_PLAIN; -import jakarta.ws.rs.core.Response; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.onap.policy.clamp.acm.runtime.util.rest.CommonRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.web.reactive.function.client.ExchangeFilterFunctions; -@AutoConfigureObservability(tracing = false) -@ExtendWith(SpringExtension.class) +@AutoConfigureObservability +@AutoConfigureWebTestClient @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -@ActiveProfiles({ "test", "default" }) -class ActuatorControllerTest extends CommonRestController { +@ActiveProfiles("test") +class ActuatorControllerTest { - private static final String HEALTH_ENDPOINT = "health"; - private static final String METRICS_ENDPOINT = "metrics"; - private static final String PROMETHEUS_ENDPOINT = "prometheus"; - private static final String SWAGGER_ENDPOINT = "v3/api-docs"; + @Autowired + WebTestClient webClient; - @LocalServerPort - private int randomServerPort; + @Value("${spring.security.user.name}") + String username; + @Value("${spring.security.user.password}") + String password; @BeforeEach - public void setUpPort() { - super.setHttpPrefix(randomServerPort); - } - - @Test - void testGetHealth_Unauthorized() { - assertUnauthorizedActGet(HEALTH_ENDPOINT); - } - - @Test - void testGetMetrics_Unauthorized() { - assertUnauthorizedActGet(METRICS_ENDPOINT); - } - - @Test - void testGetPrometheus_Unauthorized() { - assertUnauthorizedActGet(PROMETHEUS_ENDPOINT); - } - - @Test - void testGetSwagger_Unauthorized() { - assertUnauthorizedActGet(SWAGGER_ENDPOINT); + void beforeEach() { + var filter = ExchangeFilterFunctions.basicAuthentication(username, password); + webClient = webClient.mutate().filter(filter).build(); } @Test void testGetHealth() { - var invocationBuilder = super.sendActRequest(HEALTH_ENDPOINT); - var rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + webClient.get().uri("/health").accept(APPLICATION_JSON) + .exchange().expectStatus().isOk(); } @Test void testGetMetrics() { - var invocationBuilder = super.sendActRequest(METRICS_ENDPOINT); - var rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + webClient.get().uri("/metrics").accept(APPLICATION_JSON) + .exchange().expectStatus().isOk(); } @Test void testGetPrometheus() { - var invocationBuilder = super.sendActRequest(PROMETHEUS_ENDPOINT); - var rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + webClient.get().uri("/prometheus").accept(TEXT_PLAIN) + .exchange().expectStatus().isOk(); } @Test void testGetSwagger() { - var invocationBuilder = super.sendActRequest(SWAGGER_ENDPOINT); - var rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + webClient.get().uri("/v3/api-docs").accept(APPLICATION_JSON) + .exchange().expectStatus().isOk(); } } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/rest/PrometheusNoAuthTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/rest/PrometheusNoAuthTest.java index 5b94814fb..87e43ea8c 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/rest/PrometheusNoAuthTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/rest/PrometheusNoAuthTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation. + * Copyright (C) 2023-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. @@ -20,39 +20,29 @@ package org.onap.policy.clamp.acm.runtime.main.rest; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.springframework.http.MediaType.TEXT_PLAIN; -import jakarta.ws.rs.client.Invocation; -import jakarta.ws.rs.core.Response; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.onap.policy.clamp.acm.runtime.util.rest.CommonRestController; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.reactive.server.WebTestClient; @AutoConfigureObservability(tracing = false) @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@ActiveProfiles({ "prometheus-noauth", "default" }) -class PrometheusNoAuthTest extends CommonRestController { - private static final String PROMETHEUS_ENDPOINT = "prometheus"; +@ActiveProfiles({"prometheus-noauth", "default"}) +class PrometheusNoAuthTest { - @LocalServerPort - private int randomServerPort; - - @BeforeEach - public void setUpPort() { - super.setHttpPrefix(randomServerPort); - } + @Autowired + WebTestClient webClient; @Test - void testGetPrometheusNoAuth() { - Invocation.Builder invocationBuilder = super.sendNoAuthActRequest(PROMETHEUS_ENDPOINT); - Response rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + void testGetPrometheus() { + webClient.get().uri("/prometheus").accept(TEXT_PLAIN) + .exchange().expectStatus().isOk(); } } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/participant/ParticipantControllerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/participant/ParticipantControllerTest.java index f8443de33..ca3b9bfab 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/participant/ParticipantControllerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/participant/ParticipantControllerTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation. + * Copyright (C) 2023-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. @@ -45,7 +45,6 @@ import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.common.utils.resources.ResourceUtils; -import org.onap.policy.models.base.PfModelException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; @@ -71,8 +70,8 @@ class ParticipantControllerTest extends CommonRestController { private static final String PARTICIPANT_JSON2 = "src/test/resources/providers/TestParticipant2.json"; private static final List<Participant> inputParticipants = new ArrayList<>(); - private static final String originalJson = ResourceUtils.getResourceAsString(PARTICIPANT_JSON); - private static final String originalJson2 = ResourceUtils.getResourceAsString(PARTICIPANT_JSON2); + private static final String ORIGINAL_JSON = ResourceUtils.getResourceAsString(PARTICIPANT_JSON); + private static final String ORIGINAL_JSON2 = ResourceUtils.getResourceAsString(PARTICIPANT_JSON2); @Autowired private ParticipantProvider participantProvider; @@ -82,8 +81,8 @@ class ParticipantControllerTest extends CommonRestController { */ @BeforeAll public static void setUpBeforeClass() throws CoderException { - inputParticipants.add(CODER.decode(originalJson, Participant.class)); - inputParticipants.add(CODER.decode(originalJson2, Participant.class)); + inputParticipants.add(CODER.decode(ORIGINAL_JSON, Participant.class)); + inputParticipants.add(CODER.decode(ORIGINAL_JSON2, Participant.class)); } @BeforeEach @@ -104,61 +103,61 @@ class ParticipantControllerTest extends CommonRestController { @Test void testQueryParticipant() { participantProvider.saveParticipant(inputParticipants.get(0)); - UUID participantId = participantProvider.getParticipants().get(0).getParticipantId(); + var participantId = participantProvider.getParticipants().get(0).getParticipantId(); var invocationBuilder = super.sendRequest(PARTICIPANTS_ENDPOINT + "/" + participantId); - var response = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - var entityList = response.readEntity(ParticipantInformation.class); - assertNotNull(entityList); + try (var response = invocationBuilder.buildGet().invoke()) { + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + var entityList = response.readEntity(ParticipantInformation.class); + assertNotNull(entityList); + } } @Test void testBadQueryParticipant() { participantProvider.saveParticipant(inputParticipants.get(0)); var invocationBuilder = super.sendRequest(PARTICIPANTS_ENDPOINT + "/" + UUID.randomUUID()); - var response = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus()); + try (var response = invocationBuilder.buildGet().invoke()) { + assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus()); + } } @Test void getAllParticipants() { - inputParticipants.forEach(p -> { - participantProvider.saveParticipant(p); - }); + inputParticipants.forEach(p -> participantProvider.saveParticipant(p)); var invocationBuilder = super.sendRequest(PARTICIPANTS_ENDPOINT); - var response = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - List<ParticipantInformation> entityList = response.readEntity(new GenericType<>() {}); - assertThat(entityList).isNotEmpty(); - var participantIds = entityList.stream().map(ParticipantInformation::getParticipant) - .map(Participant::getParticipantId).collect(Collectors.toSet()); - inputParticipants.forEach(p -> { - assertThat(participantIds).contains(p.getParticipantId()); - }); + try (var response = invocationBuilder.buildGet().invoke()) { + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + List<ParticipantInformation> entityList = response.readEntity(new GenericType<>() {}); + assertThat(entityList).isNotEmpty(); + var participantIds = + entityList.stream().map(ParticipantInformation::getParticipant).map(Participant::getParticipantId) + .collect(Collectors.toSet()); + inputParticipants.forEach(p -> assertThat(participantIds).contains(p.getParticipantId())); + } } @Test - void testOrderParticipantReport() throws PfModelException { + void testOrderParticipantReport() { participantProvider.saveParticipant(inputParticipants.get(0)); - UUID participantId = participantProvider.getParticipants().get(0).getParticipantId(); + var participantId = participantProvider.getParticipants().get(0).getParticipantId(); var invocationBuilder = super.sendRequest(PARTICIPANTS_ENDPOINT + "/" + participantId); - var response = invocationBuilder.header("Content-Length", 0).put(Entity.entity("" - + - "", MediaType.APPLICATION_JSON)); - assertEquals(Response.Status.ACCEPTED.getStatusCode(), response.getStatus()); + try (var response = invocationBuilder.header("Content-Length", 0) + .put(Entity.entity("", MediaType.APPLICATION_JSON))) { + assertEquals(Response.Status.ACCEPTED.getStatusCode(), response.getStatus()); + } } @Test - void testBadOrderParticipantReport() throws PfModelException { + void testBadOrderParticipantReport() { var invocationBuilder = super.sendRequest(PARTICIPANTS_ENDPOINT + "/" + UUID.randomUUID()); - var response = invocationBuilder.header("Content-Length", 0).put(Entity.entity("" - + - "", MediaType.APPLICATION_JSON)); - assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus()); + try (var response = invocationBuilder.header("Content-Length", 0) + .put(Entity.entity("", MediaType.APPLICATION_JSON))) { + assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus()); + } } @Test @@ -167,9 +166,9 @@ class ParticipantControllerTest extends CommonRestController { participantProvider.saveParticipant(p); }); var invocationBuilder = super.sendRequest(PARTICIPANTS_ENDPOINT); - var response = invocationBuilder.header("Content-Length", 0).put(Entity.entity("" - + - "", MediaType.APPLICATION_JSON)); - assertEquals(Response.Status.ACCEPTED.getStatusCode(), response.getStatus()); + try (var response = invocationBuilder.header("Content-Length", 0) + .put(Entity.entity("", MediaType.APPLICATION_JSON))) { + assertEquals(Response.Status.ACCEPTED.getStatusCode(), response.getStatus()); + } } } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java index 8f39c9e2e..b104084a8 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java @@ -36,19 +36,23 @@ import java.util.UUID; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils; import org.onap.policy.clamp.acm.runtime.supervision.comm.AcElementPropertiesPublisher; +import org.onap.policy.clamp.acm.runtime.supervision.comm.AcPreparePublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionDeployPublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionMigrationPublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher; +import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher; import org.onap.policy.clamp.acm.runtime.util.CommonTestData; import org.onap.policy.clamp.models.acm.concepts.AcElementDeployAck; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; 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.StateChangeResult; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeployAck; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMessageType; +import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; class SupervisionAcHandlerTest { @@ -56,6 +60,68 @@ class SupervisionAcHandlerTest { private static final UUID IDENTIFIER = UUID.randomUUID(); @Test + void testAutomationCompositionDeployAckNull() { + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), + mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), + mock(AcElementPropertiesPublisher.class), null, + mock(ParticipantSyncPublisher.class), null); + + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud"); + automationComposition.setInstanceId(IDENTIFIER); + var automationCompositionAckMessage = + getAutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK, + automationComposition, DeployState.DEPLOYED, LockState.UNLOCKED); + automationCompositionAckMessage.setStateChangeResult(null); + handler.handleAutomationCompositionStateChangeAckMessage(automationCompositionAckMessage); + + automationCompositionAckMessage.setStateChangeResult(StateChangeResult.NO_ERROR); + automationCompositionAckMessage.setAutomationCompositionId(null); + handler.handleAutomationCompositionStateChangeAckMessage(automationCompositionAckMessage); + + automationCompositionAckMessage.setAutomationCompositionId(automationComposition.getInstanceId()); + handler.handleAutomationCompositionStateChangeAckMessage(automationCompositionAckMessage); + + automationCompositionAckMessage = + getAutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK, + automationComposition, DeployState.DEPLOYING, LockState.UNLOCKED); + handler.handleAutomationCompositionStateChangeAckMessage(automationCompositionAckMessage); + + verify(automationCompositionProvider, times(0)).updateAutomationCompositionElement(any()); + } + + @Test + void testHandleAcMigrationWithStage() { + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud"); + automationComposition.setInstanceId(IDENTIFIER); + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + when(automationCompositionProvider.findAutomationComposition(IDENTIFIER)) + .thenReturn(Optional.of(automationComposition)); + when(automationCompositionProvider.updateAcState(any(AutomationComposition.class))) + .thenReturn(automationComposition); + + var acDefinitionProvider = mock(AcDefinitionProvider.class); + when(acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId())) + .thenReturn(new AutomationCompositionDefinition()); + + var handler = new SupervisionAcHandler(automationCompositionProvider, acDefinitionProvider, + mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), + mock(AcElementPropertiesPublisher.class), null, + mock(ParticipantSyncPublisher.class), null); + + var automationCompositionAckMessage = + getAutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK, + automationComposition, DeployState.MIGRATING, LockState.LOCKED); + automationCompositionAckMessage.setStage(1); + handler.handleAutomationCompositionStateChangeAckMessage(automationCompositionAckMessage); + + verify(automationCompositionProvider, times(3)) + .updateAutomationCompositionElement(any(AutomationCompositionElement.class)); + } + + @Test void testHandleAutomationCompositionStateChangeAckMessage() { var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud"); @@ -63,10 +129,17 @@ class SupervisionAcHandlerTest { var automationCompositionProvider = mock(AutomationCompositionProvider.class); when(automationCompositionProvider.findAutomationComposition(IDENTIFIER)) .thenReturn(Optional.of(automationComposition)); + when(automationCompositionProvider.updateAcState(any(AutomationComposition.class))) + .thenReturn(automationComposition); - var handler = new SupervisionAcHandler(automationCompositionProvider, + var acDefinitionProvider = mock(AcDefinitionProvider.class); + when(acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId())) + .thenReturn(new AutomationCompositionDefinition()); + + var handler = new SupervisionAcHandler(automationCompositionProvider, acDefinitionProvider, mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), - mock(AcElementPropertiesPublisher.class), null); + mock(AcElementPropertiesPublisher.class), null, + mock(ParticipantSyncPublisher.class), null); var automationCompositionAckMessage = getAutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK, @@ -74,7 +147,7 @@ class SupervisionAcHandlerTest { handler.handleAutomationCompositionStateChangeAckMessage(automationCompositionAckMessage); verify(automationCompositionProvider, times(3)) - .updateAutomationCompositionElement(any(AutomationCompositionElement.class), any()); + .updateAutomationCompositionElement(any(AutomationCompositionElement.class)); } private AutomationCompositionDeployAck getAutomationCompositionDeployAck(ParticipantMessageType messageType, @@ -99,19 +172,26 @@ class SupervisionAcHandlerTest { var automationCompositionProvider = mock(AutomationCompositionProvider.class); when(automationCompositionProvider.findAutomationComposition(IDENTIFIER)) .thenReturn(Optional.of(automationComposition)); + when(automationCompositionProvider.updateAcState(any(AutomationComposition.class))) + .thenReturn(automationComposition); + + var acDefinitionProvider = mock(AcDefinitionProvider.class); + when(acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId())) + .thenReturn(new AutomationCompositionDefinition()); var automationCompositionAckMessage = getAutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_DEPLOY_ACK, automationComposition, DeployState.DEPLOYED, LockState.LOCKED); automationCompositionAckMessage.setParticipantId(CommonTestData.getParticipantId()); - var handler = new SupervisionAcHandler(automationCompositionProvider, + var handler = new SupervisionAcHandler(automationCompositionProvider, acDefinitionProvider, mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), - mock(AcElementPropertiesPublisher.class), null); + mock(AcElementPropertiesPublisher.class), null, + mock(ParticipantSyncPublisher.class), null); handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage); - verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class)); + verify(automationCompositionProvider).updateAcState(any(AutomationComposition.class)); } @Test @@ -142,22 +222,24 @@ class SupervisionAcHandlerTest { var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); - var handler = new SupervisionAcHandler(automationCompositionProvider, + var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), automationCompositionStateChangePublisher, null, - null); + null, mock(ParticipantSyncPublisher.class), null); handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage); verify(automationCompositionProvider) - .updateAutomationCompositionElement(any(AutomationCompositionElement.class), any()); + .updateAutomationCompositionElement(any(AutomationCompositionElement.class)); } @Test void testDeployFailed() { var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class); var automationCompositionProvider = mock(AutomationCompositionProvider.class); - var handler = new SupervisionAcHandler(automationCompositionProvider, automationCompositionDeployPublisher, - mock(AutomationCompositionStateChangePublisher.class), mock(AcElementPropertiesPublisher.class), null); + var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), + automationCompositionDeployPublisher, mock(AutomationCompositionStateChangePublisher.class), + mock(AcElementPropertiesPublisher.class), null, + mock(ParticipantSyncPublisher.class), null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); @@ -174,9 +256,10 @@ class SupervisionAcHandlerTest { void testUndeploy() { var automationCompositionProvider = mock(AutomationCompositionProvider.class); var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); - var handler = new SupervisionAcHandler(automationCompositionProvider, + var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, - mock(AcElementPropertiesPublisher.class), null); + mock(AcElementPropertiesPublisher.class), null, + mock(ParticipantSyncPublisher.class), null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var automationComposition = @@ -191,9 +274,10 @@ class SupervisionAcHandlerTest { void testUndeployFailed() { var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); var automationCompositionProvider = mock(AutomationCompositionProvider.class); - var handler = new SupervisionAcHandler(automationCompositionProvider, + var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, - mock(AcElementPropertiesPublisher.class), null); + mock(AcElementPropertiesPublisher.class), null, + mock(ParticipantSyncPublisher.class), null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); @@ -211,9 +295,10 @@ class SupervisionAcHandlerTest { void testUnlock() { var automationCompositionProvider = mock(AutomationCompositionProvider.class); var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); - var handler = new SupervisionAcHandler(automationCompositionProvider, + var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, - mock(AcElementPropertiesPublisher.class), null); + mock(AcElementPropertiesPublisher.class), null, + mock(ParticipantSyncPublisher.class), null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var automationComposition = @@ -228,9 +313,10 @@ class SupervisionAcHandlerTest { void testUnlockFailed() { var automationCompositionProvider = mock(AutomationCompositionProvider.class); var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); - var handler = new SupervisionAcHandler(automationCompositionProvider, + var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, - mock(AcElementPropertiesPublisher.class), null); + mock(AcElementPropertiesPublisher.class), null, + mock(ParticipantSyncPublisher.class), null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var automationComposition = @@ -247,9 +333,10 @@ class SupervisionAcHandlerTest { void testLock() { var automationCompositionProvider = mock(AutomationCompositionProvider.class); var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); - var handler = new SupervisionAcHandler(automationCompositionProvider, + var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, - mock(AcElementPropertiesPublisher.class), null); + mock(AcElementPropertiesPublisher.class), null, + mock(ParticipantSyncPublisher.class), null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var automationComposition = @@ -264,9 +351,10 @@ class SupervisionAcHandlerTest { void testLockFailed() { var automationCompositionProvider = mock(AutomationCompositionProvider.class); var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); - var handler = new SupervisionAcHandler(automationCompositionProvider, + var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, - mock(AcElementPropertiesPublisher.class), null); + mock(AcElementPropertiesPublisher.class), null, + mock(ParticipantSyncPublisher.class), null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var automationComposition = @@ -293,23 +381,26 @@ class SupervisionAcHandlerTest { automationCompositionAckMessage .setParticipantId(automationComposition.getElements().values().iterator().next().getParticipantId()); automationCompositionAckMessage.setAutomationCompositionId(IDENTIFIER); + automationCompositionAckMessage.setStateChangeResult(StateChangeResult.NO_ERROR); - var handler = new SupervisionAcHandler(automationCompositionProvider, + var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), - mock(AcElementPropertiesPublisher.class), null); + mock(AcElementPropertiesPublisher.class), null, + mock(ParticipantSyncPublisher.class), null); handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage); verify(automationCompositionProvider) - .updateAutomationCompositionElement(any(AutomationCompositionElement.class), any()); + .updateAutomationCompositionElement(any(AutomationCompositionElement.class)); } @Test void testUpdate() { var acElementPropertiesPublisher = mock(AcElementPropertiesPublisher.class); var handler = new SupervisionAcHandler(mock(AutomationCompositionProvider.class), - mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), - acElementPropertiesPublisher, null); + mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), + mock(AutomationCompositionStateChangePublisher.class), acElementPropertiesPublisher, null, + mock(ParticipantSyncPublisher.class), null); var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Lock"); handler.update(automationComposition); @@ -320,11 +411,49 @@ class SupervisionAcHandlerTest { void testMigrate() { var automationCompositionProvider = mock(AutomationCompositionProvider.class); var acCompositionMigrationPublisher = mock(AutomationCompositionMigrationPublisher.class); + var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), + null, null, null, + acCompositionMigrationPublisher, mock(ParticipantSyncPublisher.class), null); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Migrate"); + var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); + handler.migrate(automationComposition, serviceTemplate); + verify(acCompositionMigrationPublisher, timeout(1000)).send(any(AutomationComposition.class), anyInt()); + } + + @Test + void testMigratePrecheck() { + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + var acCompositionMigrationPublisher = mock(AutomationCompositionMigrationPublisher.class); + var handler = new SupervisionAcHandler(automationCompositionProvider, null, null, null, + null, acCompositionMigrationPublisher, null, null); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Migrate"); + handler.migratePrecheck(automationComposition); + verify(acCompositionMigrationPublisher, timeout(1000)).send(any(AutomationComposition.class), anyInt()); + } + + @Test + void testPrepare() { + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + var acPreparePublisher = mock(AcPreparePublisher.class); + var handler = new SupervisionAcHandler(automationCompositionProvider, null, null, null, + null, null, null, acPreparePublisher); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Migrate"); + handler.prepare(automationComposition); + verify(acPreparePublisher, timeout(1000)).sendPrepare(any(AutomationComposition.class)); + } + + @Test + void testReview() { + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + var acPreparePublisher = mock(AcPreparePublisher.class); var handler = new SupervisionAcHandler(automationCompositionProvider, null, null, null, - acCompositionMigrationPublisher); + null, null, null, acPreparePublisher); var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Migrate"); - handler.migrate(automationComposition, UUID.randomUUID()); - verify(acCompositionMigrationPublisher, timeout(1000)).send(any(AutomationComposition.class), any()); + handler.review(automationComposition); + verify(acPreparePublisher, timeout(1000)).sendRevew(any(AutomationComposition.class)); } } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspectTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspectTest.java index f78344bcb..7a72e0ef5 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspectTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspectTest.java @@ -32,19 +32,19 @@ class SupervisionAspectTest { @Test void testSchedule() throws Exception { var supervisionScanner = mock(SupervisionScanner.class); - var partecipantScanner = mock(SupervisionPartecipantScanner.class); - try (var supervisionAspect = new SupervisionAspect(supervisionScanner, partecipantScanner)) { + var participantScanner = mock(SupervisionParticipantScanner.class); + try (var supervisionAspect = new SupervisionAspect(supervisionScanner, participantScanner)) { supervisionAspect.schedule(); verify(supervisionScanner, timeout(500)).run(); - verify(partecipantScanner, timeout(500)).run(); + verify(participantScanner, timeout(500)).run(); } } @Test void testDoCheck() throws Exception { var supervisionScanner = mock(SupervisionScanner.class); - var partecipantScanner = mock(SupervisionPartecipantScanner.class); - try (var supervisionAspect = new SupervisionAspect(supervisionScanner, partecipantScanner)) { + var participantScanner = mock(SupervisionParticipantScanner.class); + try (var supervisionAspect = new SupervisionAspect(supervisionScanner, participantScanner)) { supervisionAspect.doCheck(); supervisionAspect.doCheck(); verify(supervisionScanner, timeout(500).times(2)).run(); diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java index 448666f8f..09a79d890 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java @@ -28,12 +28,12 @@ import static org.mockito.Mockito.when; import static org.onap.policy.clamp.acm.runtime.util.CommonTestData.TOSCA_SERVICE_TEMPLATE_YAML; import java.util.Optional; +import java.util.UUID; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils; -import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; +import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher; import org.onap.policy.clamp.acm.runtime.util.CommonTestData; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; -import org.onap.policy.clamp.models.acm.concepts.ParticipantState; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrimeAck; import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; @@ -41,23 +41,55 @@ import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvide class SupervisionHandlerTest { @Test + void testParticipantPrimeAckNull() { + var acDefinitionProvider = mock(AcDefinitionProvider.class); + var handler = new SupervisionHandler(acDefinitionProvider, mock(ParticipantSyncPublisher.class)); + + var participantPrimeAckMessage = new ParticipantPrimeAck(); + participantPrimeAckMessage.setParticipantId(CommonTestData.getParticipantId()); + handler.handleParticipantMessage(participantPrimeAckMessage); + + participantPrimeAckMessage.setCompositionId(UUID.randomUUID()); + handler.handleParticipantMessage(participantPrimeAckMessage); + + participantPrimeAckMessage.setStateChangeResult(StateChangeResult.NO_ERROR); + handler.handleParticipantMessage(participantPrimeAckMessage); + + participantPrimeAckMessage.setStateChangeResult(null); + participantPrimeAckMessage.setCompositionState(AcTypeState.PRIMED); + handler.handleParticipantMessage(participantPrimeAckMessage); + + participantPrimeAckMessage.setStateChangeResult(StateChangeResult.NO_ERROR); + participantPrimeAckMessage.setCompositionState(AcTypeState.PRIMING); + handler.handleParticipantMessage(participantPrimeAckMessage); + + participantPrimeAckMessage.setCompositionState(AcTypeState.DEPRIMING); + handler.handleParticipantMessage(participantPrimeAckMessage); + + verify(acDefinitionProvider, times(0)).findAcDefinition(any()); + verify(acDefinitionProvider, times(0)).updateAcDefinitionElement(any(), any()); + } + + @Test void testParticipantPrimeAckNotFound() { var participantPrimeAckMessage = new ParticipantPrimeAck(); participantPrimeAckMessage.setParticipantId(CommonTestData.getParticipantId()); - participantPrimeAckMessage.setState(ParticipantState.ON_LINE); + participantPrimeAckMessage.setStateChangeResult(StateChangeResult.NO_ERROR); + participantPrimeAckMessage.setCompositionId(UUID.randomUUID()); + participantPrimeAckMessage.setCompositionState(AcTypeState.PRIMED); var acDefinitionProvider = mock(AcDefinitionProvider.class); - var acRuntimeParameterGroup = mock(AcRuntimeParameterGroup.class); - var handler = new SupervisionHandler(acDefinitionProvider, acRuntimeParameterGroup); - + var handler = new SupervisionHandler(acDefinitionProvider, mock(ParticipantSyncPublisher.class)); handler.handleParticipantMessage(participantPrimeAckMessage); - verify(acDefinitionProvider).findAcDefinition(any()); + verify(acDefinitionProvider).findAcDefinition(participantPrimeAckMessage.getCompositionId()); + verify(acDefinitionProvider, times(0)).updateAcDefinitionElement(any(), any()); } @Test void testParticipantPrimeAckPrimed() { var participantPrimeAckMessage = new ParticipantPrimeAck(); participantPrimeAckMessage.setParticipantId(CommonTestData.getParticipantId()); - participantPrimeAckMessage.setState(ParticipantState.ON_LINE); + participantPrimeAckMessage.setStateChangeResult(StateChangeResult.NO_ERROR); + participantPrimeAckMessage.setCompositionState(AcTypeState.PRIMED); var acDefinition = CommonTestData.createAcDefinition( InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.PRIMED); @@ -66,9 +98,7 @@ class SupervisionHandlerTest { var acDefinitionProvider = mock(AcDefinitionProvider.class); when(acDefinitionProvider.findAcDefinition(acDefinition.getCompositionId())) .thenReturn(Optional.of(acDefinition)); - var acRuntimeParameterGroup = mock(AcRuntimeParameterGroup.class); - - var handler = new SupervisionHandler(acDefinitionProvider, acRuntimeParameterGroup); + var handler = new SupervisionHandler(acDefinitionProvider, mock(ParticipantSyncPublisher.class)); handler.handleParticipantMessage(participantPrimeAckMessage); verify(acDefinitionProvider).findAcDefinition(any()); @@ -79,7 +109,7 @@ class SupervisionHandlerTest { var participantPrimeAckMessage = new ParticipantPrimeAck(); participantPrimeAckMessage.setParticipantId(CommonTestData.getParticipantId()); participantPrimeAckMessage.setCompositionState(AcTypeState.PRIMED); - participantPrimeAckMessage.setState(ParticipantState.ON_LINE); + participantPrimeAckMessage.setStateChangeResult(StateChangeResult.NO_ERROR); var acDefinition = CommonTestData.createAcDefinition( InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.PRIMING); @@ -93,21 +123,21 @@ class SupervisionHandlerTest { when(acDefinitionProvider.findAcDefinition(acDefinition.getCompositionId())) .thenReturn(Optional.of(acDefinition)); - var handler = new SupervisionHandler(acDefinitionProvider, CommonTestData.getTestParamaterGroup()); + var handler = new SupervisionHandler(acDefinitionProvider, mock(ParticipantSyncPublisher.class)); handler.handleParticipantMessage(participantPrimeAckMessage); verify(acDefinitionProvider).findAcDefinition(any()); verify(acDefinitionProvider, times(acDefinition.getElementStateMap().size())) .updateAcDefinitionElement(any(), any()); verify(acDefinitionProvider).updateAcDefinitionState(acDefinition.getCompositionId(), AcTypeState.PRIMED, - StateChangeResult.NO_ERROR, null); + StateChangeResult.NO_ERROR); } @Test void testParticipantPrimeAckFailed() { var participantPrimeAckMessage = new ParticipantPrimeAck(); participantPrimeAckMessage.setParticipantId(CommonTestData.getParticipantId()); - participantPrimeAckMessage.setState(ParticipantState.ON_LINE); + participantPrimeAckMessage.setCompositionState(AcTypeState.COMMISSIONED); participantPrimeAckMessage.setStateChangeResult(StateChangeResult.FAILED); var acDefinition = CommonTestData.createAcDefinition( @@ -120,43 +150,12 @@ class SupervisionHandlerTest { when(acDefinitionProvider.findAcDefinition(acDefinition.getCompositionId())) .thenReturn(Optional.of(acDefinition)); - var handler = new SupervisionHandler(acDefinitionProvider, CommonTestData.getTestParamaterGroup()); + var handler = new SupervisionHandler(acDefinitionProvider, mock(ParticipantSyncPublisher.class)); handler.handleParticipantMessage(participantPrimeAckMessage); verify(acDefinitionProvider).findAcDefinition(any()); verify(acDefinitionProvider).updateAcDefinitionElement(any(), any()); verify(acDefinitionProvider).updateAcDefinitionState(acDefinition.getCompositionId(), AcTypeState.PRIMING, - StateChangeResult.FAILED, null); - } - - @Test - void testParticipantPrimeAckRestarted() { - var participantPrimeAckMessage = new ParticipantPrimeAck(); - participantPrimeAckMessage.setParticipantId(CommonTestData.getParticipantId()); - participantPrimeAckMessage.setCompositionState(AcTypeState.PRIMED); - participantPrimeAckMessage.setState(ParticipantState.ON_LINE); - - var acDefinition = CommonTestData.createAcDefinition( - InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.PRIMED); - acDefinition.setStateChangeResult(StateChangeResult.TIMEOUT); - acDefinition.setRestarting(true); - participantPrimeAckMessage.setCompositionId(acDefinition.getCompositionId()); - for (var element : acDefinition.getElementStateMap().values()) { - element.setParticipantId(CommonTestData.getParticipantId()); - element.setRestarting(true); - } - - var acDefinitionProvider = mock(AcDefinitionProvider.class); - when(acDefinitionProvider.findAcDefinition(acDefinition.getCompositionId())) - .thenReturn(Optional.of(acDefinition)); - - var handler = new SupervisionHandler(acDefinitionProvider, CommonTestData.getTestParamaterGroup()); - - handler.handleParticipantMessage(participantPrimeAckMessage); - verify(acDefinitionProvider).findAcDefinition(any()); - verify(acDefinitionProvider, times(acDefinition.getElementStateMap().size())) - .updateAcDefinitionElement(any(), any()); - verify(acDefinitionProvider).updateAcDefinitionState(acDefinition.getCompositionId(), AcTypeState.PRIMED, - StateChangeResult.NO_ERROR, null); + StateChangeResult.FAILED); } } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandlerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandlerTest.java index 41f1c9c31..aab1a1ceb 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandlerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandlerTest.java @@ -23,6 +23,7 @@ package org.onap.policy.clamp.acm.runtime.supervision; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -36,7 +37,7 @@ import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils; import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantDeregisterAckPublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantRegisterAckPublisher; -import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantRestartPublisher; +import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher; import org.onap.policy.clamp.acm.runtime.util.CommonTestData; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; @@ -45,6 +46,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionInfo; import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState; import org.onap.policy.clamp.models.acm.concepts.Participant; import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; +import org.onap.policy.clamp.models.acm.concepts.ParticipantReplica; import org.onap.policy.clamp.models.acm.concepts.ParticipantState; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantDeregister; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRegister; @@ -60,25 +62,26 @@ class SupervisionParticipantHandlerTest { @Test void testHandleParticipantDeregister() { - var participant = CommonTestData.createParticipant(CommonTestData.getParticipantId()); + var replica = CommonTestData.createParticipantReplica(CommonTestData.getReplicaId()); var participantProvider = mock(ParticipantProvider.class); - when(participantProvider.findParticipant(CommonTestData.getParticipantId())) - .thenReturn(Optional.of(participant)); + when(participantProvider.findParticipantReplica(replica.getReplicaId())) + .thenReturn(Optional.of(replica)); var participantDeregisterMessage = new ParticipantDeregister(); participantDeregisterMessage.setMessageId(UUID.randomUUID()); participantDeregisterMessage.setParticipantId(CommonTestData.getParticipantId()); + participantDeregisterMessage.setReplicaId(replica.getReplicaId()); var participantDeregisterAckPublisher = mock(ParticipantDeregisterAckPublisher.class); var handler = new SupervisionParticipantHandler(participantProvider, mock(ParticipantRegisterAckPublisher.class), participantDeregisterAckPublisher, mock(AutomationCompositionProvider.class), - mock(AcDefinitionProvider.class), mock(ParticipantRestartPublisher.class), + mock(AcDefinitionProvider.class), mock(ParticipantSyncPublisher.class), mock(AcRuntimeParameterGroup.class)); handler.handleParticipantMessage(participantDeregisterMessage); - verify(participantProvider).updateParticipant(any()); + verify(participantProvider).deleteParticipantReplica(CommonTestData.getReplicaId()); verify(participantDeregisterAckPublisher).send(participantDeregisterMessage.getMessageId()); } @@ -94,28 +97,34 @@ class SupervisionParticipantHandlerTest { var participantRegisterAckPublisher = mock(ParticipantRegisterAckPublisher.class); var handler = new SupervisionParticipantHandler(participantProvider, participantRegisterAckPublisher, mock(ParticipantDeregisterAckPublisher.class), mock(AutomationCompositionProvider.class), - mock(AcDefinitionProvider.class), mock(ParticipantRestartPublisher.class), + mock(AcDefinitionProvider.class), mock(ParticipantSyncPublisher.class), mock(AcRuntimeParameterGroup.class)); handler.handleParticipantMessage(participantRegisterMessage); verify(participantProvider).saveParticipant(any()); verify(participantRegisterAckPublisher).send(participantRegisterMessage.getMessageId(), - CommonTestData.getParticipantId()); + CommonTestData.getParticipantId(), null); } @Test - void testHandleParticipantRestart() { + void testHandleParticipantSyncRestart() { var participantRegisterMessage = new ParticipantRegister(); participantRegisterMessage.setMessageId(UUID.randomUUID()); var participantId = CommonTestData.getParticipantId(); participantRegisterMessage.setParticipantId(participantId); + var replicaId = CommonTestData.getReplicaId(); + participantRegisterMessage.setReplicaId(replicaId); var supportedElementType = CommonTestData.createParticipantSupportedElementType(); participantRegisterMessage.setParticipantSupportedElementType(List.of(supportedElementType)); var participant = new Participant(); + var replica = new ParticipantReplica(); + replica.setReplicaId(replicaId); participant.setParticipantId(participantId); + participant.getReplicas().put(replica.getReplicaId(), replica); var participantProvider = mock(ParticipantProvider.class); when(participantProvider.findParticipant(participantId)).thenReturn(Optional.of(participant)); + when(participantProvider.findParticipantReplica(replicaId)).thenReturn(Optional.of(replica)); var compositionId = UUID.randomUUID(); var composition2Id = UUID.randomUUID(); when(participantProvider.getCompositionIds(participantId)).thenReturn(Set.of(compositionId, composition2Id)); @@ -142,16 +151,18 @@ class SupervisionParticipantHandlerTest { .thenReturn(List.of(automationComposition)); var participantRegisterAckPublisher = mock(ParticipantRegisterAckPublisher.class); - var participantRestartPublisher = mock(ParticipantRestartPublisher.class); + var participantSyncPublisher = mock(ParticipantSyncPublisher.class); var handler = new SupervisionParticipantHandler(participantProvider, participantRegisterAckPublisher, mock(ParticipantDeregisterAckPublisher.class), automationCompositionProvider, acDefinitionProvider, - participantRestartPublisher, CommonTestData.getTestParamaterGroup()); + participantSyncPublisher, CommonTestData.getTestParamaterGroup()); handler.handleParticipantMessage(participantRegisterMessage); - verify(participantRegisterAckPublisher).send(participantRegisterMessage.getMessageId(), participantId); - verify(acDefinitionProvider).updateAcDefinition(any(AutomationCompositionDefinition.class), + verify(participantRegisterAckPublisher) + .send(participantRegisterMessage.getMessageId(), participantId, replicaId); + verify(acDefinitionProvider, times(0)).updateAcDefinition(any(AutomationCompositionDefinition.class), eq(CommonTestData.TOSCA_COMP_NAME)); - verify(participantRestartPublisher).send(any(), any(AutomationCompositionDefinition.class), any()); + verify(participantSyncPublisher) + .sendRestartMsg(any(), any(), any(AutomationCompositionDefinition.class), any()); } @Test @@ -164,7 +175,7 @@ class SupervisionParticipantHandlerTest { var handler = new SupervisionParticipantHandler(participantProvider, mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class), automationCompositionProvider, - mock(AcDefinitionProvider.class), mock(ParticipantRestartPublisher.class), + mock(AcDefinitionProvider.class), mock(ParticipantSyncPublisher.class), mock(AcRuntimeParameterGroup.class)); var participant = CommonTestData.createParticipant(CommonTestData.getParticipantId()); when(participantProvider.findParticipant(CommonTestData.getParticipantId())) @@ -200,8 +211,8 @@ class SupervisionParticipantHandlerTest { var handler = new SupervisionParticipantHandler(participantProvider, mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class), mock(AutomationCompositionProvider.class), - acDefinitionProvider, mock(ParticipantRestartPublisher.class), - CommonTestData.getTestParamaterGroup()); + acDefinitionProvider, mock(ParticipantSyncPublisher.class), + CommonTestData.getTestParamaterGroup()); handler.handleParticipantMessage(participantStatusMessage); verify(acDefinitionProvider).updateAcDefinition(acDefinition, CommonTestData.TOSCA_COMP_NAME); @@ -217,7 +228,7 @@ class SupervisionParticipantHandlerTest { var handler = new SupervisionParticipantHandler(participantProvider, mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class), automationCompositionProvider, - mock(AcDefinitionProvider.class), mock(ParticipantRestartPublisher.class), + mock(AcDefinitionProvider.class), mock(ParticipantSyncPublisher.class), mock(AcRuntimeParameterGroup.class)); handler.handleParticipantMessage(participantStatusMessage); @@ -235,10 +246,9 @@ class SupervisionParticipantHandlerTest { var handler = new SupervisionParticipantHandler(participantProvider, mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class), automationCompositionProvider, - mock(AcDefinitionProvider.class), mock(ParticipantRestartPublisher.class), + mock(AcDefinitionProvider.class), mock(ParticipantSyncPublisher.class), mock(AcRuntimeParameterGroup.class)); var participant = CommonTestData.createParticipant(CommonTestData.getParticipantId()); - participant.setParticipantState(ParticipantState.OFF_LINE); when(participantProvider.findParticipant(CommonTestData.getParticipantId())) .thenReturn(Optional.of(participant)); handler.handleParticipantMessage(participantStatusMessage); diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantScannerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantScannerTest.java index 3c9f91785..0ae1c1a06 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantScannerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantScannerTest.java @@ -29,28 +29,26 @@ import static org.mockito.Mockito.when; import java.util.List; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.runtime.util.CommonTestData; -import org.onap.policy.clamp.models.acm.concepts.ParticipantState; import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider; class SupervisionParticipantScannerTest { @Test void testScanParticipant() { - var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanParticipant"); - acRuntimeParameterGroup.getParticipantParameters().setMaxStatusWaitMs(-1); - - var participant = CommonTestData.createParticipant(CommonTestData.getParticipantId()); var participantProvider = mock(ParticipantProvider.class); - when(participantProvider.getParticipants()).thenReturn(List.of(participant)); + var replica = CommonTestData.createParticipantReplica(CommonTestData.getReplicaId()); + when(participantProvider.findReplicasOnLine()).thenReturn(List.of(replica)); - var supervisionScanner = new SupervisionPartecipantScanner(participantProvider, acRuntimeParameterGroup); + var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanParticipant"); + var supervisionScanner = new SupervisionParticipantScanner(participantProvider, acRuntimeParameterGroup); - participant.setParticipantState(ParticipantState.OFF_LINE); + acRuntimeParameterGroup.getParticipantParameters().setMaxStatusWaitMs(100000); supervisionScanner.run(); - verify(participantProvider, times(0)).updateParticipant(any()); + verify(participantProvider, times(0)).saveParticipantReplica(any()); - participant.setParticipantState(ParticipantState.ON_LINE); + acRuntimeParameterGroup.getParticipantParameters().setMaxStatusWaitMs(-1); + supervisionScanner = new SupervisionParticipantScanner(participantProvider, acRuntimeParameterGroup); supervisionScanner.run(); - verify(participantProvider, times(1)).updateParticipant(any()); + verify(participantProvider).deleteParticipantReplica(CommonTestData.getReplicaId()); } } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java index d5163be14..5cefd5f09 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java @@ -35,10 +35,12 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.UUID; +import java.util.function.Consumer; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionDeployPublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher; +import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher; import org.onap.policy.clamp.acm.runtime.util.CommonTestData; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; @@ -48,6 +50,7 @@ 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.NodeTemplateState; 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.persistence.provider.AcDefinitionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; import org.onap.policy.clamp.models.acm.utils.TimestampHelper; @@ -56,6 +59,8 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; class SupervisionScannerTest { private static final String AC_JSON = "src/test/resources/rest/acm/AutomationCompositionSmoke.json"; + private static final String ELEMENT_NAME = + "org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement"; private static final UUID compositionId = UUID.randomUUID(); @@ -101,9 +106,9 @@ class SupervisionScannerTest { var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner"); var supervisionScanner = new SupervisionScanner(mock(AutomationCompositionProvider.class), acDefinitionProvider, mock(AutomationCompositionStateChangePublisher.class), mock(AutomationCompositionDeployPublisher.class), - acRuntimeParameterGroup); + mock(ParticipantSyncPublisher.class), null, acRuntimeParameterGroup); supervisionScanner.run(); - verify(acDefinitionProvider, times(0)).updateAcDefinitionState(any(), any(), any(), any()); + verify(acDefinitionProvider, times(0)).updateAcDefinitionState(any(), any(), any()); } @Test @@ -113,25 +118,25 @@ class SupervisionScannerTest { var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner"); var supervisionScanner = new SupervisionScanner(mock(AutomationCompositionProvider.class), acDefinitionProvider, mock(AutomationCompositionStateChangePublisher.class), mock(AutomationCompositionDeployPublisher.class), - acRuntimeParameterGroup); + mock(ParticipantSyncPublisher.class), null, acRuntimeParameterGroup); supervisionScanner.run(); // Ac Definition in Priming state - verify(acDefinitionProvider, times(0)).updateAcDefinitionState(any(), any(), any(), any()); + verify(acDefinitionProvider, times(0)).updateAcDefinitionState(any(), any(), any()); acRuntimeParameterGroup.getParticipantParameters().setMaxStatusWaitMs(-1); supervisionScanner = new SupervisionScanner(mock(AutomationCompositionProvider.class), acDefinitionProvider, mock(AutomationCompositionStateChangePublisher.class), mock(AutomationCompositionDeployPublisher.class), - acRuntimeParameterGroup); + mock(ParticipantSyncPublisher.class), null, acRuntimeParameterGroup); supervisionScanner.run(); // set Timeout verify(acDefinitionProvider).updateAcDefinitionState(acDefinition.getCompositionId(), acDefinition.getState(), - StateChangeResult.TIMEOUT, null); + StateChangeResult.TIMEOUT); clearInvocations(acDefinitionProvider); acDefinition.setStateChangeResult(StateChangeResult.TIMEOUT); supervisionScanner.run(); // already in Timeout - verify(acDefinitionProvider, times(0)).updateAcDefinitionState(any(), any(), any(), any()); + verify(acDefinitionProvider, times(0)).updateAcDefinitionState(any(), any(), any()); clearInvocations(acDefinitionProvider); // retry by the user @@ -139,7 +144,7 @@ class SupervisionScannerTest { supervisionScanner.run(); // set Timeout verify(acDefinitionProvider).updateAcDefinitionState(acDefinition.getCompositionId(), acDefinition.getState(), - StateChangeResult.TIMEOUT, null); + StateChangeResult.TIMEOUT); clearInvocations(acDefinitionProvider); for (var element : acDefinition.getElementStateMap().values()) { @@ -148,7 +153,7 @@ class SupervisionScannerTest { supervisionScanner.run(); // completed verify(acDefinitionProvider).updateAcDefinitionState(acDefinition.getCompositionId(), AcTypeState.PRIMED, - StateChangeResult.NO_ERROR, null); + StateChangeResult.NO_ERROR); } @Test @@ -164,7 +169,7 @@ class SupervisionScannerTest { var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(), automationCompositionStateChangePublisher, automationCompositionDeployPublisher, - acRuntimeParameterGroup); + mock(ParticipantSyncPublisher.class), null, acRuntimeParameterGroup); // not in transition supervisionScanner.run(); @@ -185,6 +190,7 @@ class SupervisionScannerTest { automationComposition.setCompositionId(compositionId); var automationCompositionProvider = mock(AutomationCompositionProvider.class); when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition)); + when(automationCompositionProvider.updateAcState(any())).thenReturn(automationComposition); var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class); var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); @@ -192,10 +198,10 @@ class SupervisionScannerTest { var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(), automationCompositionStateChangePublisher, automationCompositionDeployPublisher, - acRuntimeParameterGroup); + mock(ParticipantSyncPublisher.class), null, acRuntimeParameterGroup); supervisionScanner.run(); - verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class)); + verify(automationCompositionProvider).updateAcState(any(AutomationComposition.class)); } @Test @@ -213,7 +219,7 @@ class SupervisionScannerTest { var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(), automationCompositionStateChangePublisher, automationCompositionDeployPublisher, - acRuntimeParameterGroup); + mock(ParticipantSyncPublisher.class), null, acRuntimeParameterGroup); supervisionScanner.run(); verify(automationCompositionProvider).deleteAutomationComposition(automationComposition.getInstanceId()); @@ -232,7 +238,7 @@ class SupervisionScannerTest { var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(), automationCompositionStateChangePublisher, automationCompositionDeployPublisher, - acRuntimeParameterGroup); + mock(ParticipantSyncPublisher.class), null, acRuntimeParameterGroup); supervisionScanner.run(); verify(automationCompositionProvider, times(0)).updateAutomationComposition(any(AutomationComposition.class)); @@ -254,7 +260,7 @@ class SupervisionScannerTest { var automationCompositionProvider = mock(AutomationCompositionProvider.class); when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition)); - + when(automationCompositionProvider.updateAcState(any())).thenReturn(automationComposition); var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class); var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner"); @@ -263,12 +269,12 @@ class SupervisionScannerTest { // verify timeout scenario var scannerObj2 = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(), automationCompositionStateChangePublisher, automationCompositionDeployPublisher, - acRuntimeParameterGroup); + mock(ParticipantSyncPublisher.class), null, acRuntimeParameterGroup); automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); automationComposition.setLastMsg(TimestampHelper.now()); scannerObj2.run(); - verify(automationCompositionProvider, times(1)).updateAutomationComposition(any(AutomationComposition.class)); + verify(automationCompositionProvider, times(1)).updateAcState(any(AutomationComposition.class)); assertEquals(StateChangeResult.TIMEOUT, automationComposition.getStateChangeResult()); //already in TIMEOUT @@ -281,7 +287,7 @@ class SupervisionScannerTest { entry.getValue().setDeployState(DeployState.DEPLOYED); } scannerObj2.run(); - verify(automationCompositionProvider, times(1)).updateAutomationComposition(any(AutomationComposition.class)); + verify(automationCompositionProvider, times(1)).updateAcState(any(AutomationComposition.class)); assertEquals(StateChangeResult.NO_ERROR, automationComposition.getStateChangeResult()); } @@ -293,8 +299,7 @@ class SupervisionScannerTest { automationComposition.setPhase(0); automationComposition.setCompositionId(compositionId); for (var element : automationComposition.getElements().values()) { - if ("org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement" - .equals(element.getDefinition().getName())) { + if (ELEMENT_NAME.equals(element.getDefinition().getName())) { element.setDeployState(DeployState.DEPLOYING); element.setLockState(LockState.NONE); } else { @@ -312,7 +317,7 @@ class SupervisionScannerTest { var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(), automationCompositionStateChangePublisher, automationCompositionDeployPublisher, - acRuntimeParameterGroup); + mock(ParticipantSyncPublisher.class), null, acRuntimeParameterGroup); supervisionScanner.run(); @@ -340,14 +345,20 @@ class SupervisionScannerTest { var automationCompositionProvider = mock(AutomationCompositionProvider.class); when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition)); + when(automationCompositionProvider.updateAcState(any())).thenReturn(automationComposition); var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class); var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner"); - var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(), + var definitionTarget = createAutomationCompositionDefinition(AcTypeState.PRIMED, StateChangeResult.NO_ERROR); + definitionTarget.setCompositionId(compositionTargetId); + var acDefinitionProvider = createAcDefinitionProvider(); + when(acDefinitionProvider.getAcDefinition(compositionTargetId)).thenReturn(definitionTarget); + + var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider, automationCompositionStateChangePublisher, automationCompositionDeployPublisher, - acRuntimeParameterGroup); + mock(ParticipantSyncPublisher.class), null, acRuntimeParameterGroup); supervisionScanner.run(); verify(automationCompositionProvider, times(0)).updateAutomationComposition(any(AutomationComposition.class)); @@ -357,13 +368,100 @@ class SupervisionScannerTest { automationComposition.getElements().entrySet().iterator().next().getValue() .setDeployState(DeployState.DEPLOYED); supervisionScanner.run(); - verify(automationCompositionProvider, times(1)).updateAutomationComposition(any(AutomationComposition.class)); + verify(automationCompositionProvider, times(1)).updateAcState(any(AutomationComposition.class)); assertEquals(DeployState.DEPLOYED, automationComposition.getDeployState()); assertEquals(compositionTargetId, automationComposition.getCompositionId()); } @Test + void testSendAutomationCompositionUpdate() { + var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud"); + automationComposition.setLockState(LockState.LOCKED); + automationComposition.setDeployState(DeployState.UPDATING); + for (var element : automationComposition.getElements().values()) { + element.setSubState(SubState.NONE); + element.setLockState(LockState.LOCKED); + if (ELEMENT_NAME.equals(element.getDefinition().getName())) { + element.setDeployState(DeployState.UPDATING); + } else { + element.setDeployState(DeployState.DEPLOYED); + } + } + testSimpleScan(automationComposition, element -> element.setDeployState(DeployState.DEPLOYED)); + } + + @Test + void testSendAutomationCompositionMigratingPrecheck() { + var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud"); + automationComposition.setLockState(LockState.LOCKED); + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setSubState(SubState.MIGRATION_PRECHECKING); + for (var element : automationComposition.getElements().values()) { + element.setDeployState(DeployState.DEPLOYED); + element.setSubState(SubState.NONE); + element.setLockState(LockState.LOCKED); + if (ELEMENT_NAME.equals(element.getDefinition().getName())) { + element.setSubState(SubState.MIGRATION_PRECHECKING); + } + } + testSimpleScan(automationComposition, element -> element.setSubState(SubState.NONE)); + } + + @Test + void testSendAutomationCompositionPrepare() { + var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud"); + automationComposition.setLockState(LockState.NONE); + automationComposition.setDeployState(DeployState.UNDEPLOYED); + automationComposition.setSubState(SubState.PREPARING); + for (var element : automationComposition.getElements().values()) { + element.setDeployState(DeployState.UNDEPLOYED); + element.setSubState(SubState.NONE); + element.setLockState(LockState.NONE); + if (ELEMENT_NAME.equals(element.getDefinition().getName())) { + element.setSubState(SubState.PREPARING); + } + } + testSimpleScan(automationComposition, element -> element.setSubState(SubState.NONE)); + } + + @Test + void testSendAutomationCompositionReview() { + var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud"); + automationComposition.setLockState(LockState.LOCKED); + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setSubState(SubState.REVIEWING); + for (var element : automationComposition.getElements().values()) { + element.setDeployState(DeployState.DEPLOYED); + element.setSubState(SubState.NONE); + element.setLockState(LockState.LOCKED); + if (ELEMENT_NAME.equals(element.getDefinition().getName())) { + element.setSubState(SubState.REVIEWING); + } + } + testSimpleScan(automationComposition, element -> element.setSubState(SubState.NONE)); + } + + private void testSimpleScan(AutomationComposition automationComposition, Consumer<AutomationCompositionElement> c) { + automationComposition.setLockState(LockState.NONE); + automationComposition.setCompositionId(compositionId); + automationComposition.setLastMsg(TimestampHelper.now()); + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition)); + + var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner"); + var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(), + null, null, + mock(ParticipantSyncPublisher.class), null, acRuntimeParameterGroup); + supervisionScanner.run(); + verify(automationCompositionProvider, times(0)).updateAcState(any()); + + automationComposition.getElements().values().forEach(c); + supervisionScanner.run(); + verify(automationCompositionProvider).updateAcState(any()); + } + + @Test void testSendAutomationCompositionMsgUnlocking() { var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud"); automationComposition.setDeployState(DeployState.DEPLOYED); @@ -371,8 +469,7 @@ class SupervisionScannerTest { automationComposition.setCompositionId(compositionId); automationComposition.setPhase(0); for (var element : automationComposition.getElements().values()) { - if ("org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement" - .equals(element.getDefinition().getName())) { + if (ELEMENT_NAME.equals(element.getDefinition().getName())) { element.setDeployState(DeployState.DEPLOYED); element.setLockState(LockState.UNLOCKING); } else { @@ -390,7 +487,7 @@ class SupervisionScannerTest { var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(), automationCompositionStateChangePublisher, automationCompositionDeployPublisher, - acRuntimeParameterGroup); + mock(ParticipantSyncPublisher.class), null, acRuntimeParameterGroup); supervisionScanner.run(); diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java index 31cd659b3..a1ef9b4e2 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java @@ -28,7 +28,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.onap.policy.clamp.acm.runtime.util.CommonTestData.TOSCA_SERVICE_TEMPLATE_YAML; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -36,8 +35,6 @@ import java.util.UUID; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils; import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; -import org.onap.policy.clamp.acm.runtime.main.parameters.Topics; -import org.onap.policy.clamp.acm.runtime.participants.AcmParticipantProvider; import org.onap.policy.clamp.acm.runtime.supervision.SupervisionAcHandler; import org.onap.policy.clamp.acm.runtime.supervision.SupervisionHandler; import org.onap.policy.clamp.acm.runtime.supervision.SupervisionParticipantHandler; @@ -107,6 +104,7 @@ class SupervisionMessagesTest { acDeregisterAckPublisher.stop(); } + @Test void testSendParticipantDeregisterAckNoActive() { var acDeregisterAckPublisher = new ParticipantDeregisterAckPublisher(); assertThatThrownBy(() -> acDeregisterAckPublisher.send(new ParticipantDeregisterAck())) @@ -150,7 +148,7 @@ class SupervisionMessagesTest { @Test void testParticipantPrimePublisherDecommissioning() { var publisher = new ParticipantPrimePublisher(mock(ParticipantProvider.class), - mock(AcmParticipantProvider.class), mock(AcRuntimeParameterGroup.class)); + mock(AcRuntimeParameterGroup.class)); var topicSink = mock(TopicSink.class); publisher.active(topicSink); publisher.sendDepriming(UUID.randomUUID()); @@ -171,8 +169,7 @@ class SupervisionMessagesTest { participantId); var participantProvider = mock(ParticipantProvider.class); when(participantProvider.getSupportedElementMap()).thenReturn(supportedElementMap); - var publisher = new ParticipantPrimePublisher(participantProvider, mock(AcmParticipantProvider.class), - CommonTestData.getTestParamaterGroup()); + var publisher = new ParticipantPrimePublisher(participantProvider, CommonTestData.getTestParamaterGroup()); var topicSink = mock(TopicSink.class); publisher.active(topicSink); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); @@ -203,7 +200,7 @@ class SupervisionMessagesTest { var publisher = new ParticipantRegisterAckPublisher(); var topicSink = mock(TopicSink.class); publisher.active(topicSink); - publisher.send(UUID.randomUUID(), CommonTestData.getParticipantId()); + publisher.send(UUID.randomUUID(), CommonTestData.getParticipantId(), CommonTestData.getReplicaId()); verify(topicSink).send(anyString()); } @@ -234,58 +231,97 @@ class SupervisionMessagesTest { publisher.active(topicSink); var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); - publisher.send(automationComposition, UUID.randomUUID()); + publisher.send(automationComposition, 0); verify(topicSink).send(anyString()); } @Test - void testParticipantRestartPublisher() { - var publisher = new ParticipantRestartPublisher(CommonTestData.getTestParamaterGroup()); + void testAcPreparePublisher() { + var publisher = new AcPreparePublisher(); var topicSink = mock(TopicSink.class); publisher.active(topicSink); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); + publisher.sendPrepare(automationComposition); + verify(topicSink).send(anyString()); + } - var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); - var acmDefinition = new AutomationCompositionDefinition(); - acmDefinition.setCompositionId(UUID.randomUUID()); - acmDefinition.setServiceTemplate(serviceTemplate); - var acElements = AcmUtils - .extractAcElementsFromServiceTemplate(serviceTemplate, ""); - acmDefinition.setElementStateMap(AcmUtils.createElementStateMap(acElements, AcTypeState.PRIMED)); + @Test + void testAcReviewPublisher() { + var publisher = new AcPreparePublisher(); + var topicSink = mock(TopicSink.class); + publisher.active(topicSink); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); + publisher.sendRevew(automationComposition); + verify(topicSink).send(anyString()); + } + + @Test + void testParticipantSyncPublisherAutomationComposition() { + var publisher = new ParticipantSyncPublisher(CommonTestData.getTestParamaterGroup()); + var topicSink = mock(TopicSink.class); + publisher.active(topicSink); + var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); + publisher.sendSync(serviceTemplate, automationComposition); + verify(topicSink).send(anyString()); + } - var participantId = automationComposition.getElements().values().iterator().next().getParticipantId(); - acmDefinition.getElementStateMap().values().iterator().next().setParticipantId(participantId); + @Test + void testParticipantSyncPublisherAcDefinition() { + var publisher = new ParticipantSyncPublisher(CommonTestData.getTestParamaterGroup()); + var topicSink = mock(TopicSink.class); + publisher.active(topicSink); - publisher.send(participantId, acmDefinition, List.of(automationComposition)); + var acmDefinition = getAcmDefinition(); + publisher.sendSync(acmDefinition, null); verify(topicSink).send(anyString()); } @Test - void testParticipantSyncPublisher() { + void testParticipantSyncPublisherAcDefinitionCommissioned() { var publisher = new ParticipantSyncPublisher(CommonTestData.getTestParamaterGroup()); var topicSink = mock(TopicSink.class); publisher.active(topicSink); - var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); - var acmDefinition = new AutomationCompositionDefinition(); - acmDefinition.setCompositionId(UUID.randomUUID()); - acmDefinition.setServiceTemplate(serviceTemplate); - var acElements = AcmUtils - .extractAcElementsFromServiceTemplate(serviceTemplate, ""); - acmDefinition.setElementStateMap(AcmUtils.createElementStateMap(acElements, AcTypeState.PRIMED)); + var acmDefinition = getAcmDefinition(); + acmDefinition.setState(AcTypeState.COMMISSIONED); + publisher.sendSync(acmDefinition, UUID.randomUUID()); + verify(topicSink).send(anyString()); + } + + @Test + void testParticipantSyncPublisherRestart() { + var publisher = new ParticipantSyncPublisher(CommonTestData.getTestParamaterGroup()); + var topicSink = mock(TopicSink.class); + publisher.active(topicSink); var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); - var participantId = automationComposition.getElements().values().iterator().next().getParticipantId(); + var acmDefinition = getAcmDefinition(); acmDefinition.getElementStateMap().values().iterator().next().setParticipantId(participantId); - - publisher.send(participantId, acmDefinition, List.of(automationComposition)); + var replicaId = UUID.randomUUID(); + publisher.sendRestartMsg(participantId, replicaId, acmDefinition, List.of(automationComposition)); verify(topicSink).send(anyString()); } + private AutomationCompositionDefinition getAcmDefinition() { + var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); + var acmDefinition = new AutomationCompositionDefinition(); + acmDefinition.setCompositionId(UUID.randomUUID()); + acmDefinition.setState(AcTypeState.PRIMED); + acmDefinition.setServiceTemplate(serviceTemplate); + var acElements = AcmUtils + .extractAcElementsFromServiceTemplate(serviceTemplate, TOSCA_ELEMENT_NAME); + acmDefinition.setElementStateMap(AcmUtils.createElementStateMap(acElements, AcTypeState.PRIMED)); + acmDefinition.getElementStateMap().values().forEach(element -> element.setParticipantId(UUID.randomUUID())); + return acmDefinition; + } + @Test void testParticipantRegisterListener() { final var participantRegister = new ParticipantRegister(); diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/CommonTestData.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/CommonTestData.java index e031e0f5a..c3b5ff919 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/CommonTestData.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/CommonTestData.java @@ -28,6 +28,7 @@ import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeEx import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; import org.onap.policy.clamp.models.acm.concepts.Participant; +import org.onap.policy.clamp.models.acm.concepts.ParticipantReplica; import org.onap.policy.clamp.models.acm.concepts.ParticipantState; import org.onap.policy.clamp.models.acm.concepts.ParticipantSupportedElementType; import org.onap.policy.clamp.models.acm.utils.AcmUtils; @@ -88,12 +89,24 @@ public class CommonTestData { public static Participant createParticipant(UUID participantId) { var participant = new Participant(); participant.setParticipantId(participantId); - participant.setParticipantState(ParticipantState.ON_LINE); - participant.setLastMsg(TimestampHelper.now()); return participant; } /** + * Create a new ParticipantReplica. + * + * @param replicaId the replica id + * @return a new ParticipantReplica + */ + public static ParticipantReplica createParticipantReplica(UUID replicaId) { + var replica = new ParticipantReplica(); + replica.setReplicaId(replicaId); + replica.setParticipantState(ParticipantState.ON_LINE); + replica.setLastMsg(TimestampHelper.now()); + return replica; + } + + /** * Create a new ParticipantSupportedElementType. * * @return a new ParticipantSupportedElementType @@ -105,6 +118,10 @@ public class CommonTestData { return supportedElementType; } + public static UUID getReplicaId() { + return UUID.fromString("201c62b3-8918-41b9-a747-d21eb79c6c09"); + } + public static UUID getParticipantId() { return UUID.fromString("101c62b3-8918-41b9-a747-d21eb79c6c03"); } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/rest/CommonRestController.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/rest/CommonRestController.java index 0df9719c2..9c765e1b3 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/rest/CommonRestController.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/rest/CommonRestController.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation. + * Copyright (C) 2021-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. @@ -23,6 +23,7 @@ package org.onap.policy.clamp.acm.runtime.util.rest; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; +import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation; @@ -45,6 +46,7 @@ public class CommonRestController { public static final String ACTUATOR_ENDPOINT = CONTEXT_PATH + "/"; private static String httpPrefix; + protected Client client; /** * Verifies that an endpoint appears within the swagger response. @@ -52,7 +54,7 @@ public class CommonRestController { * @param endpoint the endpoint of interest */ protected void testSwagger(final String endpoint) { - final var invocationBuilder = sendActRequest("v3/api-docs"); + final var invocationBuilder = sendActRequest(); final var resp = invocationBuilder.get(String.class); assertThat(resp).contains(endpoint); @@ -71,15 +73,14 @@ public class CommonRestController { /** * Sends a request to an actuator endpoint. * - * @param endpoint the target endpoint * @return a request builder */ - protected Invocation.Builder sendActRequest(final String endpoint) { - return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, true); + protected Invocation.Builder sendActRequest() { + return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + "v3/api-docs", true); } /** - * Sends a request to an Rest Api endpoint, without any authorization header. + * Sends a request to a Rest Api endpoint, without any authorization header. * * @param endpoint the target endpoint * @return a request builder @@ -89,16 +90,6 @@ public class CommonRestController { } /** - * Sends a request to an actuator endpoint, without any authorization header. - * - * @param endpoint the target endpoint - * @return a request builder - */ - protected Invocation.Builder sendNoAuthActRequest(final String endpoint) { - return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, false); - } - - /** * Sends a request to a fully qualified endpoint. * * @param fullyQualifiedEndpoint the fully qualified target endpoint @@ -106,7 +97,7 @@ public class CommonRestController { * @return a request builder */ protected Invocation.Builder sendFqeRequest(final String fullyQualifiedEndpoint, boolean includeAuth) { - final var client = ClientBuilder.newBuilder().build(); + client = ClientBuilder.newBuilder().build(); client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); client.register(GsonMessageBodyHandler.class); @@ -124,11 +115,12 @@ public class CommonRestController { * Assert that POST call is Unauthorized. * * @param endPoint the endpoint - * @param entity the entity ofthe body + * @param entity the entity of the body */ protected void assertUnauthorizedPost(final String endPoint, final Entity<?> entity) { var rawresp = sendNoAuthRequest(endPoint).post(entity); assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); + rawresp.close(); } /** @@ -140,6 +132,7 @@ public class CommonRestController { protected void assertUnauthorizedPut(final String endPoint, final Entity<?> entity) { var rawresp = sendNoAuthRequest(endPoint).put(entity); assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); + rawresp.close(); } /** @@ -150,16 +143,7 @@ public class CommonRestController { protected void assertUnauthorizedGet(final String endPoint) { var rawresp = sendNoAuthRequest(endPoint).buildGet().invoke(); assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); - } - - /** - * Assert that GET call to actuator endpoint is Unauthorized. - * - * @param endPoint the endpoint - */ - protected void assertUnauthorizedActGet(final String endPoint) { - var rawresp = sendNoAuthActRequest(endPoint).buildGet().invoke(); - assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); + rawresp.close(); } /** @@ -170,6 +154,7 @@ public class CommonRestController { protected void assertUnauthorizedDelete(final String endPoint) { var rawresp = sendNoAuthRequest(endPoint).delete(); assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); + rawresp.close(); } /** @@ -181,7 +166,4 @@ public class CommonRestController { httpPrefix = "http://" + SELF + ":" + port + "/"; } - protected String getHttpPrefix() { - return httpPrefix; - } } diff --git a/runtime-acm/src/test/resources/application-prometheus-noauth.yaml b/runtime-acm/src/test/resources/application-prometheus-noauth.yaml index 57da3af18..a75c5d36f 100644 --- a/runtime-acm/src/test/resources/application-prometheus-noauth.yaml +++ b/runtime-acm/src/test/resources/application-prometheus-noauth.yaml @@ -10,37 +10,6 @@ spring: ddl-auto: create open-in-view: false -server: - servlet: - context-path: /onap/policy/clamp/acm - -runtime: - topics: - operationTopic: policy-acruntime-participant - syncTopic: acm-ppnt-sync - participantParameters: - updateParameters: - maxRetryCount: 3 - topicParameterGroup: - topicSources: - - - topic: ${runtime.topics.operationTopic} - servers: - - localhost - topicCommInfrastructure: noop - fetchTimeout: 15000 - topicSinks: - - - topicCommInfrastructure: noop - servers: - - localhost - topic: ${runtime.topics.operationTopic} - - - topic: ${runtime.topics.syncTopic} - servers: - - ${topicServer:kafka:9092} - topicCommInfrastructure: noop - tracing: enabled: true exporter: diff --git a/runtime-acm/src/test/resources/application-test.yaml b/runtime-acm/src/test/resources/application-test.yaml index 31e54737e..e3d4a48df 100644 --- a/runtime-acm/src/test/resources/application-test.yaml +++ b/runtime-acm/src/test/resources/application-test.yaml @@ -7,60 +7,5 @@ spring: maximumPoolSize: 3 jpa: hibernate: - ddl-auto: create + ddl-auto: create-drop open-in-view: false - -server: - servlet: - context-path: /onap/policy/clamp/acm - -runtime: - topics: - operationTopic: policy-acruntime-participant - syncTopic: acm-ppnt-sync - participantParameters: - updateParameters: - maxRetryCount: 3 - topicParameterGroup: - topicSources: - - - topic: ${runtime.topics.operationTopic} - servers: - - kafka:9092 - topicCommInfrastructure: NOOP - fetchTimeout: 15000 - topicSinks: - - - topicCommInfrastructure: NOOP - servers: - - kafka:9092 - topic: ${runtime.topics.operationTopic} - - - topic: ${runtime.topics.syncTopic} - servers: - - ${topicServer:kafka:9092} - topicCommInfrastructure: NOOP - acmParameters: - acElementName: org.onap.policy.clamp.acm.AutomationCompositionElement - acNodeType: org.onap.policy.clamp.acm.AutomationComposition - -management: - endpoints: - web: - base-path: / - exposure: - include: health, metrics, prometheus - tracing: - propagation: - produce: b3 - sampling: - probability: 1.0 - -tracing: - enabled: true - exporter: - endpoint: http://jaeger:4317 - protocol: grpc - sampler: - jaeger-remote: - endpoint: http://jaeger:14250
\ No newline at end of file diff --git a/runtime-acm/src/test/resources/application-tracing.yaml b/runtime-acm/src/test/resources/application-tracing.yaml new file mode 100644 index 000000000..d24fe9c53 --- /dev/null +++ b/runtime-acm/src/test/resources/application-tracing.yaml @@ -0,0 +1,27 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + driverClassName: org.h2.Driver + hikari: + maxLifetime: 1800000 + maximumPoolSize: 3 + jpa: + hibernate: + ddl-auto: create-drop + open-in-view: false + +management: + tracing: + propagation: + produce: b3 + sampling: + probability: 1.0 + +tracing: + enabled: true + exporter: + endpoint: http://jaeger:4317 + protocol: grpc + sampler: + jaeger-remote: + endpoint: http://jaeger:14250
\ No newline at end of file diff --git a/runtime-acm/src/test/resources/rest/acm/AutomationCompositionMigrate.json b/runtime-acm/src/test/resources/rest/acm/AutomationCompositionMigrate.json new file mode 100644 index 000000000..d74970d4f --- /dev/null +++ b/runtime-acm/src/test/resources/rest/acm/AutomationCompositionMigrate.json @@ -0,0 +1,30 @@ +{ + "name": "PMSHInstance1", + "version": "1.0.1", + "compositionId": "709c62b3-8918-41b9-a747-d21eb79c6c40", + "deployState": "DEPLOYED", + "lockState": "LOCKED", + "description": "PMSH automation composition instance 0", + "elements": { + "709c62b3-8918-41b9-a747-d21eb79c6c21": { + "id": "709c62b3-8918-41b9-a747-d21eb79c6c21", + "definition": { + "name": "org.onap.domain.database.PMSH_K8SMicroserviceAutomationCompositionElement", + "version": "1.2.3" + }, + "deployState": "DEPLOYED", + "lockState": "LOCKED", + "description": "Automation composition element for the K8S microservice for PMSH" + }, + "709c62b3-8918-41b9-a747-d21eb79c6c22": { + "id": "709c62b3-8918-41b9-a747-d21eb79c6c22", + "definition": { + "name": "org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement", + "version": "1.2.3" + }, + "deployState": "DEPLOYED", + "lockState": "LOCKED", + "description": "Automation composition element for the operational policy for Performance Management Subscription Handling" + } + } +}
\ No newline at end of file diff --git a/runtime-acm/src/test/resources/testscripts/listenOnTopic.sh b/runtime-acm/src/test/resources/testscripts/listenOnTopic.sh deleted file mode 100755 index 5e661777b..000000000 --- a/runtime-acm/src/test/resources/testscripts/listenOnTopic.sh +++ /dev/null @@ -1,31 +0,0 @@ -#! /bin/bash -# ============LICENSE_START======================================================= -# Copyright (C) 2021 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========================================================= - -if [ $# -ne 1 ] -then - echo invalid parameters $*, specify a single parameter as the topic to listen on - exit 1 -fi - -while true -do - curl "http://localhost:3904/events/$1/TEST/1?timeout=60000" - echo "" -done - diff --git a/version.properties b/version.properties index d68ffcd49..8e64c4d15 100644 --- a/version.properties +++ b/version.properties @@ -27,7 +27,7 @@ major=8 minor=0 -patch=0 +patch=1 base_version=${major}.${minor}.${patch} |