diff options
52 files changed, 893 insertions, 337 deletions
diff --git a/common/src/main/resources/tosca/ControlLoopTOSCAServiceTemplateTypes.yaml b/common/src/main/resources/tosca/ControlLoopTOSCAServiceTemplateTypes.yaml index e45a06257..a17cb7624 100644 --- a/common/src/main/resources/tosca/ControlLoopTOSCAServiceTemplateTypes.yaml +++ b/common/src/main/resources/tosca/ControlLoopTOSCAServiceTemplateTypes.yaml @@ -47,7 +47,7 @@ node_types: type: integer required: false constraints: - - greater-or-equal: 0 + - greater_or_equal: 0 metadata: common: true description: A value indicating the start phase in which this control loop element will be started, the @@ -58,7 +58,7 @@ node_types: type: integer required: false constraints: - - greater-or-equal: 0 + - greater_or_equal: 0 default: 60 metadata: common: true @@ -67,7 +67,7 @@ node_types: type: integer required: false constraints: - - greater-or-equal: 0 + - greater_or_equal: 0 default: 60 metadata: common: true @@ -76,7 +76,7 @@ node_types: type: integer required: false constraints: - - greater-or-equal: 0 + - greater_or_equal: 0 default: 60 metadata: common: true @@ -85,11 +85,20 @@ node_types: type: integer required: false constraints: - - greater-or-equal: 0 + - greater_or_equal: 0 default: 60 metadata: common: true description: The maximum time in seconds to wait for a state chage from passive to uninitialized + startDelay: + type: integer + required: false + constraints: + - greater_or_equal: 0 + default: 0 + metadata: + common: true + description: The number of milliseconds that the start of this control loop element should be delayed org.onap.policy.clamp.controlloop.ControlLoop: version: 1.0.1 derived_from: tosca.nodetypes.Root diff --git a/common/src/test/resources/demo/Notes.txt b/common/src/test/resources/demo/Notes.txt index 43b75e915..f937e0969 100644 --- a/common/src/test/resources/demo/Notes.txt +++ b/common/src/test/resources/demo/Notes.txt @@ -14,15 +14,14 @@ Go to clamp/runtime-controlloop mvn spring-boot:run -Dspring-boot.run.arguments="--topicServer=localhost --mariadb.host=localhost" Run Participant from command line using Maven -mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8080 --topicServer=localhost" -mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8081 --topicServer=localhost" -mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8082 --topicServer=localhost" +mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8080 +mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8081 +mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=8082 Run Participant from command line using Jar -java -jar -Dserver.port=8080 -DtopicServer=localhost target/policy-clamp-participant-impl-simulator-6.1.2-SNAPSHOT.jar -java -jar -Dserver.port=8081 -DtopicServer=localhost target/policy-clamp-participant-impl-dcae-6.1.2-SNAPSHOT.jar -java -jar -Dserver.port=8082 -DtopicServer=localhost target/policy-clamp-participant-impl-policy-6.1.2-SNAPSHOT.jar -java -jar -DtopicServer=localhost target/policy-clamp-participant-impl-kubernetes-6.1.2-SNAPSHOT.jar +java -jar -Dserver.port=8080 target/policy-clamp-participant-impl-simulator-6.1.2-SNAPSHOT.jar +java -jar -Dserver.port=8082 target/policy-clamp-participant-impl-policy-6.1.2-SNAPSHOT.jar +java -jar target/policy-clamp-participant-impl-kubernetes-6.1.2-SNAPSHOT.jar Config of DB @@ -39,6 +38,24 @@ MariaDB [(none)]> SHOW GRANTS for 'policy'@localhost; +---------------------------------------------------------------------------------------------------------------+ 2 rows in set (0.000 sec) +//Generate the keystore +//clone policy/docker +cd docker/csit +./gen_truststore.sh +./gen_keystore.sh +//the keystore generated: /docker/csit/config/ks.jks + +Run Participant from command line using Docker +docker run --add-host=message-router:<ip-router> -p 6969:6969 --mount type=bind,source=<path-keystore-file>,target=/opt/app/policy/clamp/etc/ssl/policy-keystore onap/policy-clamp-cl-runtime +docker run --add-host=message-router:<ip-router> -p 8083:8083 --mount type=bind,source=<path-keystore-file>,target=/opt/app/policy/clamp/etc/ssl/policy-keystore onap/policy-clamp-cl-k8s-ppnt +docker run --add-host=message-router:<ip-router> --mount type=bind,source=<path-keystore-file>,target=/opt/app/policy/clamp/etc/ssl/policy-keystore onap/policy-clamp-cl-http-ppnt +docker run --add-host=message-router:<ip-router> --mount type=bind,source=<path-keystore-file>,target=/opt/app/policy/clamp/etc/ssl/policy-keystore onap/policy-clamp-cl-pf-ppnt + +Note: +/policy-clamp-tarball/src/main/resources/etc/ssl/policy-truststore is the truststore for DMaap of oom project +Participant-k8 swagger: https://localhost:8083/onap/k8sparticipant/swagger-ui/ +CL-Runtime swagger: https://localhost:6969/onap/controlloop/swagger-ui/ + Run Policy API: mvn exec:java -Dexec.mainClass=org.onap.policy.api.main.startstop.Main -Dexec.args="-c ../../clamp-tpn/tosca-controlloop/common/src/test/resources/demo/policy-api/PolicyAPIConfig.json" diff --git a/lombok.config b/lombok.config new file mode 100644 index 000000000..a23edb413 --- /dev/null +++ b/lombok.config @@ -0,0 +1,2 @@ +config.stopBubbling = true +lombok.addLombokGeneratedAnnotation = true
\ No newline at end of file diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoopElement.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoopElement.java index 67bcb5348..c7d85e4b6 100644 --- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoopElement.java +++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoopElement.java @@ -31,6 +31,7 @@ import lombok.ToString; import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfUtils; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; /** @@ -66,7 +67,7 @@ public class ControlLoopElement { // A map indexed by the property name. Each map entry is the serialized value of the property, // which can be deserialized into an instance of the type of the property. - private Map<String, String> commonPropertiesMap = new LinkedHashMap<>(); + private Map<String, ToscaProperty> propertiesMap = new LinkedHashMap<>(); /** * Copy constructor, does a deep copy but as all fields here are immutable, it's just a regular copy. @@ -83,6 +84,6 @@ public class ControlLoopElement { this.toscaServiceTemplateFragment = otherElement.toscaServiceTemplateFragment; this.description = otherElement.description; this.clElementStatistics = otherElement.clElementStatistics; - this.commonPropertiesMap = PfUtils.mapMap(otherElement.commonPropertiesMap, UnaryOperator.identity()); + this.propertiesMap = PfUtils.mapMap(otherElement.propertiesMap, UnaryOperator.identity()); } } diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoopElementDefinition.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoopElementDefinition.java index b9f4d6904..ae50b40ce 100644 --- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoopElementDefinition.java +++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoopElementDefinition.java @@ -30,6 +30,7 @@ import lombok.ToString; import org.onap.policy.models.base.PfUtils; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; /** * Class to represent a control loop element definition instance. @@ -47,7 +48,7 @@ public class ControlLoopElementDefinition { // A map indexed by the property name. Each map entry is the serialized value of the property, // which can be deserialized into an instance of the type of the property. - private Map<String, String> commonPropertiesMap = new LinkedHashMap<>(); + private Map<String, ToscaProperty> commonPropertiesMap = new LinkedHashMap<>(); /** * Copy constructor, does a deep copy but as all fields here are immutable, it's just a regular copy. diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/Participant.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/Participant.java index 3130b6c2f..198cf1a16 100644 --- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/Participant.java +++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/Participant.java @@ -44,6 +44,9 @@ public class Participant extends ToscaEntity implements Comparable<Participant> @NonNull private ParticipantHealthStatus healthStatus = ParticipantHealthStatus.UNKNOWN; + @NonNull + private ToscaConceptIdentifier participantType = new ToscaConceptIdentifier(); + @Override public String getType() { return definition.getName(); @@ -69,5 +72,6 @@ public class Participant extends ToscaEntity implements Comparable<Participant> this.definition = new ToscaConceptIdentifier(otherParticipant.definition); this.participantState = otherParticipant.participantState; this.healthStatus = otherParticipant.healthStatus; + this.participantType = otherParticipant.participantType; } } diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ParticipantUtils.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ParticipantUtils.java index 05f5a4bb8..4c3dd4b06 100644 --- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ParticipantUtils.java +++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ParticipantUtils.java @@ -57,6 +57,20 @@ public final class ParticipantUtils { } /** + * Finds startPhase from a map of properties. + * + * @param properties Map of properties + * @return startPhase + */ + public static int findStartPhase(Map<String, Object> properties) { + var objParticipantType = properties.get("startPhase"); + if (objParticipantType != null) { + return Integer.valueOf(objParticipantType.toString()); + } + return 0; + } + + /** * Checks If NodeTemplate Is ControlLoopElement. * * @param nodeTemplate the ToscaNodeTemplate diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaParticipant.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaParticipant.java index 4d49683bf..c8c26a8de 100644 --- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaParticipant.java +++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaParticipant.java @@ -70,6 +70,11 @@ public class JpaParticipant extends PfConcept implements PfAuthorative<Participa private PfConceptKey definition; // @formatter:on + @NotNull + @AttributeOverride(name = "name", column = @Column(name = "participant_type_name")) + @AttributeOverride(name = "version", column = @Column(name = "participant_type_version")) + private PfConceptKey participantType; + @Column @NotNull private ParticipantState participantState; @@ -125,6 +130,7 @@ public class JpaParticipant extends PfConcept implements PfAuthorative<Participa this.participantState = copyConcept.participantState; this.healthStatus = copyConcept.healthStatus; this.description = copyConcept.description; + this.participantType = copyConcept.participantType; } /** @@ -146,6 +152,7 @@ public class JpaParticipant extends PfConcept implements PfAuthorative<Participa participant.setParticipantState(participantState); participant.setHealthStatus(healthStatus); participant.setDescription(description); + participant.setParticipantType(new ToscaConceptIdentifier(participantType)); return participant; } @@ -160,6 +167,7 @@ public class JpaParticipant extends PfConcept implements PfAuthorative<Participa this.setParticipantState(participant.getParticipantState()); this.setHealthStatus(participant.getHealthStatus()); this.setDescription(participant.getDescription()); + this.participantType = participant.getParticipantType().asConceptKey(); } @Override @@ -167,6 +175,7 @@ public class JpaParticipant extends PfConcept implements PfAuthorative<Participa List<PfKey> keyList = getKey().getKeys(); keyList.add(definition); + keyList.add(participantType); return keyList; } @@ -176,6 +185,7 @@ public class JpaParticipant extends PfConcept implements PfAuthorative<Participa key.clean(); definition.clean(); description = (description == null ? null : description.trim()); + participantType.clean(); } @Override @@ -211,6 +221,11 @@ public class JpaParticipant extends PfConcept implements PfAuthorative<Participa return result; } + result = ObjectUtils.compare(participantType, other.participantType); + if (result != 0) { + return result; + } + return ObjectUtils.compare(description, other.description); } } diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ControlLoopUpdate.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ControlLoopUpdate.java index 42b9712e2..f8a47c7c9 100644 --- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ControlLoopUpdate.java +++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ControlLoopUpdate.java @@ -40,6 +40,7 @@ public class ControlLoopUpdate extends ParticipantMessage { // A list of ParticipantUpdates instances which carries details of an updated participant. private List<ParticipantUpdates> participantUpdatesList = new ArrayList<>(); + private Integer startPhase = 0; /** * Constructor for instantiating ControlLoopUpdate class with message name. diff --git a/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaParticipantTest.java b/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaParticipantTest.java index e2eb5154f..087292354 100644 --- a/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaParticipantTest.java +++ b/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaParticipantTest.java @@ -247,6 +247,7 @@ class JpaParticipantTest { testParticipant.setName("participant"); testParticipant.setVersion("0.0.1"); testParticipant.setDefinition(new ToscaConceptIdentifier("participantDefinitionName", "0.0.1")); + testParticipant.setParticipantType(new ToscaConceptIdentifier("participantTypeName", "0.0.1")); return testParticipant; } diff --git a/models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ControlLoopUpdateTest.java b/models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ControlLoopUpdateTest.java index 1b155a12a..ce56d582a 100644 --- a/models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ControlLoopUpdateTest.java +++ b/models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ControlLoopUpdateTest.java @@ -36,6 +36,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUpdates; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; /** * Test the copy constructor. @@ -62,8 +63,11 @@ class ControlLoopUpdateTest { clElement.setParticipantId(id); clElement.setParticipantType(id); - Map<String, String> commonPropertiesMap = Map.of("Prop1", "PropValue"); - clElement.setCommonPropertiesMap(commonPropertiesMap); + ToscaProperty property = new ToscaProperty(); + property.setName("test"); + property.setType("testType"); + Map<String, ToscaProperty> propertiesMap = Map.of("Prop1", property); + clElement.setPropertiesMap(propertiesMap); ParticipantUpdates participantUpdates = new ParticipantUpdates(); participantUpdates.setParticipantId(id); diff --git a/models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ParticipantStatusTest.java b/models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ParticipantStatusTest.java index f34777a70..b2bce05cc 100644 --- a/models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ParticipantStatusTest.java +++ b/models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ParticipantStatusTest.java @@ -42,6 +42,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; class ParticipantStatusTest { @@ -117,7 +118,11 @@ class ParticipantStatusTest { ControlLoopElementDefinition clDefinition = new ControlLoopElementDefinition(); clDefinition.setClElementDefinitionId(id); clDefinition.setControlLoopElementToscaNodeTemplate(toscaNodeTemplate); - Map<String, String> commonPropertiesMap = Map.of("Prop1", "PropValue"); + + ToscaProperty property = new ToscaProperty(); + property.setName("test"); + property.setType("testType"); + Map<String, ToscaProperty> commonPropertiesMap = Map.of("Prop1", property); clDefinition.setCommonPropertiesMap(commonPropertiesMap); return clDefinition; } diff --git a/models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ParticipantUpdateTest.java b/models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ParticipantUpdateTest.java index 6fe8604cf..d7023d0c1 100644 --- a/models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ParticipantUpdateTest.java +++ b/models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ParticipantUpdateTest.java @@ -35,6 +35,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; /** @@ -89,7 +90,11 @@ class ParticipantUpdateTest { ControlLoopElementDefinition clDefinition = new ControlLoopElementDefinition(); clDefinition.setClElementDefinitionId(id); clDefinition.setControlLoopElementToscaNodeTemplate(toscaNodeTemplate); - Map<String, String> commonPropertiesMap = Map.of("Prop1", "PropValue"); + + ToscaProperty property = new ToscaProperty(); + property.setName("test"); + property.setType("testType"); + Map<String, ToscaProperty> commonPropertiesMap = Map.of("Prop1", property); clDefinition.setCommonPropertiesMap(commonPropertiesMap); return clDefinition; } diff --git a/models/src/test/resources/providers/TestParticipant.json b/models/src/test/resources/providers/TestParticipant.json index c6965ce62..4722ead9b 100644 --- a/models/src/test/resources/providers/TestParticipant.json +++ b/models/src/test/resources/providers/TestParticipant.json @@ -7,5 +7,9 @@ }, "participantState": "PASSIVE", "healthStatus": "HEALTHY", - "description": "A dummy PMSH participant1" + "description": "A dummy PMSH participant1", + "participantType":{ + "name": "org.onap.domain.pmsh.PolicyControlLoopDefinition", + "version": "1.0.0" + } } diff --git a/packages/policy-clamp-docker/src/main/docker/controlloop-runtime.sh b/packages/policy-clamp-docker/src/main/docker/controlloop-runtime.sh index 6d12e590a..59d31dc8e 100644 --- a/packages/policy-clamp-docker/src/main/docker/controlloop-runtime.sh +++ b/packages/policy-clamp-docker/src/main/docker/controlloop-runtime.sh @@ -56,8 +56,9 @@ touch /app/app.jar mkdir -p "${POLICY_HOME}"/config/ cp -f "${CONFIG_FILE}" "${POLICY_HOME}"/config/ClRuntimeParameters.yaml -$JAVA_HOME/bin/java -Djavax.net.ssl.keyStore="${KEYSTORE}" \ - -Djavax.net.ssl.keyStorePassword="${KEYSTORE_PASSWD}" \ +$JAVA_HOME/bin/java -Dserver.ssl.enabled="true" \ + -Dserver.ssl.keyStore="${KEYSTORE}" \ + -Dserver.ssl.keyStorePassword="${KEYSTORE_PASSWD}" \ -Djavax.net.ssl.trustStore="${TRUSTSTORE}" \ -Djavax.net.ssl.trustStorePassword="${TRUSTSTORE_PASSWD}" \ -jar /app/app.jar \ diff --git a/packages/policy-clamp-docker/src/main/docker/http-participant.sh b/packages/policy-clamp-docker/src/main/docker/http-participant.sh index d74b903e3..17daa18f9 100644 --- a/packages/policy-clamp-docker/src/main/docker/http-participant.sh +++ b/packages/policy-clamp-docker/src/main/docker/http-participant.sh @@ -55,9 +55,10 @@ fi mkdir -p "${POLICY_HOME}"/config/ cp -f "${CONFIG_FILE}" "${POLICY_HOME}"/config/HttpParticipantParameters.yaml -$JAVA_HOME/bin/java -Dserver.ssl.keyStore="${KEYSTORE}" \ +$JAVA_HOME/bin/java -Dserver.ssl.enabled="true" \ + -Dserver.ssl.keyStore="${KEYSTORE}" \ -Dserver.ssl.keyStorePassword="${KEYSTORE_PASSWD}" \ - -Dserver.ssl.trustStore="${TRUSTSTORE}" \ - -Dserver.ssl.trustStorePassword="${TRUSTSTORE_PASSWD}" \ + -Djavax.net.ssl.trustStore="${TRUSTSTORE}" \ + -Djavax.net.ssl.trustStorePassword="${TRUSTSTORE_PASSWD}" \ -jar /app/app.jar \ --spring.config.location="${POLICY_HOME}/config/HttpParticipantParameters.yaml" diff --git a/packages/policy-clamp-docker/src/main/docker/kubernetes-participant.sh b/packages/policy-clamp-docker/src/main/docker/kubernetes-participant.sh index cb5ae9251..3c5fe5c63 100644 --- a/packages/policy-clamp-docker/src/main/docker/kubernetes-participant.sh +++ b/packages/policy-clamp-docker/src/main/docker/kubernetes-participant.sh @@ -55,9 +55,10 @@ fi mkdir -p "${POLICY_HOME}"/config/ cp -f "${CONFIG_FILE}" "${POLICY_HOME}"/config/KubernetesParticipantParameters.yaml -$JAVA_HOME/bin/java -Dserver.ssl.keyStore="${KEYSTORE}" \ +$JAVA_HOME/bin/java -Dserver.ssl.enabled="true" \ + -Dserver.ssl.keyStore="${KEYSTORE}" \ -Dserver.ssl.keyStorePassword="${KEYSTORE_PASSWD}" \ - -Dserver.ssl.trustStore="${TRUSTSTORE}" \ - -Dserver.ssl.trustStorePassword="${TRUSTSTORE_PASSWD}" \ + -Djavax.net.ssl.trustStore="${TRUSTSTORE}" \ + -Djavax.net.ssl.trustStorePassword="${TRUSTSTORE_PASSWD}" \ -jar /app/app.jar \ --spring.config.location="${POLICY_HOME}/config/KubernetesParticipantParameters.yaml" diff --git a/packages/policy-clamp-docker/src/main/docker/policy-participant.sh b/packages/policy-clamp-docker/src/main/docker/policy-participant.sh index 7949fab72..77cd0c02b 100644 --- a/packages/policy-clamp-docker/src/main/docker/policy-participant.sh +++ b/packages/policy-clamp-docker/src/main/docker/policy-participant.sh @@ -56,8 +56,9 @@ touch /app/app.jar mkdir -p "${POLICY_HOME}"/config/ cp -f "${CONFIG_FILE}" "${POLICY_HOME}"/config/PolicyParticipantParameters.yaml -$JAVA_HOME/bin/java -Djavax.net.ssl.keyStore="${KEYSTORE}" \ - -Djavax.net.ssl.keyStorePassword="${KEYSTORE_PASSWD}" \ +$JAVA_HOME/bin/java -Dserver.ssl.enabled="true" \ + -Dserver.ssl.keyStore="${KEYSTORE}" \ + -Dserver.ssl.keyStorePassword="${KEYSTORE_PASSWD}" \ -Djavax.net.ssl.trustStore="${TRUSTSTORE}" \ -Djavax.net.ssl.trustStorePassword="${TRUSTSTORE_PASSWD}" \ -jar /app/app.jar \ diff --git a/packages/policy-clamp-tarball/src/main/resources/etc/ClRuntimeParameters.yaml b/packages/policy-clamp-tarball/src/main/resources/etc/ClRuntimeParameters.yaml index ade249e99..c8601cbdd 100644 --- a/packages/policy-clamp-tarball/src/main/resources/etc/ClRuntimeParameters.yaml +++ b/packages/policy-clamp-tarball/src/main/resources/etc/ClRuntimeParameters.yaml @@ -44,12 +44,14 @@ runtime: - ${topicServer:message-router} topicCommInfrastructure: dmaap fetchTimeout: 15000 + useHttps: true topicSinks: - topic: POLICY-CLRUNTIME-PARTICIPANT servers: - ${topicServer:message-router} topicCommInfrastructure: dmaap + useHttps: true management: endpoints: diff --git a/packages/policy-clamp-tarball/src/main/resources/etc/HttpParticipantParameters.yaml b/packages/policy-clamp-tarball/src/main/resources/etc/HttpParticipantParameters.yaml index 76f48bbdd..be421fcae 100644 --- a/packages/policy-clamp-tarball/src/main/resources/etc/HttpParticipantParameters.yaml +++ b/packages/policy-clamp-tarball/src/main/resources/etc/HttpParticipantParameters.yaml @@ -15,9 +15,10 @@ participant: - ${topicServer:message-router} topicCommInfrastructure: dmaap fetchTimeout: 15000 + useHttps: true topicSinks: - topic: POLICY-CLRUNTIME-PARTICIPANT servers: - ${topicServer:message-router} topicCommInfrastructure: dmaap - + useHttps: true diff --git a/packages/policy-clamp-tarball/src/main/resources/etc/KubernetesParticipantParameters.yaml b/packages/policy-clamp-tarball/src/main/resources/etc/KubernetesParticipantParameters.yaml index ebd744f13..d605cfa1d 100644 --- a/packages/policy-clamp-tarball/src/main/resources/etc/KubernetesParticipantParameters.yaml +++ b/packages/policy-clamp-tarball/src/main/resources/etc/KubernetesParticipantParameters.yaml @@ -26,12 +26,14 @@ participant: - ${topicServer:message-router} topicCommInfrastructure: dmaap fetchTimeout: 15000 + useHttps: true topicSinks: - topic: POLICY-CLRUNTIME-PARTICIPANT servers: - ${topicServer:message-router} topicCommInfrastructure: dmaap + useHttps: true management: endpoints: @@ -42,6 +44,8 @@ server: # Configuration of the HTTP/REST server. The parameters are defined and handled by the springboot framework. # See springboot documentation. port: 8083 + servlet: + context-path: /onap/k8sparticipant logging: # Configuration of logging diff --git a/packages/policy-clamp-tarball/src/main/resources/etc/PolicyParticipantParameters.yaml b/packages/policy-clamp-tarball/src/main/resources/etc/PolicyParticipantParameters.yaml index 66e2d95b6..bd9a6260a 100644 --- a/packages/policy-clamp-tarball/src/main/resources/etc/PolicyParticipantParameters.yaml +++ b/packages/policy-clamp-tarball/src/main/resources/etc/PolicyParticipantParameters.yaml @@ -35,9 +35,11 @@ participant: - ${topicServer:message-router} topicCommInfrastructure: dmaap fetchTimeout: 15000 + useHttps: true topicSinks: - topic: POLICY-CLRUNTIME-PARTICIPANT servers: - ${topicServer:message-router} topicCommInfrastructure: dmaap + useHttps: true diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/handler/ControlLoopElementHandler.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/handler/ControlLoopElementHandler.java index cfe786865..86a864efc 100644 --- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/handler/ControlLoopElementHandler.java +++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/handler/ControlLoopElementHandler.java @@ -37,6 +37,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; +import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; import org.onap.policy.clamp.controlloop.participant.http.main.models.ConfigRequest; import org.onap.policy.clamp.controlloop.participant.http.main.webclient.ClHttpClient; import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; @@ -90,7 +91,26 @@ public class ControlLoopElementHandler implements ControlLoopElementListener, Cl @Override public void controlLoopElementStateChange(ToscaConceptIdentifier controlLoopId, UUID controlLoopElementId, ControlLoopState currentState, ControlLoopOrderedState newState) throws PfModelException { - // Implementation not needed for http participant + switch (newState) { + case UNINITIALISED: + intermediaryApi.updateControlLoopElementState(controlLoopId, + controlLoopElementId, newState, ControlLoopState.UNINITIALISED, + ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); + break; + case PASSIVE: + intermediaryApi.updateControlLoopElementState(controlLoopId, + controlLoopElementId, newState, ControlLoopState.PASSIVE, + ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); + break; + case RUNNING: + intermediaryApi.updateControlLoopElementState(controlLoopId, + controlLoopElementId, newState, ControlLoopState.RUNNING, + ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); + break; + default: + LOGGER.warn("Cannot transition from state {} to state {}", currentState, newState); + break; + } } /** @@ -108,6 +128,9 @@ public class ControlLoopElementHandler implements ControlLoopElementListener, Cl .getValidator().validate(configRequest); if (violations.isEmpty()) { invokeHttpClient(configRequest); + intermediaryApi.updateControlLoopElementState(controlLoopId, element.getId(), + ControlLoopOrderedState.PASSIVE, ControlLoopState.PASSIVE, + ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); } else { LOGGER.error("Violations found in the config request parameters: {}", violations); throw new ValidationException("Constraint violations in the config request"); diff --git a/participant/participant-impl/participant-impl-http/src/test/java/handler/ClElementHandlerTest.java b/participant/participant-impl/participant-impl-http/src/test/java/handler/ClElementHandlerTest.java index 0de25072d..d1556ea08 100644 --- a/participant/participant-impl/participant-impl-http/src/test/java/handler/ClElementHandlerTest.java +++ b/participant/participant-impl/participant-impl-http/src/test/java/handler/ClElementHandlerTest.java @@ -29,9 +29,11 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; +import org.mockito.Mock; import org.mockito.Spy; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; import org.onap.policy.clamp.controlloop.participant.http.main.handler.ControlLoopElementHandler; +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; @@ -46,6 +48,9 @@ class ClElementHandlerTest { @Spy private ControlLoopElementHandler controlLoopElementHandler = new ControlLoopElementHandler(); + @Mock + private ParticipantIntermediaryApi participantIntermediaryApi; + private CommonTestData commonTestData = new CommonTestData(); private static ToscaServiceTemplate serviceTemplate; diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java index a5d1f8841..e1e9195eb 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java @@ -103,7 +103,7 @@ public class ControlLoopElementHandler implements ControlLoopElementListener { chartMap.remove(controlLoopElementId); podStatusMap.remove(chart.getReleaseName()); } catch (ServiceException se) { - LOGGER.warn("deletion of Helm deployment failed", se); + LOGGER.warn("Deletion of Helm deployment failed", se); } } break; @@ -118,7 +118,7 @@ public class ControlLoopElementHandler implements ControlLoopElementListener { ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); break; default: - LOGGER.warn("cannot transition from state {} to state {}", currentState, newState); + LOGGER.warn("Cannot transition from state {} to state {}", currentState, newState); break; } } @@ -148,7 +148,7 @@ public class ControlLoopElementHandler implements ControlLoopElementListener { checkPodStatus(chartInfo, config.uninitializedToPassiveTimeout, config.podStatusCheckInterval); intermediaryApi.updateControlLoopElementState(controlLoopId, element.getId(), - ControlLoopOrderedState.PASSIVE, ControlLoopState.UNINITIALISED, + ControlLoopOrderedState.PASSIVE, ControlLoopState.PASSIVE, ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); } catch (ServiceException | CoderException | IOException e) { diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/rest/ChartControllerTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/rest/ChartControllerTest.java index fcac64dd6..bbb57c320 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/rest/ChartControllerTest.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/rest/ChartControllerTest.java @@ -29,7 +29,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.List; +import org.apache.commons.io.FileUtils; import org.json.JSONObject; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -65,9 +68,11 @@ class ChartControllerTest { private static final Coder CODER = new StandardCoder(); private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; private static List<ChartInfo> charts; - private static String DEFAULT_CHART_URL = "/helm/charts"; + private static String RETRIEVE_CHART_URL = "/helm/charts"; private static String INSTALL_CHART_URL = "/helm/install"; private static String UNINSTALL_CHART_URL = "/helm/uninstall/"; + private static String ONBOARD_CHART_URL = "/helm/onboard/chart"; + private static String DELETE_CHART_URL = "/helm/chart"; @Autowired private MockMvc mockMvc; @@ -107,7 +112,7 @@ class ChartControllerTest { @Test void retrieveAllCharts() throws Exception { RequestBuilder requestBuilder; - requestBuilder = MockMvcRequestBuilders.get(DEFAULT_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE); + requestBuilder = MockMvcRequestBuilders.get(RETRIEVE_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE); mockMvc.perform(requestBuilder).andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) @@ -180,7 +185,7 @@ class ChartControllerTest { //Mocking successful scenario for void uninstall method when(chartService.saveChart(charts.get(0), chartFile, null)).thenReturn(charts.get(0)); - requestBuilder = MockMvcRequestBuilders.multipart(DEFAULT_CHART_URL) + requestBuilder = MockMvcRequestBuilders.multipart(ONBOARD_CHART_URL) .file(chartFile).file(overrideFile).param("info", getChartInfoJson()); mockMvc.perform(requestBuilder).andExpect(status().isOk()); @@ -197,7 +202,7 @@ class ChartControllerTest { //Mocking successful scenario for void uninstall method doNothing().when(chartService).deleteChart(charts.get(0)); - requestBuilder = MockMvcRequestBuilders.delete(DEFAULT_CHART_URL + "/" + charts.get(0) + requestBuilder = MockMvcRequestBuilders.delete(DELETE_CHART_URL + "/" + charts.get(0) .getChartId().getName() + "/" + charts.get(0).getChartId().getVersion()) .accept(MediaType.APPLICATION_JSON_VALUE) .contentType(MediaType.APPLICATION_JSON_VALUE); @@ -219,14 +224,8 @@ class ChartControllerTest { return jsonObj.toString(); } - private String getChartInfoJson() { - JSONObject jsonObj = new JSONObject(); - jsonObj.put("chartName", charts.get(0).getChartId().getName()); - jsonObj.put("version", charts.get(0).getChartId().getVersion()); - jsonObj.put("namespace", charts.get(0).getNamespace()); - jsonObj.put("repository", charts.get(0).getRepository()); - jsonObj.put("releaseName", charts.get(0).getReleaseName()); - return jsonObj.toString(); + private String getChartInfoJson() throws IOException { + return FileUtils.readFileToString(new File(CHART_INFO_YAML), StandardCharsets.UTF_8); } } diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartServiceTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartServiceTest.java index 4c8b5b3b3..f1c8d19df 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartServiceTest.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartServiceTest.java @@ -121,7 +121,7 @@ class ChartServiceTest { doReturn("dummyRepoName").when(chartService).findChartRepo(any()); doNothing().when(helmClient).installChart(any()); chartService.installChart(charts.get(1)); - assertEquals("dummyRepoName", charts.get(1).getRepository()); + assertEquals("dummyRepoName", charts.get(1).getRepository().getRepoName()); ChartInfo testChart = charts.get(1); testChart.setRepository(null); diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/resources/ChartList.json b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/ChartList.json index 2f4ec2827..9822846f3 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/resources/ChartList.json +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/ChartList.json @@ -6,7 +6,9 @@ "version" : "1.0" }, "namespace" : "onap", - "repository" : "chartMuseum", + "repository" : { + "repoName": "chartMuseum" + }, "releaseName" : "helloworld" }, { diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java index 891d67e2d..0cb4963ec 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java @@ -34,6 +34,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; /** * This interface is used by participant implementations to use the participant intermediary. @@ -57,6 +58,14 @@ public interface ParticipantIntermediaryApi { List<Participant> getParticipants(String name, String version); /** + * Get common properties of a controlloopelement. + * + * @param clElementDef the control loop element definition + * @return the common properties + */ + Map<String, ToscaProperty> getClElementDefinitionCommonProperties(ToscaConceptIdentifier clElementDef); + + /** * Update the state of a participant. * * @param definition the definition of the participant to update the state on diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java index aa1febadd..43ac3464c 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java @@ -40,6 +40,7 @@ import org.onap.policy.clamp.controlloop.participant.intermediary.api.Participan import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ControlLoopHandler; import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; import org.springframework.stereotype.Component; /** @@ -77,6 +78,11 @@ public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryAp } @Override + public Map<String, ToscaProperty> getClElementDefinitionCommonProperties(ToscaConceptIdentifier clElementDef) { + return participantHandler.getClElementDefinitionCommonProperties(clElementDef); + } + + @Override public Participant updateParticipantState(ToscaConceptIdentifier definition, ParticipantState state) { return participantHandler.updateParticipantState(definition, state); } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java index 30a06ba22..40dc901db 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java @@ -22,6 +22,7 @@ package org.onap.policy.clamp.controlloop.participant.intermediary.handler; import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -37,6 +38,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUpdates; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUtils; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopAck; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopStateChange; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate; @@ -47,6 +49,7 @@ import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.Par import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -217,6 +220,15 @@ public class ControlLoopHandler { return; } + if (0 == updateMsg.getStartPhase()) { + handleClUpdatePhase0(updateMsg, clElementDefinitions); + } else { + handleClUpdatePhaseN(updateMsg, clElementDefinitions); + } + } + + private void handleClUpdatePhase0(ControlLoopUpdate updateMsg, + List<ControlLoopElementDefinition> clElementDefinitions) { var controlLoop = controlLoopMap.get(updateMsg.getControlLoopId()); // TODO: Updates to existing ControlLoops are not supported yet (Addition/Removal of ControlLoop @@ -242,30 +254,54 @@ public class ControlLoopHandler { var clElements = storeElementsOnThisParticipant(updateMsg.getParticipantUpdatesList()); + var clElementMap = prepareClElementMap(clElements); + controlLoop = new ControlLoop(); + controlLoop.setDefinition(updateMsg.getControlLoopId()); + controlLoop.setElements(clElementMap); + controlLoopMap.put(updateMsg.getControlLoopId(), controlLoop); + + handleControlLoopElementUpdate(clElements, clElementDefinitions, updateMsg.getStartPhase(), + updateMsg.getControlLoopId()); + } + + private void handleClUpdatePhaseN(ControlLoopUpdate updateMsg, + List<ControlLoopElementDefinition> clElementDefinitions) { + + var clElementList = updateMsg.getParticipantUpdatesList().stream() + .flatMap(participantUpdate -> participantUpdate.getControlLoopElementList().stream()) + .filter(element -> participantType.equals(element.getParticipantType())).collect(Collectors.toList()); + + handleControlLoopElementUpdate(clElementList, clElementDefinitions, updateMsg.getStartPhase(), + updateMsg.getControlLoopId()); + } + + private void handleControlLoopElementUpdate(List<ControlLoopElement> clElements, + List<ControlLoopElementDefinition> clElementDefinitions, Integer startPhaseMsg, + ToscaConceptIdentifier controlLoopId) { try { for (var element : clElements) { - var clElementNodeTemplate = - getClElementNodeTemplate(clElementDefinitions, element.getDefinition()); - for (var clElementListener : listeners) { - clElementListener.controlLoopElementUpdate(updateMsg.getControlLoopId(), element, - clElementNodeTemplate); + var clElementNodeTemplate = getClElementNodeTemplate(clElementDefinitions, element.getDefinition()); + if (clElementNodeTemplate != null) { + int startPhase = ParticipantUtils.findStartPhase(clElementNodeTemplate.getProperties()); + if (startPhaseMsg.equals(startPhase)) { + for (var clElementListener : listeners) { + clElementListener.controlLoopElementUpdate(controlLoopId, element, clElementNodeTemplate); + } + } } } } catch (PfModelException e) { - LOGGER.debug("Control loop element update failed {}", updateMsg.getControlLoopId()); + LOGGER.debug("Control loop element update failed {}", controlLoopId); } - var clElementMap = prepareClElementMap(clElements); - controlLoop = new ControlLoop(); - controlLoop.setDefinition(updateMsg.getControlLoopId()); - controlLoop.setElements(clElementMap); - controlLoopMap.put(updateMsg.getControlLoopId(), controlLoop); } private ToscaNodeTemplate getClElementNodeTemplate(List<ControlLoopElementDefinition> clElementDefinitions, ToscaConceptIdentifier clElementDefId) { + for (var clElementDefinition : clElementDefinitions) { - if (clElementDefinition.getClElementDefinitionId().equals(clElementDefId)) { + if (clElementDefId.getName().contains( + clElementDefinition.getClElementDefinitionId().getName())) { return clElementDefinition.getControlLoopElementToscaNodeTemplate(); } } @@ -273,14 +309,14 @@ public class ControlLoopHandler { } private List<ControlLoopElement> storeElementsOnThisParticipant(List<ParticipantUpdates> participantUpdates) { - var clElementMap = participantUpdates.stream() + var clElementList = participantUpdates.stream() .flatMap(participantUpdate -> participantUpdate.getControlLoopElementList().stream()) .filter(element -> participantType.equals(element.getParticipantType())).collect(Collectors.toList()); - for (var element : clElementMap) { + for (var element : clElementList) { elementsOnThisParticipant.put(element.getId(), element); } - return clElementMap; + return clElementList; } private Map<UUID, ControlLoopElement> prepareClElementMap(List<ControlLoopElement> clElements) { @@ -345,8 +381,8 @@ public class ControlLoopHandler { controlLoop.getElements().values().stream().forEach(clElement -> { for (var clElementListener : listeners) { try { - clElementListener.controlLoopElementStateChange(controlLoop.getDefinition(), - clElement.getId(), clElement.getState(), orderedState); + clElementListener.controlLoopElementStateChange(controlLoop.getDefinition(), clElement.getId(), + clElement.getState(), orderedState); } catch (PfModelException e) { LOGGER.debug("Control loop element update failed {}", controlLoop.getDefinition()); } @@ -364,4 +400,21 @@ public class ControlLoopHandler { controlLoops.setControlLoopList(new ArrayList<>(controlLoopMap.values())); return controlLoops; } + + /** + * Get properties of a controlloopelement. + * + * @param id the control loop element id + * @return the instance properties + */ + public Map<String, ToscaProperty> getClElementInstanceProperties(UUID id) { + Map<String, ToscaProperty> propertiesMap = new HashMap<>(); + for (var controlLoop : controlLoopMap.values()) { + var element = controlLoop.getElements().get(id); + if (element != null) { + propertiesMap.putAll(element.getPropertiesMap()); + } + } + return propertiesMap; + } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java index 1d445324b..e42fac46e 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java @@ -24,6 +24,7 @@ package org.onap.policy.clamp.controlloop.participant.intermediary.handler; import java.io.Closeable; import java.io.IOException; import java.util.List; +import lombok.Getter; import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager; import org.onap.policy.common.endpoints.event.comm.TopicSink; @@ -49,6 +50,7 @@ public class IntermediaryActivator extends ServiceManagerContainer implements Cl private ParticipantHandler participantHandler; + @Getter private final MessageTypeDispatcher msgDispatcher; /** diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java index 69f8febb8..ea7d84501 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java @@ -24,6 +24,7 @@ package org.onap.policy.clamp.controlloop.participant.intermediary.handler; import java.time.Instant; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -60,6 +61,7 @@ import org.onap.policy.clamp.controlloop.participant.intermediary.comm.Participa import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -206,6 +208,22 @@ public class ParticipantHandler { } /** + * Get common properties of a controlloopelement. + * + * @param clElementDef the control loop element definition + * @return the common properties + */ + public Map<String, ToscaProperty> getClElementDefinitionCommonProperties(ToscaConceptIdentifier clElementDef) { + Map<String, ToscaProperty> commonPropertiesMap = new HashMap<>(); + clElementDefsOnThisParticipant.stream().forEach(definition -> { + if (definition.getClElementDefinitionId().equals(clElementDef)) { + commonPropertiesMap.putAll(definition.getCommonPropertiesMap()); + } + }); + return commonPropertiesMap; + } + + /** * Check if a participant message applies to this participant handler. * * @param participantMsg the message to check @@ -284,15 +302,10 @@ public class ParticipantHandler { LOGGER.debug("ParticipantUpdate message received for participantId {}", participantUpdateMsg.getParticipantId()); - if (!participantUpdateMsg.appliesTo(participantType, participantId)) { - return; - } - if (!participantUpdateMsg.getParticipantDefinitionUpdates().isEmpty()) { // This message is to commission the controlloop for (ParticipantDefinition participantDefinition : participantUpdateMsg.getParticipantDefinitionUpdates()) { if (participantDefinition.getParticipantType().equals(participantType)) { - clElementDefsOnThisParticipant.clear(); clElementDefsOnThisParticipant.addAll(participantDefinition.getControlLoopElementDefinitionList()); break; } diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandlerTest.java new file mode 100644 index 000000000..29387959b --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandlerTest.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.participant.intermediary.handler; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; + +import java.time.Instant; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; +import org.onap.policy.clamp.controlloop.participant.intermediary.main.parameters.CommonTestData; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +class ControlLoopHandlerTest { + + private CommonTestData commonTestData = new CommonTestData(); + + @Test + void controlLoopHandlerTest() { + ControlLoopHandler clh = commonTestData.getMockControlLoopHandler(); + assertNotNull(clh.getControlLoops()); + + assertNotNull(clh.getControlLoopMap()); + assertNotNull(clh.getElementsOnThisParticipant()); + + UUID elementId1 = UUID.randomUUID(); + ControlLoopElement element = new ControlLoopElement(); + element.setId(elementId1); + element.setDefinition(new ToscaConceptIdentifier( + "org.onap.policy.controlloop.PolicyControlLoopParticipant", "1.0.1")); + + element.setOrderedState(ControlLoopOrderedState.PASSIVE); + + ControlLoopElementListener listener = mock(ControlLoopElementListener.class); + clh.registerControlLoopElementListener(listener); + assertThat(clh.getListeners()).contains(listener); + + } + + @Test + void updateNullControlLoopHandlerTest() { + UUID id = UUID.randomUUID(); + + ControlLoopHandler clh = commonTestData.getMockControlLoopHandler(); + assertNull(clh.updateControlLoopElementState(null, null, ControlLoopOrderedState.UNINITIALISED, + ControlLoopState.PASSIVE)); + + assertNull(clh.updateControlLoopElementState(null, id, ControlLoopOrderedState.UNINITIALISED, + ControlLoopState.PASSIVE)); + + ClElementStatistics clElementStatistics = new ClElementStatistics(); + ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier("defName", "0.0.1"); + clElementStatistics.setParticipantId(controlLoopId); + clElementStatistics.setControlLoopState(ControlLoopState.RUNNING); + clElementStatistics.setTimeStamp(Instant.now()); + + clh.updateControlLoopElementStatistics(id, clElementStatistics); + assertNull(clh.updateControlLoopElementState(controlLoopId, id, ControlLoopOrderedState.UNINITIALISED, + ControlLoopState.PASSIVE)); + + + + } + +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/DummyParticipantParameters.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/DummyParticipantParameters.java new file mode 100644 index 000000000..d60bb71bc --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/DummyParticipantParameters.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.participant.intermediary.handler; + +import javax.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; +import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; +import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; + +@Getter +@Setter +public class DummyParticipantParameters implements ParticipantParameters { + + @NotNull + private ParticipantIntermediaryParameters intermediaryParameters; +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivatorTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivatorTest.java new file mode 100644 index 000000000..bbe0412ed --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivatorTest.java @@ -0,0 +1,97 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.participant.intermediary.handler; + +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.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.List; +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatusReq; +import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantStatusReqListener; +import org.onap.policy.clamp.controlloop.participant.intermediary.main.parameters.CommonTestData; +import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.StandardCoderObject; + +class IntermediaryActivatorTest { + private static final Coder CODER = new StandardCoder(); + + private static final String TOPIC_FIRST = "TOPIC1"; + private static final String TOPIC_SECOND = "TOPIC2"; + + @Test + void testStartAndStop() throws Exception { + ParticipantParameters parameters = CommonTestData.getParticipantParameters(); + + var publisherFirst = spy(mock(Publisher.class)); + var publisherSecond = spy(mock(Publisher.class)); + var publishers = List.of(publisherFirst, publisherSecond); + + var listenerFirst = spy(mock(ParticipantStatusReqListener.class)); + when(listenerFirst.getType()).thenReturn(TOPIC_FIRST); + when(listenerFirst.getScoListener()).thenReturn(listenerFirst); + + var listenerSecond = spy(mock(ParticipantStatusReqListener.class)); + when(listenerSecond.getType()).thenReturn(TOPIC_SECOND); + when(listenerSecond.getScoListener()).thenReturn(listenerSecond); + + List<Listener<ParticipantStatusReq>> listeners = List.of(listenerFirst, listenerSecond); + + ParticipantHandler handler = mock(ParticipantHandler.class); + try (var activator = new IntermediaryActivator(parameters, handler, publishers, listeners)) { + + assertFalse(activator.isAlive()); + activator.start(); + assertTrue(activator.isAlive()); + + // repeat start - should throw an exception + assertThatIllegalStateException().isThrownBy(() -> activator.start()); + assertTrue(activator.isAlive()); + verify(publisherFirst, times(1)).active(anyList()); + verify(publisherSecond, times(1)).active(anyList()); + + StandardCoderObject sco = CODER.decode("{messageType:" + TOPIC_FIRST + "}", StandardCoderObject.class); + activator.getMsgDispatcher().onTopicEvent(null, "msg", sco); + verify(listenerFirst, times(1)).onTopicEvent(any(), any(), any()); + + sco = CODER.decode("{messageType:" + TOPIC_SECOND + "}", StandardCoderObject.class); + activator.getMsgDispatcher().onTopicEvent(null, "msg", sco); + verify(listenerSecond, times(1)).onTopicEvent(any(), any(), any()); + + activator.stop(); + assertFalse(activator.isAlive()); + + // repeat stop - should throw an exception + assertThatIllegalStateException().isThrownBy(() -> activator.stop()); + assertFalse(activator.isAlive()); + } + } +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/CommonTestData.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/CommonTestData.java index 9353cde81..ae20f4b7f 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/CommonTestData.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/CommonTestData.java @@ -21,10 +21,16 @@ package org.onap.policy.clamp.controlloop.participant.intermediary.main.parameters; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.TreeMap; +import org.mockito.Mockito; +import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantMessagePublisher; +import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ControlLoopHandler; +import org.onap.policy.clamp.controlloop.participant.intermediary.handler.DummyParticipantParameters; import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; +import org.onap.policy.common.endpoints.event.comm.TopicSink; import org.onap.policy.common.endpoints.parameters.TopicParameters; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; @@ -41,6 +47,7 @@ public class CommonTestData { public static final List<TopicParameters> TOPIC_PARAMS = Arrays.asList(getTopicParams()); public static final Coder CODER = new StandardCoder(); + private static final Object lockit = new Object(); /** * Get ParticipantIntermediaryParameters. @@ -57,12 +64,38 @@ public class CommonTestData { } /** + * Get ParticipantParameters. + * + * @return ParticipantParameters + */ + public static DummyParticipantParameters getParticipantParameters() { + try { + return CODER.convert(getParametersMap(PARTICIPANT_GROUP_NAME), + DummyParticipantParameters.class); + } catch (final CoderException e) { + throw new RuntimeException("cannot create ParticipantSimulatorParameters from map", e); + } + } + + /** + * Returns a property map for a Parameters map for test cases. + * + * @param name name of the parameters + * @return a property map suitable for constructing an object + */ + public static Map<String, Object> getParametersMap(final String name) { + final Map<String, Object> map = new TreeMap<>(); + map.put("intermediaryParameters", getIntermediaryParametersMap(name)); + return map; + } + + /** * Returns a property map for a intermediaryParameters map for test cases. * * @param name name of the parameters * @return a property map suitable for constructing an object */ - public Map<String, Object> getIntermediaryParametersMap(final String name) { + public static Map<String, Object> getIntermediaryParametersMap(final String name) { final Map<String, Object> map = new TreeMap<>(); map.put("name", name); map.put("participantId", getParticipantId()); @@ -80,7 +113,7 @@ public class CommonTestData { * @param isEmpty boolean value to represent that object created should be empty or not * @return a property map suitable for constructing an object */ - public Map<String, Object> getTopicParametersMap(final boolean isEmpty) { + public static Map<String, Object> getTopicParametersMap(final boolean isEmpty) { final Map<String, Object> map = new TreeMap<>(); if (!isEmpty) { map.put("topicSources", TOPIC_PARAMS); @@ -110,4 +143,29 @@ public class CommonTestData { public static ToscaConceptIdentifier getParticipantId() { return new ToscaConceptIdentifier("org.onap.PM_CDS_Blueprint", "1.0.1"); } + + /** + * Returns a participantMessagePublisher for MessageSender. + * + * @return participant Message Publisher + */ + private ParticipantMessagePublisher getParticipantMessagePublisher() { + synchronized (lockit) { + ParticipantMessagePublisher participantMessagePublisher = + new ParticipantMessagePublisher(); + participantMessagePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); + return participantMessagePublisher; + } + } + + /** + * Returns a mocked ControlLoopHandler for test cases. + * + * @return ControlLoopHandler + */ + public ControlLoopHandler getMockControlLoopHandler() { + return new ControlLoopHandler( + getParticipantParameters(), + getParticipantMessagePublisher()); + } } diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java index 0b7bc9a26..d2d57ed83 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java @@ -37,7 +37,6 @@ import org.apache.commons.collections4.MapUtils; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate; import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse; import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler; import org.onap.policy.models.base.PfModelException; @@ -108,23 +107,13 @@ public class CommissioningProvider { synchronized (lockit) { modelsProvider.createServiceTemplate(serviceTemplate); List<Participant> participantList = - participantProvider.getParticipants(null, - null); - - if (participantList != null) { - for (Participant participant: participantList) { - var participantType = new ToscaConceptIdentifier(); - participantType.setName(participant.getType()); - participantType.setVersion(participant.getTypeVersion()); - - var participantUpdate = new ParticipantUpdate(); - participantUpdate.setParticipantId(participant.getDefinition()); - participantUpdate.setParticipantType(participantType); - - this.supervisionHandler.handleSendCommissionMessage(participantUpdate); - } + participantProvider.getParticipants(null, null); + if (!participantList.isEmpty()) { + this.supervisionHandler.handleSendCommissionMessage( + getCommonOrInstancePropertiesFromNodeTypes(true, + serviceTemplate.getName(), + serviceTemplate.getVersion())); } - } var response = new CommissioningResponse(); @@ -159,21 +148,9 @@ public class CommissioningProvider { List<Participant> participantList = participantProvider.getParticipants(null, null); - - if (participantList != null) { - for (Participant participant : participantList) { - var participantType = new ToscaConceptIdentifier(); - participantType.setName(participant.getType()); - participantType.setVersion(participant.getTypeVersion()); - - var participantUpdate = new ParticipantUpdate(); - participantUpdate.setParticipantId(participant.getDefinition()); - participantUpdate.setParticipantType(participantType); - - this.supervisionHandler.handleSendDeCommissionMessage(participantUpdate); - } + if (!participantList.isEmpty()) { + this.supervisionHandler.handleSendDeCommissionMessage(); } - modelsProvider.deleteServiceTemplate(name, version); } @@ -342,7 +319,7 @@ public class CommissioningProvider { * @return the node types with common or instance properties * @throws PfModelException on errors getting node type properties */ - private Map<String, ToscaNodeType> getCommonOrInstancePropertiesFromNodeTypes(boolean common, String name, + public Map<String, ToscaNodeType> getCommonOrInstancePropertiesFromNodeTypes(boolean common, String name, String version) throws PfModelException { var serviceTemplates = new ToscaServiceTemplates(); serviceTemplates.setServiceTemplates(modelsProvider.getServiceTemplateList(name, version)); diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java index 28558cc02..5ec6158bd 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java @@ -32,6 +32,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.function.Function; import java.util.function.UnaryOperator; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -44,7 +45,9 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider; +import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider; import org.onap.policy.clamp.controlloop.models.messages.rest.GenericNameVersion; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.ControlLoopOrderStateResponse; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.ControlLoopPrimed; @@ -74,6 +77,7 @@ public class ControlLoopInstantiationProvider { private static final String CONTROL_LOOP_NODE_TYPE = "org.onap.policy.clamp.controlloop.ControlLoop"; private static final String CONTROL_LOOP_NODE_ELEMENT_TYPE = "ControlLoopElement"; private static final String PARTICIPANT_ID_PROPERTY_KEY = "participant_id"; + private static final String PARTICIPANT_TYPE_PROPERTY_KEY = "participantType"; private static final String CL_ELEMENT_NAME = "name"; private static final String CL_ELEMENT_VERSION = "version"; private static final String INSTANCE_TEXT = "_Instance"; @@ -83,6 +87,7 @@ public class ControlLoopInstantiationProvider { private final ControlLoopProvider controlLoopProvider; private final CommissioningProvider commissioningProvider; private final SupervisionHandler supervisionHandler; + private final ParticipantProvider participantProvider; private static final Object lockit = new Object(); @@ -94,20 +99,18 @@ public class ControlLoopInstantiationProvider { * @throws PfModelException on creation errors */ public InstancePropertiesResponse createInstanceProperties(ToscaServiceTemplate serviceTemplate) - throws PfModelException { + throws PfModelException { String instanceName = generateSequentialInstanceName(); ControlLoop controlLoop = new ControlLoop(); Map<UUID, ControlLoopElement> controlLoopElements = new HashMap<>(); - ToscaServiceTemplate toscaServiceTemplate = commissioningProvider - .getToscaServiceTemplate(null, null); + ToscaServiceTemplate toscaServiceTemplate = commissioningProvider.getToscaServiceTemplate(null, null); - Map<String, ToscaNodeTemplate> persistedNodeTemplateMap = toscaServiceTemplate - .getToscaTopologyTemplate().getNodeTemplates(); + Map<String, ToscaNodeTemplate> persistedNodeTemplateMap = + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates(); - Map<String, ToscaNodeTemplate> nodeTemplates = - deepCloneNodeTemplate(serviceTemplate); + Map<String, ToscaNodeTemplate> nodeTemplates = deepCloneNodeTemplate(serviceTemplate); nodeTemplates.forEach((key, template) -> { ToscaNodeTemplate newNodeTemplate = new ToscaNodeTemplate(); @@ -153,15 +156,14 @@ public class ControlLoopInstantiationProvider { ToscaServiceTemplate toscaServiceTemplate = commissioningProvider.getToscaServiceTemplate(name, version); - toscaServiceTemplate.getToscaTopologyTemplate() - .getNodeTemplates().forEach((key, nodeTemplate) -> { - if (!nodeTemplate.getName().contains(instanceName)) { - filteredToscaNodeTemplateMap.put(key, nodeTemplate); - } - }); + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().forEach((key, nodeTemplate) -> { + if (!nodeTemplate.getName().contains(instanceName)) { + filteredToscaNodeTemplateMap.put(key, nodeTemplate); + } + }); - List<ToscaNodeTemplate> filteredToscaNodeTemplateList = - toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().values().stream() + List<ToscaNodeTemplate> filteredToscaNodeTemplateList = toscaServiceTemplate.getToscaTopologyTemplate() + .getNodeTemplates().values().stream() .filter(nodeTemplate -> nodeTemplate.getName().contains(instanceName)).collect(Collectors.toList()); InstantiationResponse response = this.deleteControlLoop(name, version); @@ -182,8 +184,7 @@ public class ControlLoopInstantiationProvider { synchronized (lockit) { for (ControlLoop controlLoop : controlLoops.getControlLoopList()) { - var checkControlLoop = controlLoopProvider - .getControlLoop(controlLoop.getKey().asIdentifier()); + var checkControlLoop = controlLoopProvider.getControlLoop(controlLoop.getKey().asIdentifier()); if (checkControlLoop != null) { throw new PfModelException(Response.Status.BAD_REQUEST, controlLoop.getKey().asIdentifier() + " already defined"); @@ -348,12 +349,20 @@ public class ControlLoopInstantiationProvider { } synchronized (lockit) { + var participants = participantProvider.getParticipants(null, null); + if (participants.isEmpty()) { + throw new ControlLoopException(Status.BAD_REQUEST, "No participants registered"); + } List<ControlLoop> controlLoops = new ArrayList<>(command.getControlLoopIdentifierList().size()); for (ToscaConceptIdentifier id : command.getControlLoopIdentifierList()) { var controlLoop = controlLoopProvider.getControlLoop(id); controlLoop.setCascadedOrderedState(command.getOrderedState()); controlLoops.add(controlLoop); } + BeanValidationResult validationResult = validateIssueControlLoops(controlLoops, participants); + if (!validationResult.isValid()) { + throw new PfModelException(Response.Status.BAD_REQUEST, validationResult.getResult()); + } controlLoopProvider.updateControlLoops(controlLoops); } @@ -364,6 +373,37 @@ public class ControlLoopInstantiationProvider { return response; } + private BeanValidationResult validateIssueControlLoops(List<ControlLoop> controlLoops, + List<Participant> participants) { + var result = new BeanValidationResult("ControlLoops", controlLoops); + + Map<ToscaConceptIdentifier, Participant> participantMap = participants.stream() + .collect(Collectors.toMap(participant -> participant.getKey().asIdentifier(), Function.identity())); + + for (ControlLoop controlLoop : controlLoops) { + + for (var element : controlLoop.getElements().values()) { + var subResult = new BeanValidationResult("entry " + element.getDefinition().getName(), element); + + Participant p = participantMap.get(element.getParticipantId()); + if (p == null) { + subResult.addResult(new ObjectValidationResult(CONTROL_LOOP_NODE_ELEMENT_TYPE, + element.getDefinition().getName(), ValidationStatus.INVALID, + "Participant with ID " + element.getParticipantId() + " is not registered")); + } else if (!p.getParticipantType().equals(element.getParticipantType())) { + subResult.addResult(new ObjectValidationResult(CONTROL_LOOP_NODE_ELEMENT_TYPE, + element.getDefinition().getName(), ValidationStatus.INVALID, + "Participant with ID " + element.getParticipantType() + " - " + element.getParticipantId() + + " is not registered")); + } + result.addResult(subResult); + } + + } + + return result; + } + /** * Gets a list of control loops with it's ordered state. * @@ -373,7 +413,7 @@ public class ControlLoopInstantiationProvider { * @throws PfModelException on errors getting control loops */ public ControlLoopOrderStateResponse getInstantiationOrderState(String name, String version) - throws PfModelException { + throws PfModelException { List<ControlLoop> controlLoops = controlLoopProvider.getControlLoops(name, version); @@ -398,8 +438,7 @@ public class ControlLoopInstantiationProvider { * @return a list of Instantiation Command * @throws PfModelException on errors getting control loops */ - public ControlLoopPrimedResponse getControlLoopPriming(String name, String version) - throws PfModelException { + public ControlLoopPrimedResponse getControlLoopPriming(String name, String version) throws PfModelException { List<ControlLoop> controlLoops = controlLoopProvider.getControlLoops(name, version); @@ -424,8 +463,8 @@ public class ControlLoopInstantiationProvider { * @return the result of the instance properties and instantiation operation * @throws PfModelException on creation errors */ - private InstancePropertiesResponse saveInstancePropertiesAndControlLoop( - ToscaServiceTemplate serviceTemplate, ControlLoops controlLoops) throws PfModelException { + private InstancePropertiesResponse saveInstancePropertiesAndControlLoop(ToscaServiceTemplate serviceTemplate, + ControlLoops controlLoops) throws PfModelException { var response = new InstancePropertiesResponse(); @@ -436,7 +475,7 @@ public class ControlLoopInstantiationProvider { var checkControlLoop = controlLoopProvider.getControlLoop(controlLoop.getKey().asIdentifier()); if (checkControlLoop != null) { throw new PfModelException(Response.Status.BAD_REQUEST, - controlLoop.getKey().asIdentifier() + " already defined"); + "Control loop with id " + controlLoop.getKey().asIdentifier() + " already defined"); } } @@ -447,19 +486,20 @@ public class ControlLoopInstantiationProvider { } List<ToscaConceptIdentifier> affectedControlLoops = controlLoops.getControlLoopList().stream() - .map(cl -> cl.getKey().asIdentifier()).collect(Collectors.toList()); + .map(cl -> cl.getKey().asIdentifier()).collect(Collectors.toList()); List<ToscaConceptIdentifier> toscaAffectedProperties = toscaSavedNodeTemplate.values().stream() - .map(template -> template.getKey().asIdentifier()).collect(Collectors.toList()); + .map(template -> template.getKey().asIdentifier()).collect(Collectors.toList()); response.setAffectedInstanceProperties(Stream.of(affectedControlLoops, toscaAffectedProperties) - .flatMap(Collection::stream).collect(Collectors.toList())); + .flatMap(Collection::stream).collect(Collectors.toList())); return response; } /** * Crates a new Control Loop instance. + * * @param instanceName Control Loop Instance name * @param controlLoop empty Control Loop * @param controlLoopElements new Control Loop Element map @@ -467,15 +507,14 @@ public class ControlLoopInstantiationProvider { * @param newNodeTemplate new Tosca Node Template */ private void crateNewControlLoopInstance(String instanceName, ControlLoop controlLoop, - Map<UUID, ControlLoopElement> controlLoopElements, - ToscaNodeTemplate template, - ToscaNodeTemplate newNodeTemplate) { + Map<UUID, ControlLoopElement> controlLoopElements, ToscaNodeTemplate template, + ToscaNodeTemplate newNodeTemplate) { if (template.getType().equals(CONTROL_LOOP_NODE_TYPE)) { controlLoop.setDefinition(getControlLoopDefinition(newNodeTemplate)); } if (template.getType().contains(CONTROL_LOOP_NODE_ELEMENT_TYPE)) { - ControlLoopElement controlLoopElement = getControlLoopElement(instanceName, newNodeTemplate); + ControlLoopElement controlLoopElement = getControlLoopElement(newNodeTemplate); controlLoopElements.put(controlLoopElement.getId(), controlLoopElement); } @@ -486,7 +525,6 @@ public class ControlLoopInstantiationProvider { controlLoop.setOrderedState(ControlLoopOrderedState.UNINITIALISED); } - /** * Get's the instance property name of the control loop. * @@ -496,9 +534,8 @@ public class ControlLoopInstantiationProvider { * @throws PfModelException on errors getting control loops */ private String getInstancePropertyName(String name, String version) throws PfModelException { - List<String> toscaDefinitionsNames = - controlLoopProvider.getControlLoops(name, version).stream().map(ControlLoop::getDefinition) - .map(ToscaNameVersion::getName).collect(Collectors.toList()); + List<String> toscaDefinitionsNames = controlLoopProvider.getControlLoops(name, version).stream() + .map(ControlLoop::getDefinition).map(ToscaNameVersion::getName).collect(Collectors.toList()); return toscaDefinitionsNames.stream().reduce("", (s1, s2) -> { @@ -520,8 +557,7 @@ public class ControlLoopInstantiationProvider { private String generateSequentialInstanceName() { List<ToscaNodeTemplate> nodeTemplates = controlLoopProvider.getNodeTemplates(null, null); - int instanceNumber = - nodeTemplates.stream().map(ToscaNodeTemplate::getName) + int instanceNumber = nodeTemplates.stream().map(ToscaNodeTemplate::getName) .filter(name -> name.contains(INSTANCE_TEXT)).map(n -> { String[] defNameArr = n.split(INSTANCE_TEXT); @@ -548,27 +584,36 @@ public class ControlLoopInstantiationProvider { /** * Retrieves Control Loop Element. * - * @param instanceName instance name to be appended to participant name * @param template tosca node template * @return a control loop element */ @SuppressWarnings("unchecked") - private ControlLoopElement getControlLoopElement(String instanceName, ToscaNodeTemplate template) { + private ControlLoopElement getControlLoopElement(ToscaNodeTemplate template) { ControlLoopElement controlLoopElement = new ControlLoopElement(); ToscaConceptIdentifier definition = new ToscaConceptIdentifier(); definition.setName(template.getName()); definition.setVersion(template.getVersion()); controlLoopElement.setDefinition(definition); - LinkedTreeMap<String, Object> participantId = (LinkedTreeMap<String, Object>) template.getProperties() - .get(PARTICIPANT_ID_PROPERTY_KEY); + LinkedTreeMap<String, Object> participantId = + (LinkedTreeMap<String, Object>) template.getProperties().get(PARTICIPANT_ID_PROPERTY_KEY); - ToscaConceptIdentifier participantIdAndType = new ToscaConceptIdentifier(); - participantIdAndType.setName(participantId.get(CL_ELEMENT_NAME) + instanceName); - participantIdAndType.setVersion(String.valueOf(participantId.get(CL_ELEMENT_VERSION))); + if (participantId != null) { + ToscaConceptIdentifier participantIdProperty = new ToscaConceptIdentifier(); + participantIdProperty.setName(String.valueOf(participantId.get(CL_ELEMENT_NAME))); + participantIdProperty.setVersion(String.valueOf(participantId.get(CL_ELEMENT_VERSION))); + controlLoopElement.setParticipantId(participantIdProperty); + } + + LinkedTreeMap<String, Object> participantType = + (LinkedTreeMap<String, Object>) template.getProperties().get(PARTICIPANT_TYPE_PROPERTY_KEY); - controlLoopElement.setParticipantType(participantIdAndType); - controlLoopElement.setParticipantId(participantIdAndType); + if (participantType != null) { + ToscaConceptIdentifier participantTypeProperty = new ToscaConceptIdentifier(); + participantTypeProperty.setName(String.valueOf(participantType.get(CL_ELEMENT_NAME))); + participantTypeProperty.setVersion(participantType.get(CL_ELEMENT_VERSION).toString()); + controlLoopElement.setParticipantType(participantTypeProperty); + } return controlLoopElement; } diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java index c4ca568f7..20292633b 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java @@ -21,6 +21,7 @@ package org.onap.policy.clamp.controlloop.runtime.supervision; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -42,7 +43,6 @@ import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.Contr import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregister; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegister; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatus; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdateAck; import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider; import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ControlLoopStateChangePublisher; @@ -52,6 +52,7 @@ import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantReg import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantUpdatePublisher; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -142,15 +143,11 @@ public class SupervisionHandler { * * @param participantRegisterMessage the ParticipantRegister message received from a participant */ - @MessageIntercept public void handleParticipantMessage(ParticipantRegister participantRegisterMessage) { LOGGER.debug("Participant Register received {}", participantRegisterMessage); participantRegisterAckPublisher.send(participantRegisterMessage.getMessageId(), participantRegisterMessage.getParticipantId(), participantRegisterMessage.getParticipantType()); - - participantUpdatePublisher.send(participantRegisterMessage.getParticipantId(), - participantRegisterMessage.getParticipantType(), true); } /** @@ -209,25 +206,19 @@ public class SupervisionHandler { /** * Send commissioning update message to dmaap. * - * @param participantUpdateMessage the ParticipantUpdate message to send */ - public void handleSendCommissionMessage(ParticipantUpdate participantUpdateMessage) { - LOGGER.debug("Participant update message being sent {}", participantUpdateMessage); - - participantUpdatePublisher.send(participantUpdateMessage.getParticipantId(), - participantUpdateMessage.getParticipantType(), true); + public void handleSendCommissionMessage(Map<String, ToscaNodeType> commonPropertiesMap) { + LOGGER.debug("Participant update message being sent {}"); + participantUpdatePublisher.send(commonPropertiesMap, true); } /** * Send decommissioning update message to dmaap. * - * @param participantUpdateMessage the ParticipantUpdate message to send */ - public void handleSendDeCommissionMessage(ParticipantUpdate participantUpdateMessage) { - LOGGER.debug("Participant update message being sent {}", participantUpdateMessage); - - participantUpdatePublisher.send(participantUpdateMessage.getParticipantId(), - participantUpdateMessage.getParticipantType(), false); + public void handleSendDeCommissionMessage() { + LOGGER.debug("Participant update message being sent"); + participantUpdatePublisher.send(Collections.emptyMap(), false); } /** @@ -429,6 +420,7 @@ public class SupervisionHandler { participant.setName(participantStatusMessage.getParticipantId().getName()); participant.setVersion(participantStatusMessage.getParticipantId().getVersion()); participant.setDefinition(participantStatusMessage.getParticipantId()); + participant.setParticipantType(participantStatusMessage.getParticipantType()); participant.setParticipantState(participantStatusMessage.getState()); participant.setHealthStatus(participantStatusMessage.getHealthStatus()); diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionScanner.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionScanner.java index d13d66c5d..684711677 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionScanner.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionScanner.java @@ -29,6 +29,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantHealthStatus; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUtils; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider; import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; @@ -37,7 +38,10 @@ import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ControlLoopUpd import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantStatusReqPublisher; import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantUpdatePublisher; import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.provider.PolicyModelsProvider; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -55,6 +59,7 @@ public class SupervisionScanner { new HandleCounter<>(); private final ControlLoopProvider controlLoopProvider; + private final PolicyModelsProvider modelsProvider; private final ControlLoopStateChangePublisher controlLoopStateChangePublisher; private final ControlLoopUpdatePublisher controlLoopUpdatePublisher; private final ParticipantProvider participantProvider; @@ -65,6 +70,7 @@ public class SupervisionScanner { * Constructor for instantiating SupervisionScanner. * * @param controlLoopProvider the provider to use to read control loops from the database + * @param modelsProvider the Policy Models Provider * @param controlLoopStateChangePublisher the ControlLoop StateChange Publisher * @param controlLoopUpdatePublisher the ControlLoopUpdate Publisher * @param participantProvider the Participant Provider @@ -72,13 +78,14 @@ public class SupervisionScanner { * @param participantUpdatePublisher the Participant Update Publisher * @param clRuntimeParameterGroup the parameters for the control loop runtime */ - public SupervisionScanner(final ControlLoopProvider controlLoopProvider, + public SupervisionScanner(final ControlLoopProvider controlLoopProvider, PolicyModelsProvider modelsProvider, final ControlLoopStateChangePublisher controlLoopStateChangePublisher, ControlLoopUpdatePublisher controlLoopUpdatePublisher, ParticipantProvider participantProvider, ParticipantStatusReqPublisher participantStatusReqPublisher, ParticipantUpdatePublisher participantUpdatePublisher, final ClRuntimeParameterGroup clRuntimeParameterGroup) { this.controlLoopProvider = controlLoopProvider; + this.modelsProvider = modelsProvider; this.controlLoopStateChangePublisher = controlLoopStateChangePublisher; this.controlLoopUpdatePublisher = controlLoopUpdatePublisher; this.participantProvider = participantProvider; @@ -119,8 +126,13 @@ public class SupervisionScanner { } try { - for (ControlLoop controlLoop : controlLoopProvider.getControlLoops(null, null)) { - scanControlLoop(controlLoop, counterCheck); + var list = modelsProvider.getServiceTemplateList(null, null); + if (list != null && !list.isEmpty()) { + ToscaServiceTemplate toscaServiceTemplate = list.get(0); + + for (ControlLoop controlLoop : controlLoopProvider.getControlLoops(null, null)) { + scanControlLoop(controlLoop, toscaServiceTemplate, counterCheck); + } } } catch (PfModelException pfme) { LOGGER.warn("error reading control loops from database", pfme); @@ -144,7 +156,7 @@ public class SupervisionScanner { if (participantUpdateCounter.count(id)) { LOGGER.debug("retry message ParticipantUpdate"); - participantUpdatePublisher.send(id.getLeft(), id.getRight(), true); + participantUpdatePublisher.send(null, true); } else { LOGGER.debug("report Participant Update fault"); participantUpdateCounter.setFault(id); @@ -190,7 +202,8 @@ public class SupervisionScanner { participantUpdateCounter.remove(id); } - private void scanControlLoop(final ControlLoop controlLoop, boolean counterCheck) throws PfModelException { + private void scanControlLoop(final ControlLoop controlLoop, ToscaServiceTemplate toscaServiceTemplate, + boolean counterCheck) throws PfModelException { LOGGER.debug("scanning control loop {} . . .", controlLoop.getKey().asIdentifier()); if (controlLoop.getState().equals(controlLoop.getOrderedState().asState())) { @@ -202,11 +215,16 @@ public class SupervisionScanner { } var completed = true; + var minSpNotCompleted = 1000; // min startPhase not completed for (ControlLoopElement element : controlLoop.getElements().values()) { if (!element.getState().equals(element.getOrderedState().asState())) { completed = false; - break; + ToscaNodeTemplate toscaNodeTemplate = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates() + .get(element.getDefinition().getName()); + int startPhase = ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties()); + minSpNotCompleted = Math.min(minSpNotCompleted, startPhase); } + } if (completed) { @@ -222,7 +240,7 @@ public class SupervisionScanner { LOGGER.debug("control loop scan: transition from state {} to {} not completed", controlLoop.getState(), controlLoop.getOrderedState()); if (counterCheck) { - handleCounter(controlLoop); + handleCounter(controlLoop, minSpNotCompleted); } } } @@ -231,7 +249,7 @@ public class SupervisionScanner { controlLoopCounter.clear(controlLoop.getKey().asIdentifier()); } - private void handleCounter(ControlLoop controlLoop) { + private void handleCounter(ControlLoop controlLoop, int startPhase) { ToscaConceptIdentifier id = controlLoop.getKey().asIdentifier(); if (controlLoopCounter.isFault(id)) { LOGGER.debug("report ControlLoop fault"); @@ -242,7 +260,7 @@ public class SupervisionScanner { if (controlLoopCounter.count(id)) { if (ControlLoopState.UNINITIALISED2PASSIVE.equals(controlLoop.getState())) { LOGGER.debug("retry message ControlLoopUpdate"); - controlLoopUpdatePublisher.send(controlLoop); + controlLoopUpdatePublisher.send(controlLoop, startPhase); } else { LOGGER.debug("retry message ControlLoopStateChange"); controlLoopStateChangePublisher.send(controlLoop); diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ControlLoopUpdatePublisher.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ControlLoopUpdatePublisher.java index d68a643d2..74d987240 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ControlLoopUpdatePublisher.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ControlLoopUpdatePublisher.java @@ -58,7 +58,18 @@ public class ControlLoopUpdatePublisher extends AbstractParticipantPublisher<Con * @param controlLoop the ControlLoop */ public void send(ControlLoop controlLoop) { + send(controlLoop, 0); + } + + /** + * Send ControlLoopUpdate to Participant. + * + * @param controlLoop the ControlLoop + * @param startPhase the Start Phase + */ + public void send(ControlLoop controlLoop, int startPhase) { var controlLoopUpdateMsg = new ControlLoopUpdate(); + controlLoopUpdateMsg.setStartPhase(startPhase); controlLoopUpdateMsg.setControlLoopId(controlLoop.getKey().asIdentifier()); controlLoopUpdateMsg.setMessageId(UUID.randomUUID()); controlLoopUpdateMsg.setTimestamp(Instant.now()); diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ParticipantUpdatePublisher.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ParticipantUpdatePublisher.java index fe46297f1..0f6cc7cbc 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ParticipantUpdatePublisher.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ParticipantUpdatePublisher.java @@ -25,6 +25,7 @@ package org.onap.policy.clamp.controlloop.runtime.supervision.comm; import java.time.Instant; import java.util.ArrayList; import java.util.List; +import java.util.Map; import lombok.AllArgsConstructor; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition; @@ -34,6 +35,7 @@ import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.provider.PolicyModelsProvider; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,14 +55,9 @@ public class ParticipantUpdatePublisher extends AbstractParticipantPublisher<Par /** * Send ParticipantUpdate to Participant. * - * @param participantId the participant Id - * @param participantType the participant Type */ - public void send(ToscaConceptIdentifier participantId, ToscaConceptIdentifier participantType, - boolean commissionFlag) { + public void send(Map<String, ToscaNodeType> commonPropertiesMap, boolean commissionFlag) { var message = new ParticipantUpdate(); - message.setParticipantId(participantId); - message.setParticipantType(participantType); message.setTimestamp(Instant.now()); ToscaServiceTemplate toscaServiceTemplate = null; @@ -82,7 +79,7 @@ public class ParticipantUpdatePublisher extends AbstractParticipantPublisher<Par var clParticipantType = ParticipantUtils.findParticipantType(toscaInputEntry.getValue().getProperties()); prepareParticipantDefinitionUpdate(clParticipantType, toscaInputEntry.getKey(), - toscaInputEntry.getValue(), participantDefinitionUpdates); + toscaInputEntry.getValue(), participantDefinitionUpdates, commonPropertiesMap); } } } @@ -99,11 +96,17 @@ public class ParticipantUpdatePublisher extends AbstractParticipantPublisher<Par } private void prepareParticipantDefinitionUpdate(ToscaConceptIdentifier clParticipantType, String entryKey, - ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates) { + ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates, + Map<String, ToscaNodeType> commonPropertiesMap) { var clDefinition = new ControlLoopElementDefinition(); clDefinition.setClElementDefinitionId(new ToscaConceptIdentifier(entryKey, entryValue.getVersion())); clDefinition.setControlLoopElementToscaNodeTemplate(entryValue); + ToscaNodeType nodeType = commonPropertiesMap.get(entryValue.getType()); + if (nodeType != null) { + clDefinition.setCommonPropertiesMap(nodeType.getProperties()); + } + List<ControlLoopElementDefinition> controlLoopElementDefinitionList = new ArrayList<>(); if (participantDefinitionUpdates.isEmpty()) { diff --git a/runtime-controlloop/src/main/resources/application.yaml b/runtime-controlloop/src/main/resources/application.yaml index 96c340491..50c063fb3 100644 --- a/runtime-controlloop/src/main/resources/application.yaml +++ b/runtime-controlloop/src/main/resources/application.yaml @@ -26,7 +26,7 @@ runtime: heartBeatMs: 20000 maxStatusWaitMs: 100000 updateParameters: - maxRetryCount: 3 + maxRetryCount: 4 maxWaitMs: 20000 databaseProviderParameters: name: PolicyProviderParameterGroup diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java index 7f04056cf..24272e308 100644 --- a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java @@ -26,6 +26,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.io.IOException; import java.util.ArrayList; +import java.util.List; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -107,7 +108,7 @@ class ControlLoopInstantiationProviderTest { @BeforeAll public static void setUpBeforeClass() throws Exception { serviceTemplate = yamlTranslator.fromYaml(ResourceUtils.getResourceAsString(TOSCA_TEMPLATE_YAML), - ToscaServiceTemplate.class); + ToscaServiceTemplate.class); } /** @@ -119,8 +120,7 @@ class ControlLoopInstantiationProviderTest { public static void setupDbProviderParameters() throws PfModelException { ClRuntimeParameterGroup controlLoopParameters = CommonTestData.geParameterGroup("instantproviderdb"); - modelsProvider = - CommonTestData.getPolicyModelsProvider(controlLoopParameters.getDatabaseProviderParameters()); + modelsProvider = CommonTestData.getPolicyModelsProvider(controlLoopParameters.getDatabaseProviderParameters()); clProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters()); participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters()); @@ -138,8 +138,8 @@ class ControlLoopInstantiationProviderTest { var participantDeregisterAckPublisher = Mockito.mock(ParticipantDeregisterAckPublisher.class); var participantUpdatePublisher = Mockito.mock(ParticipantUpdatePublisher.class); supervisionHandler = new SupervisionHandler(clProvider, participantProvider, monitoringProvider, - controlLoopUpdatePublisher, controlLoopStateChangePublisher, - participantRegisterAckPublisher, participantDeregisterAckPublisher, participantUpdatePublisher); + controlLoopUpdatePublisher, controlLoopStateChangePublisher, participantRegisterAckPublisher, + participantDeregisterAckPublisher, participantUpdatePublisher); } @BeforeEach @@ -160,13 +160,14 @@ class ControlLoopInstantiationProviderTest { @Test void testInstantiationCrud() throws Exception { + participantProvider.createParticipants(CommonTestData.createParticipants()); ControlLoops controlLoopsCreate = InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Crud"); ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate); assertThat(controlLoopsDb.getControlLoopList()).isEmpty(); - var instantiationProvider = - new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler); + var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, + supervisionHandler, participantProvider); InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate); InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate); @@ -222,8 +223,8 @@ class ControlLoopInstantiationProviderTest { ControlLoops controlLoopsDb = new ControlLoops(); controlLoopsDb.setControlLoopList(new ArrayList<>()); - var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, - commissioningProvider, supervisionHandler); + var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, + supervisionHandler, participantProvider); for (ControlLoop controlLoop : controlLoopsSource.getControlLoopList()) { ControlLoops controlLoopsFromDb = @@ -242,12 +243,12 @@ class ControlLoopInstantiationProviderTest { ControlLoop controlLoop0 = controlLoops.getControlLoopList().get(0); - var instantiationProvider = - new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler); + var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, + supervisionHandler, participantProvider); assertThatThrownBy( - () -> instantiationProvider.deleteControlLoop(controlLoop0.getName(), controlLoop0.getVersion())) - .hasMessageMatching(CONTROL_LOOP_NOT_FOUND); + () -> instantiationProvider.deleteControlLoop(controlLoop0.getName(), controlLoop0.getVersion())) + .hasMessageMatching(CONTROL_LOOP_NOT_FOUND); InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoops), controlLoops); @@ -277,13 +278,13 @@ class ControlLoopInstantiationProviderTest { controlLoop.setState(state); - var instantiationProvider = - new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler); + var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, + supervisionHandler, participantProvider); instantiationProvider.updateControlLoops(controlLoops); assertThatThrownBy( - () -> instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion())) - .hasMessageMatching(String.format(DELETE_BAD_REQUEST, state)); + () -> instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion())) + .hasMessageMatching(String.format(DELETE_BAD_REQUEST, state)); } @Test @@ -295,8 +296,8 @@ class ControlLoopInstantiationProviderTest { ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate); assertThat(controlLoopsDb.getControlLoopList()).isEmpty(); - var instantiationProvider = - new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler); + var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, + supervisionHandler, participantProvider); InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate); InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate); @@ -315,10 +316,11 @@ class ControlLoopInstantiationProviderTest { ControlLoops controlLoops = InstantiationUtils .getControlLoopsFromResource(CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "ClElementNotFound"); - var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler); + var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler, + participantProvider); // to validate control Loop, it needs to define ToscaServiceTemplate - // InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider); + // InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider); assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty(); @@ -333,15 +335,16 @@ class ControlLoopInstantiationProviderTest { assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty(); - var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler); + var provider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler, + participantProvider); assertThatThrownBy(() -> provider.createControlLoops(controlLoops)) .hasMessageMatching(CONTROLLOOP_DEFINITION_NOT_FOUND); } @Test void testIssueControlLoopCommand_OrderedStateInvalid() throws ControlLoopRuntimeException, IOException { - var instantiationProvider = - new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler); + var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, + supervisionHandler, participantProvider); assertThatThrownBy(() -> instantiationProvider.issueControlLoopCommand(new InstantiationCommand())) .hasMessageMatching(ORDERED_STATE_INVALID); } @@ -353,8 +356,8 @@ class ControlLoopInstantiationProviderTest { InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V1"); assertThat(getControlLoopsFromDb(controlLoopsV1).getControlLoopList()).isEmpty(); - var instantiationProvider = - new ControlLoopInstantiationProvider(clProvider, commissioningProvider, supervisionHandler); + var instantiationProvider = new ControlLoopInstantiationProvider(clProvider, commissioningProvider, + supervisionHandler, participantProvider); InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV1), controlLoopsV1); diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java index 42e4ddee2..5a15687c5 100644 --- a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java @@ -36,6 +36,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; +import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.ControlLoopPrimedResponse; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse; @@ -43,6 +44,7 @@ import org.onap.policy.clamp.controlloop.runtime.instantiation.ControlLoopInstan import org.onap.policy.clamp.controlloop.runtime.instantiation.InstantiationUtils; import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; import org.onap.policy.clamp.controlloop.runtime.main.rest.InstantiationController; +import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData; import org.onap.policy.clamp.controlloop.runtime.util.rest.CommonRestController; import org.onap.policy.common.utils.coder.YamlJsonTranslator; import org.onap.policy.common.utils.resources.ResourceUtils; @@ -94,6 +96,9 @@ class InstantiationControllerTest extends CommonRestController { @Autowired private ControlLoopInstantiationProvider instantiationProvider; + @Autowired + private ParticipantProvider participantProvider; + @LocalServerPort private int randomServerPort; @@ -326,10 +331,11 @@ class InstantiationControllerTest extends CommonRestController { @Test void testCommand() throws Exception { - var controlLoops = InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Command"); instantiationProvider.createControlLoops(controlLoops); + participantProvider.createParticipants(CommonTestData.createParticipants()); + InstantiationCommand command = InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Command"); diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionScannerTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionScannerTest.java index 2ba321d36..1bf445734 100644 --- a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionScannerTest.java +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionScannerTest.java @@ -46,13 +46,16 @@ import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantSta import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantUpdatePublisher; import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData; import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.provider.PolicyModelsProvider; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; class SupervisionScannerTest { @Test void testScannerOrderedStateEqualsToState() throws PfModelException { var controlLoopProvider = mock(ControlLoopProvider.class); + var modelsProvider = mock(PolicyModelsProvider.class); var controlLoopStateChangePublisher = mock(ControlLoopStateChangePublisher.class); var controlLoopUpdatePublisher = mock(ControlLoopUpdatePublisher.class); var participantProvider = mock(ParticipantProvider.class); @@ -63,9 +66,9 @@ class SupervisionScannerTest { var controlLoop = new ControlLoop(); when(controlLoopProvider.getControlLoops(null, null)).thenReturn(List.of(controlLoop)); - var supervisionScanner = new SupervisionScanner(controlLoopProvider, controlLoopStateChangePublisher, - controlLoopUpdatePublisher, participantProvider, participantStatusReqPublisher, - participantUpdatePublisher, clRuntimeParameterGroup); + var supervisionScanner = new SupervisionScanner(controlLoopProvider, modelsProvider, + controlLoopStateChangePublisher, controlLoopUpdatePublisher, participantProvider, + participantStatusReqPublisher, participantUpdatePublisher, clRuntimeParameterGroup); supervisionScanner.run(false); verify(controlLoopProvider, times(0)).updateControlLoop(any(ControlLoop.class)); @@ -87,9 +90,12 @@ class SupervisionScannerTest { var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class); var clRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner"); - var supervisionScanner = new SupervisionScanner(controlLoopProvider, controlLoopStateChangePublisher, - controlLoopUpdatePublisher, participantProvider, participantStatusReqPublisher, - participantUpdatePublisher, clRuntimeParameterGroup); + var modelsProvider = mock(PolicyModelsProvider.class); + when(modelsProvider.getServiceTemplateList(null, null)).thenReturn(List.of(new ToscaServiceTemplate())); + + var supervisionScanner = new SupervisionScanner(controlLoopProvider, modelsProvider, + controlLoopStateChangePublisher, controlLoopUpdatePublisher, participantProvider, + participantStatusReqPublisher, participantUpdatePublisher, clRuntimeParameterGroup); supervisionScanner.run(false); verify(controlLoopProvider, times(1)).updateControlLoop(any(ControlLoop.class)); @@ -107,15 +113,16 @@ class SupervisionScannerTest { participant.setVersion("1.0.0"); when(participantProvider.getParticipants(null, null)).thenReturn(List.of(participant)); + var modelsProvider = mock(PolicyModelsProvider.class); var controlLoopUpdatePublisher = mock(ControlLoopUpdatePublisher.class); var participantStatusReqPublisher = mock(ParticipantStatusReqPublisher.class); var controlLoopStateChangePublisher = mock(ControlLoopStateChangePublisher.class); var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class); var clRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner"); - var supervisionScanner = new SupervisionScanner(controlLoopProvider, controlLoopStateChangePublisher, - controlLoopUpdatePublisher, participantProvider, participantStatusReqPublisher, - participantUpdatePublisher, clRuntimeParameterGroup); + var supervisionScanner = new SupervisionScanner(controlLoopProvider, modelsProvider, + controlLoopStateChangePublisher, controlLoopUpdatePublisher, participantProvider, + participantStatusReqPublisher, participantUpdatePublisher, clRuntimeParameterGroup); supervisionScanner.handleParticipantStatus(participant.getKey().asIdentifier()); supervisionScanner.run(true); @@ -139,17 +146,19 @@ class SupervisionScannerTest { participant.setHealthStatus(ParticipantHealthStatus.HEALTHY); participant.setParticipantState(ParticipantState.ACTIVE); participant.setDefinition(new ToscaConceptIdentifier("unknown", "0.0.0")); + participant.setParticipantType(new ToscaConceptIdentifier("ParticipantType1", "1.0.0")); var participantProvider = new ParticipantProvider(clRuntimeParameterGroup.getDatabaseProviderParameters()); participantProvider.updateParticipants(List.of(participant)); + var modelsProvider = mock(PolicyModelsProvider.class); var controlLoopUpdatePublisher = mock(ControlLoopUpdatePublisher.class); var participantStatusReqPublisher = mock(ParticipantStatusReqPublisher.class); var controlLoopStateChangePublisher = mock(ControlLoopStateChangePublisher.class); var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class); - var supervisionScanner = new SupervisionScanner(controlLoopProvider, controlLoopStateChangePublisher, - controlLoopUpdatePublisher, participantProvider, participantStatusReqPublisher, - participantUpdatePublisher, clRuntimeParameterGroup); + var supervisionScanner = new SupervisionScanner(controlLoopProvider, modelsProvider, + controlLoopStateChangePublisher, controlLoopUpdatePublisher, participantProvider, + participantStatusReqPublisher, participantUpdatePublisher, clRuntimeParameterGroup); supervisionScanner.handleParticipantStatus(participant.getKey().asIdentifier()); supervisionScanner.run(true); diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/SupervisionMessagesTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/SupervisionMessagesTest.java index bcc3a701c..70d115e47 100644 --- a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/SupervisionMessagesTest.java +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/SupervisionMessagesTest.java @@ -24,29 +24,20 @@ package org.onap.policy.clamp.controlloop.runtime.supervision.comm; import static org.assertj.core.api.Assertions.assertThatCode; import java.time.Instant; -import java.util.ArrayList; import java.util.Collections; -import java.util.List; -import java.util.Map; import java.util.UUID; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUtils; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ClElementStatisticsProvider; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantStatisticsProvider; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregister; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregisterAck; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegister; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegisterAck; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdateAck; -import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider; import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider; import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler; @@ -54,27 +45,18 @@ import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData; import org.onap.policy.clamp.controlloop.runtime.util.rest.CommonRestController; import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; import org.onap.policy.common.endpoints.event.comm.TopicSink; -import org.onap.policy.common.utils.coder.YamlJsonTranslator; -import org.onap.policy.common.utils.resources.ResourceUtils; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.provider.PolicyModelsProvider; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; class SupervisionMessagesTest extends CommonRestController { - private static final String TOSCA_SERVICE_TEMPLATE_YAML = - "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml"; private static final Object lockit = new Object(); private static final CommInfrastructure INFRA = CommInfrastructure.NOOP; private static final String TOPIC = "my-topic"; private static SupervisionHandler supervisionHandler; - private static CommissioningProvider commissioningProvider; private static ControlLoopProvider clProvider; private static PolicyModelsProvider modelsProvider; - private static ParticipantProvider participantProvider; - private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); /** * setup Db Provider Parameters. @@ -87,13 +69,11 @@ class SupervisionMessagesTest extends CommonRestController { modelsProvider = CommonTestData.getPolicyModelsProvider(controlLoopParameters.getDatabaseProviderParameters()); clProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters()); - participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters()); var participantStatisticsProvider = new ParticipantStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters()); var clElementStatisticsProvider = new ClElementStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters()); - commissioningProvider = new CommissioningProvider(modelsProvider, clProvider, null, participantProvider); var monitoringProvider = new MonitoringProvider(participantStatisticsProvider, clElementStatisticsProvider, clProvider); var participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters()); @@ -114,26 +94,6 @@ class SupervisionMessagesTest extends CommonRestController { } @Test - void testReceiveParticipantRegister() throws Exception { - final ParticipantRegister participantRegisterMsg = new ParticipantRegister(); - participantRegisterMsg.setParticipantId(getParticipantId()); - participantRegisterMsg.setTimestamp(Instant.now()); - participantRegisterMsg.setParticipantType(getParticipantType()); - - synchronized (lockit) { - ParticipantRegisterListener participantRegisterListener = - new ParticipantRegisterListener(supervisionHandler); - ToscaServiceTemplate serviceTemplate = yamlTranslator.fromYaml( - ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML), ToscaServiceTemplate.class); - - // List<ToscaNodeTemplate> listOfTemplates = commissioningProvider.getControlLoopDefinitions(null, null); - commissioningProvider.createControlLoopDefinitions(serviceTemplate); - assertThatCode(() -> participantRegisterListener.onTopicEvent(INFRA, TOPIC, null, participantRegisterMsg)) - .doesNotThrowAnyException(); - } - } - - @Test void testSendParticipantRegisterAck() throws Exception { final ParticipantRegisterAck participantRegisterAckMsg = new ParticipantRegisterAck(); participantRegisterAckMsg.setMessage("ParticipantRegisterAck message"); @@ -178,72 +138,6 @@ class SupervisionMessagesTest extends CommonRestController { } @Test - void testSendParticipantUpdate() throws Exception { - final ParticipantUpdate participantUpdateMsg = new ParticipantUpdate(); - participantUpdateMsg.setParticipantId(getParticipantId()); - participantUpdateMsg.setTimestamp(Instant.now()); - participantUpdateMsg.setParticipantType(getParticipantType()); - participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000)); - participantUpdateMsg.setMessageId(UUID.randomUUID()); - - ToscaServiceTemplate toscaServiceTemplate = commissioningProvider.getToscaServiceTemplate(null, null); - List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>(); - for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry : toscaServiceTemplate.getToscaTopologyTemplate() - .getNodeTemplates().entrySet()) { - if (ParticipantUtils.checkIfNodeTemplateIsControlLoopElement(toscaInputEntry.getValue(), - toscaServiceTemplate)) { - var clParticipantType = - ParticipantUtils.findParticipantType(toscaInputEntry.getValue().getProperties()); - prepareParticipantDefinitionUpdate(clParticipantType, toscaInputEntry.getKey(), - toscaInputEntry.getValue(), participantDefinitionUpdates); - } - } - - participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates); - synchronized (lockit) { - ParticipantUpdatePublisher participantUpdatePublisher = new ParticipantUpdatePublisher(modelsProvider); - participantUpdatePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); - assertThatCode(() -> participantUpdatePublisher.send(participantUpdateMsg)).doesNotThrowAnyException(); - } - } - - private void prepareParticipantDefinitionUpdate(ToscaConceptIdentifier clParticipantType, String entryKey, - ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates) { - - var clDefinition = new ControlLoopElementDefinition(); - clDefinition.setClElementDefinitionId(new ToscaConceptIdentifier(entryKey, entryValue.getVersion())); - clDefinition.setControlLoopElementToscaNodeTemplate(entryValue); - List<ControlLoopElementDefinition> controlLoopElementDefinitionList = new ArrayList<>(); - - if (participantDefinitionUpdates.isEmpty()) { - participantDefinitionUpdates - .add(getParticipantDefinition(clDefinition, clParticipantType, controlLoopElementDefinitionList)); - } else { - boolean participantExists = false; - for (ParticipantDefinition participantDefinitionUpdate : participantDefinitionUpdates) { - if (participantDefinitionUpdate.getParticipantType().equals(clParticipantType)) { - participantDefinitionUpdate.getControlLoopElementDefinitionList().add(clDefinition); - participantExists = true; - } - } - if (!participantExists) { - participantDefinitionUpdates.add( - getParticipantDefinition(clDefinition, clParticipantType, controlLoopElementDefinitionList)); - } - } - } - - private ParticipantDefinition getParticipantDefinition(ControlLoopElementDefinition clDefinition, - ToscaConceptIdentifier clParticipantType, - List<ControlLoopElementDefinition> controlLoopElementDefinitionList) { - ParticipantDefinition participantDefinition = new ParticipantDefinition(); - participantDefinition.setParticipantType(clParticipantType); - controlLoopElementDefinitionList.add(clDefinition); - participantDefinition.setControlLoopElementDefinitionList(controlLoopElementDefinitionList); - return participantDefinition; - } - - @Test void testReceiveParticipantUpdateAckMessage() throws Exception { final ParticipantUpdateAck participantUpdateAckMsg = new ParticipantUpdateAck(); participantUpdateAckMsg.setMessage("ParticipantUpdateAck message"); diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/CommonTestData.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/CommonTestData.java index 300c662ce..13d30e401 100644 --- a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/CommonTestData.java +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/CommonTestData.java @@ -20,8 +20,10 @@ package org.onap.policy.clamp.controlloop.runtime.util; +import java.util.List; import javax.ws.rs.core.Response.Status; import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant; import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; @@ -32,6 +34,7 @@ import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.provider.PolicyModelsProvider; import org.onap.policy.models.provider.PolicyModelsProviderFactory; import org.onap.policy.models.provider.PolicyModelsProviderParameters; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; /** * Class to hold/create all parameters for test cases. @@ -81,4 +84,40 @@ public class CommonTestData { throw new PfModelRuntimeException(e); } } + + /** + * Create a List of Participants. + * + * @return a List of Participants + */ + public static List<Participant> createParticipants() { + var participant1 = createParticipant( + new ToscaConceptIdentifier("org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant", "2.3.4"), + new ToscaConceptIdentifier("org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant", + "2.3.4")); + var participant2 = createParticipant( + new ToscaConceptIdentifier("org.onap.policy.controlloop.PolicyControlLoopParticipant", "2.3.1"), + new ToscaConceptIdentifier("org.onap.policy.controlloop.PolicyControlLoopParticipant", "2.3.1")); + var participant3 = createParticipant( + new ToscaConceptIdentifier("org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant", "2.2.1"), + new ToscaConceptIdentifier("org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant", "2.2.1")); + return List.of(participant1, participant2, participant3); + } + + /** + * Create a new Participant. + * + * @param participantType the participant Type + * @param participantId the participant id + * @return a new Participant + */ + public static Participant createParticipant(ToscaConceptIdentifier participantType, + ToscaConceptIdentifier participantId) { + var participant = new Participant(); + participant.setDefinition(participantId); + participant.setParticipantType(participantType); + participant.setName(participantId.getName()); + participant.setVersion(participantId.getVersion()); + return participant; + } } diff --git a/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopsUpdate.json b/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopsUpdate.json index 025e2a1fb..b09e46fe7 100644 --- a/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopsUpdate.json +++ b/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopsUpdate.json @@ -17,6 +17,10 @@ "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice", "version": "1.2.3" }, + "participantId": { + "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant", + "version": "2.3.4" + }, "participantType": { "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant", "version": "2.3.4" @@ -31,6 +35,10 @@ "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement", "version": "1.2.3" }, + "participantId": { + "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant", + "version": "2.3.1" + }, "participantType": { "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant", "version": "2.3.1" @@ -45,6 +53,10 @@ "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement", "version": "1.2.3" }, + "participantId": { + "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant", + "version": "2.3.1" + }, "participantType": { "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant", "version": "2.3.1" @@ -59,6 +71,10 @@ "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement", "version": "1.2.3" }, + "participantId": { + "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant", + "version": "2.2.1" + }, "participantType": { "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant", "version": "2.2.1" @@ -86,6 +102,10 @@ "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice", "version": "1.2.3" }, + "participantId": { + "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant", + "version": "2.3.4" + }, "participantType": { "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant", "version": "2.3.4" @@ -100,6 +120,10 @@ "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement", "version": "1.2.3" }, + "participantId": { + "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant", + "version": "2.3.1" + }, "participantType": { "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant", "version": "2.3.1" @@ -114,6 +138,10 @@ "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement", "version": "1.2.3" }, + "participantId": { + "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant", + "version": "2.3.1" + }, "participantType": { "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant", "version": "2.3.1" @@ -128,6 +156,10 @@ "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement", "version": "1.2.3" }, + "participantId": { + "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant", + "version": "2.2.1" + }, "participantType": { "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant", "version": "2.2.1" diff --git a/runtime/src/main/java/org/onap/policy/clamp/clds/util/JsonUtils.java b/runtime/src/main/java/org/onap/policy/clamp/clds/util/JsonUtils.java index 909b240fb..7093952be 100644 --- a/runtime/src/main/java/org/onap/policy/clamp/clds/util/JsonUtils.java +++ b/runtime/src/main/java/org/onap/policy/clamp/clds/util/JsonUtils.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP CLAMP * ================================================================================ - * Copyright (C) 2018-2019 AT&T Intellectual Property. All rights + * Copyright (C) 2018-2021 AT&T Intellectual Property. All rights * reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -40,12 +40,16 @@ public class JsonUtils { protected static final Logger logger = LoggerFactory.getLogger(JsonUtils.class); - public static final Gson GSON = new GsonBuilder().setPrettyPrinting() + public static final Gson GSON = new GsonBuilder() + .registerTypeAdapter(Instant.class, new InstantSerializer()) + .registerTypeAdapter(Instant.class, new InstantDeserializer()) + .setPrettyPrinting() .registerTypeAdapter(SecureServicePermission.class, new SecureServicePermissionDeserializer()).create(); - public static final Gson GSON_JPA_MODEL = new GsonBuilder().setPrettyPrinting() + public static final Gson GSON_JPA_MODEL = new GsonBuilder() .registerTypeAdapter(Instant.class, new InstantSerializer()) .registerTypeAdapter(Instant.class, new InstantDeserializer()).setPrettyPrinting() + .setPrettyPrinting() .excludeFieldsWithoutExposeAnnotation().create(); private JsonUtils() { diff --git a/runtime/src/test/resources/http-cache/example/policy/pap/v1/pdps/.file b/runtime/src/test/resources/http-cache/example/policy/pap/v1/pdps/.file index 467409f47..8b75fc216 100644 --- a/runtime/src/test/resources/http-cache/example/policy/pap/v1/pdps/.file +++ b/runtime/src/test/resources/http-cache/example/policy/pap/v1/pdps/.file @@ -8,7 +8,15 @@ { "currentInstanceCount": 0, "desiredInstanceCount": 1, - "pdpInstances": [], + "pdpInstances": [ + { + "instanceId": "controlloop-f8287777-5f3e-4f0f-b21b-d8829c93f57b", + "pdpState": "ACTIVE", + "healthy": "HEALTHY", + "message": "Pdp Heartbeat", + "lastUpdate": "2021-09-29T02:51:21Z" + } + ], "pdpType": "apex", "policies": [ { @@ -31,7 +39,15 @@ { "currentInstanceCount": 0, "desiredInstanceCount": 1, - "pdpInstances": [], + "pdpInstances": [ + { + "instanceId": "drools-f8287777-5f3e-4f0f-b21b-d8829c93f57b", + "pdpState": "ACTIVE", + "healthy": "HEALTHY", + "message": "Pdp Heartbeat", + "lastUpdate": "2021-09-29T02:51:21Z" + } + ], "pdpType": "drools", "policies": [ { @@ -54,7 +70,15 @@ { "currentInstanceCount": 0, "desiredInstanceCount": 1, - "pdpInstances": [], + "pdpInstances": [ + { + "instanceId": "xacml-f8287777-5f3e-4f0f-b21b-d8829c93f57b", + "pdpState": "ACTIVE", + "healthy": "HEALTHY", + "message": "Pdp Heartbeat", + "lastUpdate": "2021-09-29T02:51:21Z" + } + ], "pdpType": "xacml", "policies": [], "properties": {}, @@ -76,7 +100,15 @@ { "currentInstanceCount": 0, "desiredInstanceCount": 1, - "pdpInstances": [], + "pdpInstances": [ + { + "instanceId": "monitoring-f8287777-5f3e-4f0f-b21b-d8829c93f57b", + "pdpState": "ACTIVE", + "healthy": "HEALTHY", + "message": "Pdp Heartbeat", + "lastUpdate": "2021-09-29T02:51:21Z" + } + ], "pdpType": "xacml", "policies": [ { |