diff options
Diffstat (limited to 'runtime-acm')
54 files changed, 1650 insertions, 1114 deletions
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 - |