Adding statistics to PDP Heartbeat Messages 61/126761/20
authorisaac <isaac.adorno@att.com>
Tue, 25 Jan 2022 20:21:19 +0000 (14:21 -0600)
committerisaac <isaac.adorno@att.com>
Wed, 23 Feb 2022 15:46:27 +0000 (09:46 -0600)
Issue-ID: POLICY-3034
Signed-off-by: isaac <isaac.adorno@att.com>
Change-Id: I495da4178b9715ec710fdc790f08faef0fc456d5

main/src/main/java/org/onap/policy/pdpx/main/XacmlState.java
main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisher.java
main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpStatisticsManager.java
main/src/main/java/org/onap/policy/pdpx/main/rest/model/StatisticsReport.java
main/src/main/java/org/onap/policy/pdpx/main/rest/provider/StatisticsProvider.java
main/src/test/java/org/onap/policy/pdpx/main/XacmlStateTest.java
main/src/test/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisherTest.java

index a2c8ca9..3635a21 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019, 2021-2022 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.policy.pdpx.main;
 
+import java.time.Instant;
 import java.util.Collections;
 import org.apache.commons.lang3.StringUtils;
 import org.onap.policy.common.utils.network.NetworkUtil;
 import org.onap.policy.models.pdp.concepts.PdpMessage;
 import org.onap.policy.models.pdp.concepts.PdpResponseDetails;
 import org.onap.policy.models.pdp.concepts.PdpStateChange;
+import org.onap.policy.models.pdp.concepts.PdpStatistics;
 import org.onap.policy.models.pdp.concepts.PdpStatus;
 import org.onap.policy.models.pdp.concepts.PdpUpdate;
 import org.onap.policy.models.pdp.enums.PdpHealthStatus;
 import org.onap.policy.models.pdp.enums.PdpResponseStatus;
 import org.onap.policy.models.pdp.enums.PdpState;
 import org.onap.policy.pdpx.main.rest.XacmlPdpApplicationManager;
+import org.onap.policy.pdpx.main.rest.XacmlPdpStatisticsManager;
 import org.onap.policy.pdpx.main.startstop.XacmlPdpActivator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -90,9 +93,43 @@ public class XacmlState {
     public synchronized PdpStatus genHeartbeat() {
         // first, update status fields
         status.setHealthy(XacmlPdpActivator.getCurrent().isAlive() ? PdpHealthStatus.HEALTHY
-                        : PdpHealthStatus.NOT_HEALTHY);
+            : PdpHealthStatus.NOT_HEALTHY);
 
-        return new PdpStatus(status);
+        PdpStatus heartbeat = new PdpStatus(status);
+        heartbeat.setStatistics(getStatistics());
+        return heartbeat;
+    }
+
+    /**
+     * Generates statistics to be used in a heart beat message.
+     *
+     * @return statistics for heart beat message
+     */
+    protected PdpStatistics getStatistics() {
+        XacmlPdpStatisticsManager stats = XacmlPdpStatisticsManager.getCurrent();
+        if (stats == null) {
+            LOGGER.warn("XacmlPdpStatisticsManager is null");
+            return null;
+        }
+        stats.setTotalPolicyCount(appManager.getPolicyCount());
+
+        PdpStatistics pdpStats = new PdpStatistics();
+        pdpStats.setPdpGroupName(this.status.getPdpGroup());
+        pdpStats.setPdpSubGroupName(this.status.getPdpSubgroup());
+        pdpStats.setTimeStamp(Instant.ofEpochSecond(this.status.getTimestampMs()));
+
+        pdpStats.setPolicyExecutedCount(stats.getPermitDecisionsCount() + stats.getDenyDecisionsCount());
+        pdpStats.setPolicyExecutedSuccessCount(stats.getPermitDecisionsCount());
+        pdpStats.setPolicyExecutedFailCount(stats.getDenyDecisionsCount());
+
+        pdpStats.setPolicyDeployCount(stats.getDeploySuccessCount() + stats.getDeployFailureCount());
+        pdpStats.setPolicyDeploySuccessCount(stats.getDeploySuccessCount());
+        pdpStats.setPolicyDeployFailCount(stats.getDeployFailureCount());
+
+        pdpStats.setPolicyUndeployCount(stats.getUndeploySuccessCount() + stats.getUndeployFailureCount());
+        pdpStats.setPolicyUndeploySuccessCount(stats.getUndeploySuccessCount());
+        pdpStats.setPolicyUndeployFailCount(stats.getUndeployFailureCount());
+        return pdpStats;
     }
 
     /**
index 539b541..a00eba9 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019-2022 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -64,15 +64,20 @@ public class XacmlPdpUpdatePublisher {
         List<ToscaConceptIdentifier> toBeUndeployedIds =
                         Optional.ofNullable(message.getPoliciesToBeUndeployed()).orElse(Collections.emptyList());
 
+        var stats = XacmlPdpStatisticsManager.getCurrent();
+
         // Undeploy policies
         for (ToscaConceptIdentifier policyId: toBeUndeployedIds) {
             ToscaPolicy policy = deployedPolicies.get(policyId);
             if (policy == null) {
                 LOGGER.warn("attempt to undeploy policy that has not been previously deployed: {}", policyId);
+                stats.updateUndeployFailureCount();
             } else if (toBeDeployedPolicies.containsKey(policyId)) {
                 LOGGER.warn("not undeploying policy, as it also appears in the deployment list: {}", policyId);
+                stats.updateUndeployFailureCount();
             } else {
                 appManager.removeUndeployedPolicy(policy);
+                stats.updateUndeploySuccessCount();
             }
         }
 
@@ -83,20 +88,19 @@ public class XacmlPdpUpdatePublisher {
             if (!deployedPolicies.containsKey(policy.getIdentifier())) {
                 try {
                     appManager.loadDeployedPolicy(policy);
+                    stats.updateDeploySuccessCount();
                 } catch (XacmlApplicationException e) {
                     // Failed to load policy, return error(s) to PAP
                     LOGGER.error("Failed to load policy: {}", policy, e);
                     errorMessage.append("Failed to load policy: " + policy + ": "
-                            + e.getMessage() + XacmlPolicyUtils.LINE_SEPARATOR);
+                        + e.getMessage() + XacmlPolicyUtils.LINE_SEPARATOR);
+                    stats.updateDeployFailureCount();
                 }
             }
         }
 
         // update the policy count statistic
-        var stats = XacmlPdpStatisticsManager.getCurrent();
-        if (stats != null) {
-            stats.setTotalPolicyCount(appManager.getPolicyCount());
-        }
+        stats.setTotalPolicyCount(appManager.getPolicyCount());
 
         PdpStatus status = state.updateInternalState(message, errorMessage.toString());
         LOGGER.debug("Returning current deployed policies: {} ", status.getPolicies());
index 63d9f51..c040ae6 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019, 2021-2022 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,12 +22,12 @@ package org.onap.policy.pdpx.main.rest;
 
 import lombok.Getter;
 import lombok.Setter;
+import lombok.Synchronized;
 
 /**
  * Class to hold statistical data for xacmlPdp component.
- *
  */
-@Getter
+@Getter(onMethod_ = @Synchronized)
 public class XacmlPdpStatisticsManager {
     @Getter
     @Setter
@@ -38,6 +38,10 @@ public class XacmlPdpStatisticsManager {
     private long errorCount;
     private long permitDecisionsCount;
     private long denyDecisionsCount;
+    private long deploySuccessCount;
+    private long deployFailureCount;
+    private long undeploySuccessCount;
+    private long undeployFailureCount;
     private long indeterminantDecisionsCount;
     private long notApplicableDecisionsCount;
 
@@ -48,6 +52,7 @@ public class XacmlPdpStatisticsManager {
      *
      * @return the total
      */
+    @Synchronized
     public long setTotalPolicyTypesCount(long newCount) {
         totalPolicyTypesCount = newCount;
         return totalPolicyTypesCount;
@@ -60,6 +65,7 @@ public class XacmlPdpStatisticsManager {
      *
      * @return the total
      */
+    @Synchronized
     public long setTotalPolicyCount(long newCount) {
         totalPoliciesCount = newCount;
         return totalPoliciesCount;
@@ -70,6 +76,7 @@ public class XacmlPdpStatisticsManager {
      *
      * @return the errorDecisionsCount
      */
+    @Synchronized
     public long updateErrorCount() {
         return ++errorCount;
     }
@@ -79,6 +86,7 @@ public class XacmlPdpStatisticsManager {
      *
      * @return the permitDecisionsCount
      */
+    @Synchronized
     public long updatePermitDecisionsCount() {
         return ++permitDecisionsCount;
     }
@@ -88,15 +96,57 @@ public class XacmlPdpStatisticsManager {
      *
      * @return the denyDecisionsCount
      */
+    @Synchronized
     public long updateDenyDecisionsCount() {
         return ++denyDecisionsCount;
     }
 
+    /**
+     * Method to update the number of successful deploys.
+     *
+     * @return the deploySuccessCount
+     */
+    @Synchronized
+    public long updateDeploySuccessCount() {
+        return ++deploySuccessCount;
+    }
+
+    /**
+     * Method to update the number of failed deploys.
+     *
+     * @return the deployFailureCount
+     */
+    @Synchronized
+    public long updateDeployFailureCount() {
+        return ++deployFailureCount;
+    }
+
+    /**
+     * Method to update the number of successful undeploys.
+     *
+     * @return the undeploySuccessCount
+     */
+    @Synchronized
+    public long updateUndeploySuccessCount() {
+        return ++undeploySuccessCount;
+    }
+
+    /**
+     * Method to update the number of failed undeploys.
+     *
+     * @return the undeployFailureCount
+     */
+    @Synchronized
+    public long updateUndeployFailureCount() {
+        return ++undeployFailureCount;
+    }
+
     /**
      * Method to update the number of indeterminant decisions.
      *
      * @return the indeterminantDecisionsCount
      */
+    @Synchronized
     public long updateIndeterminantDecisionsCount() {
         return ++indeterminantDecisionsCount;
     }
@@ -106,6 +156,7 @@ public class XacmlPdpStatisticsManager {
      *
      * @return the notApplicableDecisionsCount
      */
+    @Synchronized
     public long updateNotApplicableDecisionsCount() {
         return ++notApplicableDecisionsCount;
     }
@@ -113,12 +164,17 @@ public class XacmlPdpStatisticsManager {
     /**
      * Reset all the statistics counts to 0.
      */
+    @Synchronized
     public void resetAllStatistics() {
         totalPolicyTypesCount = 0L;
         totalPoliciesCount = 0L;
         errorCount = 0L;
         permitDecisionsCount = 0L;
         denyDecisionsCount = 0L;
+        deploySuccessCount = 0L;
+        deployFailureCount = 0L;
+        undeploySuccessCount = 0L;
+        undeployFailureCount = 0L;
         indeterminantDecisionsCount = 0L;
         notApplicableDecisionsCount = 0L;
     }
index 2544527..d122449 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019, 2022 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -39,6 +39,10 @@ public class StatisticsReport {
     private long totalErrorCount;
     private long permitDecisionsCount;
     private long denyDecisionsCount;
+    private long deploySuccessCount;
+    private long deployFailureCount;
+    private long undeploySuccessCount;
+    private long undeployFailureCount;
     private long indeterminantDecisionsCount;
     private long notApplicableDecisionsCount;
 }
index 6c7a7cd..73d7436 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019, 2021-2022 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -45,6 +45,10 @@ public class StatisticsProvider {
         report.setTotalErrorCount(stats.getErrorCount());
         report.setPermitDecisionsCount(stats.getPermitDecisionsCount());
         report.setDenyDecisionsCount(stats.getDenyDecisionsCount());
+        report.setDeploySuccessCount(stats.getDeploySuccessCount());
+        report.setDeployFailureCount(stats.getDeployFailureCount());
+        report.setUndeploySuccessCount(stats.getUndeploySuccessCount());
+        report.setUndeployFailureCount(stats.getUndeployFailureCount());
         report.setIndeterminantDecisionsCount(stats.getIndeterminantDecisionsCount());
         report.setNotApplicableDecisionsCount(stats.getNotApplicableDecisionsCount());
         return report;
index 0b8d140..d8dc2ee 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019, 2021-2022 AT&T Intellectual Property. All rights reserved.
  * Modifications Copyright (C) 2021 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,23 +26,32 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import java.util.Arrays;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient;
 import org.onap.policy.models.pdp.concepts.PdpResponseDetails;
 import org.onap.policy.models.pdp.concepts.PdpStateChange;
+import org.onap.policy.models.pdp.concepts.PdpStatistics;
 import org.onap.policy.models.pdp.concepts.PdpStatus;
 import org.onap.policy.models.pdp.concepts.PdpUpdate;
 import org.onap.policy.models.pdp.enums.PdpHealthStatus;
 import org.onap.policy.models.pdp.enums.PdpResponseStatus;
 import org.onap.policy.models.pdp.enums.PdpState;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
+import org.onap.policy.pdpx.main.comm.XacmlPdpUpdatePublisher;
 import org.onap.policy.pdpx.main.rest.XacmlPdpApplicationManager;
+import org.onap.policy.pdpx.main.rest.XacmlPdpStatisticsManager;
 import org.onap.policy.pdpx.main.startstop.XacmlPdpActivator;
 
 @RunWith(MockitoJUnitRunner.class)
@@ -70,7 +79,6 @@ public class XacmlStateTest {
         pdpName = XacmlState.PDP_NAME;
 
         XacmlPdpActivator.setCurrent(act);
-
         state = new XacmlState(appmgr, GROUP, PDP_TYPE);
     }
 
@@ -106,6 +114,45 @@ public class XacmlStateTest {
         assertEquals(PdpHealthStatus.HEALTHY, status.getHealthy());
     }
 
+    @Test
+    public void testGetStatistics() {
+        XacmlPdpStatisticsManager statmgr = new XacmlPdpStatisticsManager();
+        XacmlPdpStatisticsManager.setCurrent(statmgr);
+
+        ToscaPolicy policy1 = mock(ToscaPolicy.class);
+        ToscaPolicy policy2 = mock(ToscaPolicy.class);
+        ToscaConceptIdentifier ident = new ToscaConceptIdentifier("undeployed", "2.3.4");
+        when(policy2.getIdentifier()).thenReturn(ident);
+
+        PdpUpdate message = new PdpUpdate();
+        message.setPoliciesToBeDeployed(Arrays.asList(policy1));
+        message.setPoliciesToBeUndeployed(Arrays.asList(policy2.getIdentifier()));
+
+        TopicSinkClient client = Mockito.mock(TopicSinkClient.class);
+        XacmlPdpUpdatePublisher publisher = new XacmlPdpUpdatePublisher(client, state, appmgr);
+        publisher.handlePdpUpdate(message);
+
+        PdpStatistics stats = state.getStatistics();
+        assertTrue(stats != null);
+        assertEquals(GROUP, stats.getPdpGroupName());
+        assertEquals(stats.getPolicyDeployCount(), 1);
+        assertEquals(stats.getPolicyDeploySuccessCount(), 1);
+        assertEquals(stats.getPolicyDeployFailCount(), 0);
+        assertEquals(stats.getPolicyUndeployCount(), 1);
+        assertEquals(stats.getPolicyUndeployFailCount(), 1);
+        assertEquals(stats.getPolicyUndeploySuccessCount(), 0);
+
+        PdpStatistics test = new PdpStatistics();
+        test.setTimeStamp(stats.getTimeStamp());
+        test.setPdpGroupName(GROUP);
+        test.setPolicyDeployCount(1);
+        test.setPolicyDeploySuccessCount(1);
+        test.setPolicyUndeployCount(1);
+        test.setPolicyUndeployFailCount(1);
+
+        assertEquals(stats.toString(), test.toString());
+    }
+
     @Test
     public void testUpdateInternalStatePdpStateChange() {
         PdpStateChange req = new PdpStateChange();
index 1edaab3..872bec1 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019, 2021-2022 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -102,6 +102,7 @@ public class XacmlPdpUpdatePublisherTest {
     private PdpUpdate failurePdpUpdate;
 
     private XacmlPdpUpdatePublisher publisher;
+    private XacmlPdpStatisticsManager statmgr;
 
 
     /**
@@ -150,13 +151,13 @@ public class XacmlPdpUpdatePublisherTest {
         when(client.send(any())).thenReturn(true);
 
         publisher = new XacmlPdpUpdatePublisher(client, state, appmgr);
+
+        statmgr = new XacmlPdpStatisticsManager();
+        XacmlPdpStatisticsManager.setCurrent(statmgr);
     }
 
     @Test
     public void testHandlePdpUpdate() throws XacmlApplicationException {
-        XacmlPdpStatisticsManager statmgr = new XacmlPdpStatisticsManager();
-        XacmlPdpStatisticsManager.setCurrent(statmgr);
-
         publisher.handlePdpUpdate(update);
 
         // two removed
@@ -253,16 +254,6 @@ public class XacmlPdpUpdatePublisherTest {
         verify(client).send(status);
     }
 
-    @Test
-    public void testHandlePdpUpdate_NullStats() {
-        XacmlPdpStatisticsManager.setCurrent(null);
-
-        // should work without throwing an exception
-        publisher.handlePdpUpdate(update);
-
-        verify(client).send(status);
-    }
-
     @Test
     public void testHandlePdpUpdate_SendFail() {