Only update policies in PAP REST API 19/99119/4
authorJim Hahn <jrh3@att.com>
Tue, 3 Dec 2019 18:07:57 +0000 (13:07 -0500)
committerJim Hahn <jrh3@att.com>
Mon, 9 Dec 2019 15:41:02 +0000 (10:41 -0500)
Modified the deploy controller and provider to only update the
policies within a group, while leaving the other fields unchanged.
Added delta operations so that only additions or deletions need
be included instead of providing the complete list of policies.

Change-Id: Id2b69dac15f97b8a898f459f8d3f09216fc3618e
Issue-ID: POLICY-2274
Signed-off-by: Jim Hahn <jrh3@att.com>
14 files changed:
main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupCreateOrUpdateProvider.java
main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupDeployControllerV1.java
main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupDeployProvider.java
main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupDeployControllerV1.java
main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupDeployProvider.java
main/src/test/java/org/onap/policy/pap/main/rest/e2e/PdpGroupDeployTest.java
main/src/test/resources/e2e/deployGroups.json [new file with mode: 0644]
main/src/test/resources/e2e/deployGroups2.json [new file with mode: 0644]
main/src/test/resources/e2e/deployGroupsReq.json [new file with mode: 0644]
main/src/test/resources/e2e/deployGroupsReq2.json [new file with mode: 0644]
main/src/test/resources/e2e/deployPolicies.json
main/src/test/resources/simpleDeploy/createGroupNewPolicy2.json [new file with mode: 0644]
main/src/test/resources/simpleDeploy/daoPolicyList2.json [new file with mode: 0644]
main/src/test/resources/simpleDeploy/deployGroups.json [new file with mode: 0644]

index aed0517..37f19c4 100644 (file)
@@ -3,6 +3,7 @@
  * ONAP PAP
  * ================================================================================
  * 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.
 
 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.Objects;
 import java.util.Set;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
@@ -190,7 +191,7 @@ public class PdpGroupCreateOrUpdateProvider extends ProviderBase {
     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())) {
+        if (!Objects.equals(dbgroup.getProperties(), group.getProperties())) {
             result.addResult(
                 new ObjectValidationResult("properties", "", ValidationStatus.INVALID, "cannot change properties"));
         }
@@ -398,7 +399,7 @@ public class PdpGroupCreateOrUpdateProvider extends ProviderBase {
 
         BeanValidationResult result = new BeanValidationResult(subgrp.getPdpType(), subgrp);
 
-        if (!ObjectUtils.equals(dbsub.getProperties(), subgrp.getProperties())) {
+        if (!Objects.equals(dbsub.getProperties(), subgrp.getProperties())) {
             result.addResult(
                 new ObjectValidationResult("properties", "", ValidationStatus.INVALID, "cannot change properties"));
         }
index 59fe38a..48dfd8b 100644 (file)
@@ -38,7 +38,7 @@ import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.base.PfModelRuntimeException;
 import org.onap.policy.models.pap.concepts.PdpDeployPolicies;
 import org.onap.policy.models.pap.concepts.PdpGroupDeployResponse;
-import org.onap.policy.models.pdp.concepts.PdpGroups;
+import org.onap.policy.models.pdp.concepts.DeploymentGroups;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -51,7 +51,7 @@ public class PdpGroupDeployControllerV1 extends PapRestControllerV1 {
     private final PdpGroupDeployProvider provider = new PdpGroupDeployProvider();
 
     /**
-     * Deploys or updates a PDP group.
+     * Updates policy deployments within specific PDP groups.
      *
      * @param requestId request ID used in ONAP logging
      * @param groups PDP group configuration
@@ -59,9 +59,9 @@ public class PdpGroupDeployControllerV1 extends PapRestControllerV1 {
      */
     // @formatter:off
     @POST
-    @Path("pdps")
-    @ApiOperation(value = "Deploy or update PDP Groups",
-        notes = "Deploys or updates a PDP Group, returning optional error details",
+    @Path("pdps/deployments/batch")
+    @ApiOperation(value = "Updates policy deployments within specific PDP groups",
+        notes = "Updates policy deployments within specific PDP groups, returning optional error details",
         response = PdpGroupDeployResponse.class,
         tags = {"Policy Administration (PAP) API"},
         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
@@ -82,10 +82,11 @@ public class PdpGroupDeployControllerV1 extends PapRestControllerV1 {
                     @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)})
     // @formatter:on
 
-    public Response deployGroup(@HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
-                    @ApiParam(value = "List of PDP Group Configuration", required = true) PdpGroups groups) {
+    public Response updateGroupPolicies(
+                    @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
+                    @ApiParam(value = "List of PDP Group Deployments", required = true) DeploymentGroups groups) {
 
-        return doOperation(requestId, "create groups failed", () -> provider.createOrUpdateGroups(groups));
+        return doOperation(requestId, "update policy deployments failed", () -> provider.updateGroupPolicies(groups));
     }
 
     /**
index af1aab6..ed77a43 100644 (file)
 
 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.LinkedHashSet;
 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;
@@ -39,13 +37,12 @@ import org.onap.policy.common.utils.services.Registry;
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.base.PfModelRuntimeException;
 import org.onap.policy.models.pap.concepts.PdpDeployPolicies;
+import org.onap.policy.models.pdp.concepts.DeploymentGroup;
+import org.onap.policy.models.pdp.concepts.DeploymentGroups;
+import org.onap.policy.models.pdp.concepts.DeploymentSubGroup;
 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;
@@ -76,12 +73,12 @@ public class PdpGroupDeployProvider extends ProviderBase {
     }
 
     /**
-     * Creates or updates PDP groups.
+     * Updates policies in specific PDP groups.
      *
-     * @param groups PDP group configurations to be created or updated
+     * @param groups PDP group deployments to be updated
      * @throws PfModelException if an error occurred
      */
-    public void createOrUpdateGroups(PdpGroups groups) throws PfModelException {
+    public void updateGroupPolicies(DeploymentGroups groups) throws PfModelException {
         ValidationResult result = groups.validatePapRest();
 
         if (!result.isValid()) {
@@ -90,24 +87,25 @@ public class PdpGroupDeployProvider extends ProviderBase {
             throw new PfModelException(Status.BAD_REQUEST, msg);
         }
 
-        process(groups, this::createOrUpdate);
+        process(groups, this::updateGroups);
     }
 
     /**
-     * Creates or updates PDP groups. This is the method that does the actual work.
+     * Updates policies in specific PDP groups. This is the method that does the actual work.
      *
      * @param data session data
-     * @param groups PDP group configurations
+     * @param groups PDP group deployments
      * @throws PfModelException if an error occurred
      */
-    private void createOrUpdate(SessionData data, PdpGroups groups) throws PfModelException {
+    private void updateGroups(SessionData data, DeploymentGroups groups) throws PfModelException {
         BeanValidationResult result = new BeanValidationResult("groups", groups);
 
-        for (PdpGroup group : groups.getGroups()) {
+        for (DeploymentGroup group : groups.getGroups()) {
             PdpGroup dbgroup = data.getGroup(group.getName());
 
             if (dbgroup == null) {
-                result.addResult(addGroup(data, group));
+                result.addResult(new ObjectValidationResult(group.getName(), group,
+                                ValidationStatus.INVALID, "unknown group"));
 
             } else {
                 result.addResult(updateGroup(data, dbgroup, group));
@@ -119,61 +117,6 @@ public class PdpGroupDeployProvider extends ProviderBase {
         }
     }
 
-    /**
-     * 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.
      *
@@ -183,49 +126,20 @@ public class PdpGroupDeployProvider extends ProviderBase {
      * @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);
+    private ValidationResult updateGroup(SessionData data, PdpGroup dbgroup, DeploymentGroup group)
+                    throws PfModelException {
 
-        if (!ObjectUtils.equals(dbgroup.getProperties(), group.getProperties())) {
-            result.addResult(new ObjectValidationResult("properties", "", ValidationStatus.INVALID,
-                            "cannot change properties"));
-        }
+        BeanValidationResult result = new BeanValidationResult(group.getName(), group);
 
-        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;
+        boolean updated = updateSubGroups(data, dbgroup, group, result);
 
         if (result.isValid() && updated) {
-            data.update(group);
+            data.update(dbgroup);
         }
 
         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.
      *
@@ -236,7 +150,7 @@ public class PdpGroupDeployProvider extends ProviderBase {
      * @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,
+    private boolean updateSubGroups(SessionData data, PdpGroup dbgroup, DeploymentGroup group,
                     BeanValidationResult result) throws PfModelException {
 
         // create a map of existing subgroups
@@ -245,17 +159,16 @@ public class PdpGroupDeployProvider extends ProviderBase {
 
         boolean updated = false;
 
-        for (PdpSubGroup subgrp : group.getPdpSubgroups()) {
+        for (DeploymentSubGroup subgrp : group.getDeploymentSubgroups()) {
             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);
+                subResult.addResult(new ObjectValidationResult(subgrp.getPdpType(), subgrp,
+                                ValidationStatus.INVALID, "unknown subgroup"));
 
             } else {
-                updated = updateSubGroup(data, group, dbsub, subgrp, subResult) || updated;
+                updated = updateSubGroup(data, dbgroup, dbsub, subgrp, subResult) || updated;
             }
 
             result.addResult(subResult);
@@ -264,95 +177,6 @@ public class PdpGroupDeployProvider extends ProviderBase {
         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));
-        result.addResult(validatePolicies(data, null, subgrp));
-
-        return result;
-    }
-
     /**
      * Updates an existing subgroup.
      *
@@ -366,7 +190,7 @@ public class PdpGroupDeployProvider extends ProviderBase {
      *         were no changes
      * @throws PfModelException if an error occurred
      */
-    private boolean updateSubGroup(SessionData data, PdpGroup dbgroup, PdpSubGroup dbsub, PdpSubGroup subgrp,
+    private boolean updateSubGroup(SessionData data, PdpGroup dbgroup, PdpSubGroup dbsub, DeploymentSubGroup subgrp,
                     BeanValidationResult container) throws PfModelException {
 
         // perform additional validations first
@@ -374,27 +198,59 @@ public class PdpGroupDeployProvider extends ProviderBase {
             return false;
         }
 
-        /*
-         * first, apply the changes about which the PDPs care
-         */
-        boolean updated = updatePolicies(data, dbsub, subgrp);
+        boolean updated = false;
+
+        switch (subgrp.getAction()) {
+            case POST:
+                updated = addPolicies(data, dbsub, subgrp);
+                break;
+            case DELETE:
+                updated = deletePolicies(data, dbsub, subgrp);
+                break;
+            case PATCH:
+            default:
+                updated = updatePolicies(data, dbsub, subgrp);
+                break;
+        }
 
-        // publish any changes to the PDPs
         if (updated) {
+            // publish any changes to the PDPs
             makeUpdates(data, dbgroup, dbsub);
+            return true;
         }
 
-        /*
-         * now make any remaining changes
-         */
-        updated = updateList(dbsub.getSupportedPolicyTypes(), subgrp.getSupportedPolicyTypes(),
-                        dbsub::setSupportedPolicyTypes) || updated;
+        return false;
+    }
+
+    private boolean addPolicies(SessionData data, PdpSubGroup dbsub, DeploymentSubGroup subgrp)
+                    throws PfModelException {
+
+        Set<ToscaPolicyIdentifier> policies = new LinkedHashSet<>(dbsub.getPolicies());
+        policies.addAll(subgrp.getPolicies());
+
+        DeploymentSubGroup subgrp2 = new DeploymentSubGroup(subgrp);
+        subgrp2.getPolicies().clear();
+        subgrp2.getPolicies().addAll(policies);
 
-        return updateField(dbsub.getDesiredInstanceCount(), subgrp.getDesiredInstanceCount(),
-                        dbsub::setDesiredInstanceCount) || updated;
+        return updatePolicies(data, dbsub, subgrp2);
     }
 
-    private boolean updatePolicies(SessionData data, PdpSubGroup dbsub, PdpSubGroup subgrp) throws PfModelException {
+    private boolean deletePolicies(SessionData data, PdpSubGroup dbsub, DeploymentSubGroup subgrp)
+                    throws PfModelException {
+
+        Set<ToscaPolicyIdentifier> policies = new LinkedHashSet<>(dbsub.getPolicies());
+        policies.removeAll(subgrp.getPolicies());
+
+        DeploymentSubGroup subgrp2 = new DeploymentSubGroup(subgrp);
+        subgrp2.getPolicies().clear();
+        subgrp2.getPolicies().addAll(policies);
+
+        return updatePolicies(data, dbsub, subgrp2);
+    }
+
+    private boolean updatePolicies(SessionData data, PdpSubGroup dbsub, DeploymentSubGroup subgrp)
+                    throws PfModelException {
+
         Set<ToscaPolicyIdentifier> undeployed = new HashSet<>(dbsub.getPolicies());
         undeployed.removeAll(subgrp.getPolicies());
 
@@ -407,7 +263,9 @@ public class PdpGroupDeployProvider extends ProviderBase {
         }
 
 
-        Set<String> pdps = subgrp.getPdpInstances().stream().map(Pdp::getInstanceId).collect(Collectors.toSet());
+        // TODO add code to ensure that dbsub has at least one PDP instance if policies is not empty
+
+        Set<String> pdps = dbsub.getPdpInstances().stream().map(Pdp::getInstanceId).collect(Collectors.toSet());
 
         for (ToscaPolicyIdentifier policyId : deployed) {
             data.trackDeploy(policyId, pdps);
@@ -432,66 +290,17 @@ public class PdpGroupDeployProvider extends ProviderBase {
      * @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,
+    private boolean validateSubGroup(SessionData data, PdpSubGroup dbsub, DeploymentSubGroup 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(validatePolicies(data, dbsub, subgrp));
-        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;
-    }
-
     /**
      * Performs additional validations of the policies within a subgroup.
      *
@@ -502,15 +311,13 @@ public class PdpGroupDeployProvider extends ProviderBase {
      * @param result the validation result
      * @throws PfModelException if an error occurred
      */
-    private ValidationResult validatePolicies(SessionData data, PdpSubGroup dbsub, PdpSubGroup subgrp)
+    private ValidationResult validatePolicies(SessionData data, PdpSubGroup dbsub, DeploymentSubGroup subgrp)
                     throws PfModelException {
 
         // build a map of the DB data, from policy name to (fully qualified) policy
         // version
         Map<String, String> dbname2vers = new HashMap<>();
-        if (dbsub != null) {
-            dbsub.getPolicies().forEach(ident -> dbname2vers.put(ident.getName(), ident.getVersion()));
-        }
+        dbsub.getPolicies().forEach(ident -> dbname2vers.put(ident.getName(), ident.getVersion()));
 
         BeanValidationResult result = new BeanValidationResult(subgrp.getPdpType(), subgrp);
 
@@ -532,7 +339,7 @@ public class PdpGroupDeployProvider extends ProviderBase {
                 result.addResult(new ObjectValidationResult(POLICY_RESULT_NAME, ident, ValidationStatus.INVALID,
                                 "unknown policy"));
 
-            } else if (!isPolicySupported(subgrp.getSupportedPolicyTypes(), policy.getTypeIdentifier())) {
+            } else if (!isPolicySupported(dbsub.getSupportedPolicyTypes(), policy.getTypeIdentifier())) {
                 result.addResult(new ObjectValidationResult(POLICY_RESULT_NAME, ident, ValidationStatus.INVALID,
                                 "not a supported policy for the subgroup"));
 
index a26213d..739a5f3 100644 (file)
@@ -32,8 +32,9 @@ import javax.ws.rs.core.Response;
 import org.junit.Test;
 import org.onap.policy.models.pap.concepts.PdpDeployPolicies;
 import org.onap.policy.models.pap.concepts.PdpGroupDeployResponse;
-import org.onap.policy.models.pdp.concepts.PdpGroup;
-import org.onap.policy.models.pdp.concepts.PdpSubGroup;
+import org.onap.policy.models.pdp.concepts.DeploymentGroup;
+import org.onap.policy.models.pdp.concepts.DeploymentGroups;
+import org.onap.policy.models.pdp.concepts.DeploymentSubGroup;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifierOptVersion;
 
 /**
@@ -41,7 +42,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifierOp
  */
 public class TestPdpGroupDeployControllerV1 extends CommonPapRestServer {
 
-    private static final String DEPLOY_GROUP_ENDPOINT = "pdps";
+    private static final String DEPLOY_GROUP_ENDPOINT = "pdps/deployments/batch";
     private static final String DEPLOY_POLICIES_ENDPOINT = "pdps/policies";
 
     @Test
@@ -51,8 +52,8 @@ public class TestPdpGroupDeployControllerV1 extends CommonPapRestServer {
     }
 
     @Test
-    public void testDeployGroup() throws Exception {
-        Entity<PdpGroup> entgrp = makePdpGroupEntity();
+    public void testUpdateGroupPolicies() throws Exception {
+        Entity<DeploymentGroups> entgrp = makeDeploymentGroupsEntity();
 
         Invocation.Builder invocationBuilder = sendRequest(DEPLOY_GROUP_ENDPOINT);
         Response rawresp = invocationBuilder.post(entgrp);
@@ -88,16 +89,18 @@ public class TestPdpGroupDeployControllerV1 extends CommonPapRestServer {
         checkUnauthRequest(DEPLOY_POLICIES_ENDPOINT, req -> req.post(entgrp));
     }
 
-    private Entity<PdpGroup> makePdpGroupEntity() {
-        PdpSubGroup subgrp = new PdpSubGroup();
+    private Entity<DeploymentGroups> makeDeploymentGroupsEntity() {
+        DeploymentSubGroup subgrp = new DeploymentSubGroup();
         subgrp.setPdpType("drools");
 
-        PdpGroup group = new PdpGroup();
+        DeploymentGroup group = new DeploymentGroup();
         group.setName("drools-group");
-        group.setDescription("my description");
-        group.setPdpSubgroups(Arrays.asList(subgrp));
+        group.setDeploymentSubgroups(Arrays.asList(subgrp));
 
-        return Entity.entity(group, MediaType.APPLICATION_JSON);
+        DeploymentGroups groups = new DeploymentGroups();
+        groups.setGroups(Arrays.asList(group));
+
+        return Entity.entity(groups, MediaType.APPLICATION_JSON);
     }
 
     private Entity<PdpDeployPolicies> makePdpPoliciesEntity() {
index a7fc11a..daa0504 100644 (file)
 
 package org.onap.policy.pap.main.rest;
 
+import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 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.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -33,7 +34,6 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import java.util.TreeMap;
 import java.util.TreeSet;
 import java.util.stream.Collectors;
 import javax.ws.rs.core.Response.Status;
@@ -45,21 +45,26 @@ import org.onap.policy.common.utils.services.Registry;
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.base.PfModelRuntimeException;
 import org.onap.policy.models.pap.concepts.PdpDeployPolicies;
+import org.onap.policy.models.pdp.concepts.DeploymentGroup;
+import org.onap.policy.models.pdp.concepts.DeploymentGroups;
+import org.onap.policy.models.pdp.concepts.DeploymentSubGroup;
+import org.onap.policy.models.pdp.concepts.DeploymentSubGroup.Action;
 import org.onap.policy.models.pdp.concepts.PdpGroup;
 import org.onap.policy.models.pdp.concepts.PdpGroups;
 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.ToscaPolicyTypeIdentifier;
 import org.onap.policy.pap.main.notification.PolicyPdpNotificationData;
 
 public class TestPdpGroupDeployProvider extends ProviderSuper {
     private static final String EXPECTED_EXCEPTION = "expected exception";
 
     private static final String POLICY2_NAME = "policyB";
+    private static final String POLICY3_NAME = "policyC";
     private static final String POLICY1_VERSION = "1.2.3";
+    private static final String POLICY2_VERSION = "1.2.3";
+    private static final String POLICY3_VERSION = "1.2.3";
     private static final String GROUP1_NAME = "groupA";
     private static final String PDP1_TYPE = "pdpTypeA";
     private static final String PDP2_TYPE = "pdpTypeB";
@@ -80,479 +85,402 @@ public class TestPdpGroupDeployProvider extends ProviderSuper {
      *
      * @throws Exception if an error occurs
      */
-    @Override
     @Before
     public void setUp() throws Exception {
 
         super.setUp();
 
-        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList.json"));
+        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList2.json"));
         when(dao.getPolicyTypeList("typeA", "100.2.3")).thenReturn(Arrays.asList(loadPolicyType("daoPolicyType.json")));
 
         prov = new PdpGroupDeployProvider();
     }
 
+    /**
+     * Tests updateGroupPolicies when policies are being added.
+     */
     @Test
-    public void testCreateOrUpdateGroups() throws Exception {
-        prov.createOrUpdateGroups(loadPdpGroups("emptyGroups.json"));
+    public void testUpdateGroupPoliciesAdd() throws Exception {
+        PdpGroups groups = loadPdpGroups("deployGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup dbgroup = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
 
-        // no groups, so no action should have been taken
-        assertNoGroupAction();
-    }
+        // add new policies
+        List<ToscaPolicyIdentifier> policies = newgrp.getPdpSubgroups().get(0).getPolicies();
+        policies.add(new ToscaPolicyIdentifier(POLICY2_NAME, POLICY2_VERSION));
+        policies.add(new ToscaPolicyIdentifier(POLICY3_NAME, POLICY3_VERSION));
 
-    @Test
-    public void testCreateOrUpdateGroups_InvalidRequest() throws Exception {
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(new PdpGroups())).isInstanceOf(PfModelException.class)
-                        .hasMessageContaining("is null");
-
-        assertNoGroupAction();
-    }
+        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("createGroupNewPolicy.json"))
+                        .thenReturn(loadPolicies("createGroupNewPolicy2.json"))
+                        .thenReturn(loadPolicies("daoPolicyList.json"));
 
-    @Test
-    public void testCreateOrUpdate_Invalid() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
-        groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED);
+        // add = POST
+        DeploymentGroups depgroups = toDeploymentGroups(groups);
+        depgroups.getGroups().get(0).getDeploymentSubgroups().get(0).setAction(Action.POST);
 
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
-                        .hasMessageContaining("pdpGroupState");
+        prov.updateGroupPolicies(depgroups);
 
-        assertNoGroupAction();
+        assertEquals(newgrp.toString(), dbgroup.toString());
+        assertGroupUpdate(dbgroup, dbgroup.getPdpSubgroups().get(0));
     }
 
+    /**
+     * Tests updateGroupPolicies when policies are being deleted.
+     */
     @Test
-    public void testAddGroup() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
-        PdpGroup group = groups.getGroups().get(0);
-        group.setPdpGroupState(PdpState.PASSIVE);
+    public void testUpdateGroupPoliciesDelete() throws Exception {
+        PdpGroups groups = loadPdpGroups("deployGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
 
-        prov.createOrUpdateGroups(groups);
+        // additional policies in the DB that will be removed
+        List<ToscaPolicyIdentifier> policies = newgrp.getPdpSubgroups().get(0).getPolicies();
+        policies.add(new ToscaPolicyIdentifier(POLICY2_NAME, POLICY2_VERSION));
+        policies.add(new ToscaPolicyIdentifier(POLICY3_NAME, POLICY3_VERSION));
 
-        // should not have updated the state
-        assertEquals(PdpState.PASSIVE, group.getPdpGroupState());
+        PdpGroup dbgroup = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
 
-        assertSame(group, getGroupCreates().get(0));
-    }
+        // policy that should be left
+        final ToscaPolicyIdentifier policyId1 = policies.remove(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");
+        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("createGroupNewPolicy.json"))
+                        .thenReturn(loadPolicies("createGroupNewPolicy2.json"))
+                        .thenReturn(loadPolicies("daoPolicyList.json"));
 
-        assertNoGroupAction();
-    }
+        DeploymentGroups depgroups = toDeploymentGroups(groups);
+        depgroups.getGroups().get(0).getDeploymentSubgroups().get(0).setAction(Action.DELETE);
 
-    @Test
-    public void testValidateGroupOnly_NullState() throws PfModelException {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
-        groups.getGroups().get(0).setPdpGroupState(null);
-        prov.createOrUpdateGroups(groups);
-    }
+        prov.updateGroupPolicies(depgroups);
 
-    @Test
-    public void testValidateGroupOnly_Active() throws PfModelException {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
-        groups.getGroups().get(0).setPdpGroupState(PdpState.ACTIVE);
-        prov.createOrUpdateGroups(groups);
-    }
+        // only the first policy should remain
+        policies.clear();
+        policies.add(policyId1);
 
-    @Test
-    public void testValidateGroupOnly_Passive() throws PfModelException {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
-        groups.getGroups().get(0).setPdpGroupState(PdpState.PASSIVE);
-        prov.createOrUpdateGroups(groups);
+        assertEquals(newgrp.toString(), dbgroup.toString());
+        assertGroupUpdate(dbgroup, dbgroup.getPdpSubgroups().get(0));
     }
 
+    /**
+     * Tests updateGroupPolicies when policies are being added and deleted in the same subgroup.
+     */
     @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");
-    }
+    public void testUpdateGroupPoliciesAddAndDelete() throws Exception {
+        PdpGroups groups = loadPdpGroups("deployGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpSubGroup subgrp = newgrp.getPdpSubgroups().get(0);
 
-    @Test
-    public void testUpdateGroup() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
+        // put policy3 into db subgroup
+        subgrp.getPolicies().add(new ToscaPolicyIdentifier(POLICY3_NAME, POLICY3_VERSION));
+        PdpGroup dbgroup = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
 
-        // DB group = new group
-        PdpGroup group = new PdpGroup(groups.getGroups().get(0));
-        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+        // now make the subgrp reflect our final expectation
+        subgrp.getPolicies().remove(1);
+        subgrp.getPolicies().add(new ToscaPolicyIdentifier(POLICY2_NAME, POLICY2_VERSION));
 
-        prov.createOrUpdateGroups(groups);
+        // indicate policy2 being added and policy3 being deleted
+        DeploymentSubGroup depsub1 = new DeploymentSubGroup();
+        depsub1.setAction(Action.POST);
+        depsub1.setPdpType(subgrp.getPdpType());
+        depsub1.setPolicies(Arrays.asList(new ToscaPolicyIdentifier(POLICY2_NAME, POLICY2_VERSION)));
 
-        assertNoGroupAction();
-    }
+        DeploymentSubGroup depsub2 = new DeploymentSubGroup();
+        depsub2.setAction(Action.DELETE);
+        depsub2.setPdpType(subgrp.getPdpType());
+        depsub2.setPolicies(Arrays.asList(new ToscaPolicyIdentifier(POLICY3_NAME, POLICY3_VERSION)));
 
-    @Test
-    public void testUpdateGroup_PropertiesChanged() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
+        DeploymentGroup depgroup = new DeploymentGroup();
+        depgroup.setName(newgrp.getName());
+        depgroup.setDeploymentSubgroups(Arrays.asList(depsub1, depsub2));
 
-        PdpGroup group = new PdpGroup(groups.getGroups().get(0));
-        group.setProperties(new TreeMap<>());
+        DeploymentGroups depgroups = new DeploymentGroups();
+        depgroups.setGroups(Arrays.asList(depgroup));
 
-        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("createGroupNewPolicy.json"))
+                        .thenReturn(loadPolicies("daoPolicyList.json"))
+                        .thenReturn(loadPolicies("createGroupNewPolicy2.json"));
 
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
-                        .hasMessageContaining("properties");
+        prov.updateGroupPolicies(depgroups);
 
-        assertNoGroupAction();
+        assertEquals(newgrp.toString(), dbgroup.toString());
+        assertGroupUpdate(dbgroup, dbgroup.getPdpSubgroups().get(0));
     }
 
     @Test
-    public void testUpdateGroup_NewDescription() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
+    public void testUpdateGroupPolicies() throws Exception {
+        PdpGroups groups = loadPdpGroups("deployGroups.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);
+        // something different in this subgroup
+        group.getPdpSubgroups().get(0).getPolicies().add(new ToscaPolicyIdentifier(POLICY2_NAME, POLICY2_VERSION));
 
-        assertGroupUpdateOnly(group);
+        prov.updateGroupPolicies(toDeploymentGroups(groups));
 
-        assertEquals(group.getDescription(), "my description");
         assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdate(group, group.getPdpSubgroups().get(0));
     }
 
     @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);
+    public void testUpdateGroupPolicies_EmptyRequest() throws Exception {
+        prov.updateGroupPolicies(toDeploymentGroups(loadPdpGroups("emptyGroups.json")));
 
-        assertEquals(PdpState.ACTIVE, group.getPdpGroupState());
-        assertEquals(newgrp.toString(), group.toString());
+        // no groups, so no action should have been taken
+        assertNoGroupAction();
     }
 
     @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);
+    public void testUpdateGroupPolicies_InvalidRequest() throws Exception {
+        assertThatThrownBy(() -> prov.updateGroupPolicies(new DeploymentGroups())).isInstanceOf(PfModelException.class)
+                        .hasMessageContaining("is null");
 
-        assertEquals(newgrp.toString(), group.toString());
-        assertGroupUpdateOnly(group);
+        assertNoGroupAction();
     }
 
     @Test
-    public void testUpdateGroup_MultipleChanges() 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));
-
-        PdpSubGroup subgrp = newgrp.getPdpSubgroups().get(0);
-        subgrp.setDesiredInstanceCount(30);
-        subgrp.getPolicies().add(new ToscaPolicyIdentifier(POLICY2_NAME, POLICY1_VERSION));
-        subgrp.getSupportedPolicyTypes().add(new ToscaPolicyTypeIdentifier("typeX.*", "9.8.7"));
+    public void testUpdateGroup_UnknownGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("deployGroups.json");
 
-        when(dao.getFilteredPolicyList(any()))
-                        .thenReturn(loadPolicies("createGroupNewPolicy.json"))
-                        .thenReturn(loadPolicies("daoPolicyList.json"))
-                        .thenReturn(loadPolicies("createGroupNewPolicy.json"));
+        String groupName = groups.getGroups().get(0).getName();
 
-        prov.createOrUpdateGroups(groups);
+        // group not found
+        when(dao.getPdpGroups(groupName)).thenReturn(Collections.emptyList());
 
-        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
-        Collections.sort(group.getPdpSubgroups().get(0).getPolicies());
+        assertThatThrownBy(() -> prov.updateGroupPolicies(toDeploymentGroups(groups)))
+                        .isInstanceOf(PfModelException.class).hasMessageContaining(groupName)
+                        .hasMessageContaining("unknown group");
 
-        assertEquals(newgrp.toString(), group.toString());
-
-        // this requires a PDP UPDATE message
-        assertGroupUpdate(group, subgrp);
+        assertNoGroupAction();
     }
 
     @Test
-    public void testUpdateField_Unchanged() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
-        PdpGroup newgrp = groups.getGroups().get(0);
-        PdpGroup group = new PdpGroup(newgrp);
+    public void testUpdateGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("deployGroups.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);
+        prov.updateGroupPolicies(toDeploymentGroups(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);
+    public void testUpdateGroup_NewSubGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
+        PdpGroup group = loadPdpGroups("deployGroups.json").getGroups().get(0);
         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
 
-        group.setDescription(null);
+        assertThatThrownBy(() -> prov.updateGroupPolicies(toDeploymentGroups(groups)))
+                        .isInstanceOf(PfModelException.class).hasMessageContaining("pdpTypeB")
+                        .hasMessageContaining("unknown subgroup");
 
-        prov.createOrUpdateGroups(groups);
 
-        assertEquals(newgrp.toString(), group.toString());
-        assertGroupUpdateOnly(group);
+        assertNoGroupAction();
     }
 
     @Test
-    public void testUpdateField_NowNull() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
+    public void testUpdateGroup_UpdatedSubGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("deployGroups.json");
         PdpGroup newgrp = groups.getGroups().get(0);
         PdpGroup group = new PdpGroup(newgrp);
         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
 
-        newgrp.setDescription(null);
+        // something different in this subgroup
+        group.getPdpSubgroups().get(0).getPolicies().add(new ToscaPolicyIdentifier(POLICY2_NAME, POLICY2_VERSION));
 
-        prov.createOrUpdateGroups(groups);
+        prov.updateGroupPolicies(toDeploymentGroups(groups));
 
         assertEquals(newgrp.toString(), group.toString());
-        assertGroupUpdateOnly(group);
+        assertGroupUpdate(group, group.getPdpSubgroups().get(0));
     }
 
     @Test
-    public void testUpdateField_Changed() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
+    public void testUpdateSubGroup_Invalid() throws Exception {
+        PdpGroups groups = loadPdpGroups("deployGroups.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);
-    }
 
-    /**
-     * 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);
+        // group has no policies yet
+        group.getPdpSubgroups().get(0).getPolicies().clear();
         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
 
-        prov.createOrUpdateGroups(groups);
-
-        PdpGroup newgrp = groups.getGroups().get(0);
+        // unknown policy
+        when(dao.getFilteredPolicyList(any())).thenReturn(Collections.emptyList());
 
-        PdpSubGroup newsub = newgrp.getPdpSubgroups().get(1);
-        newsub.setCurrentInstanceCount(0);
-        newsub.setPdpInstances(new ArrayList<>(0));
+        assertThatThrownBy(() -> prov.updateGroupPolicies(toDeploymentGroups(groups)))
+                        .isInstanceOf(PfModelException.class)
+                        .hasMessageContaining(newgrp.getPdpSubgroups().get(0).getPolicies().get(0).getName())
+                        .hasMessageContaining("unknown policy");
 
-        assertEquals(newgrp.toString(), group.toString());
+        assertNoGroupAction();
     }
 
-    /**
-     * Tests addSubgroup() when the new subgroup has a wild-card policy type, but the
-     * policy doesn't have a matching type.
-     *
-     * @throws PfModelException if an error occurs
-     */
     @Test
-    public void testAddSubGroupWildCardPolicyTypeUnmatched() throws PfModelException {
-        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyListWildCardUnmatched.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));
+    public void testUpdateSubGroup_Policies() throws Exception {
+        PdpGroups groups = loadPdpGroups("deployGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
 
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class);
-    }
+        // add a second subgroup, which will be left unchanged
+        PdpSubGroup subgrp = newgrp.getPdpSubgroups().get(0);
+        PdpSubGroup subgrp2 = new PdpSubGroup(subgrp);
+        subgrp2.setPdpType(PDP2_TYPE);
+        newgrp.getPdpSubgroups().add(subgrp2);
 
-    @Test
-    public void testAddSubGroup_ValidationPolicyTypeNotFound() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
-        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
         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));
+        // add two new policies
+        ToscaPolicyIdentifier policyId2 = new ToscaPolicyIdentifier(POLICY2_NAME, POLICY2_VERSION);
+        subgrp.getPolicies().add(policyId2);
 
-        PfModelException exc = new PfModelException(Status.CONFLICT, EXPECTED_EXCEPTION);
-        when(dao.getPolicyTypeList(any(), any())).thenThrow(exc);
+        ToscaPolicyIdentifier policyId3 = new ToscaPolicyIdentifier(POLICY3_NAME, POLICY3_VERSION);
+        subgrp.getPolicies().add(policyId3);
 
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isSameAs(exc);
-    }
+        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("createGroupNewPolicy.json"))
+                        .thenReturn(loadPolicies("createGroupNewPolicy2.json"))
+                        .thenReturn(loadPolicies("daoPolicyList.json"));
 
-    @Test
-    public void testAddSubGroup_ValidationPolicyNotFound() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroupsNewSubNotFound.json");
-        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
-        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+        prov.updateGroupPolicies(toDeploymentGroups(groups));
 
-        when(dao.getFilteredPolicyList(any())).thenReturn(Collections.emptyList());
+        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
+        Collections.sort(group.getPdpSubgroups().get(0).getPolicies());
 
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).hasMessageContaining("unknown policy");
-    }
+        assertEquals(newgrp.toString(), group.toString());
 
-    @Test
-    public void testAddSubGroup_ValidationPolicyDaoEx() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroupsNewSubNotFound.json");
-        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
-        when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+        // should have notified of added policy/PDPs
+        ArgumentCaptor<PolicyPdpNotificationData> captor = ArgumentCaptor.forClass(PolicyPdpNotificationData.class);
+        verify(notifier, times(2)).addDeploymentData(captor.capture());
+        assertDeploymentData(captor.getAllValues().get(0), policyId2, "[pdpA]");
+        assertDeploymentData(captor.getAllValues().get(1), policyId3, "[pdpA]");
 
-        PfModelException exc = new PfModelException(Status.CONFLICT, EXPECTED_EXCEPTION);
-        when(dao.getFilteredPolicyList(any())).thenThrow(exc);
+        // should NOT have notified of any deleted policy/PDPs
+        verify(notifier, never()).addUndeploymentData(any());
 
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isSameAs(exc);
+        // this requires a PDP UPDATE message
+        assertGroupUpdate(newgrp, subgrp);
     }
 
     @Test
-    public void testUpdateSubGroup_Invalid() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
+    public void testUpdateSubGroup_PolicyVersionPrefix() throws Exception {
+        PdpGroups groups = loadPdpGroups("deployGroups.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();
-    }
+        // use version prefix
+        PdpSubGroup subgrp = newgrp.getPdpSubgroups().get(0);
+        ToscaPolicyIdentifier ident = subgrp.getPolicies().get(0);
+        String version = ident.getVersion();
+        ident.setVersion("1");
 
-    @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));
+        prov.updateGroupPolicies(toDeploymentGroups(groups));
 
-        newgrp.getPdpSubgroups().get(0).getSupportedPolicyTypes()
-                        .add(new ToscaPolicyTypeIdentifier("typeX.*", "9.8.7"));
+        // restore full type before comparing
+        ident.setVersion(version);
 
-        prov.createOrUpdateGroups(groups);
+        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
+        Collections.sort(group.getPdpSubgroups().get(0).getPolicies());
 
         assertEquals(newgrp.toString(), group.toString());
-        assertGroupUpdateOnly(group);
+
+        assertNoGroupAction();
     }
 
     @Test
-    public void testUpdateSubGroup_DesiredCount() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroups.json");
+    public void testUpdateSubGroup_PolicyVersionPrefixMismatch() throws Exception {
+        PdpGroups groups = loadPdpGroups("deployGroups.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);
+        // use incorrect version prefix
+        newgrp.getPdpSubgroups().get(0).getPolicies().get(0).setVersion("9");
 
-        prov.createOrUpdateGroups(groups);
+        assertThatThrownBy(() -> prov.updateGroupPolicies(toDeploymentGroups(groups)))
+                        .isInstanceOf(PfModelException.class)
+                        .hasMessageContaining("different version already deployed");
 
-        assertEquals(newgrp.toString(), group.toString());
-        assertGroupUpdateOnly(group);
+        assertNoGroupAction();
     }
 
     @Test
-    public void testUpdateSubGroup_Policies() throws Exception {
-        PdpGroups groups = loadPdpGroups("createGroupsDelPolicy.json");
-        PdpGroup newgrp = groups.getGroups().get(0);
+    public void testUpdateSubGroup_Unchanged() throws Exception {
+        PdpGroups dbgroups = loadPdpGroups("deployGroups.json");
+        PdpGroup newgrp = dbgroups.getGroups().get(0);
         PdpGroup group = new PdpGroup(newgrp);
         when(dao.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
 
-        PdpSubGroup subgrp = newgrp.getPdpSubgroups().get(0);
-
-        // delete second policy
-        subgrp.setPolicies(subgrp.getPolicies().subList(0, 1));
-
-        // add new policy
-        ToscaPolicyIdentifier policyId2 = new ToscaPolicyIdentifier(POLICY2_NAME, POLICY1_VERSION);
-        subgrp.getPolicies().add(policyId2);
-
-        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("createGroupNewPolicy.json"))
-                        .thenReturn(loadPolicies("daoPolicyList.json"))
-                        .thenReturn(loadPolicies("daoPolicyListDelPolicy.json"))
-                        .thenReturn(loadPolicies("createGroupNewPolicy.json"));
-
-        prov.createOrUpdateGroups(groups);
+        prov.updateGroupPolicies(toDeploymentGroups(dbgroups));
 
         Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
         Collections.sort(group.getPdpSubgroups().get(0).getPolicies());
 
         assertEquals(newgrp.toString(), group.toString());
 
-        // should have notified of added policy/PDPs
-        ArgumentCaptor<PolicyPdpNotificationData> captor = ArgumentCaptor.forClass(PolicyPdpNotificationData.class);
-        verify(notifier).addDeploymentData(captor.capture());
-        assertDeploymentData(captor, policyId2, "[pdpA]");
-
-        // should have notified of deleted policy/PDPs
-        captor = ArgumentCaptor.forClass(PolicyPdpNotificationData.class);
-        verify(notifier).addUndeploymentData(captor.capture());
-        assertDeploymentData(captor, new ToscaPolicyIdentifier("ToBeDeleted", POLICY1_VERSION), "[pdpA]");
+        // no notifications
+        verify(notifier, never()).addDeploymentData(any());
+        verify(notifier, never()).addUndeploymentData(any());
 
-        // this requires a PDP UPDATE message
-        assertGroupUpdate(group, subgrp);
+        // no group updates
+        assertNoGroupAction();
     }
 
     @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);
+    public void testUpdateSubGroup_PolicyVersionMismatch() throws Exception {
+        PdpGroups dbgroups = loadPdpGroups("deployGroups.json");
+        PdpGroup newgrp = dbgroups.getGroups().get(0);
+        PdpGroup dbgroup = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
 
-        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
-        Collections.sort(group.getPdpSubgroups().get(0).getPolicies());
+        // arrange for DB policy version to be different
+        PdpSubGroup dbsubgrp = dbgroup.getPdpSubgroups().get(0);
+        dbsubgrp.getPolicies().get(0).setVersion("9.9.9");
 
-        assertEquals(newgrp.toString(), group.toString());
+        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList.json"));
 
-        // no notifications
-        verify(notifier, never()).addDeploymentData(any());
-        verify(notifier, never()).addUndeploymentData(any());
+        assertThatThrownBy(() -> prov.updateGroupPolicies(toDeploymentGroups(dbgroups)))
+                        .isInstanceOf(PfModelException.class)
+                        .hasMessageContaining("different version already deployed");
 
-        // 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));
+    public void testUpdateSubGroup_UnsupportedType() throws Exception {
+        PdpGroups dbgroups = loadPdpGroups("deployGroups.json");
+        PdpGroup newgrp = dbgroups.getGroups().get(0);
+        PdpGroup dbgroup = new PdpGroup(newgrp);
+        when(dao.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
+
+        final DeploymentGroups groups = toDeploymentGroups(dbgroups);
+
+        PdpSubGroup dbsubgrp = dbgroup.getPdpSubgroups().get(0);
+
+        // DB has no policies
+        dbsubgrp.getPolicies().clear();
 
-        newgrp.setProperties(new TreeMap<>());
+        // DB has a different supported type
+        dbsubgrp.getSupportedPolicyTypes().get(0).setName("some-other-type");
 
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
-                        .hasMessageContaining("properties");
+        when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList.json"));
+
+        assertThatThrownBy(() -> prov.updateGroupPolicies(groups))
+                        .isInstanceOf(PfModelException.class)
+                        .hasMessageContaining(newgrp.getPdpSubgroups().get(0).getPolicies().get(0).getName())
+                        .hasMessageContaining("not a supported policy for the subgroup");
 
         assertNoGroupAction();
     }
 
     @Test
     public void testDeployPolicies() throws PfModelException {
-        prov.deployPolicies(loadEmptyRequest());
+        assertThatCode(() -> prov.deployPolicies(loadEmptyRequest())).doesNotThrowAnyException();
     }
 
     /**
@@ -584,7 +512,7 @@ public class TestPdpGroupDeployProvider extends ProviderSuper {
         // should have notified of added policy/PDPs
         ArgumentCaptor<PolicyPdpNotificationData> captor = ArgumentCaptor.forClass(PolicyPdpNotificationData.class);
         verify(notifier).addDeploymentData(captor.capture());
-        assertDeploymentData(captor, policy1.getIdentifier(), "[pdpB]");
+        assertDeploymentData(captor.getValue(), policy1.getIdentifier(), "[pdpB]");
 
         // no undeployment notifications
         verify(notifier, never()).addUndeploymentData(any());
@@ -592,7 +520,7 @@ public class TestPdpGroupDeployProvider extends ProviderSuper {
 
     @Test
     public void testDeploySimplePolicies() throws Exception {
-        prov.deployPolicies(loadEmptyRequest());
+        assertThatCode(() -> prov.deployPolicies(loadEmptyRequest())).doesNotThrowAnyException();
     }
 
     @Test
@@ -654,7 +582,7 @@ public class TestPdpGroupDeployProvider extends ProviderSuper {
         // should have notified of added policy/PDPs
         ArgumentCaptor<PolicyPdpNotificationData> captor = ArgumentCaptor.forClass(PolicyPdpNotificationData.class);
         verify(notifier).addDeploymentData(captor.capture());
-        assertDeploymentData(captor, policy1.getIdentifier(), "[pdpB, pdpD]");
+        assertDeploymentData(captor.getValue(), policy1.getIdentifier(), "[pdpB, pdpD]");
 
         // no undeployment notifications
         verify(notifier, never()).addUndeploymentData(any());
@@ -729,17 +657,8 @@ public class TestPdpGroupDeployProvider extends ProviderSuper {
         assertEquals(Arrays.asList(group), updates);
     }
 
-    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);
-    }
-
-    private void assertDeploymentData(ArgumentCaptor<PolicyPdpNotificationData> captor, ToscaPolicyIdentifier policyId,
+    private void assertDeploymentData(PolicyPdpNotificationData data, ToscaPolicyIdentifier policyId,
                     String expectedPdps) {
-        PolicyPdpNotificationData data = captor.getValue();
         assertEquals(policyId, data.getPolicyId());
         assertEquals(policy1.getTypeIdentifier(), data.getPolicyType());
         assertEquals(expectedPdps, new TreeSet<>(data.getPdps()).toString());
@@ -772,4 +691,32 @@ public class TestPdpGroupDeployProvider extends ProviderSuper {
     protected PdpDeployPolicies loadEmptyRequest() {
         return loadRequest("emptyRequest.json");
     }
+
+    private DeploymentGroups toDeploymentGroups(PdpGroups dbgroups) {
+        DeploymentGroups groups = new DeploymentGroups();
+
+        groups.setGroups(dbgroups.getGroups().stream().map(this::toDeploymentGroup).collect(Collectors.toList()));
+
+        return groups;
+    }
+
+    private DeploymentGroup toDeploymentGroup(PdpGroup dbgroup) {
+        DeploymentGroup group = new DeploymentGroup();
+
+        group.setName(dbgroup.getName());
+        group.setDeploymentSubgroups(dbgroup.getPdpSubgroups().stream().map(this::toDeploymentSubGroup)
+                        .collect(Collectors.toList()));
+
+        return group;
+    }
+
+    private DeploymentSubGroup toDeploymentSubGroup(PdpSubGroup dbsubgrp) {
+        DeploymentSubGroup subgrp = new DeploymentSubGroup();
+
+        subgrp.setAction(Action.PATCH);
+        subgrp.setPdpType(dbsubgrp.getPdpType());
+        subgrp.setPolicies(new ArrayList<>(dbsubgrp.getPolicies()));
+
+        return subgrp;
+    }
 }
index 69165d1..1f04970 100644 (file)
@@ -36,7 +36,8 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 import org.onap.policy.models.pap.concepts.PdpDeployPolicies;
 import org.onap.policy.models.pap.concepts.PdpGroupDeployResponse;
-import org.onap.policy.models.pdp.concepts.PdpGroups;
+import org.onap.policy.models.pdp.concepts.DeploymentGroup;
+import org.onap.policy.models.pdp.concepts.DeploymentGroups;
 import org.onap.policy.models.pdp.concepts.PdpStatus;
 import org.onap.policy.models.pdp.enums.PdpState;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
@@ -46,10 +47,9 @@ import org.slf4j.LoggerFactory;
 public class PdpGroupDeployTest extends End2EndBase {
     private static final Logger logger = LoggerFactory.getLogger(PdpGroupDeployTest.class);
 
-    private static final String DEPLOY_GROUP_ENDPOINT = "pdps";
+    private static final String DEPLOY_GROUP_ENDPOINT = "pdps/deployments/batch";
     private static final String DEPLOY_POLICIES_ENDPOINT = "pdps/policies";
     private static final String DELETE_GROUP_ENDPOINT = "pdps/groups";
-    private static final String CREATE_SUBGROUP = "pdpTypeA";
     private static final String DEPLOY_SUBGROUP = "pdpTypeA";
 
     /**
@@ -82,27 +82,47 @@ public class PdpGroupDeployTest extends End2EndBase {
     public void tearDown() {
         // delete the group that was inserted
         try {
-            sendRequest(DELETE_GROUP_ENDPOINT + "/createGroups").delete();
+            sendRequest(DELETE_GROUP_ENDPOINT + "/deployGroups").delete();
         } catch (Exception e) {
-            logger.warn("cannot delete group: createGroups", e);
+            logger.warn("cannot delete group: deployGroups", e);
         }
 
         super.tearDown();
     }
 
     @Test
-    public void testCreateGroups() throws Exception {
+    public void testUpdateGroupPolicies() throws Exception {
 
-        context.addPdp("pdpAA_1", CREATE_SUBGROUP);
-        context.addPdp("pdpAA_2", CREATE_SUBGROUP);
-        context.addPdp("pdpAB_1", "pdpTypeB");
+        addGroups("deployGroups.json");
+
+        PdpStatus status11 = new PdpStatus();
+        status11.setName("pdpAA_1");
+        status11.setState(PdpState.ACTIVE);
+        status11.setPdpGroup("deployPolicies");
+        status11.setPdpType(DEPLOY_SUBGROUP);
+        status11.setPdpSubgroup(DEPLOY_SUBGROUP);
+
+        List<ToscaPolicyIdentifier> idents = Arrays.asList(new ToscaPolicyIdentifier("onap.restart.tca", "1.0.0"));
+        status11.setPolicies(idents);
+
+        PdpStatus status12 = new PdpStatus();
+        status12.setName("pdpAA_2");
+        status12.setState(PdpState.ACTIVE);
+        status12.setPdpGroup("deployPolicies");
+        status12.setPdpType(DEPLOY_SUBGROUP);
+        status12.setPdpSubgroup(DEPLOY_SUBGROUP);
+        status12.setPolicies(idents);
+
+        context.addPdp("pdpAA_1", DEPLOY_SUBGROUP).addReply(status11);
+        context.addPdp("pdpAA_2", DEPLOY_SUBGROUP).addReply(status12);
+        context.addPdp("pdpAB_1", "pdpTypeA");
 
         context.startThreads();
 
         Invocation.Builder invocationBuilder = sendRequest(DEPLOY_GROUP_ENDPOINT);
 
-        PdpGroups groups = loadJsonFile("createGroups.json", PdpGroups.class);
-        Entity<PdpGroups> entity = Entity.entity(groups, MediaType.APPLICATION_JSON);
+        DeploymentGroups groups = loadJsonFile("deployGroupsReq.json", DeploymentGroups.class);
+        Entity<DeploymentGroups> entity = Entity.entity(groups, MediaType.APPLICATION_JSON);
         Response rawresp = invocationBuilder.post(entity);
         PdpGroupDeployResponse resp = rawresp.readEntity(PdpGroupDeployResponse.class);
         assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
@@ -110,9 +130,8 @@ public class PdpGroupDeployTest extends End2EndBase {
 
         context.await();
 
-        // none of the PDPs should have handled any requests
-        assertEquals(context.getPdps().size(),
-                        context.getPdps().stream().filter(pdp -> pdp.getHandled().isEmpty()).count());
+        // one of the PDPs should not have handled any requests
+        assertEquals(1, context.getPdps().stream().filter(pdp -> pdp.getHandled().isEmpty()).count());
 
         // repeat - should be OK
         rawresp = invocationBuilder.post(entity);
@@ -120,12 +139,13 @@ public class PdpGroupDeployTest extends End2EndBase {
         assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
         assertNull(resp.getErrorDetails());
 
-        // repeat with different properties - should fail
-        groups.getGroups().get(0).setProperties(null);
+        // repeat with unknown group - should fail
+        DeploymentGroup group = groups.getGroups().get(0);
+        group.setName("unknown-group");
         rawresp = invocationBuilder.post(entity);
         resp = rawresp.readEntity(PdpGroupDeployResponse.class);
         assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), rawresp.getStatus());
-        assertTrue(resp.getErrorDetails().contains("cannot change properties"));
+        assertTrue(resp.getErrorDetails().contains("unknown group"));
     }
 
     @Test
diff --git a/main/src/test/resources/e2e/deployGroups.json b/main/src/test/resources/e2e/deployGroups.json
new file mode 100644 (file)
index 0000000..1b9c33c
--- /dev/null
@@ -0,0 +1,56 @@
+{
+    "groups": [
+        {
+            "name": "deployGroups",
+            "pdpGroupState": "PASSIVE",
+            "properties": {
+                "hello": "world"
+            },
+            "pdpSubgroups": [
+                {
+                    "pdpType": "pdpTypeA",
+                    "desiredInstanceCount": 2,
+                    "properties": {},
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpAA_1",
+                            "pdpState": "ACTIVE",
+                            "healthy": "HEALTHY"
+                        },
+                        {
+                            "instanceId": "pdpAA_2",
+                            "pdpState": "ACTIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": []
+                },
+                {
+                    "pdpType": "pdpTypeB",
+                    "desiredInstanceCount": 1,
+                    "properties": {},
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpAB_1",
+                            "pdpState": "ACTIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": []
+                }
+            ]
+        }
+    ]
+}
diff --git a/main/src/test/resources/e2e/deployGroups2.json b/main/src/test/resources/e2e/deployGroups2.json
new file mode 100644 (file)
index 0000000..6d784bf
--- /dev/null
@@ -0,0 +1,69 @@
+{
+    "groups": [
+        {
+            "name": "deployGroups",
+            "pdpGroupState": "PASSIVE",
+            "properties": {
+                "hello": "world"
+            },
+            "pdpSubgroups": [
+                {
+                    "pdpType": "pdpTypeA",
+                    "desiredInstanceCount": 2,
+                    "properties": {},
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpAA_1",
+                            "pdpState": "ACTIVE",
+                            "healthy": "HEALTHY"
+                        },
+                        {
+                            "instanceId": "pdpAA_2",
+                            "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"
+                        },
+                        {
+                            "name": "onap.restart.tcaB",
+                            "version": "1.0.0"
+                        },
+                        {
+                            "name": "onap.restart.tcaC",
+                            "version": "1.0.0"
+                        }
+                    ]
+                },
+                {
+                    "pdpType": "pdpTypeB",
+                    "desiredInstanceCount": 1,
+                    "properties": {},
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpAB_1",
+                            "pdpState": "ACTIVE",
+                            "healthy": "HEALTHY"
+                        }
+                    ],
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+                            "version": "1.0.0"
+                        }
+                    ],
+                    "policies": []
+                }
+            ]
+        }
+    ]
+}
diff --git a/main/src/test/resources/e2e/deployGroupsReq.json b/main/src/test/resources/e2e/deployGroupsReq.json
new file mode 100644 (file)
index 0000000..2e397d1
--- /dev/null
@@ -0,0 +1,24 @@
+{
+    "groups": [
+        {
+            "name": "deployGroups",
+            "deploymentSubgroups": [
+                {
+                    "pdpType": "pdpTypeA",
+                    "action": "PATCH",
+                    "policies": [
+                        {
+                            "name": "onap.restart.tca",
+                            "version": "1.0.0"
+                        }
+                    ]
+                },
+                {
+                    "pdpType": "pdpTypeB",
+                    "action": "PATCH",
+                    "policies": []
+                }
+            ]
+        }
+    ]
+}
diff --git a/main/src/test/resources/e2e/deployGroupsReq2.json b/main/src/test/resources/e2e/deployGroupsReq2.json
new file mode 100644 (file)
index 0000000..0993ddf
--- /dev/null
@@ -0,0 +1,28 @@
+{
+    "groups": [
+        {
+            "name": "deployGroups",
+            "deploymentSubgroups": [
+                {
+                    "pdpType": "pdpTypeA",
+                    "action": "PATCH",
+                    "policies": [
+                        {
+                            "name": "onap.restart.tcaB",
+                            "version": "1.0.0"
+                        },
+                        {
+                            "name": "onap.restart.tcaC",
+                            "version": "1.0.0"
+                        }
+                    ]
+                },
+                {
+                    "pdpType": "pdpTypeB",
+                    "action": "PATCH",
+                    "policies": []
+                }
+            ]
+        }
+    ]
+}
index 4cafe77..90363ee 100644 (file)
@@ -1,7 +1,7 @@
 {
     "groups": [
         {
-            "name": "deployPolicies",
+            "name": "deployGroups",
             "pdpGroupState": "ACTIVE",
             "pdpSubgroups": [
                 {
diff --git a/main/src/test/resources/simpleDeploy/createGroupNewPolicy2.json b/main/src/test/resources/simpleDeploy/createGroupNewPolicy2.json
new file mode 100644 (file)
index 0000000..84ea228
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "policies":  [
+        {
+            "name": "policyC",
+            "version": "1.2.3",
+            "type": "typeA",
+            "type_version": "100.2.3"
+        }
+    ]
+}
diff --git a/main/src/test/resources/simpleDeploy/daoPolicyList2.json b/main/src/test/resources/simpleDeploy/daoPolicyList2.json
new file mode 100644 (file)
index 0000000..d4d1446
--- /dev/null
@@ -0,0 +1,22 @@
+{
+    "policies":  [
+        {
+            "name": "policyA",
+            "version": "1.2.3",
+            "type": "typeA",
+            "type_version": "100.2.3"
+        },
+        {
+            "name": "policyB",
+            "version": "1.2.3",
+            "type": "typeA",
+            "type_version": "100.2.3"
+        },
+        {
+            "name": "policyC",
+            "version": "1.2.3",
+            "type": "typeA",
+            "type_version": "100.2.3"
+        }
+    ]
+}
diff --git a/main/src/test/resources/simpleDeploy/deployGroups.json b/main/src/test/resources/simpleDeploy/deployGroups.json
new file mode 100644 (file)
index 0000000..59c4eb8
--- /dev/null
@@ -0,0 +1,39 @@
+{
+    "groups": [
+        {
+            "name": "groupA",
+            "version": "200.2.3",
+            "description": "my description",
+            "pdpGroupState": "ACTIVE",
+            "properties": {
+                "hello": "world"
+            },
+            "pdpSubgroups": [
+                {
+                    "pdpType": "pdpTypeA",
+                    "desiredInstanceCount": 1,
+                    "properties": {
+                        "abc": "def"
+                    },
+                    "supportedPolicyTypes": [
+                        {
+                            "name": "typeA",
+                            "version": "100.2.3"
+                        }
+                    ],
+                    "pdpInstances": [
+                        {
+                            "instanceId": "pdpA"
+                        }
+                    ],
+                    "policies": [
+                        {
+                            "name": "policyA",
+                            "version": "1.2.3"
+                        }
+                    ]
+                }
+            ]
+        }
+    ]
+}