From 7c6f474a643730190961f4671004bf1794962e3b Mon Sep 17 00:00:00 2001 From: FrancescoFioraEst Date: Mon, 8 Apr 2024 08:39:50 +0100 Subject: Refactor ACM participant-intermediary Refactor AutomationCompositionHandler to improve the maintainability. Issue-ID: POLICY-4959 Change-Id: Id112ade5b786d964d61021fe82689aa9512b4bc3 Signed-off-by: FrancescoFioraEst --- .../intermediary/handler/AcDefinitionHandler.java | 137 +++++++++++ .../intermediary/handler/AcLockHandler.java | 104 +++++++++ .../handler/AutomationCompositionHandler.java | 252 ++------------------- .../intermediary/handler/CacheProvider.java | 17 ++ .../intermediary/handler/ParticipantHandler.java | 44 +--- .../handler/AcDefinitionHandlerTest.java | 111 +++++++++ .../intermediary/handler/AcLockHandlerTest.java | 112 +++++++++ .../handler/AutomationCompositionHandlerTest.java | 129 ----------- .../intermediary/handler/CacheProviderTest.java | 21 ++ .../handler/ParticipantHandlerTest.java | 101 ++++----- .../main/parameters/CommonTestData.java | 23 +- 11 files changed, 589 insertions(+), 462 deletions(-) create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcDefinitionHandler.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java create mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcDefinitionHandlerTest.java create mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandlerTest.java 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 new file mode 100644 index 000000000..e1d4b0959 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcDefinitionHandler.java @@ -0,0 +1,137 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * 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.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; +import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher; +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.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.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class AcDefinitionHandler { + + private final CacheProvider cacheProvider; + private final ParticipantMessagePublisher publisher; + private final ThreadHandler listener; + + /** + * Handle a participant Prime message. + * + * @param participantPrimeMsg the ParticipantPrime message + */ + public void handlePrime(ParticipantPrime participantPrimeMsg) { + if (!participantPrimeMsg.getParticipantDefinitionUpdates().isEmpty()) { + // prime + List list = new ArrayList<>(); + for (var participantDefinition : participantPrimeMsg.getParticipantDefinitionUpdates()) { + if (participantDefinition.getParticipantId().equals(cacheProvider.getParticipantId())) { + list.addAll(participantDefinition.getAutomationCompositionElementDefinitionList()); + } + } + if (!list.isEmpty()) { + cacheProvider.addElementDefinition(participantPrimeMsg.getCompositionId(), list); + prime(participantPrimeMsg.getMessageId(), participantPrimeMsg.getCompositionId(), list); + } + } else { + // deprime + deprime(participantPrimeMsg.getMessageId(), participantPrimeMsg.getCompositionId()); + } + } + + private void prime(UUID messageId, UUID compositionId, List list) { + var inPropertiesMap = list.stream().collect(Collectors.toMap( + AutomationCompositionElementDefinition::getAcElementDefinitionId, + el -> el.getAutomationCompositionElementToscaNodeTemplate().getProperties())); + var outPropertiesMap = list.stream().collect(Collectors.toMap( + AutomationCompositionElementDefinition::getAcElementDefinitionId, + AutomationCompositionElementDefinition::getOutProperties)); + listener.prime(messageId, new CompositionDto(compositionId, inPropertiesMap, outPropertiesMap)); + } + + private void deprime(UUID messageId, UUID compositionId) { + var acElementsDefinitions = cacheProvider.getAcElementsDefinitions().get(compositionId); + if (acElementsDefinitions == null) { + // this participant does not handle this composition + var participantPrimeAck = new ParticipantPrimeAck(); + participantPrimeAck.setCompositionId(compositionId); + participantPrimeAck.setMessage("Already deprimed or never primed"); + participantPrimeAck.setResult(true); + participantPrimeAck.setResponseTo(messageId); + participantPrimeAck.setCompositionState(AcTypeState.COMMISSIONED); + participantPrimeAck.setStateChangeResult(StateChangeResult.NO_ERROR); + participantPrimeAck.setParticipantId(cacheProvider.getParticipantId()); + participantPrimeAck.setState(ParticipantState.ON_LINE); + publisher.sendParticipantPrimeAck(participantPrimeAck); + return; + } + var list = new ArrayList<>(acElementsDefinitions.values()); + var inPropertiesMap = list.stream().collect(Collectors.toMap( + AutomationCompositionElementDefinition::getAcElementDefinitionId, + el -> el.getAutomationCompositionElementToscaNodeTemplate().getProperties())); + var outPropertiesMap = list.stream().collect(Collectors.toMap( + AutomationCompositionElementDefinition::getAcElementDefinitionId, + AutomationCompositionElementDefinition::getOutProperties)); + listener.deprime(messageId, new CompositionDto(compositionId, inPropertiesMap, outPropertiesMap)); + } + + /** + * Handle a ParticipantRestart message. + * + * @param participantRestartMsg the participantRestart message + */ + public void handleParticipantRestart(ParticipantRestart participantRestartMsg) { + List list = new ArrayList<>(); + for (var participantDefinition : participantRestartMsg.getParticipantDefinitionUpdates()) { + list.addAll(participantDefinition.getAutomationCompositionElementDefinitionList()); + } + if (!AcTypeState.COMMISSIONED.equals(participantRestartMsg.getState())) { + cacheProvider.addElementDefinition(participantRestartMsg.getCompositionId(), list); + } + + for (var automationcomposition : participantRestartMsg.getAutomationcompositionList()) { + cacheProvider + .initializeAutomationComposition(participantRestartMsg.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 new file mode 100644 index 000000000..ddf465a2d --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java @@ -0,0 +1,104 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * 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.UUID; +import lombok.RequiredArgsConstructor; +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.messages.kafka.participant.AutomationCompositionStateChange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class AcLockHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(AcLockHandler.class); + + private final CacheProvider cacheProvider; + private final ThreadHandler listener; + + /** + * Handle a automation composition state change message. + * + * @param stateChangeMsg the state change message + */ + public void handleAutomationCompositionStateChange(AutomationCompositionStateChange stateChangeMsg) { + if (stateChangeMsg.getAutomationCompositionId() == null) { + return; + } + + var automationComposition = cacheProvider.getAutomationComposition(stateChangeMsg.getAutomationCompositionId()); + + if (automationComposition == null) { + LOGGER.debug("Automation composition {} does not use this participant", + stateChangeMsg.getAutomationCompositionId()); + return; + } + + switch (stateChangeMsg.getLockOrderedState()) { + case LOCK -> handleLockState(stateChangeMsg.getMessageId(), automationComposition, + stateChangeMsg.getStartPhase()); + case UNLOCK -> handleUnlockState(stateChangeMsg.getMessageId(), automationComposition, + stateChangeMsg.getStartPhase()); + default -> LOGGER.error("StateChange message has no lock order {}", automationComposition.getKey()); + } + } + + private void handleLockState(UUID messageId, final AutomationComposition automationComposition, + Integer startPhaseMsg) { + 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); + var compositionElement = cacheProvider.createCompositionElementDto( + automationComposition.getCompositionId(), element, compositionInProperties); + var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(), + null, element.getProperties(), element.getOutProperties()); + listener.lock(messageId, compositionElement, instanceElement); + } + } + } + + private void handleUnlockState(UUID messageId, final AutomationComposition automationComposition, + Integer startPhaseMsg) { + 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); + var compositionElement = cacheProvider.createCompositionElementDto( + automationComposition.getCompositionId(), element, compositionInProperties); + var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(), + null, 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/AutomationCompositionHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java index 3f3d5756a..5c54861f7 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,26 +21,18 @@ package org.onap.policy.clamp.acm.participant.intermediary.handler; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.stream.Collectors; -import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; +import lombok.RequiredArgsConstructor; 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.comm.ParticipantMessagePublisher; 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.AutomationComposition; -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; -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.ParticipantState; 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.messages.kafka.participant.AutomationCompositionDeploy; @@ -48,11 +40,8 @@ import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCom import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionStateChange; 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.PropertiesUpdate; 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.provider.AcInstanceStateResolver; import org.onap.policy.clamp.models.acm.utils.AcmUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,28 +51,14 @@ import org.springframework.stereotype.Component; * This class is responsible for managing the state of all automation compositions in the participant. */ @Component +@RequiredArgsConstructor public class AutomationCompositionHandler { private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionHandler.class); private final CacheProvider cacheProvider; private final ParticipantMessagePublisher publisher; private final ThreadHandler listener; - private final AcInstanceStateResolver acInstanceStateResolver; - /** - * Constructor, set the participant ID and messageSender. - * - * @param cacheProvider the Cache Provider - * @param publisher the ParticipantMessage Publisher - * @param listener the ThreadHandler Listener - */ - public AutomationCompositionHandler(CacheProvider cacheProvider, ParticipantMessagePublisher publisher, - ThreadHandler listener) { - this.cacheProvider = cacheProvider; - this.publisher = publisher; - this.listener = listener; - this.acInstanceStateResolver = new AcInstanceStateResolver(); - } /** * Handle a automation composition state change message. @@ -115,77 +90,13 @@ public class AutomationCompositionHandler { return; } - if (!checkConsistantOrderState(automationComposition, stateChangeMsg.getDeployOrderedState(), - stateChangeMsg.getLockOrderedState())) { - LOGGER.warn("Not Consistant OrderState Automation composition {}", - stateChangeMsg.getAutomationCompositionId()); - return; - } - - if (DeployOrder.NONE.equals(stateChangeMsg.getDeployOrderedState())) { - handleLockOrderState(stateChangeMsg.getMessageId(), automationComposition, - stateChangeMsg.getLockOrderedState(), stateChangeMsg.getStartPhase()); - } else { - handleDeployOrderState(stateChangeMsg.getMessageId(), automationComposition, - stateChangeMsg.getDeployOrderedState(), stateChangeMsg.getStartPhase()); - } - } - - private boolean checkConsistantOrderState(AutomationComposition automationComposition, DeployOrder deployOrder, - LockOrder lockOrder) { - if (DeployOrder.UPDATE.equals(deployOrder)) { - return true; - } - return acInstanceStateResolver.resolve(deployOrder, lockOrder, automationComposition.getDeployState(), - automationComposition.getLockState(), automationComposition.getStateChangeResult()) != null; - } - - /** - * Method to handle state changes. - * - * @param messageId the messageId - * @param automationComposition participant response - * @param orderedState automation composition ordered state - * @param startPhaseMsg startPhase from message - */ - private void handleDeployOrderState(UUID messageId, final AutomationComposition automationComposition, - DeployOrder orderedState, Integer startPhaseMsg) { - - switch (orderedState) { - case UNDEPLOY: - handleUndeployState(messageId, automationComposition, startPhaseMsg); - break; - case DELETE: - handleDeleteState(messageId, automationComposition, startPhaseMsg); - break; - - default: - LOGGER.error("StateChange message has no state, state is null {}", automationComposition.getKey()); - break; - } - } - - /** - * Method to handle state changes. - * - * @param messageId the messageId - * @param automationComposition participant response - * @param orderedState automation composition ordered state - * @param startPhaseMsg startPhase from message - */ - private void handleLockOrderState(UUID messageId, final AutomationComposition automationComposition, - LockOrder orderedState, Integer startPhaseMsg) { - - switch (orderedState) { - case LOCK: - handleLockState(messageId, automationComposition, startPhaseMsg); - break; - case UNLOCK: - handleUnlockState(messageId, automationComposition, startPhaseMsg); - break; - default: - LOGGER.error("StateChange message has no state, state is null {}", automationComposition.getKey()); - break; + switch (stateChangeMsg.getDeployOrderedState()) { + case UNDEPLOY -> handleUndeployState(stateChangeMsg.getMessageId(), automationComposition, + stateChangeMsg.getStartPhase()); + case DELETE -> handleDeleteState(stateChangeMsg.getMessageId(), automationComposition, + stateChangeMsg.getStartPhase()); + default -> + LOGGER.error("StateChange message has no state, state is null {}", automationComposition.getKey()); } } @@ -248,8 +159,8 @@ public class AutomationCompositionHandler { .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition()); int startPhase = ParticipantUtils.findStartPhase(compositionInProperties); if (startPhaseMsg.equals(startPhase)) { - var compositionElement = createCompositionElementDto(automationComposition.getCompositionId(), - element, compositionInProperties); + var compositionElement = cacheProvider.createCompositionElementDto( + automationComposition.getCompositionId(), element, compositionInProperties); var instanceElement = new InstanceElementDto(instanceId, elementDeploy.getId(), elementDeploy.getToscaServiceTemplateFragment(), elementDeploy.getProperties(), element.getOutProperties()); @@ -258,20 +169,13 @@ public class AutomationCompositionHandler { } } - private CompositionElementDto createCompositionElementDto(UUID compositionId, AutomationCompositionElement element, - Map compositionInProperties) { - var compositionOutProperties = cacheProvider.getAcElementsDefinitions() - .get(compositionId).get(element.getDefinition()).getOutProperties(); - return new CompositionElementDto(compositionId, - element.getDefinition(), compositionInProperties, compositionOutProperties); - } - private Map getCompositionElementDtoMap(AutomationComposition automationComposition, UUID compositionId) { Map map = new HashMap<>(); for (var element : automationComposition.getElements().values()) { var compositionInProperties = cacheProvider.getCommonProperties(compositionId, element.getDefinition()); - var compositionElement = createCompositionElementDto(compositionId, element, compositionInProperties); + var compositionElement = cacheProvider + .createCompositionElementDto(compositionId, element, compositionInProperties); map.put(element.getId(), compositionElement); } return map; @@ -330,8 +234,8 @@ public class AutomationCompositionHandler { int startPhase = ParticipantUtils.findStartPhase(compositionInProperties); if (startPhaseMsg.equals(startPhase)) { element.setDeployState(DeployState.UNDEPLOYING); - var compositionElement = createCompositionElementDto(automationComposition.getCompositionId(), - element, compositionInProperties); + var compositionElement = cacheProvider.createCompositionElementDto( + automationComposition.getCompositionId(), element, compositionInProperties); var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(), null, element.getProperties(), element.getOutProperties()); listener.undeploy(messageId, compositionElement, instanceElement); @@ -347,8 +251,8 @@ public class AutomationCompositionHandler { int startPhase = ParticipantUtils.findStartPhase(compositionInProperties); if (startPhaseMsg.equals(startPhase)) { element.setDeployState(DeployState.DELETING); - var compositionElement = createCompositionElementDto(automationComposition.getCompositionId(), - element, compositionInProperties); + var compositionElement = cacheProvider.createCompositionElementDto( + automationComposition.getCompositionId(), element, compositionInProperties); var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(), null, element.getProperties(), element.getOutProperties()); listener.delete(messageId, compositionElement, instanceElement); @@ -356,128 +260,6 @@ public class AutomationCompositionHandler { } } - /** - * Method to handle when the new state from participant is PASSIVE state. - * - * @param messageId the messageId - * @param automationComposition participant response - * @param startPhaseMsg startPhase from message - */ - private void handleLockState(UUID messageId, final AutomationComposition automationComposition, - Integer startPhaseMsg) { - 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); - var compositionElement = createCompositionElementDto(automationComposition.getCompositionId(), - element, compositionInProperties); - var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(), - null, element.getProperties(), element.getOutProperties()); - listener.lock(messageId, compositionElement, instanceElement); - } - } - } - - /** - * Method to handle when the new state from participant is RUNNING state. - * - * @param messageId the messageId - * @param automationComposition participant response - * @param startPhaseMsg startPhase from message - */ - private void handleUnlockState(UUID messageId, final AutomationComposition automationComposition, - Integer startPhaseMsg) { - 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); - var compositionElement = createCompositionElementDto(automationComposition.getCompositionId(), - element, compositionInProperties); - var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(), - null, element.getProperties(), element.getOutProperties()); - listener.unlock(messageId, compositionElement, instanceElement); - } - } - } - - /** - * Handles prime a Composition Definition. - * - * @param messageId the messageId - * @param compositionId the compositionId - * @param list the list of AutomationCompositionElementDefinition - */ - public void prime(UUID messageId, UUID compositionId, List list) { - var inPropertiesMap = list.stream().collect(Collectors.toMap( - AutomationCompositionElementDefinition::getAcElementDefinitionId, - el -> el.getAutomationCompositionElementToscaNodeTemplate().getProperties())); - var outPropertiesMap = list.stream().collect(Collectors.toMap( - AutomationCompositionElementDefinition::getAcElementDefinitionId, - AutomationCompositionElementDefinition::getOutProperties)); - listener.prime(messageId, new CompositionDto(compositionId, inPropertiesMap, outPropertiesMap)); - } - - /** - * Handles deprime a Composition Definition. - * - * @param messageId the messageId - * @param compositionId the compositionId - */ - public void deprime(UUID messageId, UUID compositionId) { - var acElementsDefinitions = cacheProvider.getAcElementsDefinitions().get(compositionId); - if (acElementsDefinitions == null) { - // this participant does not handle this composition - var participantPrimeAck = new ParticipantPrimeAck(); - participantPrimeAck.setCompositionId(compositionId); - participantPrimeAck.setMessage("Already deprimed or never primed"); - participantPrimeAck.setResult(true); - participantPrimeAck.setResponseTo(messageId); - participantPrimeAck.setCompositionState(AcTypeState.COMMISSIONED); - participantPrimeAck.setStateChangeResult(StateChangeResult.NO_ERROR); - participantPrimeAck.setParticipantId(cacheProvider.getParticipantId()); - participantPrimeAck.setState(ParticipantState.ON_LINE); - publisher.sendParticipantPrimeAck(participantPrimeAck); - return; - } - var list = new ArrayList<>(acElementsDefinitions.values()); - var inPropertiesMap = list.stream().collect(Collectors.toMap( - AutomationCompositionElementDefinition::getAcElementDefinitionId, - el -> el.getAutomationCompositionElementToscaNodeTemplate().getProperties())); - var outPropertiesMap = list.stream().collect(Collectors.toMap( - AutomationCompositionElementDefinition::getAcElementDefinitionId, - AutomationCompositionElementDefinition::getOutProperties)); - listener.deprime(messageId, new CompositionDto(compositionId, inPropertiesMap, outPropertiesMap)); - } - - /** - * Handles restarted scenario. - * - * @param messageId the messageId - * @param compositionId the compositionId - * @param list the list of AutomationCompositionElementDefinition - * @param state the state of the composition - * @param automationCompositionList list of ParticipantRestartAc - */ - public void restarted(UUID messageId, UUID compositionId, List list, - AcTypeState state, List automationCompositionList) { - - for (var automationcomposition : automationCompositionList) { - cacheProvider.initializeAutomationComposition(compositionId, 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(compositionId, inPropertiesMap, outPropertiesMap); - listener.restarted(messageId, composition, state, automationCompositionList); - } - /** * Handles AutomationComposition Migration. * 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 630dfc6ab..f51e8baad 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 @@ -28,6 +28,7 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import lombok.Getter; import lombok.NonNull; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; @@ -201,4 +202,20 @@ public class CacheProvider { automationComposition.setElements(acElementMap); automationCompositions.put(automationComposition.getInstanceId(), automationComposition); } + + /** + * Create CompositionElementDto. + * + * @param compositionId the composition Id + * @param element AutomationComposition Element + * @param compositionInProperties composition definition InProperties + * @return the CompositionElementDto + */ + public CompositionElementDto createCompositionElementDto(UUID compositionId, AutomationCompositionElement element, + Map compositionInProperties) { + var compositionOutProperties = getAcElementsDefinitions() + .get(compositionId).get(element.getDefinition()).getOutProperties(); + return new CompositionElementDto(compositionId, + element.getDefinition(), compositionInProperties, compositionOutProperties); + } } 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 ce0da680b..a4a92f883 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 @@ -23,12 +23,8 @@ package org.onap.policy.clamp.acm.participant.intermediary.handler; import io.micrometer.core.annotation.Timed; -import java.util.ArrayList; -import java.util.List; import lombok.RequiredArgsConstructor; import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher; -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.ParticipantState; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeploy; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration; @@ -44,6 +40,7 @@ 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.clamp.models.acm.messages.kafka.participant.PropertiesUpdate; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -57,6 +54,8 @@ public class ParticipantHandler { private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantHandler.class); private final AutomationCompositionHandler automationCompositionHandler; + private final AcLockHandler acLockHandler; + private final AcDefinitionHandler acDefinitionHandler; private final ParticipantMessagePublisher publisher; private final CacheProvider cacheProvider; @@ -91,7 +90,11 @@ public class ParticipantHandler { value = "listener.automation_composition_state_change", description = "AUTOMATION_COMPOSITION_STATE_CHANGE messages received") public void handleAutomationCompositionStateChange(AutomationCompositionStateChange stateChangeMsg) { - automationCompositionHandler.handleAutomationCompositionStateChange(stateChangeMsg); + if (DeployOrder.NONE.equals(stateChangeMsg.getDeployOrderedState())) { + acLockHandler.handleAutomationCompositionStateChange(stateChangeMsg); + } else { + automationCompositionHandler.handleAutomationCompositionStateChange(stateChangeMsg); + } } /** @@ -187,25 +190,7 @@ public class ParticipantHandler { @Timed(value = "listener.participant_prime", description = "PARTICIPANT_PRIME messages received") public void handleParticipantPrime(ParticipantPrime participantPrimeMsg) { LOGGER.debug("ParticipantPrime message received for participantId {}", participantPrimeMsg.getParticipantId()); - - if (!participantPrimeMsg.getParticipantDefinitionUpdates().isEmpty()) { - // prime - List list = new ArrayList<>(); - for (var participantDefinition : participantPrimeMsg.getParticipantDefinitionUpdates()) { - if (participantDefinition.getParticipantId().equals(cacheProvider.getParticipantId())) { - list.addAll(participantDefinition.getAutomationCompositionElementDefinitionList()); - } - } - if (!list.isEmpty()) { - cacheProvider.addElementDefinition(participantPrimeMsg.getCompositionId(), list); - automationCompositionHandler.prime(participantPrimeMsg.getMessageId(), - participantPrimeMsg.getCompositionId(), list); - } - } else { - // deprime - automationCompositionHandler.deprime(participantPrimeMsg.getMessageId(), - participantPrimeMsg.getCompositionId()); - } + acDefinitionHandler.handlePrime(participantPrimeMsg); } /** @@ -217,16 +202,7 @@ public class ParticipantHandler { public void handleParticipantRestart(ParticipantRestart participantRestartMsg) { LOGGER.debug("ParticipantRestart message received for participantId {}", participantRestartMsg.getParticipantId()); - List list = new ArrayList<>(); - for (var participantDefinition : participantRestartMsg.getParticipantDefinitionUpdates()) { - list.addAll(participantDefinition.getAutomationCompositionElementDefinitionList()); - } - if (!AcTypeState.COMMISSIONED.equals(participantRestartMsg.getState())) { - cacheProvider.addElementDefinition(participantRestartMsg.getCompositionId(), list); - } - automationCompositionHandler.restarted(participantRestartMsg.getMessageId(), - participantRestartMsg.getCompositionId(), list, participantRestartMsg.getState(), - participantRestartMsg.getAutomationcompositionList()); + acDefinitionHandler.handleParticipantRestart(participantRestartMsg); } /** 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 new file mode 100644 index 000000000..3bbdc3dbf --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcDefinitionHandlerTest.java @@ -0,0 +1,111 @@ +/*- + * ============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.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +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.comm.ParticipantMessagePublisher; +import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData; +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.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +public class AcDefinitionHandlerTest { + + @Test + void handleComposiotPrimeTest() { + var listener = mock(ThreadHandler.class); + var cacheProvider = mock(CacheProvider.class); + when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); + var ach = new AcDefinitionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), listener); + var participantPrimeMsg = new ParticipantPrime(); + participantPrimeMsg.setCompositionId(UUID.randomUUID()); + participantPrimeMsg.setParticipantDefinitionUpdates(List.of(createParticipantDefinition())); + ach.handlePrime(participantPrimeMsg); + verify(cacheProvider).addElementDefinition(any(UUID.class), anyList()); + verify(listener).prime(any(UUID.class), any(CompositionDto.class)); + } + + private ParticipantDefinition createParticipantDefinition() { + var def = new ParticipantDefinition(); + def.setParticipantId(CommonTestData.getParticipantId()); + def.setAutomationCompositionElementDefinitionList( + List.of(CommonTestData.createAutomationCompositionElementDefinition( + new ToscaConceptIdentifier("key", "1.0.0")))); + return def; + } + + @Test + void handleCompositionDeprimeTest() { + var acElementDefinition = CommonTestData.createAutomationCompositionElementDefinition( + new ToscaConceptIdentifier("key", "1.0.0")); + var compositionId = UUID.randomUUID(); + var listener = mock(ThreadHandler.class); + var cacheProvider = mock(CacheProvider.class); + var ach = new AcDefinitionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), listener); + when(cacheProvider.getAcElementsDefinitions()) + .thenReturn(Map.of(compositionId, Map.of(new ToscaConceptIdentifier(), acElementDefinition))); + var participantPrimeMsg = new ParticipantPrime(); + participantPrimeMsg.setCompositionId(compositionId); + ach.handlePrime(participantPrimeMsg); + verify(listener).deprime(any(UUID.class), any(CompositionDto.class)); + } + + @Test + void handleCompositionAlreadyDeprimedTest() { + var compositionId = UUID.randomUUID(); + var participantMessagePublisher = mock(ParticipantMessagePublisher.class); + var ach = new AcDefinitionHandler(mock(CacheProvider.class), participantMessagePublisher, + mock(ThreadHandler.class)); + var participantPrimeMsg = new ParticipantPrime(); + participantPrimeMsg.setCompositionId(compositionId); + ach.handlePrime(participantPrimeMsg); + verify(participantMessagePublisher).sendParticipantPrimeAck(any(ParticipantPrimeAck.class)); + } + + @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())); + + var cacheProvider = mock(CacheProvider.class); + var listener = mock(ThreadHandler.class); + var ach = new AcDefinitionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), listener); + ach.handleParticipantRestart(participantRestartMsg); + verify(cacheProvider).initializeAutomationComposition(any(UUID.class), any()); + verify(cacheProvider).addElementDefinition(any(), any()); + } +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandlerTest.java new file mode 100644 index 000000000..ebc9c8da3 --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandlerTest.java @@ -0,0 +1,112 @@ +/*- + * ============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.junit.jupiter.api.Assertions.assertEquals; +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.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.AutomationCompositionElementDefinition; +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.messages.kafka.participant.AutomationCompositionStateChange; +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.ToscaConceptIdentifier; + +class AcLockHandlerTest { + + @Test + void handleAcStateChangeNullTest() { + var cacheProvider = mock(CacheProvider.class); + var ach = new AcLockHandler(cacheProvider, mock(ThreadHandler.class)); + + var automationCompositionStateChange = new AutomationCompositionStateChange(); + assertDoesNotThrow(() -> ach.handleAutomationCompositionStateChange(automationCompositionStateChange)); + + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + automationCompositionStateChange.setAutomationCompositionId(automationComposition.getInstanceId()); + assertDoesNotThrow(() -> ach.handleAutomationCompositionStateChange(automationCompositionStateChange)); + } + + @Test + void handleAcStateChangeLockTest() { + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.UNLOCKED); + var cacheProvider = mock(CacheProvider.class); + when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) + .thenReturn(automationComposition); + when(cacheProvider.getCommonProperties(any(UUID.class), any(UUID.class))).thenReturn(Map.of()); + + var listener = mock(ThreadHandler.class); + var ach = new AcLockHandler(cacheProvider, listener); + Map map = new HashMap<>(); + for (var element : automationComposition.getElements().values()) { + map.put(element.getDefinition(), new AutomationCompositionElementDefinition()); + } + when(cacheProvider.getAcElementsDefinitions()) + .thenReturn(Map.of(automationComposition.getCompositionId(), map)); + var automationCompositionStateChange = CommonTestData.getStateChange(CommonTestData.getParticipantId(), + automationComposition.getInstanceId(), DeployOrder.NONE, LockOrder.LOCK); + ach.handleAutomationCompositionStateChange(automationCompositionStateChange); + verify(listener, times(automationComposition.getElements().size())).lock(any(), any(), any()); + for (var element : automationComposition.getElements().values()) { + assertEquals(LockState.LOCKING, element.getLockState()); + } + } + + @Test + void handleAcStateChangeUnlockTest() { + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.LOCKED); + var cacheProvider = mock(CacheProvider.class); + when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) + .thenReturn(automationComposition); + when(cacheProvider.getCommonProperties(any(UUID.class), any(UUID.class))).thenReturn(Map.of()); + + var listener = mock(ThreadHandler.class); + var ach = new AcLockHandler(cacheProvider, listener); + Map map = new HashMap<>(); + for (var element : automationComposition.getElements().values()) { + map.put(element.getDefinition(), new AutomationCompositionElementDefinition()); + } + when(cacheProvider.getAcElementsDefinitions()) + .thenReturn(Map.of(automationComposition.getCompositionId(), map)); + var automationCompositionStateChange = CommonTestData.getStateChange(CommonTestData.getParticipantId(), + automationComposition.getInstanceId(), DeployOrder.NONE, LockOrder.UNLOCK); + ach.handleAutomationCompositionStateChange(automationCompositionStateChange); + verify(listener, times(automationComposition.getElements().size())).unlock(any(), any(), any()); + for (var element : automationComposition.getElements().values()) { + assertEquals(LockState.UNLOCKING, element.getLockState()); + } + } +} 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 b8fd3b42d..40e3b1eec 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 @@ -29,33 +29,24 @@ 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.junit.jupiter.api.extension.ExtendWith; -import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; 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.AcTypeState; 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.LockState; import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy; 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; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionStateChange; -import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrimeAck; 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; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.springframework.test.context.junit.jupiter.SpringExtension; -@ExtendWith(SpringExtension.class) class AutomationCompositionHandlerTest { @Test @@ -108,58 +99,6 @@ class AutomationCompositionHandlerTest { } } - @Test - void handleAutomationCompositionStateChangeLockTest() { - var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); - var cacheProvider = mock(CacheProvider.class); - when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) - .thenReturn(automationComposition); - when(cacheProvider.getCommonProperties(any(UUID.class), any(UUID.class))).thenReturn(Map.of()); - - var participantMessagePublisher = mock(ParticipantMessagePublisher.class); - var listener = mock(ThreadHandler.class); - var ach = new AutomationCompositionHandler(cacheProvider, participantMessagePublisher, listener); - Map map = new HashMap<>(); - for (var element : automationComposition.getElements().values()) { - map.put(element.getDefinition(), new AutomationCompositionElementDefinition()); - } - when(cacheProvider.getAcElementsDefinitions()) - .thenReturn(Map.of(automationComposition.getCompositionId(), map)); - var automationCompositionStateChange = CommonTestData.getStateChange(CommonTestData.getParticipantId(), - automationComposition.getInstanceId(), DeployOrder.NONE, LockOrder.LOCK); - ach.handleAutomationCompositionStateChange(automationCompositionStateChange); - verify(listener, times(automationComposition.getElements().size())).lock(any(), any(), any()); - for (var element : automationComposition.getElements().values()) { - assertEquals(LockState.LOCKING, element.getLockState()); - } - } - - @Test - void handleAutomationCompositionStateChangeUnlockTest() { - var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); - var cacheProvider = mock(CacheProvider.class); - when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) - .thenReturn(automationComposition); - when(cacheProvider.getCommonProperties(any(UUID.class), any(UUID.class))).thenReturn(Map.of()); - - var participantMessagePublisher = mock(ParticipantMessagePublisher.class); - var listener = mock(ThreadHandler.class); - var ach = new AutomationCompositionHandler(cacheProvider, participantMessagePublisher, listener); - Map map = new HashMap<>(); - for (var element : automationComposition.getElements().values()) { - map.put(element.getDefinition(), new AutomationCompositionElementDefinition()); - } - when(cacheProvider.getAcElementsDefinitions()) - .thenReturn(Map.of(automationComposition.getCompositionId(), map)); - var automationCompositionStateChange = CommonTestData.getStateChange(CommonTestData.getParticipantId(), - automationComposition.getInstanceId(), DeployOrder.NONE, LockOrder.UNLOCK); - ach.handleAutomationCompositionStateChange(automationCompositionStateChange); - verify(listener, times(automationComposition.getElements().size())).unlock(any(), any(), any()); - for (var element : automationComposition.getElements().values()) { - assertEquals(LockState.UNLOCKING, element.getLockState()); - } - } - @Test void handleAutomationCompositionStateChangeDeleteTest() { var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); @@ -256,74 +195,6 @@ class AutomationCompositionHandlerTest { verify(listener, times(automationComposition.getElements().size())).deploy(any(), any(), any()); } - @Test - void handleComposiotPrimeTest() { - var acElementDefinition = new AutomationCompositionElementDefinition(); - acElementDefinition.setAcElementDefinitionId(new ToscaConceptIdentifier("key", "1.0.0")); - var toscaNodeTemplate = new ToscaNodeTemplate(); - toscaNodeTemplate.setProperties(Map.of()); - acElementDefinition.setAutomationCompositionElementToscaNodeTemplate(toscaNodeTemplate); - var list = List.of(acElementDefinition); - var compositionId = UUID.randomUUID(); - var messageId = UUID.randomUUID(); - var listener = mock(ThreadHandler.class); - var ach = new AutomationCompositionHandler(mock(CacheProvider.class), mock(ParticipantMessagePublisher.class), - listener); - ach.prime(messageId, compositionId, list); - verify(listener).prime(any(UUID.class), any(CompositionDto.class)); - } - - @Test - void handleCompositionDeprimeTest() { - var acElementDefinition = new AutomationCompositionElementDefinition(); - acElementDefinition.setAcElementDefinitionId(new ToscaConceptIdentifier("key", "1.0.0")); - var toscaNodeTemplate = new ToscaNodeTemplate(); - toscaNodeTemplate.setProperties(Map.of()); - acElementDefinition.setAutomationCompositionElementToscaNodeTemplate(toscaNodeTemplate); - var compositionId = UUID.randomUUID(); - var listener = mock(ThreadHandler.class); - var cacheProvider = mock(CacheProvider.class); - var ach = new AutomationCompositionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), - listener); - when(cacheProvider.getAcElementsDefinitions()) - .thenReturn(Map.of(compositionId, Map.of(new ToscaConceptIdentifier(), acElementDefinition))); - var messageId = UUID.randomUUID(); - ach.deprime(messageId, compositionId); - verify(listener).deprime(any(UUID.class), any(CompositionDto.class)); - } - - @Test - void handleCompositionAlreadyDeprimedTest() { - var messageId = UUID.randomUUID(); - var compositionId = UUID.randomUUID(); - var participantMessagePublisher = mock(ParticipantMessagePublisher.class); - var ach = new AutomationCompositionHandler(mock(CacheProvider.class), participantMessagePublisher, - mock(ThreadHandler.class)); - ach.deprime(messageId, compositionId); - verify(participantMessagePublisher).sendParticipantPrimeAck(any(ParticipantPrimeAck.class)); - } - - @Test - void restartedTest() { - var acElementDefinition = new AutomationCompositionElementDefinition(); - acElementDefinition.setAcElementDefinitionId(new ToscaConceptIdentifier("key", "1.0.0")); - var toscaNodeTemplate = new ToscaNodeTemplate(); - toscaNodeTemplate.setProperties(Map.of()); - acElementDefinition.setAutomationCompositionElementToscaNodeTemplate(toscaNodeTemplate); - var list = List.of(acElementDefinition); - var state = AcTypeState.PRIMED; - var participantRestartAc = CommonTestData.createParticipantRestartAc(); - var automationCompositionList = List.of(participantRestartAc); - var listener = mock(ThreadHandler.class); - var cacheProvider = mock(CacheProvider.class); - var ach = new AutomationCompositionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), listener); - var compositionId = UUID.randomUUID(); - var messageId = UUID.randomUUID(); - ach.restarted(messageId, compositionId, list, state, automationCompositionList); - verify(cacheProvider).initializeAutomationComposition(compositionId, participantRestartAc); - verify(listener).restarted(any(), any(), any(), any()); - } - @Test void handleAutomationCompositionMigrationTest() { var listener = mock(ThreadHandler.class); 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 d5fe5785b..9451f0138 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 @@ -96,6 +96,10 @@ class CacheProviderTest { var commonProperties = cacheProvider.getCommonProperties(automationComposition.getInstanceId(), element.getId()); assertEquals("value", commonProperties.get("key")); + + commonProperties = cacheProvider + .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition()); + assertEquals("value", commonProperties.get("key")); } assertEquals(automationComposition.getInstanceId(), @@ -165,4 +169,21 @@ class CacheProviderTest { assertEquals(element.getOutProperties(), acElementRestart.getOutProperties()); } } + + @Test + void testCreateCompositionElementDto() { + 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)); + for (var element : automationComposition.getElements().values()) { + var result = cacheProvider.createCompositionElementDto(compositionId, element, Map.of()); + assertEquals(compositionId, result.compositionId()); + assertEquals(element.getDefinition(), result.elementDefinitionId()); + } + } } 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 4b58ae177..8aac93138 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 @@ -34,8 +34,6 @@ 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.AcTypeState; -import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; -import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; import org.onap.policy.clamp.models.acm.concepts.ParticipantSupportedElementType; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeploy; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration; @@ -52,6 +50,8 @@ 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.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; class ParticipantHandlerTest { @@ -59,8 +59,8 @@ class ParticipantHandlerTest { void handleParticipantStatusReqTest() { var publisher = mock(ParticipantMessagePublisher.class); var cacheProvider = mock(CacheProvider.class); - var participantHandler = - new ParticipantHandler(mock(AutomationCompositionHandler.class), publisher, cacheProvider); + var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), + mock(AcLockHandler.class), mock(AcDefinitionHandler.class), publisher, cacheProvider); participantHandler.handleParticipantStatusReq(new ParticipantStatusReq()); verify(publisher).sendParticipantStatus(any(ParticipantStatus.class)); } @@ -68,8 +68,8 @@ class ParticipantHandlerTest { @Test void handleAutomationCompositionDeployTest() { var acHandler = mock(AutomationCompositionHandler.class); - var participantHandler = - new ParticipantHandler(acHandler, mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); + var participantHandler = new ParticipantHandler(acHandler, mock(AcLockHandler.class), + mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); var automationCompositionDeploy = new AutomationCompositionDeploy(); participantHandler.handleAutomationCompositionDeploy(automationCompositionDeploy); verify(acHandler).handleAutomationCompositionDeploy(automationCompositionDeploy); @@ -78,18 +78,27 @@ class ParticipantHandlerTest { @Test void handleAutomationCompositionStateChangeTest() { var acHandler = mock(AutomationCompositionHandler.class); - var participantHandler = - new ParticipantHandler(acHandler, mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); + var acLockHandler = mock(AcLockHandler.class); + var participantHandler = new ParticipantHandler(acHandler, acLockHandler, mock(AcDefinitionHandler.class), + mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); var acStateChange = new AutomationCompositionStateChange(); + + acStateChange.setDeployOrderedState(DeployOrder.DEPLOY); + acStateChange.setLockOrderedState(LockOrder.NONE); participantHandler.handleAutomationCompositionStateChange(acStateChange); verify(acHandler).handleAutomationCompositionStateChange(acStateChange); + + acStateChange.setDeployOrderedState(DeployOrder.NONE); + acStateChange.setLockOrderedState(LockOrder.LOCK); + participantHandler.handleAutomationCompositionStateChange(acStateChange); + verify(acLockHandler).handleAutomationCompositionStateChange(acStateChange); } @Test void handleAutomationCompositionMigrationTest() { var acHandler = mock(AutomationCompositionHandler.class); - var participantHandler = - new ParticipantHandler(acHandler, mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); + var participantHandler = new ParticipantHandler(acHandler, mock(AcLockHandler.class), + mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); var migrationMsg = new AutomationCompositionMigration(); participantHandler.handleAutomationCompositionMigration(migrationMsg); verify(acHandler).handleAutomationCompositionMigration(migrationMsg); @@ -98,8 +107,8 @@ class ParticipantHandlerTest { @Test void handleAcPropertyUpdateTest() { var acHandler = mock(AutomationCompositionHandler.class); - var participantHandler = - new ParticipantHandler(acHandler, mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); + var participantHandler = new ParticipantHandler(acHandler, mock(AcLockHandler.class), + mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); var propertyUpdateMsg = new PropertiesUpdate(); participantHandler.handleAcPropertyUpdate(propertyUpdateMsg); verify(acHandler).handleAcPropertyUpdate(propertyUpdateMsg); @@ -110,7 +119,8 @@ class ParticipantHandlerTest { var cacheProvider = mock(CacheProvider.class); when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), - mock(ParticipantMessagePublisher.class), cacheProvider); + mock(AcLockHandler.class), mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), + cacheProvider); var participantAckMsg = new ParticipantAckMessage(ParticipantMessageType.AUTOMATION_COMPOSITION_DEPLOY); assertTrue(participantHandler.appliesTo(participantAckMsg)); @@ -128,8 +138,8 @@ class ParticipantHandlerTest { var cacheProvider = mock(CacheProvider.class); when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); when(cacheProvider.getSupportedAcElementTypes()).thenReturn(List.of(new ParticipantSupportedElementType())); - var participantHandler = - new ParticipantHandler(mock(AutomationCompositionHandler.class), publisher, cacheProvider); + var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), + mock(AcLockHandler.class), mock(AcDefinitionHandler.class), publisher, cacheProvider); participantHandler.sendParticipantRegister(); verify(publisher).sendParticipantRegister(any(ParticipantRegister.class)); @@ -140,8 +150,8 @@ class ParticipantHandlerTest { var publisher = mock(ParticipantMessagePublisher.class); var cacheProvider = mock(CacheProvider.class); when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); - var participantHandler = - new ParticipantHandler(mock(AutomationCompositionHandler.class), publisher, cacheProvider); + var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), + mock(AcLockHandler.class), mock(AcDefinitionHandler.class), publisher, cacheProvider); participantHandler.handleParticipantRegisterAck(new ParticipantRegisterAck()); verify(publisher).sendParticipantStatus(any(ParticipantStatus.class)); @@ -152,8 +162,8 @@ class ParticipantHandlerTest { var publisher = mock(ParticipantMessagePublisher.class); var cacheProvider = mock(CacheProvider.class); when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); - var participantHandler = - new ParticipantHandler(mock(AutomationCompositionHandler.class), publisher, cacheProvider); + var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), + mock(AcLockHandler.class), mock(AcDefinitionHandler.class), publisher, cacheProvider); participantHandler.sendParticipantDeregister(); verify(publisher).sendParticipantDeregister(any(ParticipantDeregister.class)); @@ -162,28 +172,25 @@ class ParticipantHandlerTest { @Test void handleParticipantDeregisterAckTest() { var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), - mock(ParticipantMessagePublisher.class), mock(CacheProvider.class)); + mock(AcLockHandler.class), mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), + mock(CacheProvider.class)); var participantDeregisterAck = new ParticipantDeregisterAck(); assertDoesNotThrow(() -> participantHandler.handleParticipantDeregisterAck(participantDeregisterAck)); } @Test void handleParticipantPrimeTest() { - var cacheProvider = mock(CacheProvider.class); - when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); - var participantPrime = new ParticipantPrime(); participantPrime.setCompositionId(UUID.randomUUID()); participantPrime.setMessageId(UUID.randomUUID()); - participantPrime.setParticipantDefinitionUpdates(List.of(createParticipantDefinition())); - var publisher = mock(ParticipantMessagePublisher.class); - var acHandler = mock(AutomationCompositionHandler.class); - var participantHandler = new ParticipantHandler(acHandler, publisher, cacheProvider); + var acHandler = mock(AcDefinitionHandler.class); + var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), + mock(AcLockHandler.class), acHandler, mock(ParticipantMessagePublisher.class), + mock(CacheProvider.class)); participantHandler.handleParticipantPrime(participantPrime); - verify(cacheProvider).addElementDefinition(any(), any()); - verify(acHandler).prime(any(), any(), any()); + verify(acHandler).handlePrime(participantPrime); } @Test @@ -191,32 +198,15 @@ class ParticipantHandlerTest { var participantRestartMsg = new ParticipantRestart(); participantRestartMsg.setState(AcTypeState.PRIMED); participantRestartMsg.setCompositionId(UUID.randomUUID()); - participantRestartMsg.getParticipantDefinitionUpdates().add(new ParticipantDefinition()); var cacheProvider = mock(CacheProvider.class); var publisher = mock(ParticipantMessagePublisher.class); - var acHandler = mock(AutomationCompositionHandler.class); - var participantHandler = new ParticipantHandler(acHandler, publisher, cacheProvider); + var acHandler = mock(AcDefinitionHandler.class); + var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), + mock(AcLockHandler.class), acHandler, publisher, cacheProvider); participantHandler.handleParticipantRestart(participantRestartMsg); - verify(cacheProvider).addElementDefinition(any(), any()); - verify(acHandler).restarted(any(), any(), any(), any(), any()); - } - - @Test - void handleParticipantDeprimeTest() { - var cacheProvider = mock(CacheProvider.class); - when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); - var publisher = mock(ParticipantMessagePublisher.class); - var acHandler = mock(AutomationCompositionHandler.class); - var participantHandler = new ParticipantHandler(acHandler, publisher, cacheProvider); - var participantPrime = new ParticipantPrime(); - var compositionId = UUID.randomUUID(); - participantPrime.setCompositionId(compositionId); - var messageId = UUID.randomUUID(); - participantPrime.setMessageId(messageId); - participantHandler.handleParticipantPrime(participantPrime); - verify(acHandler).deprime(messageId, compositionId); + verify(acHandler).handleParticipantRestart(participantRestartMsg); } @Test @@ -226,16 +216,11 @@ class ParticipantHandlerTest { when(cacheProvider.getAutomationCompositions()).thenReturn(CommonTestData.getTestAutomationCompositionMap()); var publisher = mock(ParticipantMessagePublisher.class); when(publisher.isActive()).thenReturn(true); - var participantHandler = - new ParticipantHandler(mock(AutomationCompositionHandler.class), publisher, cacheProvider); + var acHandler = mock(AcDefinitionHandler.class); + var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class), + mock(AcLockHandler.class), acHandler, publisher, cacheProvider); participantHandler.sendHeartbeat(); verify(publisher).sendHeartbeat(any(ParticipantStatus.class)); } - private ParticipantDefinition createParticipantDefinition() { - var def = new ParticipantDefinition(); - def.setParticipantId(CommonTestData.getParticipantId()); - def.setAutomationCompositionElementDefinitionList(List.of(new AutomationCompositionElementDefinition())); - return def; - } } 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 168bfaf83..3011c91f5 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 @@ -277,13 +277,24 @@ public class CommonTestData { createAutomationCompositionElementDefinitionList(AutomationComposition automationComposition) { List definitions = new ArrayList<>(); for (var element : automationComposition.getElements().values()) { - var acElementDefinition = new AutomationCompositionElementDefinition(); - acElementDefinition.setAcElementDefinitionId(element.getDefinition()); - var nodeTemplate = new ToscaNodeTemplate(); - nodeTemplate.setProperties(Map.of("key", "value")); - acElementDefinition.setAutomationCompositionElementToscaNodeTemplate(nodeTemplate); - definitions.add(acElementDefinition); + definitions.add(createAutomationCompositionElementDefinition(element.getDefinition())); } return definitions; } + + /** + * create a new example of AutomationCompositionElementDefinition. + * + * @param definition the composition definition element id + * @return the AutomationCompositionElementDefinition + */ + public static AutomationCompositionElementDefinition createAutomationCompositionElementDefinition( + ToscaConceptIdentifier definition) { + var acElementDefinition = new AutomationCompositionElementDefinition(); + acElementDefinition.setAcElementDefinitionId(definition); + var nodeTemplate = new ToscaNodeTemplate(); + nodeTemplate.setProperties(Map.of("key", "value")); + acElementDefinition.setAutomationCompositionElementToscaNodeTemplate(nodeTemplate); + return acElementDefinition; + } } -- cgit 1.2.3-korg