diff options
Diffstat (limited to 'tosca-controlloop')
18 files changed, 1348 insertions, 97 deletions
diff --git a/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ClElementStatistics.java b/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ClElementStatistics.java index ec96830e2..014323090 100644 --- a/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ClElementStatistics.java +++ b/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ClElementStatistics.java @@ -22,21 +22,23 @@ package org.onap.policy.clamp.controlloop.models.controlloop.concepts; import java.io.Serializable; import java.time.Instant; +import java.util.UUID; import lombok.Data; import lombok.NoArgsConstructor; import lombok.NonNull; -import lombok.ToString; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; @NoArgsConstructor @Data -@ToString public class ClElementStatistics implements Serializable { private static final long serialVersionUID = 3284285693112271055L; @NonNull - private ToscaConceptIdentifier controlLoopElementId; + private UUID id = UUID.randomUUID(); + + @NonNull + private ToscaConceptIdentifier participantId; @NonNull private Instant timeStamp; diff --git a/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaClElementStatistics.java b/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaClElementStatistics.java index abe0737f6..ec5dbb32c 100644 --- a/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaClElementStatistics.java +++ b/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaClElementStatistics.java @@ -22,16 +22,18 @@ package org.onap.policy.clamp.controlloop.models.controlloop.persistence.concept import java.io.Serializable; import java.util.List; +import java.util.UUID; import javax.persistence.AttributeOverride; +import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Table; +import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; import lombok.NonNull; import org.apache.commons.lang3.builder.CompareToBuilder; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; @@ -41,7 +43,7 @@ import org.onap.policy.models.base.PfAuthorative; import org.onap.policy.models.base.PfConcept; import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfKey; -import org.onap.policy.models.base.PfTimestampKey; +import org.onap.policy.models.base.PfReferenceTimestampKey; import org.onap.policy.models.base.validation.annotations.VerifyKey; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; @@ -54,7 +56,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; @Table(name = "ClElementStatistics") @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) @Data -@NoArgsConstructor +@AllArgsConstructor @EqualsAndHashCode(callSuper = false) public class JpaClElementStatistics extends PfConcept implements PfAuthorative<ClElementStatistics>, Serializable { @@ -63,14 +65,15 @@ public class JpaClElementStatistics extends PfConcept implements PfAuthorative<C @EmbeddedId @VerifyKey @NotNull - private PfTimestampKey key = new PfTimestampKey(); + private PfReferenceTimestampKey key = new PfReferenceTimestampKey(); + @VerifyKey @NotNull // @formatter:off - @AttributeOverride(name = "name", column = @Column(name = "cl_element_name")) - @AttributeOverride(name = "version", column = @Column(name = "cl_element_version")) - private PfConceptKey clElementId; + @AttributeOverride(name = "name", column = @Column(name = "participant_name")) + @AttributeOverride(name = "version", column = @Column(name = "participant_version")) + private PfConceptKey participantId; // @formatter: on @Column @@ -80,24 +83,34 @@ public class JpaClElementStatistics extends PfConcept implements PfAuthorative<C @Column private long clElementUptime; + /** - * The Key Constructor creates a {@link JpaClElementStatistics} object with the given Timestamp key. + * The Default Constructor creates a {@link JpaClElementStatistics} object with a null key. + */ + public JpaClElementStatistics() { + this(new PfReferenceTimestampKey()); + } + + + /** + * The Key Constructor creates a {@link JpaClElementStatistics} object with the given Reference Timestamp key. * * @param key the key */ - public JpaClElementStatistics(@NonNull final PfTimestampKey key) { - this(key, new PfConceptKey()); + public JpaClElementStatistics(@NonNull final PfReferenceTimestampKey key) { + this(key, new PfConceptKey(), ControlLoopState.PASSIVE, 0L); } /** * The Key Constructor creates a {@link JpaClElementStatistics} object with all mandatory fields. * * @param key the key - * @param clElementId the TOSCA definition of the control loop element + * @param participantId the TOSCA definition of the control loop element */ - public JpaClElementStatistics(@NonNull final PfTimestampKey key, @NonNull final PfConceptKey clElementId) { + public JpaClElementStatistics(@NonNull final PfReferenceTimestampKey key, + @NonNull final PfConceptKey participantId) { this.key = key; - this.clElementId = clElementId; + this.participantId = participantId; } /** @@ -107,8 +120,8 @@ public class JpaClElementStatistics extends PfConcept implements PfAuthorative<C */ public JpaClElementStatistics(@NonNull final JpaClElementStatistics copyConcept) { super(copyConcept); - this.key = new PfTimestampKey(copyConcept.key); - this.clElementId = new PfConceptKey(copyConcept.clElementId); + this.key = new PfReferenceTimestampKey(copyConcept.key); + this.participantId = new PfConceptKey(copyConcept.participantId); this.state = copyConcept.state; this.clElementUptime = copyConcept.clElementUptime; } @@ -123,11 +136,14 @@ public class JpaClElementStatistics extends PfConcept implements PfAuthorative<C this.fromAuthorative(authorativeConcept); } + + @Override public ClElementStatistics toAuthorative() { ClElementStatistics clElementStatistics = new ClElementStatistics(); - clElementStatistics.setTimeStamp(key.getTimeStamp().toInstant()); - clElementStatistics.setControlLoopElementId(new ToscaConceptIdentifier(clElementId)); + clElementStatistics.setId(UUID.fromString(getKey().getReferenceKey().getLocalName())); + clElementStatistics.setTimeStamp(key.getInstant()); + clElementStatistics.setParticipantId(new ToscaConceptIdentifier(participantId)); clElementStatistics.setControlLoopState(state); clElementStatistics.setClElementUptime(clElementUptime); @@ -138,14 +154,12 @@ public class JpaClElementStatistics extends PfConcept implements PfAuthorative<C public void fromAuthorative(@NonNull ClElementStatistics clElementStatistics) { // @formatter:off if (this.key == null || this.getKey().isNullKey()) { - this.setKey( - new PfTimestampKey( - clElementStatistics.getControlLoopElementId().getName(), - clElementStatistics.getControlLoopElementId().getVersion(), - clElementStatistics.getTimeStamp())); + this.setKey(new PfReferenceTimestampKey(clElementStatistics.getParticipantId().getName(), + clElementStatistics.getParticipantId().getVersion(), clElementStatistics.getId().toString(), + clElementStatistics.getTimeStamp())); } // @formatter:on - this.setClElementId(clElementStatistics.getControlLoopElementId().asConceptKey()); + this.setParticipantId(clElementStatistics.getParticipantId().asConceptKey()); this.setState(clElementStatistics.getControlLoopState()); this.setClElementUptime(clElementStatistics.getClElementUptime()); } @@ -158,7 +172,7 @@ public class JpaClElementStatistics extends PfConcept implements PfAuthorative<C @Override public void clean() { key.clean(); - clElementId.clean(); + participantId.clean(); } @@ -176,6 +190,6 @@ public class JpaClElementStatistics extends PfConcept implements PfAuthorative<C final JpaClElementStatistics other = (JpaClElementStatistics) otherConcept; return new CompareToBuilder().append(this.key, other.key).append(this.state, other.state) - .append(this.clElementUptime, other.clElementUptime).toComparison(); + .append(this.clElementUptime, other.clElementUptime).toComparison(); } } diff --git a/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaParticipantStatistics.java b/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaParticipantStatistics.java index 84c7f0d59..b97f9ed69 100644 --- a/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaParticipantStatistics.java +++ b/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaParticipantStatistics.java @@ -53,7 +53,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; * @author Ramesh Murugan Iyer (ramesh.murugan.iyer@est.tech) */ @Entity -@Table(name = "ControlLoopStatistics") +@Table(name = "ParticipantStatistics") @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) @Data @AllArgsConstructor diff --git a/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProvider.java b/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProvider.java index 1250dfce0..c09658f80 100644 --- a/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProvider.java +++ b/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProvider.java @@ -32,7 +32,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; -import org.onap.policy.models.base.PfTimestampKey; +import org.onap.policy.models.base.PfReferenceTimestampKey; import org.onap.policy.models.provider.PolicyModelsProviderParameters; import org.onap.policy.models.provider.impl.AbstractModelsProvider; @@ -62,10 +62,10 @@ public class ClElementStatisticsProvider extends AbstractModelsProvider { * @throws PfModelException on errors creating clElement statistics */ public List<ClElementStatistics> createClElementStatistics( - @NonNull final List<ClElementStatistics> clElementStatisticsList) throws PfModelException { + @NonNull final List<ClElementStatistics> clElementStatisticsList) throws PfModelException { BeanValidationResult validationResult = - new BeanValidationResult("control loop element statistics list", clElementStatisticsList); + new BeanValidationResult("control loop element statistics list", clElementStatisticsList); for (ClElementStatistics clElementStatistics : clElementStatisticsList) { JpaClElementStatistics jpaClElementStatistics = new JpaClElementStatistics(); jpaClElementStatistics.fromAuthorative(clElementStatistics); @@ -80,7 +80,6 @@ public class ClElementStatisticsProvider extends AbstractModelsProvider { for (ClElementStatistics clElementStatistics : clElementStatisticsList) { JpaClElementStatistics jpaClElementStatistics = new JpaClElementStatistics(); jpaClElementStatistics.fromAuthorative(clElementStatistics); - getPfDao().create(jpaClElementStatistics); } @@ -89,8 +88,9 @@ public class ClElementStatisticsProvider extends AbstractModelsProvider { for (ClElementStatistics clElementStat : clElementStatisticsList) { JpaClElementStatistics jpaClElementStatistics = getPfDao().get(JpaClElementStatistics.class, - new PfTimestampKey(clElementStat.getControlLoopElementId().getName(), - clElementStat.getControlLoopElementId().getVersion(), clElementStat.getTimeStamp())); + new PfReferenceTimestampKey(clElementStat.getParticipantId().getName(), + clElementStat.getParticipantId().getVersion(), clElementStat.getId().toString(), + clElementStat.getTimeStamp())); elementStatistics.add(jpaClElementStatistics.toAuthorative()); } @@ -110,21 +110,28 @@ public class ClElementStatisticsProvider extends AbstractModelsProvider { /** * Get clElement statistics. * - * @param name the name of the clElement statistics to get, null to get all stats + * @param name the name of the participant + * @param version version of the participant + * @param id of the control loop element + * @param timestamp timestamp of the statistics * @return the clElement statistics found * @throws PfModelException on errors getting clElement statistics */ - public List<ClElementStatistics> getClElementStatistics(final String name, final String version, - final Instant timestamp) throws PfModelException { - - if (name != null && version != null && timestamp != null) { - List<ClElementStatistics> clElementStatistics = new ArrayList<>(1); + public List<ClElementStatistics> getClElementStatistics(final String name, final String version, final String id, + final Instant timestamp) throws PfModelException { + List<ClElementStatistics> clElementStatistics = new ArrayList<>(1); + if (name != null && version != null && timestamp != null && id != null) { clElementStatistics.add(getPfDao() - .get(JpaClElementStatistics.class, new PfTimestampKey(name, version, timestamp)).toAuthorative()); + .get(JpaClElementStatistics.class, new PfReferenceTimestampKey(name, version, id, timestamp)) + .toAuthorative()); return clElementStatistics; + } else if (name != null) { + clElementStatistics.addAll(getFilteredClElementStatistics(name, version, null, null, null, + "DESC", 0)); } else { - return asClElementStatisticsList(getPfDao().getAll(JpaClElementStatistics.class)); + clElementStatistics.addAll(asClElementStatisticsList(getPfDao().getAll(JpaClElementStatistics.class))); } + return clElementStatistics; } /** @@ -139,9 +146,11 @@ public class ClElementStatisticsProvider extends AbstractModelsProvider { * @throws PfModelException on errors getting policies */ public List<ClElementStatistics> getFilteredClElementStatistics(final String name, final String version, - final Instant startTimeStamp, final Instant endTimeStamp, Map<String, Object> filterMap, - final String sortOrder, final int getRecordNum) { + final Instant startTimeStamp, + final Instant endTimeStamp, + Map<String, Object> filterMap, + final String sortOrder, final int getRecordNum) { return asClElementStatisticsList(getPfDao().getFiltered(JpaClElementStatistics.class, name, version, - startTimeStamp, endTimeStamp, filterMap, sortOrder, getRecordNum)); + startTimeStamp, endTimeStamp, filterMap, sortOrder, getRecordNum)); } } diff --git a/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantStatisticsProvider.java b/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantStatisticsProvider.java index 3cbe901ab..ebb81942b 100644 --- a/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantStatisticsProvider.java +++ b/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantStatisticsProvider.java @@ -62,13 +62,16 @@ public class ParticipantStatisticsProvider extends AbstractModelsProvider { * @throws PfModelException on errors getting participant statistics */ public List<ParticipantStatistics> getParticipantStatistics(final String name, final String version, - final Instant timestamp) throws PfModelException { + final Instant timestamp) throws PfModelException { if (name != null && version != null && timestamp != null) { List<ParticipantStatistics> participantStatistics = new ArrayList<>(1); participantStatistics.add(getPfDao() - .get(JpaParticipantStatistics.class, new PfTimestampKey(name, version, timestamp)).toAuthorative()); + .get(JpaParticipantStatistics.class, new PfTimestampKey(name, version, timestamp)).toAuthorative()); return participantStatistics; + } else if (name != null) { + return getFilteredParticipantStatistics(name, version, timestamp, null, null, + "DESC", 0); } else { return asParticipantStatisticsList(getPfDao().getAll(JpaParticipantStatistics.class)); } @@ -87,11 +90,14 @@ public class ParticipantStatisticsProvider extends AbstractModelsProvider { * @throws PfModelException on errors getting policies */ public List<ParticipantStatistics> getFilteredParticipantStatistics(final String name, final String version, - final Instant startTimeStamp, final Instant endTimeStamp, Map<String, Object> filterMap, - final String sortOrder, final int getRecordNum) { + final Instant startTimeStamp, + final Instant endTimeStamp, + Map<String, Object> filterMap, + final String sortOrder, + final int getRecordNum) { return asParticipantStatisticsList(getPfDao().getFiltered(JpaParticipantStatistics.class, name, version, - startTimeStamp, endTimeStamp, filterMap, sortOrder, getRecordNum)); + startTimeStamp, endTimeStamp, filterMap, sortOrder, getRecordNum)); } @@ -103,10 +109,10 @@ public class ParticipantStatisticsProvider extends AbstractModelsProvider { * @throws PfModelException on errors creating participant statistics */ public List<ParticipantStatistics> createParticipantStatistics( - @NonNull final List<ParticipantStatistics> participantStatisticsList) throws PfModelException { + @NonNull final List<ParticipantStatistics> participantStatisticsList) throws PfModelException { BeanValidationResult validationResult = - new BeanValidationResult("participant statistics List", participantStatisticsList); + new BeanValidationResult("participant statistics List", participantStatisticsList); for (ParticipantStatistics participantStatistics : participantStatisticsList) { JpaParticipantStatistics jpaParticipantStatistics = new JpaParticipantStatistics(); @@ -131,9 +137,9 @@ public class ParticipantStatisticsProvider extends AbstractModelsProvider { for (ParticipantStatistics participantStatisticsItem : participantStatisticsList) { JpaParticipantStatistics jpaParticipantStatistics = getPfDao().get(JpaParticipantStatistics.class, - new PfTimestampKey(participantStatisticsItem.getParticipantId().getName(), - participantStatisticsItem.getParticipantId().getVersion(), - participantStatisticsItem.getTimeStamp())); + new PfTimestampKey(participantStatisticsItem.getParticipantId().getName(), + participantStatisticsItem.getParticipantId().getVersion(), + participantStatisticsItem.getTimeStamp())); participantStatistics.add(jpaParticipantStatistics.toAuthorative()); } @@ -148,9 +154,9 @@ public class ParticipantStatisticsProvider extends AbstractModelsProvider { * @return the participant statistics list */ private List<ParticipantStatistics> asParticipantStatisticsList( - List<JpaParticipantStatistics> jpaParticipantStatisticsList) { + List<JpaParticipantStatistics> jpaParticipantStatisticsList) { return jpaParticipantStatisticsList.stream().map(JpaParticipantStatistics::toAuthorative) - .collect(Collectors.toList()); + .collect(Collectors.toList()); } } diff --git a/tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ClElementStatisticsTest.java b/tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ClElementStatisticsTest.java index 5318fcfc3..0addc25ad 100644 --- a/tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ClElementStatisticsTest.java +++ b/tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ClElementStatisticsTest.java @@ -27,6 +27,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import java.time.Instant; +import java.util.UUID; import org.junit.Test; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; @@ -43,7 +44,7 @@ public class ClElementStatisticsTest { ClElementStatistics cles1 = new ClElementStatistics(); - cles1.setControlLoopElementId(new ToscaConceptIdentifier("defName", "0.0.1")); + cles1.setParticipantId(new ToscaConceptIdentifier("defName", "0.0.1")); cles1.setTimeStamp(Instant.now()); assertThat(cles1.toString()).contains("ClElementStatistics("); @@ -54,12 +55,13 @@ public class ClElementStatisticsTest { assertNotEquals(cles1, cles0); ClElementStatistics cles2 = new ClElementStatistics(); + cles2.setId(UUID.randomUUID()); // @formatter:off - assertThatThrownBy(() -> cles2.setControlLoopElementId(null)).isInstanceOf(NullPointerException.class); - assertThatThrownBy(() -> cles2.setTimeStamp(null)). isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> cles2.setParticipantId(null)).isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> cles2.setTimeStamp(null)).isInstanceOf(NullPointerException.class); // @formatter:on - assertEquals(cles2, cles0); + assertNotEquals(cles2, cles0); } } diff --git a/tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaClElementStatisticsTest.java b/tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaClElementStatisticsTest.java index 5c41d9647..c82dcf060 100644 --- a/tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaClElementStatisticsTest.java +++ b/tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaClElementStatisticsTest.java @@ -28,12 +28,13 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.time.Instant; +import java.util.UUID; import org.junit.Test; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant; import org.onap.policy.models.base.PfConceptKey; -import org.onap.policy.models.base.PfTimestampKey; +import org.onap.policy.models.base.PfReferenceTimestampKey; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; /** @@ -50,7 +51,7 @@ public class JpaClElementStatisticsTest { }).hasMessageMatching("copyConcept is marked .*ull but is null"); assertThatThrownBy(() -> { - new JpaClElementStatistics((PfTimestampKey) null); + new JpaClElementStatistics((PfReferenceTimestampKey) null); }).hasMessageMatching(NULL_KEY_ERROR); assertThatThrownBy(() -> { @@ -62,12 +63,12 @@ public class JpaClElementStatisticsTest { }).hasMessageMatching(NULL_KEY_ERROR); assertThatThrownBy(() -> { - new JpaClElementStatistics(new PfTimestampKey(), null); - }).hasMessageMatching("clElementId is marked .*ull but is null"); + new JpaClElementStatistics(new PfReferenceTimestampKey(), null); + }).hasMessageMatching("participantId is marked .*ull but is null"); assertNotNull(new JpaClElementStatistics()); - assertNotNull(new JpaClElementStatistics((new PfTimestampKey()))); - assertNotNull(new JpaClElementStatistics(new PfTimestampKey(), new PfConceptKey())); + assertNotNull(new JpaClElementStatistics((new PfReferenceTimestampKey()))); + assertNotNull(new JpaClElementStatistics(new PfReferenceTimestampKey(), new PfConceptKey())); } @Test @@ -82,16 +83,17 @@ public class JpaClElementStatisticsTest { }).hasMessageMatching("clElementStatistics is marked .*ull but is null"); assertThatThrownBy(() -> new JpaClElementStatistics((JpaClElementStatistics) null)) - .isInstanceOf(NullPointerException.class); + .isInstanceOf(NullPointerException.class); JpaClElementStatistics testJpaClElementStatisticsFa = new JpaClElementStatistics(); testJpaClElementStatisticsFa.setKey(null); testJpaClElementStatisticsFa.fromAuthorative(cles); assertEquals(testJpaClElementStatistics, testJpaClElementStatisticsFa); - testJpaClElementStatisticsFa.setKey(PfTimestampKey.getNullKey()); + testJpaClElementStatisticsFa.setKey(PfReferenceTimestampKey.getNullKey()); testJpaClElementStatisticsFa.fromAuthorative(cles); assertEquals(testJpaClElementStatistics, testJpaClElementStatisticsFa); - testJpaClElementStatisticsFa.setKey(new PfTimestampKey("elementName", "0.0.1", Instant.ofEpochMilli(123456L))); + testJpaClElementStatisticsFa.setKey(new PfReferenceTimestampKey("elementName", "0.0.1", + "a95757ba-b34a-4049-a2a8-46773abcbe5e", Instant.ofEpochSecond(123456L))); testJpaClElementStatisticsFa.fromAuthorative(cles); assertEquals(testJpaClElementStatistics, testJpaClElementStatisticsFa); @@ -100,10 +102,10 @@ public class JpaClElementStatisticsTest { assertEquals(1, testJpaClElementStatistics.getKeys().size()); - assertEquals("elementName", testJpaClElementStatistics.getKey().getName()); + assertEquals("elementName", testJpaClElementStatistics.getKey().getReferenceKey().getParentKeyName()); testJpaClElementStatistics.clean(); - assertEquals("elementName", testJpaClElementStatistics.getKey().getName()); + assertEquals("elementName", testJpaClElementStatistics.getKey().getReferenceKey().getParentKeyName()); JpaClElementStatistics testJpaClElementStatistics2 = new JpaClElementStatistics(testJpaClElementStatistics); assertEquals(testJpaClElementStatistics, testJpaClElementStatistics2); @@ -121,7 +123,7 @@ public class JpaClElementStatisticsTest { } @Test - public void testJpaClElementStatisticsConmpareTo() { + public void testJpaClElementStatisticsCompareTo() { JpaClElementStatistics testJpaClElementStatistics = createJpaClElementStatisticsInstance(); JpaClElementStatistics otherJpaClElementStatistics = new JpaClElementStatistics(testJpaClElementStatistics); @@ -169,7 +171,7 @@ public class JpaClElementStatisticsTest { JpaClElementStatistics testJpaClElementStatistics = new JpaClElementStatistics(); testJpaClElementStatistics.setKey(null); testJpaClElementStatistics.fromAuthorative(testCles); - testJpaClElementStatistics.setKey(PfTimestampKey.getNullKey()); + testJpaClElementStatistics.setKey(PfReferenceTimestampKey.getNullKey()); testJpaClElementStatistics.fromAuthorative(testCles); return testJpaClElementStatistics; @@ -177,8 +179,9 @@ public class JpaClElementStatisticsTest { private ClElementStatistics createClElementStatisticsInstance() { ClElementStatistics clElementStatistics = new ClElementStatistics(); - clElementStatistics.setControlLoopElementId(new ToscaConceptIdentifier("elementName", "0.0.1")); - clElementStatistics.setTimeStamp(Instant.ofEpochMilli(123456L)); + clElementStatistics.setParticipantId(new ToscaConceptIdentifier("elementName", "0.0.1")); + clElementStatistics.setId(UUID.fromString("a95757ba-b34a-4049-a2a8-46773abcbe5e")); + clElementStatistics.setTimeStamp(Instant.ofEpochSecond(123456L)); clElementStatistics.setControlLoopState(ControlLoopState.UNINITIALISED); return clElementStatistics; diff --git a/tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProviderTest.java b/tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProviderTest.java index 1d2b9913a..f5d094f9e 100644 --- a/tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProviderTest.java +++ b/tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProviderTest.java @@ -95,16 +95,18 @@ public class ClElementStatisticsProviderTest { List<ClElementStatistics> getResponse; //Return empty list when no data present in db - getResponse = clElementStatisticsProvider.getClElementStatistics(null, null, null); + getResponse = clElementStatisticsProvider.getClElementStatistics(null, null, null, + null); assertThat(getResponse).isEmpty(); clElementStatisticsProvider.createClElementStatistics(inputClElementStats .getClElementStatistics()); ToscaConceptIdentifier identifier = inputClElementStats.getClElementStatistics().get(0) - .getControlLoopElementId(); + .getParticipantId(); Instant instant = inputClElementStats.getClElementStatistics().get(0).getTimeStamp(); + String id = inputClElementStats.getClElementStatistics().get(0).getId().toString(); assertEquals(1, clElementStatisticsProvider.getClElementStatistics(identifier.getName(), - identifier.getVersion(), instant).size()); + identifier.getVersion(), id, instant).size()); assertEquals(1, clElementStatisticsProvider.getFilteredClElementStatistics("name2", "1.0.1", null, null, null, diff --git a/tosca-controlloop/models/src/test/resources/providers/TestClElementStatistics.json b/tosca-controlloop/models/src/test/resources/providers/TestClElementStatistics.json index 78aeb3a6e..ae19e560d 100644 --- a/tosca-controlloop/models/src/test/resources/providers/TestClElementStatistics.json +++ b/tosca-controlloop/models/src/test/resources/providers/TestClElementStatistics.json @@ -1,19 +1,21 @@ { "clElementStatistics":[ { - "controlLoopElementId":{ + "participantId":{ "name":"name1", "version":"1.001" }, + "id": "709c62b3-8918-41b9-a747-d21eb79c6c20", "timeStamp": "2021-01-10T13:45:00.000Z", "controlLoopState": "UNINITIALISED", "clElementUptime":250 }, { - "controlLoopElementId":{ + "participantId":{ "name":"name2", "version":"1.001" }, + "id": "709c62b3-8918-41b9-a747-d21eb79c6c21", "timeStamp": "2021-01-10T14:25:00.000Z", "controlLoopState": "UNINITIALISED", "clElementUptime":330 diff --git a/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java index 7586a692c..6fd5f3225 100644 --- a/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java +++ b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java @@ -25,26 +25,36 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.function.UnaryOperator; import java.util.stream.Collectors; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; 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.persistence.provider.ControlLoopProvider; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse; +import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.ObjectValidationResult; +import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.parameters.ValidationStatus; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.provider.PolicyModelsProviderParameters; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; /** * This class is dedicated to the Instantiation of Commissioned control loop. */ public class ControlLoopInstantiationProvider implements Closeable { private final ControlLoopProvider controlLoopProvider; + private final CommissioningProvider commissioningProvider; private static final Object lockit = new Object(); @@ -56,6 +66,7 @@ public class ControlLoopInstantiationProvider implements Closeable { public ControlLoopInstantiationProvider(PolicyModelsProviderParameters databaseProviderParameters) { try { controlLoopProvider = new ControlLoopProvider(databaseProviderParameters); + commissioningProvider = new CommissioningProvider(databaseProviderParameters); } catch (PfModelException e) { throw new PfModelRuntimeException(e); } @@ -83,6 +94,10 @@ public class ControlLoopInstantiationProvider implements Closeable { controlLoop.getKey().asIdentifier() + " already defined"); } } + BeanValidationResult validationResult = validateControlLoops(controlLoops); + if (!validationResult.isValid()) { + throw new PfModelException(Response.Status.BAD_REQUEST, validationResult.getResult()); + } controlLoopProvider.createControlLoops(controlLoops.getControlLoopList()); } @@ -102,6 +117,10 @@ public class ControlLoopInstantiationProvider implements Closeable { */ public InstantiationResponse updateControlLoops(ControlLoops controlLoops) throws PfModelException { synchronized (lockit) { + BeanValidationResult validationResult = validateControlLoops(controlLoops); + if (!validationResult.isValid()) { + throw new PfModelException(Response.Status.BAD_REQUEST, validationResult.getResult()); + } controlLoopProvider.updateControlLoops(controlLoops.getControlLoopList()); } @@ -113,6 +132,71 @@ public class ControlLoopInstantiationProvider implements Closeable { } /** + * Validate ControlLoops. + * + * @param controlLoops ControlLoops to validate + * @result the result of validation + * @throws PfModelException if controlLoops is not valid + */ + private BeanValidationResult validateControlLoops(ControlLoops controlLoops) throws PfModelException { + + BeanValidationResult validationResult = new BeanValidationResult("ControlLoops", controlLoops); + + for (ControlLoop controlLoop : controlLoops.getControlLoopList()) { + + List<ToscaNodeTemplate> toscaNodeTemplates = commissioningProvider.getControlLoopDefinitions( + controlLoop.getDefinition().getName(), controlLoop.getDefinition().getVersion()); + + if (toscaNodeTemplates.isEmpty()) { + validationResult + .addResult(new ObjectValidationResult("ControlLoop", controlLoop.getDefinition().getName(), + ValidationStatus.INVALID, "Commissioned control loop definition not FOUND")); + } else if (toscaNodeTemplates.size() > 1) { + validationResult + .addResult(new ObjectValidationResult("ControlLoop", controlLoop.getDefinition().getName(), + ValidationStatus.INVALID, "Commissioned control loop definition not VALID")); + } else { + + List<ToscaNodeTemplate> clElementDefinitions = + commissioningProvider.getControlLoopElementDefinitions(toscaNodeTemplates.get(0)); + + // @formatter:off + Map<String, ToscaConceptIdentifier> definitions = clElementDefinitions + .stream() + .map(nodeTemplate -> nodeTemplate.getKey().asIdentifier()) + .collect(Collectors.toMap(ToscaConceptIdentifier::getName, UnaryOperator.identity())); + // @formatter:on + + for (ControlLoopElement element : controlLoop.getElements()) { + validationResult.addResult(validateDefinition(definitions, element.getDefinition())); + } + } + } + return validationResult; + } + + /** + * Validate ToscaConceptIdentifier, checking if exist in ToscaConceptIdentifiers map. + * + * @param definitions map of all ToscaConceptIdentifiers + * @param definition ToscaConceptIdentifier to validate + * @result result the validation result + */ + private ValidationResult validateDefinition(Map<String, ToscaConceptIdentifier> definitions, + ToscaConceptIdentifier definition) { + BeanValidationResult result = new BeanValidationResult(definition.getName(), definition); + ToscaConceptIdentifier identifier = definitions.get(definition.getName()); + if (identifier == null) { + result.setResult(ValidationStatus.INVALID, "Not FOUND"); + } else if (!identifier.equals(definition)) { + result.setResult(ValidationStatus.INVALID, "Version not matching"); + } else { + result.setResult(ValidationStatus.CLEAN); + } + return (result.isClean() ? null : result); + } + + /** * Delete the control loop with the given name and version. * * @param name the name of the control loop to delete diff --git a/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringHandler.java b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringHandler.java new file mode 100644 index 000000000..04f458e7d --- /dev/null +++ b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringHandler.java @@ -0,0 +1,104 @@ +/*- + * ============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.runtime.monitoring; + +import java.io.IOException; +import java.util.List; +import java.util.Set; +import javax.ws.rs.core.Response; +import lombok.Getter; +import org.onap.policy.clamp.controlloop.common.handler.ControlLoopHandler; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; +import org.onap.policy.clamp.controlloop.runtime.monitoring.rest.MonitoringQueryController; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher; +import org.onap.policy.common.utils.services.Registry; +import org.onap.policy.models.base.PfModelRuntimeException; + +/** + * This class handles monitoring of control loop definitions, + * so only one object of this type should be built at a time. + * + * <p/> + * It is effectively a singleton that is started at system start. + */ +public class MonitoringHandler extends ControlLoopHandler { + + @Getter + private MonitoringProvider monitoringProvider; + + /** + * Gets the Monitoring Handler. + * + * @return MonitoringHandler + */ + public static MonitoringHandler getInstance() { + return Registry.get(MonitoringHandler.class.getName()); + } + + /** + * Create a handler. + * + * @param controlLoopParameters the parameters for access to the database + */ + public MonitoringHandler(ClRuntimeParameterGroup controlLoopParameters) { + super(controlLoopParameters.getDatabaseProviderParameters()); + } + + @Override + public Set<Class<?>> getProviderClasses() { + return Set.of(MonitoringQueryController.class); + } + + @Override + public void startAndRegisterListeners(MessageTypeDispatcher msgDispatcher) { + // No topic communication on this handler + } + + @Override + public void startAndRegisterPublishers(List<TopicSink> topicSinks) { + // No topic communication on this handler + } + + @Override + public void stopAndUnregisterPublishers() { + // No topic communication on this handler + } + + @Override + public void stopAndUnregisterListeners(MessageTypeDispatcher msgDispatcher) { + // No topic communication on this handler + } + + @Override + public void startProviders() { + monitoringProvider = new MonitoringProvider(getDatabaseProviderParameters()); + } + + @Override + public void stopProviders() { + try { + monitoringProvider.close(); + } catch (IOException e) { + throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, "Cannot stop provider", e); + } + } +} diff --git a/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java new file mode 100644 index 000000000..aeabce7a5 --- /dev/null +++ b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java @@ -0,0 +1,273 @@ +/*- + * ============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.runtime.monitoring; + +import java.io.Closeable; +import java.io.IOException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.NonNull; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatisticsList; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatisticsList; +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.ParticipantStatisticsProvider; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.provider.PolicyModelsProviderParameters; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +/** + * This class provides information about statistics data of CL elements and CL Participants in database to callers. + */ +public class MonitoringProvider implements Closeable { + + private static final String DESC_ORDER = "DESC"; + private final ParticipantStatisticsProvider participantStatisticsProvider; + private final ClElementStatisticsProvider clElementStatisticsProvider; + private final ControlLoopProvider controlLoopProvider; + + /** + * Create a Monitoring provider. + * + */ + public MonitoringProvider(PolicyModelsProviderParameters parameters) { + + try { + participantStatisticsProvider = new ParticipantStatisticsProvider(parameters); + clElementStatisticsProvider = new ClElementStatisticsProvider(parameters); + controlLoopProvider = new ControlLoopProvider(parameters); + } catch (PfModelException e) { + throw new PfModelRuntimeException(e); + } + } + + @Override + public void close() throws IOException { + controlLoopProvider.close(); + clElementStatisticsProvider.close(); + participantStatisticsProvider.close(); + } + + /** + * Create participant statistics. + * + * @param participantStatistics the participant statistics + * @return the result of create operation + * @throws PfModelException on creation errors + */ + public ParticipantStatisticsList createParticipantStatistics(List<ParticipantStatistics> participantStatistics) + throws PfModelException { + ParticipantStatisticsList participantStatisticsList = new ParticipantStatisticsList(); + participantStatisticsList.setStatisticsList(participantStatisticsProvider + .createParticipantStatistics(participantStatistics)); + + return participantStatisticsList; + } + + /** + * Create clElement statistics. + * + * @param clElementStatisticsList the clElement statistics + * @return the result of create operation + * @throws PfModelException on creation errors + */ + public ClElementStatisticsList createClElementStatistics(List<ClElementStatistics> clElementStatisticsList) + throws PfModelException { + ClElementStatisticsList elementStatisticsList = new ClElementStatisticsList(); + elementStatisticsList.setClElementStatistics(clElementStatisticsProvider + .createClElementStatistics(clElementStatisticsList)); + + return elementStatisticsList; + } + + /** + * Get participant statistics based on specific filters. + * + * @param name the name of the participant statistics to get, null to get all statistics + * @param version the version of the participant statistics to get, null to get all statistics + * @param recordCount number of records to be fetched. + * @param startTime start of the timestamp, from statistics to be filtered + * @param endTime end of the timestamp up to which statistics to be filtered + * @return the participant found + */ + public ParticipantStatisticsList fetchFilteredParticipantStatistics(@NonNull final String name, + final String version, int recordCount, + Instant startTime, Instant endTime) { + ParticipantStatisticsList participantStatisticsList = new ParticipantStatisticsList(); + + //Additional parameters can be added in filterMap for filtering data. + Map<String, Object> filterMap = null; + participantStatisticsList.setStatisticsList(participantStatisticsProvider.getFilteredParticipantStatistics( + name, version, startTime, endTime, filterMap, DESC_ORDER, recordCount)); + + return participantStatisticsList; + } + + /** + * Get all participant statistics records found for a specific control loop. * + * + * @param controlLoopName name of the control loop + * @param controlLoopVersion version of the control loop + * @return All the participant statistics found + * @throws PfModelException on errors getting participant statistics + */ + public ParticipantStatisticsList fetchParticipantStatsPerControlLoop(@NonNull final String controlLoopName, + @NonNull final String controlLoopVersion) + throws PfModelException { + ParticipantStatisticsList statisticsList = new ParticipantStatisticsList(); + List<ParticipantStatistics> participantStatistics = new ArrayList<>(); + try { + //Fetch all participantIds for a specific control loop + List<ToscaConceptIdentifier> participantIds = getAllParticipantIdsPerControlLoop(controlLoopName, + controlLoopVersion); + for (ToscaConceptIdentifier id: participantIds) { + participantStatistics.addAll(participantStatisticsProvider.getFilteredParticipantStatistics( + id.getName(), id.getVersion(), null, null, null, DESC_ORDER, 0)); + } + statisticsList.setStatisticsList(participantStatistics); + } catch (PfModelException e) { + throw new PfModelRuntimeException(e); + } + return statisticsList; + } + + + + /** + * Get clElement statistics based on specific filters. + * + * @param name the name of the clElement statistics to get, null to get all statistics + * @param version the version of the clElement statistics to get, null to get all statistics + * @param id UUID of the control loop element + * @param startTime start of the timestamp, from statistics to be filtered + * @param endTime end of the timestamp up to which statistics to be filtered + * @param recordCount number of records to be fetched. + * @return the participant found + * @throws PfModelException on errors getting control loop statistics + */ + public ClElementStatisticsList fetchFilteredClElementStatistics(@NonNull final String name, final String version, + final String id, Instant startTime, Instant endTime, + int recordCount) throws PfModelException { + ClElementStatisticsList clElementStatisticsList = new ClElementStatisticsList(); + Map<String, Object> filterMap = new HashMap<>(); + //Adding UUID in filter if present + if (id != null) { + filterMap.put("localName", id); + } + clElementStatisticsList.setClElementStatistics(clElementStatisticsProvider.getFilteredClElementStatistics( + name, version, startTime, endTime, filterMap, DESC_ORDER, recordCount)); + + return clElementStatisticsList; + } + + + /** + * Get clElement statistics per control loop. + * + * @param name the name of the control loop + * @param version the version of the control loop + * @return the clElement statistics found + * @throws PfModelException on errors getting control loop statistics + */ + public ClElementStatisticsList fetchClElementStatsPerControlLoop(@NonNull final String name, + @NonNull final String version) + throws PfModelException { + ClElementStatisticsList clElementStatisticsList = new ClElementStatisticsList(); + List<ClElementStatistics> clElementStats = new ArrayList<>(); + try { + List<ControlLoopElement> clElements = new ArrayList<>(); + //Fetch all control loop elements for the control loop + ControlLoop controlLoop = controlLoopProvider.getControlLoop(new ToscaConceptIdentifier(name, + version)); + clElements.addAll(controlLoop.getElements()); + + //Collect control loop element statistics for each cl element. + for (ControlLoopElement clElement : clElements) { + clElementStats.addAll(fetchFilteredClElementStatistics(clElement.getParticipantId().getName(), + clElement.getParticipantId().getVersion(), clElement.getId().toString(), null, + null, 0).getClElementStatistics()); + } + clElementStatisticsList.setClElementStatistics(clElementStats); + } catch (PfModelException e) { + throw new PfModelRuntimeException(e); + } + + return clElementStatisticsList; + } + + /** + * If required, REST end point can be defined for this method to fetch associated participant Ids + * for a control loop. + * + * @param name the name of the control loop + * @param version the version of the control loop + * @return List of participant Id + * @throws PfModelException on errors + */ + public List<ToscaConceptIdentifier> getAllParticipantIdsPerControlLoop(String name, String version) + throws PfModelException { + List<ToscaConceptIdentifier> participantIds = new ArrayList<>(); + ControlLoop controlLoop = controlLoopProvider.getControlLoop(new ToscaConceptIdentifier(name, version)); + if (controlLoop != null) { + for (ControlLoopElement clElement : controlLoop.getElements()) { + participantIds.add(clElement.getParticipantId()); + } + } + return participantIds; + } + + /** + * If required, REST end point can be defined for this method to fetch associated control loop element Ids + * for a control loop. + * + * @param name the name of the control loop + * @param version the version of the control loop + * @return Map of control loop Id and participant details + * @throws PfModelException on errors + */ + public Map<String, ToscaConceptIdentifier> getAllClElementsIdPerControlLoop(String name, String version) + throws PfModelException { + Map<String, ToscaConceptIdentifier> clElementId = new HashMap<>(); + ControlLoop controlLoop = controlLoopProvider.getControlLoop(new ToscaConceptIdentifier(name, version)); + for (ControlLoopElement clElement : controlLoop.getElements()) { + clElementId.put(clElement.getId().toString(), clElement.getParticipantId()); + } + return clElementId; + } + + + + public void updateClElementStatistics(List<ClElementStatistics> clElementStatistics) { + // TODO Auto-generated method stub + } + + public void updateParticipantStatistics(List<ParticipantStatistics> statisticsList) { + // TODO Auto-generated method stub + } +} diff --git a/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryController.java b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryController.java new file mode 100644 index 000000000..2e19ffe3a --- /dev/null +++ b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryController.java @@ -0,0 +1,371 @@ +/*- + * ============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.runtime.monitoring.rest; + +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Authorization; +import io.swagger.annotations.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.ResponseHeader; +import java.time.Instant; +import java.util.UUID; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatisticsList; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatisticsList; +import org.onap.policy.clamp.controlloop.runtime.main.rest.RestController; +import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringHandler; +import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.base.PfModelRuntimeException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class handles REST endpoints for CL Statistics monitoring. + */ +public class MonitoringQueryController extends RestController { + + private static final Logger LOGGER = LoggerFactory.getLogger(MonitoringQueryController.class); + private final MonitoringProvider provider; + + /** + * Create Monitoring Controller. + */ + public MonitoringQueryController() { + this.provider = MonitoringHandler.getInstance().getMonitoringProvider(); + } + + + /** + * Queries details of control loop participants statistics. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the participant to get, null for all participants statistics + * @param recordCount the record count to be fetched + * @return the participant statistics + */ + // @formatter:off + @GET + @Path("/monitoring/participant") + @ApiOperation(value = "Query details of the requested participant stats", + notes = "Queries details of the requested participant stats, returning all participant stats", + response = ParticipantStatisticsList.class, + tags = { + "Clamp control loop Monitoring API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public Response queryParticipantStatistics(@HeaderParam(REQUEST_ID_NAME) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop participant name", required = true) + @QueryParam("name") final String name, + @ApiParam(value = "Control Loop participant version", required = true) + @QueryParam("version") final String version, + @ApiParam(value = "Record count", required = false) @DefaultValue("0") + @QueryParam("recordCount") final int recordCount, + @ApiParam(value = "start time", required = false) + @QueryParam("startTime") final String startTime, + @ApiParam(value = "end time", required = false) + @QueryParam("endTime") final String endTime) { + + try { + Instant startTimestamp = null; + Instant endTimestamp = null; + + if (startTime != null) { + startTimestamp = Instant.parse(startTime); + } + if (endTime != null) { + endTimestamp = Instant.parse(endTime); + } + ParticipantStatisticsList response = provider.fetchFilteredParticipantStatistics(name, version, recordCount, + startTimestamp, endTimestamp); + return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) + .entity(response) + .build(); + + } catch (PfModelRuntimeException e) { + LOGGER.warn("Monitoring of participants statistics failed", e); + return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())), + requestId).build(); + } + + } + + /** + * Queries details of all participant statistics per control loop. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the control loop + * @param version version of the control loop + * @return the control loop element statistics + */ + // @formatter:off + @GET + @Path("/monitoring/participants/controlloop") + @ApiOperation(value = "Query details of all the participant stats in a control loop", + notes = "Queries details of the participant stats, returning all participant stats", + response = ClElementStatisticsList.class, + tags = { + "Clamp control loop Monitoring API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + }) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public Response queryParticipantStatisticsPerControlLoop(@HeaderParam(REQUEST_ID_NAME) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop name", required = true) + @QueryParam("name") final String name, + @ApiParam(value = "Control Loop version", required = true) + @QueryParam("version") final String version) { + + try { + ParticipantStatisticsList response = provider.fetchParticipantStatsPerControlLoop(name, version); + return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) + .entity(response) + .build(); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("Monitoring of Cl participant statistics failed", e); + return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())), + requestId).build(); + } + + } + + + + /** + * Queries details of all control loop element statistics per control loop. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the control loop + * @param version version of the control loop + * @return the control loop element statistics + */ + // @formatter:off + @GET + @Path("/monitoring/clelements/controlloop") + @ApiOperation(value = "Query details of the requested cl element stats in a control loop", + notes = "Queries details of the requested cl element stats, returning all clElement stats", + response = ClElementStatisticsList.class, + tags = { + "Clamp control loop Monitoring API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + }) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public Response queryElementStatisticsPerControlLoop(@HeaderParam(REQUEST_ID_NAME) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop name", required = true) + @QueryParam("name") final String name, + @ApiParam(value = "Control Loop version", required = true) + @QueryParam("version") final String version) { + + try { + ClElementStatisticsList response = provider.fetchClElementStatsPerControlLoop(name, version); + return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) + .entity(response) + .build(); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("Monitoring of Cl Element statistics failed", e); + return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())), + requestId).build(); + } + + } + + + + + /** + * Queries details of all control loop element statistics per control loop. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the control loop + * @param version version of the control loop + * @param id Id of the control loop element + * @param recordCount the record count to be fetched + * @return the control loop element statistics + */ + // @formatter:off + @GET + @Path("/monitoring/clelement") + @ApiOperation(value = "Query details of the requested cl element stats", + notes = "Queries details of the requested cl element stats, returning all clElement stats", + response = ClElementStatisticsList.class, + tags = { + "Clamp control loop Monitoring API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + }) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public Response queryElementStatistics(@HeaderParam(REQUEST_ID_NAME) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Participant name", required = true) + @QueryParam("name") final String name, + @ApiParam(value = "Participant version", required = true) + @QueryParam("version") final String version, + @ApiParam(value = "Record count", required = false) + @DefaultValue("0") @QueryParam("recordCount") final int recordCount, + @ApiParam(value = "Control Loop element id", required = false) + @QueryParam("id") final String id, + @ApiParam(value = "start time", required = false) + @QueryParam("startTime") final String startTime, + @ApiParam(value = "end time", required = false) + @QueryParam("endTime") final String endTime) { + + try { + Instant startTimestamp = null; + Instant endTimestamp = null; + + if (startTime != null) { + startTimestamp = Instant.parse(startTime); + } + if (endTime != null) { + endTimestamp = Instant.parse(endTime); + } + ClElementStatisticsList response = provider.fetchFilteredClElementStatistics(name, version, id, + startTimestamp, endTimestamp, recordCount); + return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) + .entity(response) + .build(); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("Monitoring of Cl Element statistics failed", e); + return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())), + requestId).build(); + } + + } + +} diff --git a/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java index a0940ef97..0ec8fe3e8 100644 --- a/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java +++ b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java @@ -28,7 +28,6 @@ import java.util.ArrayList; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; @@ -51,15 +50,36 @@ public class ControlLoopInstantiationProviderTest { "src/test/resources/rest/controlloops/ControlLoopsUpdate.json"; private static final String CL_INSTANTIATION_CHANGE_STATE_JSON = "src/test/resources/rest/controlloops/PassiveCommand.json"; + private static final String CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON = + "src/test/resources/rest/controlloops/ControlLoopsElementsNotFound.json"; + private static final String CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON = + "src/test/resources/rest/controlloops/ControlLoopsNotFound.json"; + private static final String TOSCA_TEMPLATE_YAML = "examples/controlloop/PMSubscriptionHandling.yaml"; private static final String CONTROL_LOOP_NOT_FOUND = "Control Loop not found"; private static final String DELETE_BAD_REQUEST = "Control Loop State is still %s"; private static final String ORDERED_STATE_INVALID = "ordered state invalid or not specified on command"; + private static final String CONTROLLOOP_ELEMENT_NAME_NOT_FOUND = + "\"ControlLoops\" INVALID, item has status INVALID\n" + + " \"org.onap.domain.pmsh.NotExistFirst\" INVALID, Not FOUND\n" + + " \"org.onap.domain.pmsh.NotExistSecond\" INVALID, Not FOUND\n"; + + private static final String CONTROLLOOP_DEFINITION_NOT_FOUND = "\"ControlLoops\" INVALID, item has status INVALID\n" + + " item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID," + + " Commissioned control loop definition not FOUND\n" + + " item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID," + + " Commissioned control loop definition not FOUND\n"; + private static PolicyModelsProviderParameters databaseProviderParameters; + /** + * setup Db Provider Parameters. + * + * @throws PfModelException if an error occurs + */ @BeforeClass - public static void setupDbProviderParameters() throws ControlLoopException, PfModelException { + public static void setupDbProviderParameters() throws PfModelException { databaseProviderParameters = CommonTestData.geParameterGroup(0, "instantproviderdb").getDatabaseProviderParameters(); } @@ -74,6 +94,10 @@ public class ControlLoopInstantiationProviderTest { try (ControlLoopInstantiationProvider instantiationProvider = new ControlLoopInstantiationProvider(databaseProviderParameters)) { + + // to validate control Loop, it needs to define ToscaServiceTemplate + InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters); + InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate); InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate); @@ -152,9 +176,12 @@ public class ControlLoopInstantiationProviderTest { try (ControlLoopInstantiationProvider instantiationProvider = new ControlLoopInstantiationProvider(databaseProviderParameters)) { - assertThatThrownBy(() -> { - instantiationProvider.deleteControlLoop(controlLoop0.getName(), controlLoop0.getVersion()); - }).hasMessageMatching(CONTROL_LOOP_NOT_FOUND); + // to validate control Loop, it needs to define ToscaServiceTemplate + InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters); + + assertThatThrownBy( + () -> instantiationProvider.deleteControlLoop(controlLoop0.getName(), controlLoop0.getVersion())) + .hasMessageMatching(CONTROL_LOOP_NOT_FOUND); InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoops), controlLoops); @@ -189,15 +216,14 @@ public class ControlLoopInstantiationProviderTest { new ControlLoopInstantiationProvider(databaseProviderParameters)) { instantiationProvider.updateControlLoops(controlLoops); - assertThatThrownBy(() -> { - instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion()); - }).hasMessageMatching(String.format(DELETE_BAD_REQUEST, state)); + assertThatThrownBy( + () -> instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion())) + .hasMessageMatching(String.format(DELETE_BAD_REQUEST, state)); } } @Test public void testCreateControlLoops_NoDuplicates() throws Exception { - ControlLoops controlLoopsCreate = InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "NoDuplicates"); @@ -206,12 +232,14 @@ public class ControlLoopInstantiationProviderTest { try (ControlLoopInstantiationProvider instantiationProvider = new ControlLoopInstantiationProvider(databaseProviderParameters)) { + + // to validate control Loop, it needs to define ToscaServiceTemplate + InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters); + InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate); InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate); - assertThatThrownBy(() -> { - instantiationProvider.createControlLoops(controlLoopsCreate); - }).hasMessageMatching( + assertThatThrownBy(() -> instantiationProvider.createControlLoops(controlLoopsCreate)).hasMessageMatching( controlLoopsCreate.getControlLoopList().get(0).getKey().asIdentifier() + " already defined"); for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) { @@ -221,12 +249,43 @@ public class ControlLoopInstantiationProviderTest { } @Test + public void testCreateControlLoops_CommissionedClElementNotFound() throws Exception { + ControlLoops controlLoops = InstantiationUtils + .getControlLoopsFromResource(CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "ClElementNotFound"); + + try (ControlLoopInstantiationProvider provider = + new ControlLoopInstantiationProvider(databaseProviderParameters)) { + + // to validate control Loop, it needs to define ToscaServiceTemplate + InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters); + + assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty(); + + assertThatThrownBy(() -> provider.createControlLoops(controlLoops)) + .hasMessageMatching(CONTROLLOOP_ELEMENT_NAME_NOT_FOUND); + } + } + + @Test + public void testCreateControlLoops_CommissionedClNotFound() throws Exception { + ControlLoops controlLoops = InstantiationUtils + .getControlLoopsFromResource(CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON, "ClNotFound"); + + assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty(); + + try (ControlLoopInstantiationProvider provider = + new ControlLoopInstantiationProvider(databaseProviderParameters)) { + assertThatThrownBy(() -> provider.createControlLoops(controlLoops)) + .hasMessageMatching(CONTROLLOOP_DEFINITION_NOT_FOUND); + } + } + + @Test public void testIssueControlLoopCommand_OrderedStateInvalid() throws ControlLoopRuntimeException, IOException { try (ControlLoopInstantiationProvider instantiationProvider = new ControlLoopInstantiationProvider(databaseProviderParameters)) { - assertThatThrownBy(() -> { - instantiationProvider.issueControlLoopCommand(new InstantiationCommand()); - }).hasMessageMatching(ORDERED_STATE_INVALID); + assertThatThrownBy(() -> instantiationProvider.issueControlLoopCommand(new InstantiationCommand())) + .hasMessageMatching(ORDERED_STATE_INVALID); } } @@ -240,6 +299,10 @@ public class ControlLoopInstantiationProviderTest { try (ControlLoopInstantiationProvider instantiationProvider = new ControlLoopInstantiationProvider(databaseProviderParameters)) { + + // to validate control Loop, it needs to define ToscaServiceTemplate + InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters); + InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV1), controlLoopsV1); diff --git a/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java index a10156807..958d91dff 100644 --- a/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java +++ b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java @@ -33,7 +33,14 @@ import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.Inst import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.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.provider.PolicyModelsProviderFactory; +import org.onap.policy.models.provider.PolicyModelsProviderParameters; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; /** * Utility methods supporting tests for Instantiation. @@ -41,6 +48,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; public class InstantiationUtils { private static final Coder CODER = new StandardCoder(); + private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); /** * Gets the ControlLoops from Resource. @@ -119,4 +127,23 @@ public class InstantiationUtils { assertEquals(1, response.getAffectedControlLoops().size()); assertEquals(0, response.getAffectedControlLoops().get(0).compareTo(controlLoop.getKey().asIdentifier())); } + + /** + * Store ToscaServiceTemplate from resource to DB. + * + * @param path path of the resource + * @param parameters The parameters for the implementation of the PolicyModelProvider + * @throws PfModelException if an error occurs + */ + public static void storeToscaServiceTemplate(String path, PolicyModelsProviderParameters parameters) + throws PfModelException { + + ToscaServiceTemplate template = + yamlTranslator.fromYaml(ResourceUtils.getResourceAsString(path), ToscaServiceTemplate.class); + + try (PolicyModelsProvider modelsProvider = + new PolicyModelsProviderFactory().createPolicyModelsProvider(parameters)) { + modelsProvider.createServiceTemplate(template); + } + } } diff --git a/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java index eaeefb327..63d5a52a4 100644 --- a/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java +++ b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java @@ -58,6 +58,8 @@ public class InstantiationControllerTest extends CommonRestController { private static final String INSTANTIATION_COMMAND_ENDPOINT = "instantiation/command"; + private static final String TOSCA_TEMPLATE_YAML = "examples/controlloop/PMSubscriptionHandling.yaml"; + /** * starts Main and inserts a commissioning template. * @@ -67,6 +69,9 @@ public class InstantiationControllerTest extends CommonRestController { public static void setUpBeforeClass() throws Exception { CommonRestController.setUpBeforeClass("InstApi"); + // to validate control Loop, it needs to define ToscaServiceTemplate + InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, getParameters()); + ControlLoops controlLoops = InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Command"); try (ControlLoopInstantiationProvider instantiationProvider = diff --git a/tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsElementsNotFound.json b/tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsElementsNotFound.json new file mode 100644 index 000000000..2c8ca20d4 --- /dev/null +++ b/tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsElementsNotFound.json @@ -0,0 +1,142 @@ +{ + "controlLoopList": [ + { + "name": "PMSHInstance0", + "version": "1.0.1", + "definition": { + "name": "org.onap.domain.pmsh.PMSHControlLoopDefinition", + "version": "1.2.3" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "PMSH control loop instance 0", + "elements": [ + { + "id": "709c62b3-8918-41b9-a747-d21eb79c6c20", + "definition": { + "name": "org.onap.domain.pmsh.NotExistFirst", + "version": "1.2.3" + }, + "participantId": { + "name": "DCAEParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "DCAE Control Loop Element for the PMSH instance 0 control loop" + }, + { + "id": "709c62b3-8918-41b9-a747-d21eb79c6c21", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement", + "version": "1.2.3" + }, + "participantId": { + "name": "PolicyParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "Monitoring Policy Control Loop Element for the PMSH instance 0 control loop" + }, + { + "id": "709c62b3-8918-41b9-a747-d21eb79c6c22", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement", + "version": "1.2.3" + }, + "participantId": { + "name": "PolicyParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "Operational Policy Control Loop Element for the PMSH instance 0 control loop" + }, + { + "id": "709c62b3-8918-41b9-a747-d21eb79c6c23", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement", + "version": "1.2.3" + }, + "participantId": { + "name": "CDSParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "CDS Control Loop Element for the PMSH instance 0 control loop" + } + ] + }, + { + "name": "PMSHInstance1", + "version": "1.0.1", + "definition": { + "name": "org.onap.domain.pmsh.PMSHControlLoopDefinition", + "version": "1.2.3" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "PMSH control loop instance 1", + "elements": [ + { + "id": "709c62b3-8918-41b9-a747-e21eb79c6c24", + "definition": { + "name": "org.onap.domain.pmsh.NotExistSecond", + "version": "1.2.3" + }, + "participantId": { + "name": "DCAEParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "DCAE Control Loop Element for the PMSH instance 1 control loop" + }, + { + "id": "709c62b3-8918-41b9-a747-e21eb79c6c25", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement", + "version": "1.2.3" + }, + "participantId": { + "name": "PolicyParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "Monitoring Policy Control Loop Element for the PMSH instance 1 control loop" + }, + { + "id": "709c62b3-8918-41b9-a747-e21eb79c6c26", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement", + "version": "1.2.3" + }, + "participantId": { + "name": "PolicyParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "Operational Policy Control Loop Element for the PMSH instance 1 control loop" + }, + { + "id": "709c62b3-8918-41b9-a747-e21eb79c6c27", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement", + "version": "1.2.3" + }, + "participantId": { + "name": "CDSParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "CDS Control Loop Element for the PMSH instance 1 control loop" + } + ] + } + ] +} diff --git a/tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsNotFound.json b/tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsNotFound.json new file mode 100644 index 000000000..2e13c688f --- /dev/null +++ b/tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsNotFound.json @@ -0,0 +1,142 @@ +{ + "controlLoopList": [ + { + "name": "PMSHInstance0", + "version": "1.0.1", + "definition": { + "name": "org.onap.domain.PMSHControlLoopDefinition", + "version": "1.2.3" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "PMSH control loop instance 0", + "elements": [ + { + "id": "709c62b3-8918-41b9-a747-d21eb79c6c20", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice", + "version": "1.2.3" + }, + "participantId": { + "name": "DCAEParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "DCAE Control Loop Element for the PMSH instance 0 control loop" + }, + { + "id": "709c62b3-8918-41b9-a747-d21eb79c6c21", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement", + "version": "1.2.3" + }, + "participantId": { + "name": "PolicyParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "Monitoring Policy Control Loop Element for the PMSH instance 0 control loop" + }, + { + "id": "709c62b3-8918-41b9-a747-d21eb79c6c22", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement", + "version": "1.2.3" + }, + "participantId": { + "name": "PolicyParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "Operational Policy Control Loop Element for the PMSH instance 0 control loop" + }, + { + "id": "709c62b3-8918-41b9-a747-d21eb79c6c23", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement", + "version": "1.2.3" + }, + "participantId": { + "name": "CDSParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "CDS Control Loop Element for the PMSH instance 0 control loop" + } + ] + }, + { + "name": "PMSHInstance1", + "version": "1.0.1", + "definition": { + "name": "org.onap.domain.PMSHControlLoopDefinition", + "version": "1.2.3" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "PMSH control loop instance 1", + "elements": [ + { + "id": "709c62b3-8918-41b9-a747-e21eb79c6c24", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice", + "version": "1.2.3" + }, + "participantId": { + "name": "DCAEParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "DCAE Control Loop Element for the PMSH instance 1 control loop" + }, + { + "id": "709c62b3-8918-41b9-a747-e21eb79c6c25", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement", + "version": "1.2.3" + }, + "participantId": { + "name": "PolicyParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "Monitoring Policy Control Loop Element for the PMSH instance 1 control loop" + }, + { + "id": "709c62b3-8918-41b9-a747-e21eb79c6c26", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement", + "version": "1.2.3" + }, + "participantId": { + "name": "PolicyParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "Operational Policy Control Loop Element for the PMSH instance 1 control loop" + }, + { + "id": "709c62b3-8918-41b9-a747-e21eb79c6c27", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement", + "version": "1.2.3" + }, + "participantId": { + "name": "CDSParticipant0", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "CDS Control Loop Element for the PMSH instance 1 control loop" + } + ] + } + ] +} |