summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Hahn <jrh3@att.com>2019-11-01 15:13:10 -0400
committerJim Hahn <jrh3@att.com>2019-11-04 16:17:24 -0500
commitb8c8f44f81eee778f6f038ae8dd171cc9f583741 (patch)
tree61851d4a59b4195e635020192880d7d5d2131e58
parent85a229538caa5c066266520683a9455d970f390f (diff)
Add REST api to query policy status from PAP
As part of this, added code to pre-load the deployed policy tracker by reading the policies and groups from the DB. Change-Id: Ifc6c787d114a3a7add4ea54acc1cc969d6c3ca1c Issue-ID: POLICY-2024 Signed-off-by: Jim Hahn <jrh3@att.com>
-rw-r--r--main/src/main/java/org/onap/policy/pap/main/notification/PolicyCommonTracker.java49
-rw-r--r--main/src/main/java/org/onap/policy/pap/main/notification/PolicyNotifier.java121
-rw-r--r--main/src/main/java/org/onap/policy/pap/main/rest/PolicyStatusControllerV1.java198
-rw-r--r--main/src/main/java/org/onap/policy/pap/main/startstop/PapActivator.java6
-rw-r--r--main/src/test/java/org/onap/policy/pap/main/notification/PolicyCommonTrackerTest.java54
-rw-r--r--main/src/test/java/org/onap/policy/pap/main/notification/PolicyNotifierTest.java146
-rw-r--r--main/src/test/java/org/onap/policy/pap/main/rest/CommonPapRestServer.java23
-rw-r--r--main/src/test/java/org/onap/policy/pap/main/rest/TestPolicyStatusControllerV1.java76
-rw-r--r--main/src/test/java/org/onap/policy/pap/main/rest/e2e/End2EndBase.java23
-rw-r--r--main/src/test/java/org/onap/policy/pap/main/rest/e2e/PolicyStatusTest.java112
-rw-r--r--main/src/test/resources/e2e/policyStatus.json56
11 files changed, 840 insertions, 24 deletions
diff --git a/main/src/main/java/org/onap/policy/pap/main/notification/PolicyCommonTracker.java b/main/src/main/java/org/onap/policy/pap/main/notification/PolicyCommonTracker.java
index 0404e1fe..67d9b988 100644
--- a/main/src/main/java/org/onap/policy/pap/main/notification/PolicyCommonTracker.java
+++ b/main/src/main/java/org/onap/policy/pap/main/notification/PolicyCommonTracker.java
@@ -27,8 +27,10 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Optional;
import java.util.Set;
import java.util.function.BiPredicate;
+import java.util.stream.Collectors;
import org.onap.policy.models.pap.concepts.PolicyStatus;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
@@ -56,6 +58,39 @@ public abstract class PolicyCommonTracker {
}
/**
+ * Gets the status of all policies being tracked.
+ *
+ * @return the status of all policies
+ */
+ public List<PolicyStatus> getStatus() {
+ return policy2data.entrySet().stream().map(this::makeStatus).collect(Collectors.toList());
+ }
+
+ /**
+ * Gets the status of all versions of a policy.
+ *
+ * @param policyId ID of the policy of interest, without the version
+ * @return the status of all versions of the policy having the given ID
+ */
+ public List<PolicyStatus> getStatus(String policyId) {
+ // version is not specified - have to scan the whole list
+ return policy2data.entrySet().stream().filter(ent -> ent.getKey().getName().equals(policyId))
+ .map(this::makeStatus).collect(Collectors.toList());
+ }
+
+ /**
+ * Gets the status of a particular policy.
+ *
+ * @param ident identifier of the policy of interest
+ * @return the status of the given policy, or empty if the policy is not found
+ */
+ public Optional<PolicyStatus> getStatus(ToscaPolicyIdentifier ident) {
+ ToscaPolicyIdentifier ident2 = new ToscaPolicyIdentifier(ident.getName(), ident.getVersion());
+ PolicyTrackerData data = policy2data.get(ident2);
+ return Optional.ofNullable(data == null ? null : makeStatus(ident2, data));
+ }
+
+ /**
* Adds data to the tracker.
*
* @param data data to be added to the tracker
@@ -156,7 +191,7 @@ public abstract class PolicyCommonTracker {
}
// this policy is complete - notify
- statusList.add(makeStatus(policyId, data));
+ statusList.add(makeStatus(ent));
if (shouldRemove(data)) {
iter.remove();
@@ -187,13 +222,23 @@ public abstract class PolicyCommonTracker {
protected abstract boolean shouldRemove(PolicyTrackerData data);
/**
+ * Makes a status notification for the given policy entry.
+ *
+ * @param entry policy entry
+ * @return a new status notification
+ */
+ private PolicyStatus makeStatus(Map.Entry<ToscaPolicyIdentifier, PolicyTrackerData> entry) {
+ return makeStatus(entry.getKey(), entry.getValue());
+ }
+
+ /**
* Makes a status notification for the given policy.
*
* @param policyId policy ID
* @param data data to be used to set the status fields
* @return a new status notification
*/
- private synchronized PolicyStatus makeStatus(ToscaPolicyIdentifier policyId, PolicyTrackerData data) {
+ private PolicyStatus makeStatus(ToscaPolicyIdentifier policyId, PolicyTrackerData data) {
PolicyStatus status = new PolicyStatus(data.getPolicyType(), policyId);
data.putValuesInto(status);
diff --git a/main/src/main/java/org/onap/policy/pap/main/notification/PolicyNotifier.java b/main/src/main/java/org/onap/policy/pap/main/notification/PolicyNotifier.java
index 97a862be..c24cafca 100644
--- a/main/src/main/java/org/onap/policy/pap/main/notification/PolicyNotifier.java
+++ b/main/src/main/java/org/onap/policy/pap/main/notification/PolicyNotifier.java
@@ -21,17 +21,36 @@
package org.onap.policy.pap.main.notification;
import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
+import org.onap.policy.models.base.PfModelException;
import org.onap.policy.models.pap.concepts.PolicyNotification;
+import org.onap.policy.models.pap.concepts.PolicyStatus;
+import org.onap.policy.models.pdp.concepts.Pdp;
+import org.onap.policy.models.pdp.concepts.PdpGroup;
+import org.onap.policy.models.pdp.concepts.PdpSubGroup;
+import org.onap.policy.models.provider.PolicyModelsProvider;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyFilter;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
+import org.onap.policy.pap.main.PolicyModelsProviderFactoryWrapper;
import org.onap.policy.pap.main.comm.Publisher;
import org.onap.policy.pap.main.comm.QueueToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Notifier for completion of policy updates.
*/
public class PolicyNotifier {
+ private static final Logger logger = LoggerFactory.getLogger(PolicyNotifier.class);
+
/**
* Notification publisher.
*/
@@ -49,12 +68,110 @@ public class PolicyNotifier {
/**
- * Constructs the object.
+ * Constructs the object. Loads all deployed policies into the internal cache.
*
* @param publisher notification publisher
+ * @param daoFactory factory used to load policy deployment data from the DB
+ * @throws PfModelException if a DB error occurs
*/
- public PolicyNotifier(Publisher<PolicyNotification> publisher) {
+ public PolicyNotifier(Publisher<PolicyNotification> publisher, PolicyModelsProviderFactoryWrapper daoFactory)
+ throws PfModelException {
+
this.publisher = publisher;
+
+ try (PolicyModelsProvider dao = daoFactory.create()) {
+ Map<ToscaPolicyIdentifier, ToscaPolicyTypeIdentifier> id2type = loadPolicyTypes(dao);
+ loadPolicies(dao, id2type);
+ }
+ }
+
+ /**
+ * Loads policy types from the DB.
+ *
+ * @param dao provider used to retrieve policies from the DB
+ * @return a mapping from policy id to policy type
+ * @throws PfModelException if a DB error occurs
+ */
+ private Map<ToscaPolicyIdentifier, ToscaPolicyTypeIdentifier> loadPolicyTypes(PolicyModelsProvider dao)
+ throws PfModelException {
+
+ Map<ToscaPolicyIdentifier, ToscaPolicyTypeIdentifier> id2type = new HashMap<>();
+
+ for (ToscaPolicy policy : dao.getFilteredPolicyList(ToscaPolicyFilter.builder().build())) {
+ id2type.put(policy.getIdentifier(), policy.getTypeIdentifier());
+ }
+
+ return id2type;
+ }
+
+ /**
+ * Loads deployed policies.
+ *
+ * @param id2type mapping from policy id to policy type
+ * @param dao provider used to retrieve policies from the DB
+ * @throws PfModelException if a DB error occurs
+ */
+ private void loadPolicies(PolicyModelsProvider dao, Map<ToscaPolicyIdentifier, ToscaPolicyTypeIdentifier> id2type)
+ throws PfModelException {
+ for (PdpGroup group : dao.getPdpGroups(null)) {
+ for (PdpSubGroup subgrp : group.getPdpSubgroups()) {
+ loadPolicies(id2type, group, subgrp);
+ }
+ }
+ }
+
+ /**
+ * Loads a subgroup's deployed policies.
+ *
+ * @param id2type maps a policy id to its type
+ * @param group group containing the subgroup
+ * @param subgrp subgroup whose policies are to be loaded
+ */
+ private void loadPolicies(Map<ToscaPolicyIdentifier, ToscaPolicyTypeIdentifier> id2type, PdpGroup group,
+ PdpSubGroup subgrp) {
+
+ for (ToscaPolicyIdentifier policyId : subgrp.getPolicies()) {
+
+ ToscaPolicyTypeIdentifier type = id2type.get(policyId);
+ if (type == null) {
+ logger.error("group {}:{} refers to non-existent policy {}:{}", group.getName(), subgrp.getPdpType(),
+ policyId.getName(), policyId.getVersion());
+ continue;
+ }
+
+ PolicyPdpNotificationData data = new PolicyPdpNotificationData(policyId, type);
+ data.addAll(subgrp.getPdpInstances().stream().map(Pdp::getInstanceId).collect(Collectors.toList()));
+ deployTracker.addData(data);
+ }
+ }
+
+ /**
+ * Gets the status of all deployed policies.
+ *
+ * @return the status of all deployed policies
+ */
+ public synchronized List<PolicyStatus> getStatus() {
+ return deployTracker.getStatus();
+ }
+
+ /**
+ * Gets the status of a particular deployed policy.
+ *
+ * @param policyId ID of the policy of interest, without the version
+ * @return the status of all deployed policies matching the given identifier
+ */
+ public synchronized List<PolicyStatus> getStatus(String policyId) {
+ return deployTracker.getStatus(policyId);
+ }
+
+ /**
+ * Gets the status of a particular deployed policy.
+ *
+ * @param ident identifier of the policy of interest
+ * @return the status of the given policy, or empty if the policy is not found
+ */
+ public synchronized Optional<PolicyStatus> getStatus(ToscaPolicyIdentifier ident) {
+ return deployTracker.getStatus(ident);
}
/**
diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/PolicyStatusControllerV1.java b/main/src/main/java/org/onap/policy/pap/main/rest/PolicyStatusControllerV1.java
new file mode 100644
index 00000000..cbacd5bf
--- /dev/null
+++ b/main/src/main/java/org/onap/policy/pap/main/rest/PolicyStatusControllerV1.java
@@ -0,0 +1,198 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 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.
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+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.List;
+import java.util.Optional;
+import java.util.UUID;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Response;
+import org.onap.policy.common.utils.services.Registry;
+import org.onap.policy.models.pap.concepts.PolicyStatus;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
+import org.onap.policy.pap.main.PapConstants;
+import org.onap.policy.pap.main.notification.PolicyNotifier;
+
+/**
+ * Class to provide REST end points for PAP component to retrieve the status of deployed
+ * policies.
+ */
+public class PolicyStatusControllerV1 extends PapRestControllerV1 {
+ private final PolicyNotifier notifier;
+
+ public PolicyStatusControllerV1() {
+ this.notifier = Registry.get(PapConstants.REG_POLICY_NOTIFIER, PolicyNotifier.class);
+ }
+
+ /**
+ * Queries status of all deployed policies.
+ *
+ * @param requestId request ID used in ONAP logging
+ * @return a response
+ */
+ // @formatter:off
+ @GET
+ @Path("policies/deployed")
+ @ApiOperation(value = "Queries status of all deployed policies",
+ notes = "Queries status of all deployed policies, returning success and failure counts of the PDPs",
+ responseContainer = "List", response = PolicyStatus.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)})
+ // @formatter:on
+
+ public Response queryAllDeployedPolicies(
+ @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
+
+ return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
+ .entity(notifier.getStatus()).build();
+ }
+
+
+ /**
+ * Queries status of specific deployed policies.
+ *
+ * @param requestId request ID used in ONAP logging
+ * @return a response
+ */
+ // @formatter:off
+ @GET
+ @Path("policies/deployed/{name}")
+ @ApiOperation(value = "Queries status of specific deployed policies",
+ notes = "Queries status of specific deployed policies, returning success and failure counts of the PDPs",
+ responseContainer = "List", response = PolicyStatus.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)})
+ // @formatter:on
+
+ public Response queryDeployedPolicies(
+ @ApiParam(value = "Policy Id", required = true) @PathParam("name") String name,
+ @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
+
+ List<PolicyStatus> result = notifier.getStatus(name);
+ if (result.isEmpty()) {
+ return makeNotFoundResponse(requestId);
+
+ } else {
+ return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
+ .entity(result).build();
+ }
+ }
+
+
+ /**
+ * Queries status of a specific deployed policy.
+ *
+ * @param requestId request ID used in ONAP logging
+ * @return a response
+ */
+ // @formatter:off
+ @GET
+ @Path("policies/deployed/{name}/{version}")
+ @ApiOperation(value = "Queries status of a specific deployed policy",
+ notes = "Queries status of a specific deployed policy, returning success and failure counts of the PDPs",
+ response = PolicyStatus.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)})
+ // @formatter:on
+
+ public Response queryDeployedPolicy(@ApiParam(value = "Policy Id", required = true) @PathParam("name") String name,
+ @ApiParam(value = "Policy Version", required = true) @PathParam("version") String version,
+ @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
+
+ ToscaPolicyIdentifier ident = new ToscaPolicyIdentifier(name, version);
+ Optional<PolicyStatus> result = notifier.getStatus(ident);
+ if (result.isPresent()) {
+ return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
+ .entity(result.get()).build();
+
+ } else {
+ return makeNotFoundResponse(requestId);
+ }
+ }
+
+
+ /**
+ * Makes a "not found" response.
+ *
+ * @param requestId request ID
+ * @return a "not found" response
+ */
+ private Response makeNotFoundResponse(final UUID requestId) {
+ return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.NOT_FOUND)), requestId)
+ .build();
+ }
+}
diff --git a/main/src/main/java/org/onap/policy/pap/main/startstop/PapActivator.java b/main/src/main/java/org/onap/policy/pap/main/startstop/PapActivator.java
index 8d2fd3ea..1fc9784e 100644
--- a/main/src/main/java/org/onap/policy/pap/main/startstop/PapActivator.java
+++ b/main/src/main/java/org/onap/policy/pap/main/startstop/PapActivator.java
@@ -53,6 +53,7 @@ import org.onap.policy.pap.main.rest.PapStatisticsManager;
import org.onap.policy.pap.main.rest.PdpGroupHealthCheckControllerV1;
import org.onap.policy.pap.main.rest.PdpGroupQueryControllerV1;
import org.onap.policy.pap.main.rest.PdpGroupStateChangeControllerV1;
+import org.onap.policy.pap.main.rest.PolicyStatusControllerV1;
import org.onap.policy.pap.main.rest.StatisticsRestControllerV1;
import org.onap.policy.pap.main.rest.depundep.PdpGroupDeleteControllerV1;
import org.onap.policy.pap.main.rest.depundep.PdpGroupDeployControllerV1;
@@ -170,7 +171,7 @@ public class PapActivator extends ServiceManagerContainer {
() -> {
notifyPub.set(new Publisher<>(PapConstants.TOPIC_POLICY_NOTIFICATION));
startThread(notifyPub.get());
- notifier.set(new PolicyNotifier(notifyPub.get()));
+ notifier.set(new PolicyNotifier(notifyPub.get(), daoFactory.get()));
},
() -> notifyPub.get().stop());
@@ -238,7 +239,8 @@ public class PapActivator extends ServiceManagerContainer {
PdpGroupDeleteControllerV1.class,
PdpGroupStateChangeControllerV1.class,
PdpGroupQueryControllerV1.class,
- PdpGroupHealthCheckControllerV1.class);
+ PdpGroupHealthCheckControllerV1.class,
+ PolicyStatusControllerV1.class);
restServer.set(server);
restServer.get().start();
},
diff --git a/main/src/test/java/org/onap/policy/pap/main/notification/PolicyCommonTrackerTest.java b/main/src/test/java/org/onap/policy/pap/main/notification/PolicyCommonTrackerTest.java
index 3318684c..e8c03d1d 100644
--- a/main/src/test/java/org/onap/policy/pap/main/notification/PolicyCommonTrackerTest.java
+++ b/main/src/test/java/org/onap/policy/pap/main/notification/PolicyCommonTrackerTest.java
@@ -30,6 +30,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;
import org.onap.policy.models.pap.concepts.PolicyStatus;
@@ -52,6 +55,54 @@ public class PolicyCommonTrackerTest extends PolicyCommonSupport {
}
@Test
+ public void testGetStatus() {
+ tracker.addData(makeData(policy1, PDP1, PDP2));
+ tracker.addData(makeData(policy2, PDP2));
+
+ List<PolicyStatus> statusList = tracker.getStatus();
+ assertEquals(2, statusList.size());
+
+ Set<String> names = statusList.stream().map(PolicyStatus::getPolicyId).collect(Collectors.toSet());
+ assertTrue(names.contains(policy1.getName()));
+ assertTrue(names.contains(policy2.getName()));
+ }
+
+ @Test
+ public void testGetStatusString() {
+ tracker.addData(makeData(policy1, PDP1, PDP2));
+ tracker.addData(makeData(policy2, PDP2));
+
+ policy3 = new ToscaPolicyIdentifier(policy1.getName(), policy1.getVersion() + "0");
+ tracker.addData(makeData(policy3, PDP3));
+
+ List<PolicyStatus> statusList = tracker.getStatus(policy1.getName());
+ assertEquals(2, statusList.size());
+
+ Set<ToscaPolicyIdentifier> idents =
+ statusList.stream().map(PolicyStatus::getPolicy).collect(Collectors.toSet());
+ assertTrue(idents.contains(policy1));
+ assertTrue(idents.contains(policy3));
+ }
+
+ @Test
+ public void testGetStatusToscaPolicyIdentifier() {
+ tracker.addData(makeData(policy1, PDP1, PDP2));
+ tracker.addData(makeData(policy2, PDP2));
+
+ policy3 = new ToscaPolicyIdentifier(policy1.getName(), policy1.getVersion() + "0");
+ tracker.addData(makeData(policy3, PDP3));
+
+ Optional<PolicyStatus> status = tracker.getStatus(policy1);
+ assertTrue(status.isPresent());
+
+ assertEquals(policy1, status.get().getPolicy());
+
+ // check not-found case
+ status = tracker.getStatus(policy4);
+ assertFalse(status.isPresent());
+ }
+
+ @Test
public void testAddData() {
tracker.addData(makeData(policy1, PDP1, PDP2));
assertEquals(1, map.size());
@@ -113,7 +164,8 @@ public class PolicyCommonTrackerTest extends PolicyCommonSupport {
}
/**
- * Tests removeData() when the subclass indicates that the policy should NOT be removed.
+ * Tests removeData() when the subclass indicates that the policy should NOT be
+ * removed.
*/
@Test
public void testRemoveDataDoNotRemovePolicy() {
diff --git a/main/src/test/java/org/onap/policy/pap/main/notification/PolicyNotifierTest.java b/main/src/test/java/org/onap/policy/pap/main/notification/PolicyNotifierTest.java
index 1c65dd10..8c84337a 100644
--- a/main/src/test/java/org/onap/policy/pap/main/notification/PolicyNotifierTest.java
+++ b/main/src/test/java/org/onap/policy/pap/main/notification/PolicyNotifierTest.java
@@ -21,15 +21,22 @@
package org.onap.policy.pap.main.notification;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
+import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
@@ -37,9 +44,18 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
+import org.onap.policy.models.base.PfModelException;
import org.onap.policy.models.pap.concepts.PolicyNotification;
import org.onap.policy.models.pap.concepts.PolicyStatus;
+import org.onap.policy.models.pdp.concepts.Pdp;
+import org.onap.policy.models.pdp.concepts.PdpGroup;
+import org.onap.policy.models.pdp.concepts.PdpSubGroup;
+import org.onap.policy.models.provider.PolicyModelsProvider;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
+import org.onap.policy.pap.main.PolicyModelsProviderFactoryWrapper;
+import org.onap.policy.pap.main.PolicyPapRuntimeException;
import org.onap.policy.pap.main.comm.Publisher;
import org.onap.policy.pap.main.comm.QueueToken;
@@ -49,6 +65,12 @@ public class PolicyNotifierTest extends PolicyCommonSupport {
private Publisher<PolicyNotification> publisher;
@Mock
+ private PolicyModelsProviderFactoryWrapper daoFactory;
+
+ @Mock
+ private PolicyModelsProvider dao;
+
+ @Mock
private PolicyDeployTracker deploy;
@Mock
@@ -80,7 +102,123 @@ public class PolicyNotifierTest extends PolicyCommonSupport {
super.setUp();
+ try {
+ when(daoFactory.create()).thenReturn(dao);
+ when(dao.getPdpGroups(null)).thenReturn(Collections.emptyList());
+
+ notifier = new MyNotifier(publisher);
+
+ } catch (PfModelException e) {
+ throw new PolicyPapRuntimeException(e);
+ }
+ }
+
+ @Test
+ public void testLoadPoliciesPolicyModelsProviderFactoryWrapper() throws PfModelException {
+ final PdpGroup group1 = makeGroup("my group #1", makeSubGroup("sub #1 A", 2, policy1, policy4),
+ makeSubGroup("sub #1 B", 1, policy2));
+
+ // one policy is a duplicate
+ final PdpGroup group2 = makeGroup("my group #2", makeSubGroup("sub #2 A", 1, policy1, policy3));
+
+ when(dao.getPdpGroups(null)).thenReturn(Arrays.asList(group1, group2));
+
+ ToscaPolicyTypeIdentifier type2 = new ToscaPolicyTypeIdentifier("my other type", "8.8.8");
+
+ // note: no mapping for policy4
+ when(dao.getFilteredPolicyList(any())).thenReturn(Arrays.asList(makePolicy(policy1, type),
+ makePolicy(policy2, type2), makePolicy(policy3, type)));
+
+ // load it
notifier = new MyNotifier(publisher);
+
+ ArgumentCaptor<PolicyPdpNotificationData> captor = ArgumentCaptor.forClass(PolicyPdpNotificationData.class);
+
+ // should have added policy1, policy2, policy1 (duplicate), policy3, but not
+ // policy4
+ verify(deploy, times(4)).addData(captor.capture());
+
+ Iterator<PolicyPdpNotificationData> iter = captor.getAllValues().iterator();
+ PolicyPdpNotificationData data = iter.next();
+ assertEquals(policy1, data.getPolicyId());
+ assertEquals(type, data.getPolicyType());
+ assertEquals("[sub #1 A 0, sub #1 A 1]", data.getPdps().toString());
+
+ data = iter.next();
+ assertEquals(policy2, data.getPolicyId());
+ assertEquals(type2, data.getPolicyType());
+ assertEquals("[sub #1 B 0]", data.getPdps().toString());
+
+ data = iter.next();
+ assertEquals(policy1, data.getPolicyId());
+ assertEquals(type, data.getPolicyType());
+ assertEquals("[sub #2 A 0]", data.getPdps().toString());
+
+ data = iter.next();
+ assertEquals(policy3, data.getPolicyId());
+ assertEquals(type, data.getPolicyType());
+ assertEquals("[sub #2 A 0]", data.getPdps().toString());
+ }
+
+ private ToscaPolicy makePolicy(ToscaPolicyIdentifier policyId, ToscaPolicyTypeIdentifier type) {
+ ToscaPolicy policy = new ToscaPolicy();
+
+ policy.setName(policyId.getName());
+ policy.setVersion(policyId.getVersion());
+ policy.setType(type.getName());
+ policy.setTypeVersion(type.getVersion());
+
+ return policy;
+ }
+
+ private PdpGroup makeGroup(String name, PdpSubGroup... subgrps) {
+ final PdpGroup group = new PdpGroup();
+ group.setName(name);
+
+ group.setPdpSubgroups(Arrays.asList(subgrps));
+
+ return group;
+ }
+
+ private PdpSubGroup makeSubGroup(String name, int numPdps, ToscaPolicyIdentifier... policies) {
+ final PdpSubGroup subgrp = new PdpSubGroup();
+ subgrp.setPdpType(name);
+ subgrp.setPdpInstances(new ArrayList<>(numPdps));
+
+ for (int x = 0; x < numPdps; ++x) {
+ Pdp pdp = new Pdp();
+ pdp.setInstanceId(name + " " + x);
+
+ subgrp.getPdpInstances().add(pdp);
+ }
+
+ subgrp.setPolicies(Arrays.asList(policies));
+
+ return subgrp;
+ }
+
+ @Test
+ public void testGetStatus() {
+ List<PolicyStatus> statusList = Arrays.asList(status1);
+ when(deploy.getStatus()).thenReturn(statusList);
+
+ assertSame(statusList, notifier.getStatus());
+ }
+
+ @Test
+ public void testGetStatusString() {
+ List<PolicyStatus> statusList = Arrays.asList(status1);
+ when(deploy.getStatus("a policy")).thenReturn(statusList);
+
+ assertSame(statusList, notifier.getStatus("a policy"));
+ }
+
+ @Test
+ public void testGetStatusToscaPolicyIdentifier() {
+ Optional<PolicyStatus> status = Optional.of(status1);
+ when(deploy.getStatus(policy1)).thenReturn(status);
+
+ assertSame(status, notifier.getStatus(policy1));
}
@Test
@@ -161,9 +299,9 @@ public class PolicyNotifierTest extends PolicyCommonSupport {
}
@Test
- public void testMakeDeploymentTracker_testMakeUndeploymentTracker() {
+ public void testMakeDeploymentTracker_testMakeUndeploymentTracker() throws PfModelException {
// make real object, which will invoke the real makeXxx() methods
- new PolicyNotifier(publisher).removePdp(PDP1);
+ new PolicyNotifier(publisher, daoFactory).removePdp(PDP1);
verify(publisher, never()).enqueue(any());
}
@@ -197,8 +335,8 @@ public class PolicyNotifierTest extends PolicyCommonSupport {
private class MyNotifier extends PolicyNotifier {
- public MyNotifier(Publisher<PolicyNotification> publisher) {
- super(publisher);
+ public MyNotifier(Publisher<PolicyNotification> publisher) throws PfModelException {
+ super(publisher, daoFactory);
}
@Override
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/CommonPapRestServer.java b/main/src/test/java/org/onap/policy/pap/main/rest/CommonPapRestServer.java
index 91245084..8660d005 100644
--- a/main/src/test/java/org/onap/policy/pap/main/rest/CommonPapRestServer.java
+++ b/main/src/test/java/org/onap/policy/pap/main/rest/CommonPapRestServer.java
@@ -64,6 +64,8 @@ import org.slf4j.LoggerFactory;
*/
public class CommonPapRestServer {
+ protected static final String CONFIG_FILE = "src/test/resources/parameters/TestConfigParams.json";
+
private static final Logger LOGGER = LoggerFactory.getLogger(CommonPapRestServer.class);
private static String KEYSTORE = System.getProperty("user.dir") + "/src/test/resources/ssl/policy-keystore";
@@ -88,6 +90,17 @@ public class CommonPapRestServer {
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception {
+ setUpBeforeClass(true);
+ }
+
+ /**
+ * Allocates a port for the server, writes a config file, and then starts Main, if
+ * specified.
+ *
+ * @param shouldStart {@code true} if Main should be started, {@code false} otherwise
+ * @throws Exception if an error occurs
+ */
+ public static void setUpBeforeClass(boolean shouldStart) throws Exception {
port = NetworkUtil.allocPort();
httpsPrefix = "https://localhost:" + port + "/";
@@ -99,7 +112,9 @@ public class CommonPapRestServer {
CommonTestData.newDb();
- startMain();
+ if (shouldStart) {
+ startMain();
+ }
}
/**
@@ -159,7 +174,7 @@ public class CommonPapRestServer {
private static void makeConfigFile() throws Exception {
String json = new CommonTestData().getPapParameterGroupAsString(port);
- File file = new File("src/test/resources/parameters/TestConfigParams.json");
+ File file = new File(CONFIG_FILE);
file.deleteOnExit();
try (FileOutputStream output = new FileOutputStream(file)) {
@@ -172,7 +187,7 @@ public class CommonPapRestServer {
*
* @throws Exception if an error occurs
*/
- private static void startMain() throws Exception {
+ protected static void startMain() throws Exception {
Registry.newRegistry();
// make sure port is available
@@ -185,7 +200,7 @@ public class CommonPapRestServer {
systemProps.put("javax.net.ssl.keyStorePassword", "Pol1cy_0nap");
System.setProperties(systemProps);
- final String[] papConfigParameters = { "-c", "src/test/resources/parameters/TestConfigParams.json" };
+ final String[] papConfigParameters = { "-c", CONFIG_FILE };
main = new Main(papConfigParameters);
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/TestPolicyStatusControllerV1.java b/main/src/test/java/org/onap/policy/pap/main/rest/TestPolicyStatusControllerV1.java
new file mode 100644
index 00000000..1f7c6d0f
--- /dev/null
+++ b/main/src/test/java/org/onap/policy/pap/main/rest/TestPolicyStatusControllerV1.java
@@ -0,0 +1,76 @@
+/*
+ * ============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 static org.junit.Assert.assertEquals;
+
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.Response;
+import org.junit.Test;
+
+/**
+ * Note: this tests failure cases; success cases are tested by tests in the "e2e" package.
+ */
+public class TestPolicyStatusControllerV1 extends CommonPapRestServer {
+
+ private static final String POLICY_STATUS_ENDPOINT = "policies/deployed";
+
+ @Test
+ public void testSwagger() throws Exception {
+ super.testSwagger(POLICY_STATUS_ENDPOINT);
+
+ super.testSwagger(POLICY_STATUS_ENDPOINT + "/{name}");
+ super.testSwagger(POLICY_STATUS_ENDPOINT + "/{name}/{version}");
+ }
+
+ @Test
+ public void queryAllDeployedPolicies() throws Exception {
+ String uri = POLICY_STATUS_ENDPOINT;
+
+ // verify it fails when no authorization info is included
+ checkUnauthRequest(uri, req -> req.get());
+ }
+
+ @Test
+ public void testQueryDeployedPolicies() throws Exception {
+ String uri = POLICY_STATUS_ENDPOINT + "/my-name";
+
+ Invocation.Builder invocationBuilder = sendRequest(uri);
+ Response rawresp = invocationBuilder.get();
+ assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawresp.getStatus());
+
+ // verify it fails when no authorization info is included
+ checkUnauthRequest(uri, req -> req.get());
+ }
+
+ @Test
+ public void queryDeployedPolicy() throws Exception {
+ String uri = POLICY_STATUS_ENDPOINT + "/my-name/1.2.3";
+
+ Invocation.Builder invocationBuilder = sendRequest(uri);
+ Response rawresp = invocationBuilder.get();
+ assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawresp.getStatus());
+
+ // verify it fails when no authorization info is included
+ checkUnauthRequest(uri, req -> req.get());
+ }
+}
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/e2e/End2EndBase.java b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/End2EndBase.java
index 7e217423..10c791ea 100644
--- a/main/src/test/java/org/onap/policy/pap/main/rest/e2e/End2EndBase.java
+++ b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/End2EndBase.java
@@ -32,14 +32,13 @@ import org.onap.policy.common.utils.coder.Coder;
import org.onap.policy.common.utils.coder.CoderException;
import org.onap.policy.common.utils.coder.StandardCoder;
import org.onap.policy.common.utils.resources.ResourceUtils;
-import org.onap.policy.common.utils.services.Registry;
import org.onap.policy.models.base.PfModelException;
import org.onap.policy.models.pdp.concepts.PdpGroups;
import org.onap.policy.models.provider.PolicyModelsProvider;
import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
-import org.onap.policy.pap.main.PapConstants;
import org.onap.policy.pap.main.PolicyModelsProviderFactoryWrapper;
import org.onap.policy.pap.main.PolicyPapRuntimeException;
+import org.onap.policy.pap.main.parameters.PapParameterGroup;
import org.onap.policy.pap.main.rest.CommonPapRestServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -75,15 +74,21 @@ public class End2EndBase extends CommonPapRestServer {
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception {
- CommonPapRestServer.setUpBeforeClass();
+ setUpBeforeClass(true);
+ }
- daoFactory = Registry.get(PapConstants.REG_PAP_DAO_FACTORY, PolicyModelsProviderFactoryWrapper.class);
+ /**
+ * Starts Main, if specified, and connects to the DB.
+ *
+ * @param shouldStart {@code true} if Main should be started, {@code false} otherwise
+ * @throws Exception if an error occurs
+ */
+ public static void setUpBeforeClass(boolean shouldStart) throws Exception {
+ CommonPapRestServer.setUpBeforeClass(shouldStart);
- try {
- dbConn = daoFactory.create();
- } catch (PfModelException e) {
- throw new PolicyPapRuntimeException("cannot connect to DB", e);
- }
+ PapParameterGroup params = new StandardCoder().decode(new File(CONFIG_FILE), PapParameterGroup.class);
+ daoFactory = new PolicyModelsProviderFactoryWrapper(params.getDatabaseProviderParameters());
+ dbConn = daoFactory.create();
}
/**
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PolicyStatusTest.java b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PolicyStatusTest.java
new file mode 100644
index 00000000..afabb892
--- /dev/null
+++ b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PolicyStatusTest.java
@@ -0,0 +1,112 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 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.
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.rest.e2e;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.Response;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.models.pap.concepts.PolicyStatus;
+
+public class PolicyStatusTest extends End2EndBase {
+ private static final String POLICY_STATUS_ENDPOINT = "policies/deployed";
+
+ /**
+ * Starts Main and adds policies to the DB.
+ *
+ * @throws Exception if an error occurs
+ */
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ // don't start Main until AFTER we add the policies to the DB
+ End2EndBase.setUpBeforeClass(false);
+
+ addToscaPolicyTypes("monitoring.policy-type.yaml");
+ addToscaPolicies("monitoring.policy.yaml");
+ addGroups("policyStatus.json");
+
+ startMain();
+ }
+
+ @Test
+ public void testQueryAllDeployedPolicies() throws Exception {
+ String uri = POLICY_STATUS_ENDPOINT;
+
+ Invocation.Builder invocationBuilder = sendRequest(uri);
+ Response rawresp = invocationBuilder.get();
+ assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+
+ List<PolicyStatus> resp = rawresp.readEntity(new GenericType<List<PolicyStatus>>() {});
+ assertEquals(1, resp.size());
+
+ PolicyStatus status = resp.get(0);
+ assertEquals("onap.restart.tca", status.getPolicyId());
+ assertEquals("1.0.0", status.getPolicyVersion());
+ assertEquals("onap.policies.monitoring.cdap.tca.hi.lo.app", status.getPolicyTypeId());
+ assertEquals("1.0.0", status.getPolicyTypeVersion());
+ assertEquals(0, status.getFailureCount());
+ assertEquals(1, status.getIncompleteCount());
+ assertEquals(0, status.getSuccessCount());
+ }
+
+ @Test
+ public void testQueryDeployedPolicies() throws Exception {
+ String uri = POLICY_STATUS_ENDPOINT + "/onap.restart.tca";
+
+ Invocation.Builder invocationBuilder = sendRequest(uri);
+ Response rawresp = invocationBuilder.get();
+ assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+
+ List<PolicyStatus> resp = rawresp.readEntity(new GenericType<List<PolicyStatus>>() {});
+ assertEquals(1, resp.size());
+
+ PolicyStatus status = resp.get(0);
+ assertEquals("onap.restart.tca", status.getPolicyId());
+ assertEquals("1.0.0", status.getPolicyVersion());
+ assertEquals("onap.policies.monitoring.cdap.tca.hi.lo.app", status.getPolicyTypeId());
+ assertEquals("1.0.0", status.getPolicyTypeVersion());
+ assertEquals(0, status.getFailureCount());
+ assertEquals(1, status.getIncompleteCount());
+ assertEquals(0, status.getSuccessCount());
+ }
+
+ @Test
+ public void testQueryDeployedPolicy() throws Exception {
+ String uri = POLICY_STATUS_ENDPOINT + "/onap.restart.tca/1.0.0";
+
+ Invocation.Builder invocationBuilder = sendRequest(uri);
+ Response rawresp = invocationBuilder.get();
+ assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+
+ PolicyStatus status = rawresp.readEntity(PolicyStatus.class);
+ assertEquals("onap.restart.tca", status.getPolicyId());
+ assertEquals("1.0.0", status.getPolicyVersion());
+ assertEquals("onap.policies.monitoring.cdap.tca.hi.lo.app", status.getPolicyTypeId());
+ assertEquals("1.0.0", status.getPolicyTypeVersion());
+ assertEquals(0, status.getFailureCount());
+ assertEquals(1, status.getIncompleteCount());
+ assertEquals(0, status.getSuccessCount());
+ }
+}
diff --git a/main/src/test/resources/e2e/policyStatus.json b/main/src/test/resources/e2e/policyStatus.json
new file mode 100644
index 00000000..973e2c0e
--- /dev/null
+++ b/main/src/test/resources/e2e/policyStatus.json
@@ -0,0 +1,56 @@
+{
+ "groups": [
+ {
+ "name": "policyStatus",
+ "pdpGroupState": "ACTIVE",
+ "pdpSubgroups": [
+ {
+ "pdpType": "pdpTypeA",
+ "desiredInstanceCount": 2,
+ "pdpInstances": [
+ {
+ "instanceId": "pdpA_1",
+ "pdpState": "ACTIVE",
+ "healthy": "HEALTHY"
+ },
+ {
+ "instanceId": "pdpA_2",
+ "pdpState": "ACTIVE",
+ "healthy": "HEALTHY"
+ }
+ ],
+ "supportedPolicyTypes": [
+ {
+ "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+ "version": "1.0.0"
+ }
+ ],
+ "policies": []
+ },
+ {
+ "pdpType": "pdpTypeB",
+ "desiredInstanceCount": 1,
+ "pdpInstances": [
+ {
+ "instanceId": "pdpB_1",
+ "pdpState": "ACTIVE",
+ "healthy": "HEALTHY"
+ }
+ ],
+ "supportedPolicyTypes": [
+ {
+ "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+ "version": "1.0.0"
+ }
+ ],
+ "policies": [
+ {
+ "name": "onap.restart.tca",
+ "version": "1.0.0"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}