statistics rest api update

Issue-ID: POLICY-1629
Signed-off-by: ning.xi <ning.xi@est.tech>
Change-Id: I104fc448d27a282c01e7f54db300f918374b8d07
diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/StatisticsProvider.java b/main/src/main/java/org/onap/policy/pap/main/rest/StatisticsProvider.java
deleted file mode 100644
index 8e6410a..0000000
--- a/main/src/main/java/org/onap/policy/pap/main/rest/StatisticsProvider.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
- *  Modifications Copyright (C) 2019 AT&T Intellectual Property.
- * ================================================================================
- * 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.pap.main.rest;
-
-import org.onap.policy.common.utils.services.Registry;
-import org.onap.policy.pap.main.PapConstants;
-import org.onap.policy.pap.main.startstop.PapActivator;
-
-/**
- * Class to fetch statistics of pap component.
- *
- * @author Ram Krishna Verma (ram.krishna.verma@est.tech)
- */
-public class StatisticsProvider {
-
-    /**
-     * Returns the current statistics of pap component.
-     *
-     * @return Report containing statistics of pap component
-     */
-    public StatisticsReport fetchCurrentStatistics() {
-        final StatisticsReport report = new StatisticsReport();
-        report.setCode(Registry.get(PapConstants.REG_PAP_ACTIVATOR, PapActivator.class).isAlive() ? 200 : 500);
-
-        PapStatisticsManager mgr = Registry.get(PapConstants.REG_STATISTICS_MANAGER, PapStatisticsManager.class);
-        report.setTotalPdpCount(mgr.getTotalPdpCount());
-        report.setTotalPdpGroupCount(mgr.getTotalPdpGroupCount());
-        report.setTotalPolicyDownloadCount(mgr.getTotalPolicyDownloadCount());
-        report.setPolicyDownloadSuccessCount(mgr.getPolicyDownloadSuccessCount());
-        report.setPolicyDownloadFailureCount(mgr.getPolicyDownloadFailureCount());
-        report.setTotalPolicyDeployCount(mgr.getTotalPolicyDeployCount());
-        report.setPolicyDeploySuccessCount(mgr.getPolicyDeploySuccessCount());
-        report.setPolicyDeployFailureCount(mgr.getPolicyDeployFailureCount());
-
-        return report;
-    }
-}
diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/StatisticsRestControllerV1.java b/main/src/main/java/org/onap/policy/pap/main/rest/StatisticsRestControllerV1.java
index e864586..5b36330 100644
--- a/main/src/main/java/org/onap/policy/pap/main/rest/StatisticsRestControllerV1.java
+++ b/main/src/main/java/org/onap/policy/pap/main/rest/StatisticsRestControllerV1.java
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019-2020 Nordix Foundation.
  *  Modifications Copyright (C) 2019 AT&T Intellectual Property.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,12 +22,25 @@
 package org.onap.policy.pap.main.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.util.Map;
+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.PathParam;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
+import org.onap.policy.models.base.PfModelException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Class to provide REST endpoints for PAP component statistics.
@@ -36,15 +49,209 @@
  */
 public class StatisticsRestControllerV1 extends PapRestControllerV1 {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(StatisticsRestControllerV1.class);
+    private static final String GET_STATISTICS_ERR_MSG = "get pdpStatistics failed";
+    private static final int NO_COUNT_LIMIT = 0;
+
+    /**
+     * get statistics of PAP.
+     *
+     *
+     * @return a response
+     */
     @GET
     @Path("statistics")
     @ApiOperation(value = "Fetch current statistics",
-                    notes = "Returns current statistics of the Policy Administration component",
-                    response = StatisticsReport.class, authorizations = @Authorization(value = AUTHORIZATION_TYPE))
+            notes = "Returns current statistics of the Policy Administration component",
+            response = StatisticsReport.class, authorizations = @Authorization(value = AUTHORIZATION_TYPE))
     @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)})
-    public Response statistics() {
-        return Response.status(Response.Status.OK).entity(new StatisticsProvider().fetchCurrentStatistics()).build();
+            @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
+            @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)})
+    public Response statistics(
+            @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
+        return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
+                .entity(new StatisticsRestProvider().fetchCurrentStatistics())
+                .build();
+    }
+
+    /**
+     * get all statistics of PDP groups.
+     *
+     *
+     * @return a response
+     */
+    @GET
+    @Path("pdps/statistics")
+    @ApiOperation(value = "Fetch  statistics for all PDP Groups and subgroups in the system",
+            notes = "Returns for all PDP Groups and subgroups statistics of the Policy Administration component",
+            response = Map.class, tags = {"Policy Administration (PAP) 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)})
+    public Response pdpStatistics(
+            @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
+        try {
+            return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
+                    .entity(new StatisticsRestProvider().fetchDatabaseStatistics(null, null, null, NO_COUNT_LIMIT))
+                    .build();
+        } catch (final PfModelException exp) {
+            LOGGER.info(GET_STATISTICS_ERR_MSG, exp);
+            return addLoggingHeaders(
+                    addVersionControlHeaders(Response.status(exp.getErrorResponse().getResponseCode())), requestId)
+                            .build();
+        }
+    }
+
+    /**
+     * get all statistics of a PDP group.
+     *
+     * @param groupName name of the PDP group
+     * @return a response
+     */
+    @GET
+    @Path("pdps/statistics/{group}")
+    @ApiOperation(value = "Fetch current statistics for given PDP Group",
+            notes = "Returns statistics for given PDP Group of the Policy Administration component",
+            response = Map.class, tags = {"Policy Administration (PAP) 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)})
+    public Response pdpGroupStatistics(
+            @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId,
+            @ApiParam(value = "PDP Group Name", required = true) @PathParam("group") final String groupName) {
+        try {
+            return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
+                    .entity(new StatisticsRestProvider().fetchDatabaseStatistics(groupName, null, null, NO_COUNT_LIMIT))
+                    .build();
+        } catch (final PfModelException exp) {
+            LOGGER.info(GET_STATISTICS_ERR_MSG, exp);
+            return addLoggingHeaders(
+                    addVersionControlHeaders(Response.status(exp.getErrorResponse().getResponseCode())), requestId)
+                            .build();
+        }
+    }
+
+    /**
+     * get all statistics of sub PDP group.
+     *
+     * @param groupName name of the PDP group
+     * @param subType type of the sub PDP group
+     * @return a response
+     */
+    @GET
+    @Path("pdps/statistics/{group}/{type}")
+    @ApiOperation(value = "Fetch statistics for the specified subgroup",
+            notes = "Returns  statistics for the specified subgroup of the Policy Administration component",
+            response = Map.class, tags = {"Policy Administration (PAP) 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)})
+    public Response pdpSubGroupStatistics(
+            @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId,
+            @ApiParam(value = "PDP Group Name", required = true) @PathParam("group") final String groupName,
+            @ApiParam(value = "PDP SubGroup type", required = true) @PathParam("type") final String subType) {
+        try {
+            return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
+                    .entity(new StatisticsRestProvider().fetchDatabaseStatistics(groupName, subType, null,
+                            NO_COUNT_LIMIT))
+                    .build();
+        } catch (final PfModelException exp) {
+            LOGGER.info(GET_STATISTICS_ERR_MSG, exp);
+            return addLoggingHeaders(
+                    addVersionControlHeaders(Response.status(exp.getErrorResponse().getResponseCode())), requestId)
+                            .build();
+        }
+    }
+
+    /**
+     * get all statistics of one PDP.
+     *
+     * @param groupName name of the PDP group
+     * @param subType type of the sub PDP group
+     * @param pdpName the name of the PDP
+     * @param recordCount the count of the query response, optional, default return all statistics stored
+     * @return a response
+     */
+    @GET
+    @Path("pdps/statistics/{group}/{type}/{pdp}")
+    @ApiOperation(value = "Fetch statistics for the specified pdp",
+            notes = "Returns  statistics for the specified pdp of the Policy Administration component",
+            response = Map.class,
+            tags = {"Policy Administration (PAP) 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)})
+
+    public Response pdpInstanceStatistics(
+            @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId,
+            @ApiParam(value = "PDP Group Name", required = true) @PathParam("group") final String groupName,
+            @ApiParam(value = "PDP SubGroup type", required = true) @PathParam("type") final String subType,
+            @ApiParam(value = "PDP Instance name", required = true) @PathParam("pdp") final String pdpName,
+            @ApiParam(value = "Record Count",
+                    required = false) @DefaultValue("0") @QueryParam("recordCount") final int recordCount) {
+        try {
+            return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
+                    .entity(new StatisticsRestProvider().fetchDatabaseStatistics(groupName, subType, pdpName,
+                            recordCount))
+                    .build();
+        } catch (final PfModelException exp) {
+            LOGGER.info(GET_STATISTICS_ERR_MSG, exp);
+            return addLoggingHeaders(
+                    addVersionControlHeaders(Response.status(exp.getErrorResponse().getResponseCode())), requestId)
+                            .build();
+        }
     }
 }
diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/StatisticsRestProvider.java b/main/src/main/java/org/onap/policy/pap/main/rest/StatisticsRestProvider.java
new file mode 100644
index 0000000..9a28339
--- /dev/null
+++ b/main/src/main/java/org/onap/policy/pap/main/rest/StatisticsRestProvider.java
@@ -0,0 +1,125 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ *  Modifications Copyright (C) 2019 AT&T Intellectual Property.
+ * ================================================================================
+ * 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.pap.main.rest;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.core.Response;
+import org.onap.policy.common.utils.services.Registry;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.base.PfModelRuntimeException;
+import org.onap.policy.models.pdp.concepts.PdpStatistics;
+import org.onap.policy.models.provider.PolicyModelsProvider;
+import org.onap.policy.pap.main.PapConstants;
+import org.onap.policy.pap.main.PolicyModelsProviderFactoryWrapper;
+import org.onap.policy.pap.main.startstop.PapActivator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class to fetch statistics of pap component.
+ *
+ * @author Ram Krishna Verma (ram.krishna.verma@est.tech)
+ */
+public class StatisticsRestProvider {
+    private static final Logger LOGGER = LoggerFactory.getLogger(StatisticsRestProvider.class);
+    private static final String GET_STATISTICS_ERR_MSG = "fetch database failed";
+    private static final String DESC_ORDER = "DESC";
+
+    /**
+     * Returns the current statistics of pap component.
+     *
+     * @return Report containing statistics of pap component
+     */
+    public StatisticsReport fetchCurrentStatistics() {
+        final StatisticsReport report = new StatisticsReport();
+        report.setCode(Registry.get(PapConstants.REG_PAP_ACTIVATOR, PapActivator.class).isAlive() ? 200 : 500);
+
+        PapStatisticsManager mgr = Registry.get(PapConstants.REG_STATISTICS_MANAGER, PapStatisticsManager.class);
+        report.setTotalPdpCount(mgr.getTotalPdpCount());
+        report.setTotalPdpGroupCount(mgr.getTotalPdpGroupCount());
+        report.setTotalPolicyDownloadCount(mgr.getTotalPolicyDownloadCount());
+        report.setPolicyDownloadSuccessCount(mgr.getPolicyDownloadSuccessCount());
+        report.setPolicyDownloadFailureCount(mgr.getPolicyDownloadFailureCount());
+        report.setTotalPolicyDeployCount(mgr.getTotalPolicyDeployCount());
+        report.setPolicyDeploySuccessCount(mgr.getPolicyDeploySuccessCount());
+        report.setPolicyDeployFailureCount(mgr.getPolicyDeployFailureCount());
+
+        return report;
+    }
+
+    /**
+     * Returns statistics of pdp component from database.
+     *
+     * @param groupName name of the PDP group
+     * @param subType type of the sub PDP group
+     * @param pdpName the name of the PDP
+     * @param recordCount the count to query from database
+     * @return Report containing statistics of pdp component
+     * @throws PfModelException when database can not found
+     */
+    public Map<String, Map<String, List<PdpStatistics>>> fetchDatabaseStatistics(String groupName, String subType,
+            String pdpName, int recordCount) throws PfModelException {
+        final PolicyModelsProviderFactoryWrapper modelProviderWrapper =
+                Registry.get(PapConstants.REG_PAP_DAO_FACTORY, PolicyModelsProviderFactoryWrapper.class);
+        Map<String, Map<String, List<PdpStatistics>>> pdpStatisticsMap;
+        try (PolicyModelsProvider databaseProvider = modelProviderWrapper.create()) {
+            Date startTime = null;
+            Date endTime = null;
+
+            if (groupName == null) {
+                pdpStatisticsMap = generatePdpStatistics(databaseProvider.getPdpStatistics(pdpName, startTime));
+            } else {
+                pdpStatisticsMap = generatePdpStatistics(databaseProvider.getFilteredPdpStatistics(pdpName, groupName,
+                        subType, startTime, endTime, DESC_ORDER, recordCount));
+            }
+        } catch (final PfModelException exp) {
+            String errorMessage = GET_STATISTICS_ERR_MSG + "groupName:" + groupName + "subType:" + subType + "pdpName:"
+                    + pdpName + exp.getMessage();
+            LOGGER.debug(errorMessage, exp);
+            throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage);
+        }
+        return pdpStatisticsMap;
+    }
+
+    /**
+     * generate the statistics of pap component by group/subgroup.
+     *
+     */
+    private Map<String, Map<String, List<PdpStatistics>>> generatePdpStatistics(List<PdpStatistics> pdpStatisticsList) {
+        Map<String, Map<String, List<PdpStatistics>>> groupMap = new HashMap<>();
+        if (pdpStatisticsList != null) {
+            pdpStatisticsList.stream().forEach(s -> {
+                String curGroup = s.getPdpGroupName();
+                String curSubGroup = s.getPdpSubGroupName();
+                groupMap.computeIfAbsent(curGroup, curGroupMap -> new HashMap<>())
+                        .computeIfAbsent(curSubGroup, curSubGroupList -> new ArrayList<>()).add(s);
+            });
+        }
+        return groupMap;
+    }
+}
+
+
diff --git a/main/src/main/resources/META-INF/persistence.xml b/main/src/main/resources/META-INF/persistence.xml
index 18c5754..4a678b0 100644
--- a/main/src/main/resources/META-INF/persistence.xml
+++ b/main/src/main/resources/META-INF/persistence.xml
@@ -32,6 +32,7 @@
         <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdpGroup</class>
         <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdpSubGroup</class>
         <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdp</class>
+        <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdpStatistics</class>
 
         <properties>
             <property name="javax.persistence.schema-generation.database.action" value="create" />
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/TestStatisticsRestControllerV1.java b/main/src/test/java/org/onap/policy/pap/main/rest/TestStatisticsRestControllerV1.java
index 1894fd7..70deedc 100644
--- a/main/src/test/java/org/onap/policy/pap/main/rest/TestStatisticsRestControllerV1.java
+++ b/main/src/test/java/org/onap/policy/pap/main/rest/TestStatisticsRestControllerV1.java
@@ -1,6 +1,6 @@
 /*
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019-2020 Nordix Foundation.
  *  Modifications Copyright (C) 2019 AT&T Intellectual Property.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -36,10 +36,15 @@
 public class TestStatisticsRestControllerV1 extends CommonPapRestServer {
 
     private static final String STATISTICS_ENDPOINT = "statistics";
+    private static final String STATISTICS_DB_ENDPOINT = "pdps/statistics";
 
     @Test
     public void testSwagger() throws Exception {
         super.testSwagger(STATISTICS_ENDPOINT);
+        super.testSwagger(STATISTICS_DB_ENDPOINT);
+        super.testSwagger(STATISTICS_DB_ENDPOINT + "/{group}");
+        super.testSwagger(STATISTICS_DB_ENDPOINT + "/{group}" + "/{type}");
+        super.testSwagger(STATISTICS_DB_ENDPOINT + "/{group}" + "/{type}" + "/{pdp}");
     }
 
     @Test
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/e2e/StatisticsTest.java b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/StatisticsTest.java
index 13492cf..aa2c59e 100644
--- a/main/src/test/java/org/onap/policy/pap/main/rest/e2e/StatisticsTest.java
+++ b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/StatisticsTest.java
@@ -3,6 +3,7 @@
  * ONAP PAP
  * ================================================================================
  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,15 +24,27 @@
 import static org.junit.Assert.assertEquals;
 
 import java.net.HttpURLConnection;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
 import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.Response;
 import org.junit.Test;
 import org.onap.policy.common.utils.services.Registry;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.base.PfModelRuntimeException;
+import org.onap.policy.models.pdp.concepts.PdpStatistics;
+import org.onap.policy.models.provider.PolicyModelsProvider;
 import org.onap.policy.pap.main.PapConstants;
+import org.onap.policy.pap.main.PolicyModelsProviderFactoryWrapper;
 import org.onap.policy.pap.main.rest.PapStatisticsManager;
 import org.onap.policy.pap.main.rest.StatisticsReport;
 
 public class StatisticsTest extends End2EndBase {
     private static final String STATISTICS_ENDPOINT = "statistics";
+    private List<PdpStatistics> recordList = new ArrayList<>();
 
 
     @Test
@@ -56,6 +69,47 @@
         assertEquals(report.getPolicyDeployFailureCount() + 1, report2.getPolicyDeployFailureCount());
     }
 
+    @Test
+    public void testDb() throws Exception {
+        setupEnv();
+        Invocation.Builder invocationBuilder = sendRequest("pdps/statistics");
+        Response testResponse = invocationBuilder.get();
+        verifyResponse(testResponse);
+    }
+
+    @Test
+    public void testDbWithGroup() throws Exception {
+        setupEnv();
+        Invocation.Builder invocationBuilder = sendRequest("pdps/statistics/defaultGroup");
+        Response testResponse = invocationBuilder.get();
+        verifyResponse(testResponse);
+
+    }
+
+    @Test
+    public void testDbWithSubGroup() throws Exception {
+        setupEnv();
+        Invocation.Builder invocationBuilder = sendRequest("pdps/statistics/defaultGroup/apex");
+        Response testResponse = invocationBuilder.get();
+        verifyResponse(testResponse);
+    }
+
+    @Test
+    public void testDbWithPdp() throws Exception {
+        setupEnv();
+        Invocation.Builder invocationBuilder = sendRequest("pdps/statistics/defaultGroup/apex/pdp1");
+        Response testResponse = invocationBuilder.get();
+        verifyResponse(testResponse);
+    }
+
+    @Test
+    public void testDbWithPdpLatest() throws Exception {
+        setupEnv();
+        Invocation.Builder invocationBuilder = sendRequest("pdps/statistics/defaultGroup/apex/pdp1?recordCount=5");
+        Response testResponse = invocationBuilder.get();
+        verifyResponse(testResponse);
+    }
+
     private void updateDistributionStatistics() {
         PapStatisticsManager mgr = Registry.get(PapConstants.REG_STATISTICS_MANAGER, PapStatisticsManager.class);
 
@@ -68,4 +122,38 @@
         mgr.updatePolicyDownloadSuccessCount();
         mgr.updatePolicyDownloadFailureCount();
     }
+
+    private void setupEnv() {
+        PolicyModelsProviderFactoryWrapper modelProviderWrapper =
+                Registry.get(PapConstants.REG_PAP_DAO_FACTORY, PolicyModelsProviderFactoryWrapper.class);
+
+        try (PolicyModelsProvider databaseProvider = modelProviderWrapper.create()) {
+            PdpStatistics pdpStatisticsRecord = new PdpStatistics();
+            pdpStatisticsRecord.setPdpGroupName("defaultGroup");
+            pdpStatisticsRecord.setPdpSubGroupName("apex");
+            pdpStatisticsRecord.setPdpInstanceId("pdp1");
+            pdpStatisticsRecord.setTimeStamp(new Date());
+            pdpStatisticsRecord.setPolicyDeployCount(1);
+            pdpStatisticsRecord.setPolicyDeployFailCount(0);
+            pdpStatisticsRecord.setPolicyDeploySuccessCount(1);
+            pdpStatisticsRecord.setPolicyExecutedCount(1);
+            pdpStatisticsRecord.setPolicyExecutedFailCount(0);
+            pdpStatisticsRecord.setPolicyExecutedSuccessCount(1);
+            recordList.add(pdpStatisticsRecord);
+            databaseProvider.createPdpStatistics(recordList);
+        } catch (final PfModelException exp) {
+            throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, exp.getMessage());
+        }
+    }
+
+    private void verifyResponse(Response testResponse) {
+        assertEquals(Response.Status.OK.getStatusCode(), testResponse.getStatus());
+        Map<String, Map<String, List<PdpStatistics>>> map =
+                testResponse.readEntity(new GenericType<Map<String, Map<String, List<PdpStatistics>>>>() {});
+        Map<String, List<PdpStatistics>> subMap = map.get("defaultGroup");
+        List<PdpStatistics> resRecord = subMap.get("apex");
+        assertEquals("pdp1", resRecord.get(0).getPdpInstanceId());
+        assertEquals("apex", resRecord.get(0).getPdpSubGroupName());
+        assertEquals("defaultGroup", resRecord.get(0).getPdpGroupName());
+    }
 }
diff --git a/main/src/test/resources/META-INF/persistence.xml b/main/src/test/resources/META-INF/persistence.xml
index 40b6219..ed09e78 100644
--- a/main/src/test/resources/META-INF/persistence.xml
+++ b/main/src/test/resources/META-INF/persistence.xml
@@ -32,6 +32,7 @@
         <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdpGroup</class>
         <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdpSubGroup</class>
         <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdp</class>
+        <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdpStatistics</class>
 
         <properties>
             <property name="javax.persistence.schema-generation.database.action" value="create" />