Create PAP API to only create/update PdpGroups 79/99079/6
authora.sreekumar <ajith.sreekumar@est.tech>
Tue, 3 Dec 2019 19:10:47 +0000 (19:10 +0000)
committera.sreekumar <ajith.sreekumar@est.tech>
Thu, 5 Dec 2019 16:43:14 +0000 (16:43 +0000)
Create an API to create/update PdpGroups.
Policies are not allowed to be deployed as part of PDPGroup
create/update operation. There will be a separate API as part of
POLICY-2274 to deploy policies into individual group/subgroups.

Change-Id: I4e2cb43fefe08b22d6f70a1db7c026e83f0ebde0
Issue-ID: POLICY-2273
Signed-off-by: a.sreekumar <ajith.sreekumar@est.tech>
main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupCreateOrUpdateControllerV1.java [new file with mode: 0644]
main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupCreateOrUpdateProvider.java [new file with mode: 0644]
main/src/main/java/org/onap/policy/pap/main/startstop/PapActivator.java
main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupCreateOrUpdateControllerV1.java [new file with mode: 0644]
main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupCreateOrUpdateProvider.java [new file with mode: 0644]
main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupDeployProvider.java
main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupCreateOrUpdateTest.java [new file with mode: 0644]
main/src/test/resources/e2e/createGroups.json
main/src/test/resources/e2e/createNewGroups.json [new file with mode: 0644]
main/src/test/resources/simpleDeploy/createGroups.json
main/src/test/resources/simpleDeploy/createGroupsDelSub.json

diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupCreateOrUpdateControllerV1.java b/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupCreateOrUpdateControllerV1.java
new file mode 100644 (file)
index 0000000..9f72816
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============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.UUID;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.base.PfModelRuntimeException;
+import org.onap.policy.models.pap.concepts.PdpGroupUpdateResponse;
+import org.onap.policy.models.pdp.concepts.PdpGroups;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class to provide REST end points for PAP component to create or update PDP groups.
+ */
+public class PdpGroupCreateOrUpdateControllerV1 extends PapRestControllerV1 {
+    private static final Logger logger = LoggerFactory.getLogger(PdpGroupCreateOrUpdateControllerV1.class);
+
+    private final PdpGroupCreateOrUpdateProvider provider = new PdpGroupCreateOrUpdateProvider();
+
+    /**
+     * Creates or updates one or more PDP groups.
+     *
+     * @param requestId request ID used in ONAP logging
+     * @param groups PDP group configuration
+     * @return a response
+     */
+    // @formatter:off
+    @POST
+    @Path("pdps/groups/batch")
+    @ApiOperation(value = "Create or update PDP Groups",
+        notes = "Create or update one or more PDP Groups, returning optional error details",
+        response = PdpGroupUpdateResponse.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 createOrUpdateGroups(
+        @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
+        @ApiParam(value = "List of PDP Group Configuration", required = true) PdpGroups groups) {
+
+        return doOperation(requestId, "create groups failed", () -> provider.createOrUpdateGroups(groups));
+    }
+
+    /**
+     * Invokes an operation.
+     *
+     * @param requestId request ID
+     * @param errmsg error message to log if the operation throws an exception
+     * @param runnable operation to invoke
+     * @return a {@link PdpGroupUpdateResponse} response entity
+     */
+    private Response doOperation(UUID requestId, String errmsg, RunnableWithPfEx runnable) {
+        try {
+            runnable.run();
+            return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId)
+                .entity(new PdpGroupUpdateResponse()).build();
+
+        } catch (PfModelException | PfModelRuntimeException e) {
+            logger.warn(errmsg, e);
+            PdpGroupUpdateResponse resp = new PdpGroupUpdateResponse();
+            resp.setErrorDetails(e.getErrorResponse().getErrorMessage());
+            return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
+                requestId).entity(resp).build();
+        }
+    }
+}
diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupCreateOrUpdateProvider.java b/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupCreateOrUpdateProvider.java
new file mode 100644 (file)
index 0000000..aed0517
--- /dev/null
@@ -0,0 +1,459 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.rest;
+
+import com.att.aft.dme2.internal.apache.commons.lang.ObjectUtils;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import javax.ws.rs.core.Response.Status;
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.parameters.ObjectValidationResult;
+import org.onap.policy.common.parameters.ValidationResult;
+import org.onap.policy.common.parameters.ValidationStatus;
+import org.onap.policy.common.utils.services.Registry;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.pdp.concepts.Pdp;
+import org.onap.policy.models.pdp.concepts.PdpGroup;
+import org.onap.policy.models.pdp.concepts.PdpGroups;
+import org.onap.policy.models.pdp.concepts.PdpStateChange;
+import org.onap.policy.models.pdp.concepts.PdpSubGroup;
+import org.onap.policy.models.pdp.concepts.PdpUpdate;
+import org.onap.policy.models.pdp.enums.PdpState;
+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.ToscaPolicyIdentifierOptVersion;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provider for PAP component to create or update PDP groups. The following items must be in the
+ * {@link Registry}:
+ * <ul>
+ * <li>PDP Modification Lock</li>
+ * <li>PDP Modify Request Map</li>
+ * <li>PAP DAO Factory</li>
+ * </ul>
+ */
+public class PdpGroupCreateOrUpdateProvider extends ProviderBase {
+    private static final Logger logger = LoggerFactory.getLogger(PdpGroupCreateOrUpdateProvider.class);
+
+    /**
+     * Constructs the object.
+     */
+    public PdpGroupCreateOrUpdateProvider() {
+        super();
+    }
+
+    /**
+     * Creates or updates PDP groups.
+     *
+     * @param groups PDP group configurations to be created or updated
+     * @throws PfModelException if an error occurred
+     */
+    public void createOrUpdateGroups(PdpGroups groups) throws PfModelException {
+        ValidationResult result = groups.validatePapRest();
+
+        if (!result.isValid()) {
+            String msg = result.getResult().trim();
+            logger.warn(msg);
+            throw new PfModelException(Status.BAD_REQUEST, msg);
+        }
+        // During PdpGroup create/update, policies are not supposed to be deployed/undeployed into the group.
+        // There is a separate API for this.
+        List<PdpSubGroup> subGroupsWithPolicies =
+            groups.getGroups().parallelStream().flatMap(group -> group.getPdpSubgroups().parallelStream())
+                .filter(subGroup -> !subGroup.getPolicies().isEmpty()).collect(Collectors.toList());
+        if (!subGroupsWithPolicies.isEmpty()) {
+            logger.warn(
+                "Policies cannot be deployed during PdpGroup Create/Update operation. Ignoring the list of policies");
+            subGroupsWithPolicies.forEach(subGroup -> subGroup.setPolicies(Collections.emptyList()));
+        }
+        process(groups, this::createOrUpdate);
+    }
+
+    /**
+     * Creates or updates PDP groups. This is the method that does the actual work.
+     *
+     * @param data session data
+     * @param groups PDP group configurations
+     * @throws PfModelException if an error occurred
+     */
+    private void createOrUpdate(SessionData data, PdpGroups groups) throws PfModelException {
+        BeanValidationResult result = new BeanValidationResult("groups", groups);
+
+        for (PdpGroup group : groups.getGroups()) {
+            PdpGroup dbgroup = data.getGroup(group.getName());
+
+            if (dbgroup == null) {
+                result.addResult(addGroup(data, group));
+
+            } else {
+                result.addResult(updateGroup(data, dbgroup, group));
+            }
+        }
+
+        if (!result.isValid()) {
+            throw new PfModelException(Status.BAD_REQUEST, result.getResult().trim());
+        }
+    }
+
+    /**
+     * Adds a new group.
+     *
+     * @param data session data
+     * @param group the group to be added
+     * @return the validation result
+     * @throws PfModelException if an error occurred
+     */
+    private ValidationResult addGroup(SessionData data, PdpGroup group) throws PfModelException {
+        BeanValidationResult result = new BeanValidationResult(group.getName(), group);
+
+        validateGroupOnly(group, result);
+        if (!result.isValid()) {
+            return result;
+        }
+
+        // default to active
+        if (group.getPdpGroupState() == null) {
+            group.setPdpGroupState(PdpState.ACTIVE);
+        }
+
+        for (PdpSubGroup subgrp : group.getPdpSubgroups()) {
+            result.addResult(addSubGroup(data, subgrp));
+        }
+
+        if (result.isValid()) {
+            data.create(group);
+        }
+
+        return result;
+    }
+
+    /**
+     * Performs additional validations of a group, but does not examine the subgroups.
+     *
+     * @param group the group to be validated
+     * @param result the validation result
+     */
+    private void validateGroupOnly(PdpGroup group, BeanValidationResult result) {
+        if (group.getPdpGroupState() == null) {
+            return;
+        }
+
+        switch (group.getPdpGroupState()) {
+            case ACTIVE:
+            case PASSIVE:
+                break;
+
+            default:
+                result.addResult(new ObjectValidationResult("pdpGroupState", group.getPdpGroupState(),
+                    ValidationStatus.INVALID, "must be null, ACTIVE, or PASSIVE"));
+                break;
+        }
+    }
+
+    /**
+     * Updates an existing group.
+     *
+     * @param data session data
+     * @param dbgroup the group, as it appears within the DB
+     * @param group the group to be added
+     * @return the validation result
+     * @throws PfModelException if an error occurred
+     */
+    private ValidationResult updateGroup(SessionData data, PdpGroup dbgroup, PdpGroup group) throws PfModelException {
+        BeanValidationResult result = new BeanValidationResult(group.getName(), group);
+
+        if (!ObjectUtils.equals(dbgroup.getProperties(), group.getProperties())) {
+            result.addResult(
+                new ObjectValidationResult("properties", "", ValidationStatus.INVALID, "cannot change properties"));
+        }
+
+        boolean updated = updateField(dbgroup.getDescription(), group.getDescription(), dbgroup::setDescription);
+        updated =
+            updateField(dbgroup.getPdpGroupState(), group.getPdpGroupState(), dbgroup::setPdpGroupState) || updated;
+        updated = notifyPdpsDelSubGroups(data, dbgroup, group) || updated;
+        updated = addOrUpdateSubGroups(data, dbgroup, group, result) || updated;
+
+        if (result.isValid() && updated) {
+            data.update(group);
+        }
+
+        return result;
+    }
+
+    /**
+     * Updates a field, if the new value is different than the old value.
+     *
+     * @param oldValue old value
+     * @param newValue new value
+     * @param setter function to set the field to the new value
+     * @return {@code true} if the field was updated, {@code false} if it already matched
+     *         the new value
+     */
+    private <T> boolean updateField(T oldValue, T newValue, Consumer<T> setter) {
+        if (oldValue == newValue) {
+            return false;
+        }
+
+        if (oldValue != null && oldValue.equals(newValue)) {
+            return false;
+        }
+
+        setter.accept(newValue);
+        return true;
+    }
+
+    /**
+     * Adds or updates subgroups within the group.
+     *
+     * @param data session data
+     * @param dbgroup the group, as it appears within the DB
+     * @param group the group to be added
+     * @param result the validation result
+     * @return {@code true} if the DB group was modified, {@code false} otherwise
+     * @throws PfModelException if an error occurred
+     */
+    private boolean addOrUpdateSubGroups(SessionData data, PdpGroup dbgroup, PdpGroup group,
+        BeanValidationResult result) throws PfModelException {
+
+        // create a map of existing subgroups
+        Map<String, PdpSubGroup> type2sub = new HashMap<>();
+        dbgroup.getPdpSubgroups().forEach(subgrp -> type2sub.put(subgrp.getPdpType(), subgrp));
+
+        boolean updated = false;
+
+        for (PdpSubGroup subgrp : group.getPdpSubgroups()) {
+            PdpSubGroup dbsub = type2sub.get(subgrp.getPdpType());
+            BeanValidationResult subResult = new BeanValidationResult(subgrp.getPdpType(), subgrp);
+
+            if (dbsub == null) {
+                updated = true;
+                subResult.addResult(addSubGroup(data, subgrp));
+                dbgroup.getPdpSubgroups().add(subgrp);
+
+            } else {
+                updated = updateSubGroup(data, dbsub, subgrp, subResult) || updated;
+            }
+
+            result.addResult(subResult);
+        }
+
+        return updated;
+    }
+
+    /**
+     * Notifies any PDPs whose subgroups are being removed.
+     *
+     * @param data session data
+     * @param dbgroup the group, as it appears within the DB
+     * @param group the group being updated
+     * @return {@code true} if a subgroup was removed, {@code false} otherwise
+     * @throws PfModelException if an error occurred
+     */
+    private boolean notifyPdpsDelSubGroups(SessionData data, PdpGroup dbgroup, PdpGroup group) throws PfModelException {
+        boolean updated = false;
+
+        // subgroups, as they appear within the updated group
+        Set<String> subgroups = new HashSet<>();
+        group.getPdpSubgroups().forEach(subgrp -> subgroups.add(subgrp.getPdpType()));
+
+        // loop through subgroups as they appear within the DB
+        for (PdpSubGroup subgrp : dbgroup.getPdpSubgroups()) {
+
+            if (!subgroups.contains(subgrp.getPdpType())) {
+                // this subgroup no longer appears - notify its PDPs
+                updated = true;
+                notifyPdpsDelSubGroup(data, subgrp);
+                trackPdpsDelSubGroup(data, subgrp);
+            }
+        }
+
+        return updated;
+    }
+
+    /**
+     * Notifies the PDPs that their subgroup is being removed.
+     *
+     * @param data session data
+     * @param subgrp subgroup that is being removed
+     */
+    private void notifyPdpsDelSubGroup(SessionData data, PdpSubGroup subgrp) {
+        for (Pdp pdp : subgrp.getPdpInstances()) {
+            String name = pdp.getInstanceId();
+
+            // make it passive
+            PdpStateChange change = new PdpStateChange();
+            change.setName(name);
+            change.setState(PdpState.PASSIVE);
+
+            // remove it from subgroup and undeploy all policies
+            PdpUpdate update = new PdpUpdate();
+            update.setName(name);
+
+            data.addRequests(update, change);
+        }
+    }
+
+    /**
+     * Tracks PDP responses when their subgroup is removed.
+     *
+     * @param data session data
+     * @param subgrp subgroup that is being removed
+     * @throws PfModelException if an error occurred
+     */
+    private void trackPdpsDelSubGroup(SessionData data, PdpSubGroup subgrp) throws PfModelException {
+        Set<String> pdps = subgrp.getPdpInstances().stream().map(Pdp::getInstanceId).collect(Collectors.toSet());
+
+        for (ToscaPolicyIdentifier policyId : subgrp.getPolicies()) {
+            data.trackUndeploy(policyId, pdps);
+        }
+    }
+
+    /**
+     * Adds a new subgroup.
+     *
+     * @param data session data
+     * @param subgrp the subgroup to be added, updated to fully qualified versions upon
+     *        return
+     * @return the validation result
+     * @throws PfModelException if an error occurred
+     */
+    private ValidationResult addSubGroup(SessionData data, PdpSubGroup subgrp) throws PfModelException {
+        subgrp.setCurrentInstanceCount(0);
+        subgrp.setPdpInstances(Collections.emptyList());
+
+        BeanValidationResult result = new BeanValidationResult(subgrp.getPdpType(), subgrp);
+
+        result.addResult(validateSupportedTypes(data, subgrp));
+        return result;
+    }
+
+    /**
+     * Updates an existing subgroup.
+     *
+     * @param data session data
+     * @param dbsub the subgroup, from the DB
+     * @param subgrp the subgroup to be updated, updated to fully qualified versions upon
+     *        return
+     * @param container container for additional validation results
+     * @return {@code true} if the subgroup content was changed, {@code false} if there
+     *         were no changes
+     * @throws PfModelException if an error occurred
+     */
+    private boolean updateSubGroup(SessionData data, PdpSubGroup dbsub, PdpSubGroup subgrp,
+        BeanValidationResult container) throws PfModelException {
+
+        // perform additional validations first
+        if (!validateSubGroup(data, dbsub, subgrp, container)) {
+            return false;
+        }
+
+        boolean updated = updateList(dbsub.getSupportedPolicyTypes(), subgrp.getSupportedPolicyTypes(),
+            dbsub::setSupportedPolicyTypes);
+
+        return updateField(dbsub.getDesiredInstanceCount(), subgrp.getDesiredInstanceCount(),
+            dbsub::setDesiredInstanceCount) || updated;
+    }
+
+    /**
+     * Performs additional validations of a subgroup.
+     *
+     * @param data session data
+     * @param dbsub the subgroup, from the DB
+     * @param subgrp the subgroup to be validated, updated to fully qualified versions
+     *        upon return
+     * @param container container for additional validation results
+     * @return {@code true} if the subgroup is valid, {@code false} otherwise
+     * @throws PfModelException if an error occurred
+     */
+    private boolean validateSubGroup(SessionData data, PdpSubGroup dbsub, PdpSubGroup subgrp,
+        BeanValidationResult container) throws PfModelException {
+
+        BeanValidationResult result = new BeanValidationResult(subgrp.getPdpType(), subgrp);
+
+        if (!ObjectUtils.equals(dbsub.getProperties(), subgrp.getProperties())) {
+            result.addResult(
+                new ObjectValidationResult("properties", "", ValidationStatus.INVALID, "cannot change properties"));
+        }
+
+        result.addResult(validateSupportedTypes(data, subgrp));
+        container.addResult(result);
+
+        return result.isValid();
+    }
+
+    /**
+     * Updates a DB list with items from a new list.
+     *
+     * @param dblist the list from the DB
+     * @param newList the new list
+     * @param setter function to set the new list
+     * @return {@code true} if the list changed, {@code false} if the lists were the same
+     */
+    private <T> boolean updateList(List<T> dblist, List<T> newList, Consumer<List<T>> setter) {
+
+        Set<T> dbTypes = new HashSet<>(dblist);
+        Set<T> newTypes = new HashSet<>(newList);
+
+        if (dbTypes.equals(newTypes)) {
+            return false;
+        }
+
+        setter.accept(new ArrayList<>(newTypes));
+
+        return true;
+    }
+
+    /**
+     * Performs additional validations of the supported policy types within a subgroup.
+     *
+     * @param data session data
+     * @param subgrp the subgroup to be validated
+     * @param result the validation result
+     * @throws PfModelException if an error occurred
+     */
+    private ValidationResult validateSupportedTypes(SessionData data, PdpSubGroup subgrp) throws PfModelException {
+        BeanValidationResult result = new BeanValidationResult(subgrp.getPdpType(), subgrp);
+
+        for (ToscaPolicyTypeIdentifier type : subgrp.getSupportedPolicyTypes()) {
+            if (!type.getName().endsWith(".*") && data.getPolicyType(type) == null) {
+                result.addResult(
+                    new ObjectValidationResult("policy type", type, ValidationStatus.INVALID, "unknown policy type"));
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    protected Updater makeUpdater(SessionData data, ToscaPolicy policy, ToscaPolicyIdentifierOptVersion desiredPolicy) {
+        throw new UnsupportedOperationException("makeUpdater should not be invoked");
+    }
+}
index f784ed5..1721cb0 100644 (file)
@@ -50,6 +50,7 @@ import org.onap.policy.pap.main.parameters.PdpParameters;
 import org.onap.policy.pap.main.rest.HealthCheckRestControllerV1;
 import org.onap.policy.pap.main.rest.PapAafFilter;
 import org.onap.policy.pap.main.rest.PapStatisticsManager;
+import org.onap.policy.pap.main.rest.PdpGroupCreateOrUpdateControllerV1;
 import org.onap.policy.pap.main.rest.PdpGroupDeleteControllerV1;
 import org.onap.policy.pap.main.rest.PdpGroupDeployControllerV1;
 import org.onap.policy.pap.main.rest.PdpGroupHealthCheckControllerV1;
@@ -239,6 +240,7 @@ public class PapActivator extends ServiceManagerContainer {
                 RestServer server = new RestServer(papParameterGroup.getRestServerParameters(), PapAafFilter.class,
                                 HealthCheckRestControllerV1.class,
                                 StatisticsRestControllerV1.class,
+                                PdpGroupCreateOrUpdateControllerV1.class,
                                 PdpGroupDeployControllerV1.class,
                                 PdpGroupDeleteControllerV1.class,
                                 PdpGroupStateChangeControllerV1.class,
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupCreateOrUpdateControllerV1.java b/main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupCreateOrUpdateControllerV1.java
new file mode 100644 (file)
index 0000000..3124641
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.rest;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Arrays;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.junit.Test;
+import org.onap.policy.models.pap.concepts.PdpGroupUpdateResponse;
+import org.onap.policy.models.pdp.concepts.PdpGroup;
+import org.onap.policy.models.pdp.concepts.PdpGroups;
+import org.onap.policy.models.pdp.concepts.PdpSubGroup;
+
+/**
+ * Note: this tests failure cases; success cases are tested by tests in the "e2e" package.
+ */
+public class TestPdpGroupCreateOrUpdateControllerV1 extends CommonPapRestServer {
+
+    private static final String CREATEORUPDATE_GROUPS_ENDPOINT = "pdps/groups/batch";
+
+    @Test
+    public void testSwagger() throws Exception {
+        super.testSwagger(CREATEORUPDATE_GROUPS_ENDPOINT);
+    }
+
+    @Test
+    public void testCreateOrUpdateGroups() throws Exception {
+        Entity<PdpGroups> entgrp = makePdpGroupsEntity();
+
+        Invocation.Builder invocationBuilder = sendRequest(CREATEORUPDATE_GROUPS_ENDPOINT);
+        Response rawresp = invocationBuilder.post(entgrp);
+        PdpGroupUpdateResponse resp = rawresp.readEntity(PdpGroupUpdateResponse.class);
+        assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), rawresp.getStatus());
+        assertNotNull(resp.getErrorDetails());
+
+        rawresp = invocationBuilder.post(entgrp);
+        resp = rawresp.readEntity(PdpGroupUpdateResponse.class);
+        assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), rawresp.getStatus());
+        assertNotNull(resp.getErrorDetails());
+
+        // verify it fails when no authorization info is included
+        checkUnauthRequest(CREATEORUPDATE_GROUPS_ENDPOINT, req -> req.post(entgrp));
+    }
+
+    private Entity<PdpGroups> makePdpGroupsEntity() {
+        PdpSubGroup subgrp = new PdpSubGroup();
+        subgrp.setPdpType("drools");
+
+        PdpGroup group = new PdpGroup();
+        group.setName("drools-group");
+        group.setDescription("my description");
+        group.setPdpSubgroups(Arrays.asList(subgrp));
+        PdpGroups groups = new PdpGroups();
+        groups.setGroups(Arrays.asList(group));
+        return Entity.entity(groups, MediaType.APPLICATION_JSON);
+    }
+}
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupCreateOrUpdateProvider.java b/main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupCreateOrUpdateProvider.java
new file mode 100644 (file)
index 0000000..1ac97c7
--- /dev/null
@@ -0,0 +1,563 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.rest;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.never;
+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.List;
+import java.util.TreeMap;
+import javax.ws.rs.core.Response.Status;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.common.utils.services.Registry;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.pdp.concepts.PdpGroup;
+import org.onap.policy.models.pdp.concepts.PdpGroups;
+import org.onap.policy.models.pdp.concepts.PdpStateChange;
+import org.onap.policy.models.pdp.concepts.PdpSubGroup;
+import org.onap.policy.models.pdp.concepts.PdpUpdate;
+import org.onap.policy.models.pdp.enums.PdpState;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
+
+public class TestPdpGroupCreateOrUpdateProvider extends ProviderSuper {
+    private static final String EXPECTED_EXCEPTION = "expected exception";
+
+    private static final String PDP2 = "pdpB";
+    private static final String PDP4 = "pdpD";
+
+    private PdpGroupCreateOrUpdateProvider prov;
+
+    @AfterClass
+    public static void tearDownAfterClass() {
+        Registry.newRegistry();
+    }
+
+    /**
+     * Configures mocks and objects.
+     *
+     * @throws Exception if an error occurs
+     */
+    @Override
+    @Before
+    public void setUp() throws Exception {
+
+        super.setUp();
+
+        when(dao.getPolicyTypeList("typeA", "100.2.3")).thenReturn(Arrays.asList(loadPolicyType("daoPolicyType.json")));
+
+        prov = new PdpGroupCreateOrUpdateProvider();
+    }
+
+    @Test
+    public void testCreateOrUpdateGroups() throws Exception {
+        prov.createOrUpdateGroups(loadPdpGroups("emptyGroups.json"));
+
+        // no groups, so no action should have been taken
+        assertNoGroupAction();
+    }
+
+    @Test
+    public void testCreateOrUpdateGroups_InvalidRequest() throws Exception {
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(new PdpGroups())).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("is null");
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    public void testCreateOrUpdate_Invalid() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED);
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("pdpGroupState");
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    public void testAddGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup group = groups.getGroups().get(0);
+        group.setPdpGroupState(PdpState.PASSIVE);
+
+        prov.createOrUpdateGroups(groups);
+
+        // should not have updated the state
+        assertEquals(PdpState.PASSIVE, group.getPdpGroupState());
+
+        assertSame(group, getGroupCreates().get(0));
+    }
+
+    @Test
+    public void testAddGroup_Invalid() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED);
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("pdpGroupState");
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    public void testAddGroup_InvalidSubGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+
+        groups.getGroups().get(0).getPdpSubgroups().get(0).getSupportedPolicyTypes().get(0).setVersion("99.99.99");
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("unknown policy type");
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    public void testValidateGroupOnly_NullState() throws PfModelException {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        groups.getGroups().get(0).setPdpGroupState(null);
+        prov.createOrUpdateGroups(groups);
+    }
+
+    @Test
+    public void testValidateGroupOnly_Active() throws PfModelException {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        groups.getGroups().get(0).setPdpGroupState(PdpState.ACTIVE);
+        prov.createOrUpdateGroups(groups);
+    }
+
+    @Test
+    public void testValidateGroupOnly_Passive() throws PfModelException {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        groups.getGroups().get(0).setPdpGroupState(PdpState.PASSIVE);
+        prov.createOrUpdateGroups(groups);
+    }
+
+    @Test
+    public void testValidateGroupOnly_Invalid() {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED);
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("pdpGroupState");
+    }
+
+    @Test
+    public void testUpdateGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+
+        // DB group = new group
+        PdpGroup group = new PdpGroup(groups.getGroups().get(0));
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    public void testUpdateGroup_PropertiesChanged() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+
+        PdpGroup group = new PdpGroup(groups.getGroups().get(0));
+        group.setProperties(new TreeMap<>());
+
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("properties");
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    public void testUpdateGroup_NewDescription() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        group.setDescription("old description");
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        assertGroupUpdateOnly(group);
+
+        assertEquals(group.getDescription(), "my description");
+        assertEquals(newgrp.toString(), group.toString());
+    }
+
+    @Test
+    public void testUpdateGroup_NewState() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        group.setPdpGroupState(PdpState.TEST);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        assertGroupUpdateOnly(group);
+
+        assertEquals(PdpState.ACTIVE, group.getPdpGroupState());
+        assertEquals(newgrp.toString(), group.toString());
+    }
+
+    @Test
+    public void testUpdateGroup_NewSubGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
+        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        PdpGroup newgrp = groups.getGroups().get(0);
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    @Test
+    public void testUpdateGroup_UpdatedSubGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        // something different in this subgroup
+        group.getPdpSubgroups().get(0).setDesiredInstanceCount(10);
+
+        prov.createOrUpdateGroups(groups);
+
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    @Test
+    public void testUpdateGroup_notifyPdpsDelSubGroups() throws Exception {
+        PdpGroup dbgroup = new PdpGroup(loadPdpGroups("createGroupsDelSub.json").getGroups().get(0));
+        when(dao.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
+
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+
+        prov.createOrUpdateGroups(groups);
+
+        // verify that DB group was updated
+        List<PdpGroup> updates = getGroupUpdates();
+        assertEquals(1, updates.size());
+        dbgroup = updates.get(0);
+
+        PdpGroup newgrp = groups.getGroups().get(0);
+
+        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
+        Collections.sort(dbgroup.getPdpSubgroups().get(0).getPolicies());
+
+        assertEquals(newgrp.toString(), dbgroup.toString());
+
+        // no deployment notifications
+        verify(notifier, never()).addDeploymentData(any());
+
+        // this requires a PDP UPDATE message
+        List<PdpUpdate> pdpUpdates = getUpdateRequests(2);
+        assertEquals(2, pdpUpdates.size());
+
+        PdpUpdate pdpUpdate = pdpUpdates.get(0);
+        assertEquals(PDP2, pdpUpdate.getName());
+        assertNull(pdpUpdate.getPdpGroup());
+
+        pdpUpdate = pdpUpdates.get(1);
+        assertEquals(PDP4, pdpUpdate.getName());
+        assertNull(pdpUpdate.getPdpGroup());
+
+        // it also requires a PDP STATE-CHANGE message
+        List<PdpStateChange> changes = getStateChangeRequests(2);
+        assertEquals(2, changes.size());
+
+        PdpStateChange change = changes.get(0);
+        assertEquals(PDP2, change.getName());
+        assertEquals(PdpState.PASSIVE, change.getState());
+
+        change = changes.get(1);
+        assertEquals(PDP4, change.getName());
+        assertEquals(PdpState.PASSIVE, change.getState());
+    }
+
+    @Test
+    public void testUpdateField_Unchanged() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    public void testUpdateField_WasNull() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        group.setDescription(null);
+
+        prov.createOrUpdateGroups(groups);
+
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    @Test
+    public void testUpdateField_NowNull() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        newgrp.setDescription(null);
+
+        prov.createOrUpdateGroups(groups);
+
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    @Test
+    public void testUpdateField_Changed() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        newgrp.setDescription(group.getDescription() + "-changed");
+
+        prov.createOrUpdateGroups(groups);
+
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    @Test
+    public void testAddSubGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
+        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        PdpGroup newgrp = groups.getGroups().get(0);
+
+        PdpSubGroup newsub = newgrp.getPdpSubgroups().get(1);
+        newsub.setCurrentInstanceCount(0);
+        newsub.setPdpInstances(new ArrayList<>(0));
+
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    /**
+     * Tests addSubgroup() when the new subgroup has a wild-card policy type.
+     *
+     * @throws Exception if an error occurs
+     */
+    @Test
+    public void testAddSubGroupWildCardPolicyType() throws Exception {
+        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyListWildCard.json"));
+        when(dao.getPolicyTypeList("some.*", "2.3.4")).thenReturn(Collections.emptyList());
+
+        PdpGroups groups = loadPdpGroups("createGroupsWildCard.json");
+        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        PdpGroup newgrp = groups.getGroups().get(0);
+
+        PdpSubGroup newsub = newgrp.getPdpSubgroups().get(1);
+        newsub.setCurrentInstanceCount(0);
+        newsub.setPdpInstances(new ArrayList<>(0));
+
+        assertEquals(newgrp.toString(), group.toString());
+    }
+
+    @Test
+    public void testAddSubGroup_ValidationPolicyTypeNotFound() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
+        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        when(dao.getPolicyTypeList(any(), any())).thenReturn(Collections.emptyList());
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).hasMessageContaining("unknown policy type");
+    }
+
+    @Test
+    public void testAddSubGroup_ValidationPolicyTypeDaoEx() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
+        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        PfModelException exc = new PfModelException(Status.CONFLICT, EXPECTED_EXCEPTION);
+        when(dao.getPolicyTypeList(any(), any())).thenThrow(exc);
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isSameAs(exc);
+    }
+
+    @Test
+    public void testAddSubGroup_ValidateVersionPrefixMatch() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup dbgroup = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
+
+        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("createGroupNewPolicy.json"))
+            .thenReturn(loadPolicies("daoPolicyList.json")).thenReturn(loadPolicies("createGroupNewPolicy.json"));
+
+        PdpGroups reqgroups = loadPdpGroups("createGroupsVersPrefix.json");
+
+        prov.createOrUpdateGroups(reqgroups);
+
+        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
+        Collections.sort(dbgroup.getPdpSubgroups().get(0).getPolicies());
+
+        assertEquals(newgrp.toString(), dbgroup.toString());
+    }
+
+    @Test
+    public void testUpdateSubGroup_Invalid() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        // change properties
+        newgrp.getPdpSubgroups().get(0).setProperties(new TreeMap<>());
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("properties");
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    public void testUpdateSubGroup_SupportedPolicies() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        newgrp.getPdpSubgroups().get(0).getSupportedPolicyTypes()
+            .add(new ToscaPolicyTypeIdentifier("typeX.*", "9.8.7"));
+
+        prov.createOrUpdateGroups(groups);
+
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    @Test
+    public void testUpdateSubGroup_DesiredCount() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        newgrp.getPdpSubgroups().get(0).setDesiredInstanceCount(20);
+
+        prov.createOrUpdateGroups(groups);
+
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    @Test
+    public void testUpdateSubGroup_Unchanged() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
+        Collections.sort(group.getPdpSubgroups().get(0).getPolicies());
+
+        assertEquals(newgrp.toString(), group.toString());
+
+        // no notifications
+        verify(notifier, never()).addDeploymentData(any());
+        verify(notifier, never()).addUndeploymentData(any());
+
+        // no group updates
+        assertNoGroupAction();
+    }
+
+    @Test
+    public void testValidateSubGroup_PropertiesMismatch() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        newgrp.setProperties(new TreeMap<>());
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("properties");
+
+        assertNoGroupAction();
+    }
+
+    protected void assertUpdate(List<PdpUpdate> updates, String groupName, String pdpType, String pdpName) {
+
+        PdpUpdate update = updates.remove(0);
+
+        assertEquals(groupName, update.getPdpGroup());
+        assertEquals(pdpType, update.getPdpSubgroup());
+        assertEquals(pdpName, update.getName());
+        assertTrue(update.getPolicies().contains(policy1));
+    }
+
+    private void assertNoGroupAction() throws Exception {
+        verify(dao, never()).createPdpGroups(any());
+        verify(dao, never()).updatePdpGroups(any());
+        verify(reqmap, never()).addRequest(any(), any());
+    }
+
+    private void assertGroupUpdateOnly(PdpGroup group) throws Exception {
+        verify(dao, never()).createPdpGroups(any());
+        verify(reqmap, never()).addRequest(any(), any());
+
+        List<PdpGroup> updates = getGroupUpdates();
+        assertEquals(Arrays.asList(group), updates);
+    }
+}
index 39a1139..a7fc11a 100644 (file)
@@ -22,7 +22,6 @@ package org.onap.policy.pap.main.rest;
 
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
@@ -48,7 +47,6 @@ import org.onap.policy.models.base.PfModelRuntimeException;
 import org.onap.policy.models.pap.concepts.PdpDeployPolicies;
 import org.onap.policy.models.pdp.concepts.PdpGroup;
 import org.onap.policy.models.pdp.concepts.PdpGroups;
-import org.onap.policy.models.pdp.concepts.PdpStateChange;
 import org.onap.policy.models.pdp.concepts.PdpSubGroup;
 import org.onap.policy.models.pdp.concepts.PdpUpdate;
 import org.onap.policy.models.pdp.enums.PdpState;
@@ -82,6 +80,7 @@ public class TestPdpGroupDeployProvider extends ProviderSuper {
      *
      * @throws Exception if an error occurs
      */
+    @Override
     @Before
     public void setUp() throws Exception {
 
@@ -145,19 +144,6 @@ public class TestPdpGroupDeployProvider extends ProviderSuper {
         assertNoGroupAction();
     }
 
-    @Test
-    public void testAddGroup_InvalidSubGroup() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
-
-        // policy won't match supported type
-        groups.getGroups().get(0).getPdpSubgroups().get(0).getSupportedPolicyTypes().get(0).setVersion("99.99.99");
-
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
-                        .hasMessageContaining("supported policy");
-
-        assertNoGroupAction();
-    }
-
     @Test
     public void testValidateGroupOnly_NullState() throws PfModelException {
         PdpGroups groups = loadPdpGroups("createGroups.json");
@@ -248,19 +234,6 @@ public class TestPdpGroupDeployProvider extends ProviderSuper {
         assertEquals(newgrp.toString(), group.toString());
     }
 
-    @Test
-    public void testUpdateGroup_NewSubGroup() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
-        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
-        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
-
-        prov.createOrUpdateGroups(groups);
-
-        PdpGroup newgrp = groups.getGroups().get(0);
-        assertEquals(newgrp.toString(), group.toString());
-        assertGroupUpdateOnly(group);
-    }
-
     @Test
     public void testUpdateGroup_UpdatedSubGroup() throws Exception {
         PdpGroups groups = loadPdpGroups("createGroups.json");
@@ -277,60 +250,6 @@ public class TestPdpGroupDeployProvider extends ProviderSuper {
         assertGroupUpdateOnly(group);
     }
 
-    @Test
-    public void testUpdateGroup_notifyPdpsDelSubGroups() throws Exception {
-        PdpGroup dbgroup = new PdpGroup(loadPdpGroups("createGroupsDelSub.json").getGroups().get(0));
-        when(dao.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
-
-        PdpGroups groups = loadPdpGroups("createGroups.json");
-
-        prov.createOrUpdateGroups(groups);
-
-        // verify that DB group was updated
-        List<PdpGroup> updates = getGroupUpdates();
-        assertEquals(1, updates.size());
-        dbgroup = updates.get(0);
-
-        PdpGroup newgrp = groups.getGroups().get(0);
-
-        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
-        Collections.sort(dbgroup.getPdpSubgroups().get(0).getPolicies());
-
-        assertEquals(newgrp.toString(), dbgroup.toString());
-
-        // no deployment notifications
-        verify(notifier, never()).addDeploymentData(any());
-
-        // should have notified of deleted subgroup's policies/PDPs
-        ArgumentCaptor<PolicyPdpNotificationData> captor = ArgumentCaptor.forClass(PolicyPdpNotificationData.class);
-        verify(notifier).addUndeploymentData(captor.capture());
-        assertDeploymentData(captor, policy1.getIdentifier(), "[pdpB, pdpD]");
-
-        // this requires a PDP UPDATE message
-        List<PdpUpdate> pdpUpdates = getUpdateRequests(2);
-        assertEquals(2, pdpUpdates.size());
-
-        PdpUpdate pdpUpdate = pdpUpdates.get(0);
-        assertEquals(PDP2, pdpUpdate.getName());
-        assertNull(pdpUpdate.getPdpGroup());
-
-        pdpUpdate = pdpUpdates.get(1);
-        assertEquals(PDP4, pdpUpdate.getName());
-        assertNull(pdpUpdate.getPdpGroup());
-
-        // it also requires a PDP STATE-CHANGE message
-        List<PdpStateChange> changes = getStateChangeRequests(2);
-        assertEquals(2, changes.size());
-
-        PdpStateChange change = changes.get(0);
-        assertEquals(PDP2, change.getName());
-        assertEquals(PdpState.PASSIVE, change.getState());
-
-        change = changes.get(1);
-        assertEquals(PDP4, change.getName());
-        assertEquals(PdpState.PASSIVE, change.getState());
-    }
-
     @Test
     public void testUpdateGroup_MultipleChanges() throws Exception {
         PdpGroups groups = loadPdpGroups("createGroups.json");
@@ -416,24 +335,6 @@ public class TestPdpGroupDeployProvider extends ProviderSuper {
         assertGroupUpdateOnly(group);
     }
 
-    @Test
-    public void testAddSubGroup() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
-        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
-        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
-
-        prov.createOrUpdateGroups(groups);
-
-        PdpGroup newgrp = groups.getGroups().get(0);
-
-        PdpSubGroup newsub = newgrp.getPdpSubgroups().get(1);
-        newsub.setCurrentInstanceCount(0);
-        newsub.setPdpInstances(new ArrayList<>(0));
-
-        assertEquals(newgrp.toString(), group.toString());
-        assertGroupUpdateOnly(group);
-    }
-
     /**
      * Tests addSubgroup() when the new subgroup has a wild-card policy type.
      *
@@ -523,45 +424,6 @@ public class TestPdpGroupDeployProvider extends ProviderSuper {
         assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isSameAs(exc);
     }
 
-    @Test
-    public void testAddSubGroup_ValidateVersionPrefixMatch() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
-        PdpGroup newgrp = groups.getGroups().get(0);
-        PdpGroup dbgroup = new PdpGroup(newgrp);
-        when(dao.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
-
-        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("createGroupNewPolicy.json"))
-                        .thenReturn(loadPolicies("daoPolicyList.json"))
-                        .thenReturn(loadPolicies("createGroupNewPolicy.json"));
-
-        PdpGroups reqgroups = loadPdpGroups("createGroupsVersPrefix.json");
-
-        prov.createOrUpdateGroups(reqgroups);
-
-        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
-        Collections.sort(dbgroup.getPdpSubgroups().get(0).getPolicies());
-
-        assertEquals(newgrp.toString(), dbgroup.toString());
-    }
-
-    @Test
-    public void testAddSubGroup_ValidateVersionPrefixMismatch() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
-        PdpGroup newgrp = groups.getGroups().get(0);
-        PdpGroup dbgroup = new PdpGroup(newgrp);
-        when(dao.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
-
-        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList.json"));
-
-
-        PdpGroups reqgroups = loadPdpGroups("createGroupsVersPrefixMismatch.json");
-
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(reqgroups)).isInstanceOf(PfModelException.class)
-                        .hasMessageContaining("different version already deployed");
-
-        assertNoGroupAction();
-    }
-
     @Test
     public void testUpdateSubGroup_Invalid() throws Exception {
         PdpGroups groups = loadPdpGroups("createGroups.json");
@@ -673,25 +535,6 @@ public class TestPdpGroupDeployProvider extends ProviderSuper {
         assertNoGroupAction();
     }
 
-    @Test
-    public void testUpdateSubGroup_PolicyVersionMismatch() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
-        PdpGroup newgrp = groups.getGroups().get(0);
-        PdpGroup dbgroup = new PdpGroup(newgrp);
-        when(dao.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
-
-        // arrange for DB policy version to be different
-        PdpSubGroup dbsubgrp = dbgroup.getPdpSubgroups().get(0);
-        dbsubgrp.getPolicies().get(0).setVersion("9.9.9");
-
-        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList.json"));
-
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
-                        .hasMessageContaining("different version already deployed");
-
-        assertNoGroupAction();
-    }
-
     @Test
     public void testValidateSubGroup_PropertiesMismatch() throws Exception {
         PdpGroups groups = loadPdpGroups("createGroups.json");
diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupCreateOrUpdateTest.java b/main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupCreateOrUpdateTest.java
new file mode 100644 (file)
index 0000000..dacee67
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.rest.e2e;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Optional;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.models.pap.concepts.PdpGroupUpdateResponse;
+import org.onap.policy.models.pdp.concepts.PdpGroup;
+import org.onap.policy.models.pdp.concepts.PdpGroups;
+import org.onap.policy.models.pdp.enums.PdpState;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PdpGroupCreateOrUpdateTest extends End2EndBase {
+    private static final Logger logger = LoggerFactory.getLogger(PdpGroupCreateOrUpdateTest.class);
+
+    private static final String CREATEORUPDATE_GROUPS_ENDPOINT = "pdps/groups/batch";
+    private static final String DELETE_GROUP_ENDPOINT = "pdps/groups/";
+    private static final String CREATE_SUBGROUP = "pdpTypeA";
+    private static final String GROUP_ENDPOINT = "pdps";
+
+    /**
+     * Starts Main and adds policies to the DB.
+     *
+     * @throws Exception if an error occurs
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        End2EndBase.setUpBeforeClass();
+
+        addToscaPolicyTypes("monitoring.policy-type.yaml");
+    }
+
+    /**
+     * Sets up.
+     */
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        context = new End2EndContext();
+    }
+
+    /**
+     * Deletes the deployed group.
+     */
+    @Override
+    @After
+    public void tearDown() {
+        // delete the group that was inserted
+        try {
+            sendRequest(DELETE_GROUP_ENDPOINT + "createGroups").delete();
+        } catch (Exception e) {
+            logger.warn("cannot delete group: createGroups", e);
+        }
+
+        super.tearDown();
+    }
+
+    @Test
+    public void testCreateGroups() throws Exception {
+
+        context.addPdp("pdpAA_1", CREATE_SUBGROUP);
+        context.addPdp("pdpAA_2", CREATE_SUBGROUP);
+        context.addPdp("pdpAB_1", "pdpTypeB");
+
+        context.startThreads();
+
+        Invocation.Builder invocationBuilder = sendRequest(CREATEORUPDATE_GROUPS_ENDPOINT);
+
+        PdpGroups groups = loadJsonFile("createGroups.json", PdpGroups.class);
+        Entity<PdpGroups> entity = Entity.entity(groups, MediaType.APPLICATION_JSON);
+        Response rawresp = invocationBuilder.post(entity);
+        PdpGroupUpdateResponse resp = rawresp.readEntity(PdpGroupUpdateResponse.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        assertNull(resp.getErrorDetails());
+
+        context.await();
+
+        // none of the PDPs should have handled any requests
+        assertEquals(context.getPdps().size(),
+            context.getPdps().stream().filter(pdp -> pdp.getHandled().isEmpty()).count());
+
+        // repeat - should be OK
+        rawresp = invocationBuilder.post(entity);
+        resp = rawresp.readEntity(PdpGroupUpdateResponse.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        assertNull(resp.getErrorDetails());
+
+        // repeat with different properties - should fail
+        groups.getGroups().get(0).setProperties(null);
+        rawresp = invocationBuilder.post(entity);
+        resp = rawresp.readEntity(PdpGroupUpdateResponse.class);
+        assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), rawresp.getStatus());
+        assertTrue(resp.getErrorDetails().contains("cannot change properties"));
+    }
+
+    @Test
+    public void testCreateAndUpdate_MultipleGroups() throws Exception {
+
+        Invocation.Builder invocationBuilderForGroupUpdate = sendRequest(CREATEORUPDATE_GROUPS_ENDPOINT);
+
+        PdpGroups groups = loadJsonFile("createGroups.json", PdpGroups.class);
+        Entity<PdpGroups> entity = Entity.entity(groups, MediaType.APPLICATION_JSON);
+        Response rawPdpGroupUpdateResponse = invocationBuilderForGroupUpdate.post(entity);
+        PdpGroupUpdateResponse pdpGroupUpdateResponse =
+            rawPdpGroupUpdateResponse.readEntity(PdpGroupUpdateResponse.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawPdpGroupUpdateResponse.getStatus());
+        assertNull(pdpGroupUpdateResponse.getErrorDetails());
+
+        Invocation.Builder invocationBuilderForGroupQuery = sendRequest(GROUP_ENDPOINT);
+        Response pdpGroupQueryResponse = invocationBuilderForGroupQuery.get();
+        assertEquals(Response.Status.OK.getStatusCode(), pdpGroupQueryResponse.getStatus());
+        PdpGroups pdpGroupsInDb = pdpGroupQueryResponse.readEntity(PdpGroups.class);
+        assertEquals(1, pdpGroupsInDb.getGroups().size());
+        assertEquals("createGroups", pdpGroupsInDb.getGroups().get(0).getName());
+        assertEquals(PdpState.PASSIVE, pdpGroupsInDb.getGroups().get(0).getPdpGroupState());
+
+        // creating 2 new groups
+        PdpGroups newGroups = loadJsonFile("createNewGroups.json", PdpGroups.class);
+        entity = Entity.entity(newGroups, MediaType.APPLICATION_JSON);
+        rawPdpGroupUpdateResponse = invocationBuilderForGroupUpdate.post(entity);
+        pdpGroupUpdateResponse = rawPdpGroupUpdateResponse.readEntity(PdpGroupUpdateResponse.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawPdpGroupUpdateResponse.getStatus());
+        assertNull(pdpGroupUpdateResponse.getErrorDetails());
+
+        invocationBuilderForGroupQuery = sendRequest(GROUP_ENDPOINT);
+        pdpGroupQueryResponse = invocationBuilderForGroupQuery.get();
+        assertEquals(Response.Status.OK.getStatusCode(), pdpGroupQueryResponse.getStatus());
+        pdpGroupsInDb = pdpGroupQueryResponse.readEntity(PdpGroups.class);
+        assertEquals(3, pdpGroupsInDb.getGroups().size());
+
+        // updating a group, changing state of old group to active
+        groups.getGroups().get(0).setPdpGroupState(PdpState.ACTIVE);
+        entity = Entity.entity(groups, MediaType.APPLICATION_JSON);
+        rawPdpGroupUpdateResponse = invocationBuilderForGroupUpdate.post(entity);
+        pdpGroupUpdateResponse = rawPdpGroupUpdateResponse.readEntity(PdpGroupUpdateResponse.class);
+        assertEquals(Response.Status.OK.getStatusCode(), rawPdpGroupUpdateResponse.getStatus());
+        assertNull(pdpGroupUpdateResponse.getErrorDetails());
+
+        invocationBuilderForGroupQuery = sendRequest(GROUP_ENDPOINT);
+        pdpGroupQueryResponse = invocationBuilderForGroupQuery.get();
+        assertEquals(Response.Status.OK.getStatusCode(), pdpGroupQueryResponse.getStatus());
+        pdpGroupsInDb = pdpGroupQueryResponse.readEntity(PdpGroups.class);
+        assertEquals(3, pdpGroupsInDb.getGroups().size());
+        Optional<PdpGroup> oldGroupInDb =
+            pdpGroupsInDb.getGroups().stream().filter(group -> group.getName().equals("createGroups")).findAny();
+        assertEquals(PdpState.ACTIVE, oldGroupInDb.get().getPdpGroupState());
+    }
+}
index 1c8774b..1630a8d 100644 (file)
                             "version": "1.0.0"
                         }
                     ],
-                    "policies": [
-                        {
-                            "name": "onap.restart.tca",
-                            "version": "1.0.0"
-                        }
-                    ]
+                    "policies": []
                 },
                 {
                     "pdpType": "pdpTypeB",
diff --git a/main/src/test/resources/e2e/createNewGroups.json b/main/src/test/resources/e2e/createNewGroups.json
new file mode 100644 (file)
index 0000000..4533932
--- /dev/null
@@ -0,0 +1,48 @@
+{
+    "groups": [
+        {
+            "name": "newGroup1",
+            "pdpGroupState": "ACTIVE",
+            "properties": {
+                "hello": "world"
+            },
+            "pdpSubgroups": [
+                {
+                    "pdpType": "pdpTypeA",
+                    "desiredInstanceCount": 2,
+                    "properties": {},
+                    "pdpInstances": [],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": []
+                }
+            ]
+        },
+        {
+            "name": "newGroup2",
+            "pdpGroupState": "ACTIVE",
+            "properties": {
+                "hello": "world"
+            },
+            "pdpSubgroups": [
+                {
+                    "pdpType": "pdpTypeB",
+                    "desiredInstanceCount": 2,
+                    "properties": {},
+                    "pdpInstances": [],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": []
+                }
+            ]
+        }
+    ]
+}
index 59c4eb8..daef17b 100644 (file)
                             "instanceId": "pdpA"
                         }
                     ],
-                    "policies": [
-                        {
-                            "name": "policyA",
-                            "version": "1.2.3"
-                        }
-                    ]
+                    "policies": []
                 }
             ]
         }
index cba308e..bcaa1c1 100644 (file)
                             "instanceId": "pdpA"
                         }
                     ],
-                    "policies": [
-                        {
-                            "name": "policyA",
-                            "version": "1.2.3"
-                        }
-                    ]
+                    "policies": []
                 },
                 {
                     "pdpType": "pdpTypeB",
                             "instanceId": "pdpD"
                         }
                     ],
-                    "policies": [
-                        {
-                            "name": "policyA",
-                            "version": "1.2.3"
-                        }
-                    ]
+                    "policies": []
                 }
             ]
         }