Add Monitoring runtime classes and PfReferenceTimestamp key changes to tosca-poc. 66/119366/4
authorrameshiyer27 <ramesh.murugan.iyer@est.tech>
Tue, 16 Mar 2021 06:49:33 +0000 (06:49 +0000)
committerAjith Sreekumar <ajith.sreekumar@bell.ca>
Fri, 19 Mar 2021 11:50:37 +0000 (11:50 +0000)
Junits for Monitoring runtime will be added as a separate review.

Issue-ID: POLICY-3051
Signed-off-by: zrrmmua <ramesh.murugan.iyer@est.tech>
Change-Id: I8c38fac4f9347a836db379e11ed65361710e207e

12 files changed:
tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ClElementStatistics.java
tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaClElementStatistics.java
tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaParticipantStatistics.java
tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProvider.java
tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantStatisticsProvider.java
tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ClElementStatisticsTest.java
tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaClElementStatisticsTest.java
tosca-controlloop/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProviderTest.java
tosca-controlloop/models/src/test/resources/providers/TestClElementStatistics.json
tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringHandler.java [new file with mode: 0644]
tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java [new file with mode: 0644]
tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryController.java [new file with mode: 0644]

index ec96830..0143230 100644 (file)
@@ -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;
index abe0737..ec5dbb3 100644 (file)
@@ -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();
     }
 }
index 84c7f0d..b97f9ed 100644 (file)
@@ -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
index 1250dfc..c09658f 100644 (file)
@@ -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));
     }
 }
index 3cbe901..ebb8194 100644 (file)
@@ -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());
     }
 }
index 5318fcf..0addc25 100644 (file)
@@ -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);
     }
 }
index 5c41d96..c82dcf0 100644 (file)
@@ -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;
index 1d2b991..f5d094f 100644 (file)
@@ -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,
index 78aeb3a..ae19e56 100644 (file)
@@ -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/monitoring/MonitoringHandler.java b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringHandler.java
new file mode 100644 (file)
index 0000000..04f458e
--- /dev/null
@@ -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 (file)
index 0000000..aeabce7
--- /dev/null
@@ -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 (file)
index 0000000..2e19ffe
--- /dev/null
@@ -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();
+        }
+
+    }
+
+}