diff options
author | Jim Hahn <jrh3@att.com> | 2019-04-05 09:52:35 -0400 |
---|---|---|
committer | Jim Hahn <jrh3@att.com> | 2019-04-05 11:51:26 -0400 |
commit | 287e9d464e487ed5ae5fe5250ab960194f179c01 (patch) | |
tree | 4e1d9295b308f4328c894bafe2190c0728089f46 /main | |
parent | 457c9b19c058877ca59c9b0826d22f3f97392daf (diff) |
Flesh out policy deployment REST API
Also moved the controller, the provider, and supporting classes
to their own dep_undep package.
Change-Id: Ifea1c4dd2ecbf93a8f4d45e130830cf9271103d3
Issue-ID: POLICY-1542
Signed-off-by: Jim Hahn <jrh3@att.com>
Diffstat (limited to 'main')
34 files changed, 2295 insertions, 222 deletions
diff --git a/main/src/main/java/org/onap/policy/pap/main/comm/msgdata/UpdateData.java b/main/src/main/java/org/onap/policy/pap/main/comm/msgdata/UpdateData.java index 0d861e21..eca0b384 100644 --- a/main/src/main/java/org/onap/policy/pap/main/comm/msgdata/UpdateData.java +++ b/main/src/main/java/org/onap/policy/pap/main/comm/msgdata/UpdateData.java @@ -20,8 +20,8 @@ package org.onap.policy.pap.main.comm.msgdata; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import org.onap.policy.models.pdp.concepts.PdpStatus; import org.onap.policy.models.pdp.concepts.PdpUpdate; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; @@ -62,32 +62,16 @@ public abstract class UpdateData extends MessageData { } // see if the other has any policies that this does not have - ArrayList<ToscaPolicyIdentifier> lst = new ArrayList<>(response.getPolicies()); - List<ToscaPolicy> mypolicies = update.getPolicies(); + Set<ToscaPolicyIdentifier> set = new HashSet<>(response.getPolicies()); - if (mypolicies.size() != lst.size()) { - return "policies do not match"; + for (ToscaPolicy policy : update.getPolicies()) { + set.remove(policy.getIdentifier()); } - lst.removeAll(convertToscaPolicyToToscaPolicyIndentifier(update.getPolicies())); - if (!lst.isEmpty()) { + if (!set.isEmpty()) { return "policies do not match"; } return null; } - - /** - * Converts a ToscaPolicy list to ToscaPolicyIdentifier list. - * - * @param toscaPolicies the list of ToscaPolicy - * @return the ToscaPolicyIdentifier list - */ - private List<ToscaPolicyIdentifier> convertToscaPolicyToToscaPolicyIndentifier(List<ToscaPolicy> toscaPolicies) { - final List<ToscaPolicyIdentifier> toscaPolicyIdentifiers = new ArrayList<>(); - for (final ToscaPolicy toscaPolicy : toscaPolicies) { - toscaPolicyIdentifiers.add(new ToscaPolicyIdentifier(toscaPolicy.getName(), toscaPolicy.getVersion())); - } - return toscaPolicyIdentifiers; - } } diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/PapRestServer.java b/main/src/main/java/org/onap/policy/pap/main/rest/PapRestServer.java index 28587077..05ba2901 100644 --- a/main/src/main/java/org/onap/policy/pap/main/rest/PapRestServer.java +++ b/main/src/main/java/org/onap/policy/pap/main/rest/PapRestServer.java @@ -30,6 +30,7 @@ import org.onap.policy.common.endpoints.http.server.HttpServletServer; import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; import org.onap.policy.common.gson.GsonMessageBodyHandler; import org.onap.policy.pap.main.parameters.RestServerParameters; +import org.onap.policy.pap.main.rest.depundep.PdpGroupDeployControllerV1; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupDeployProvider.java b/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupDeployProvider.java deleted file mode 100644 index f0636fc6..00000000 --- a/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupDeployProvider.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP PAP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.pap.main.rest; - -import javax.ws.rs.core.Response; - -import org.apache.commons.lang3.tuple.Pair; -import org.onap.policy.models.pap.concepts.PdpDeployPolicies; -import org.onap.policy.models.pap.concepts.PdpGroupDeployResponse; -import org.onap.policy.models.pdp.concepts.PdpGroups; - -/** - * Provider for PAP component to deploy PDP groups. - */ -public class PdpGroupDeployProvider { - - /** - * Deploys or updates a PDP group. - * - * @param groups PDP group configuration - * @return a pair containing the status and the response - */ - public Pair<Response.Status, PdpGroupDeployResponse> deployGroup(PdpGroups groups) { - - /* - * TODO Lock for updates - return error if already locked. - */ - - /* - * TODO Make updates - sending initial messages to PDPs and arranging for - * listeners to complete the deployment actions (in the background). The final - * step for the listener is to unlock. - */ - - /* - * TODO Return error if unable to send updates to all PDPs. - */ - - return Pair.of(Response.Status.OK, new PdpGroupDeployResponse()); - } - - /** - * Deploys or updates PDP policies. - * - * @param policies PDP policies - * @return a pair containing the status and the response - */ - public Pair<Response.Status, PdpGroupDeployResponse> deployPolicies(PdpDeployPolicies policies) { - - /* - * TODO Lock for updates - return error if already locked. - */ - - /* - * TODO Make updates - sending initial messages to PDPs and arranging for - * listeners to complete the deployment actions (in the background). The final - * step for the listener is to unlock. - */ - - /* - * TODO Return error if unable to send updates to all PDPs. - */ - - return Pair.of(Response.Status.OK, new PdpGroupDeployResponse()); - } -} diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupDeployControllerV1.java b/main/src/main/java/org/onap/policy/pap/main/rest/depundep/PdpGroupDeployControllerV1.java index d67974dd..6d4dc7ed 100644 --- a/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupDeployControllerV1.java +++ b/main/src/main/java/org/onap/policy/pap/main/rest/depundep/PdpGroupDeployControllerV1.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.pap.main.rest; +package org.onap.policy.pap.main.rest.depundep; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -28,19 +28,17 @@ 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.apache.commons.lang3.tuple.Pair; 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.pap.main.rest.PapRestControllerV1; /** * Class to provide REST end points for PAP component to deploy a PDP group. @@ -123,7 +121,7 @@ public class PdpGroupDeployControllerV1 extends PapRestControllerV1 { // @formatter:on public Response deployPolicies(@HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "PDP Policies; only the name and policyVersion are required", + @ApiParam(value = "PDP Policies; only the name is required", required = true) PdpDeployPolicies policies) { Pair<Status, PdpGroupDeployResponse> pair = provider.deployPolicies(policies); diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/depundep/PdpGroupDeployProvider.java b/main/src/main/java/org/onap/policy/pap/main/rest/depundep/PdpGroupDeployProvider.java new file mode 100644 index 00000000..eef14388 --- /dev/null +++ b/main/src/main/java/org/onap/policy/pap/main/rest/depundep/PdpGroupDeployProvider.java @@ -0,0 +1,156 @@ +/* + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.rest.depundep; + +import java.util.List; +import java.util.function.BiFunction; +import javax.ws.rs.core.Response; +import org.apache.commons.lang3.tuple.Pair; +import org.onap.policy.common.utils.services.Registry; +import org.onap.policy.models.base.PfModelException; +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.PdpGroups; +import org.onap.policy.models.pdp.concepts.PdpSubGroup; +import org.onap.policy.models.pdp.concepts.PdpUpdate; +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.onap.policy.pap.main.PolicyPapRuntimeException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provider for PAP component to deploy 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 PdpGroupDeployProvider extends ProviderBase<PdpGroupDeployResponse> { + private static final Logger logger = LoggerFactory.getLogger(PdpGroupDeployProvider.class); + + + /** + * Constructs the object. + */ + public PdpGroupDeployProvider() { + super(); + } + + /** + * Deploys or updates PDP groups. + * + * @param groups PDP group configurations + * @return a pair containing the status and the response + */ + public Pair<Response.Status, PdpGroupDeployResponse> deployGroup(PdpGroups groups) { + return process(groups, this::deployGroups); + } + + /** + * Deploys or updates PDP groups. + * + * @param data session data + * @param groups PDP group configurations + * @return a list of requests that should be sent to configure the PDPs + */ + private List<PdpUpdate> deployGroups(SessionData data, PdpGroups groups) { + throw new PolicyPapRuntimeException("not implemented yet"); + } + + /** + * Deploys or updates PDP policies. + * + * @param policies PDP policies + * @return a pair containing the status and the response + */ + public Pair<Response.Status, PdpGroupDeployResponse> deployPolicies(PdpDeployPolicies policies) { + return process(policies, this::deploySimplePolicies); + } + + /** + * Deploys or updates PDP policies using the simple API. + * + * @param data session data + * @param extPolicies external PDP policies + * @return a list of requests that should be sent to configure the PDPs + */ + private void deploySimplePolicies(SessionData data, PdpDeployPolicies policies) { + + for (ToscaPolicyIdentifierOptVersion desiredPolicy : policies.getPolicies()) { + + try { + processPolicy(data, desiredPolicy); + + } catch (PfModelException e) { + // no need to log the error here, as it will be logged by the invoker + logger.warn("failed to deploy policy: {}", desiredPolicy); + throw new PolicyPapRuntimeException(DB_ERROR_MSG, e); + + } catch (RuntimeException e) { + // no need to log the error here, as it will be logged by the invoker + logger.warn("failed to deploy policy: {}", desiredPolicy); + throw e; + } + } + } + + @Override + protected BiFunction<PdpGroup, PdpSubGroup, Boolean> makeUpdater(ToscaPolicy policy) { + ToscaPolicyIdentifier desiredIdent = policy.getIdentifier(); + ToscaPolicyTypeIdentifier desiredType = policy.getTypeIdentifier(); + + return (group, subgroup) -> { + + if (!subgroup.getSupportedPolicyTypes().contains(desiredType)) { + // doesn't support the desired policy type + return false; + } + + if (subgroup.getPolicies().contains(desiredIdent)) { + // already has the desired policy + return false; + } + + if (subgroup.getPdpInstances().isEmpty()) { + throw new PolicyPapRuntimeException("group " + group.getName() + " subgroup " + subgroup.getPdpType() + + " has no active PDPs"); + } + + + // add the policy to the subgroup + subgroup.getPolicies().add(desiredIdent); + return true; + }; + } + + @Override + public PdpGroupDeployResponse makeResponse(String errorMsg) { + PdpGroupDeployResponse resp = new PdpGroupDeployResponse(); + resp.setErrorDetails(errorMsg); + return resp; + } +} diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/depundep/ProviderBase.java b/main/src/main/java/org/onap/policy/pap/main/rest/depundep/ProviderBase.java new file mode 100644 index 00000000..29d3b3ca --- /dev/null +++ b/main/src/main/java/org/onap/policy/pap/main/rest/depundep/ProviderBase.java @@ -0,0 +1,369 @@ +/* + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.rest.depundep; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.stream.Collectors; +import javax.ws.rs.core.Response; +import org.apache.commons.lang3.tuple.Pair; +import org.onap.policy.common.utils.services.Registry; +import org.onap.policy.common.utils.validation.Version; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.pap.concepts.SimpleResponse; +import org.onap.policy.models.pdp.concepts.Pdp; +import org.onap.policy.models.pdp.concepts.PdpGroup; +import org.onap.policy.models.pdp.concepts.PdpSubGroup; +import org.onap.policy.models.pdp.concepts.PdpUpdate; +import org.onap.policy.models.pdp.enums.PdpState; +import org.onap.policy.models.provider.PolicyModelsProvider; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifierOptVersion; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; +import org.onap.policy.pap.main.PapConstants; +import org.onap.policy.pap.main.PolicyModelsProviderFactoryWrapper; +import org.onap.policy.pap.main.PolicyPapRuntimeException; +import org.onap.policy.pap.main.comm.PdpModifyRequestMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Super class of providers that deploy and undeploy 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> + * + * @param <R> the response type + */ +public abstract class ProviderBase<R extends SimpleResponse> { + private static final String DEPLOY_FAILED = "failed to deploy/undeploy policies"; + + public static final String DB_ERROR_MSG = "DB error"; + + private static final Logger logger = LoggerFactory.getLogger(ProviderBase.class); + + /** + * Lock used when updating PDPs. + */ + private final Object updateLock; + + /** + * Used to send UPDATE and STATE-CHANGE requests to the PDPs. + */ + private final PdpModifyRequestMap requestMap; + + /** + * Factory for PAP DAO. + */ + private final PolicyModelsProviderFactoryWrapper daoFactory; + + + /** + * Constructs the object. + */ + public ProviderBase() { + this.updateLock = Registry.get(PapConstants.REG_PDP_MODIFY_LOCK, Object.class); + this.requestMap = Registry.get(PapConstants.REG_PDP_MODIFY_MAP, PdpModifyRequestMap.class); + this.daoFactory = Registry.get(PapConstants.REG_PAP_DAO_FACTORY, PolicyModelsProviderFactoryWrapper.class); + } + + /** + * Processes a policy request. + * + * @param request PDP policy request + * @param processor function that processes the request + * @return a pair containing the status and the response + */ + protected <T> Pair<Response.Status, R> process(T request, BiConsumer<SessionData, T> processor) { + + synchronized (updateLock) { + // list of requests to be published to the PDPs + Collection<PdpUpdate> requests = Collections.emptyList(); + + try (PolicyModelsProvider dao = daoFactory.create()) { + + SessionData data = new SessionData(dao); + processor.accept(data, request); + + requests = data.getUpdates(); + + } catch (PfModelException e) { + logger.warn(DEPLOY_FAILED, e); + return Pair.of(Response.Status.INTERNAL_SERVER_ERROR, makeResponse(DB_ERROR_MSG)); + + } catch (PolicyPapRuntimeException e) { + logger.warn(DEPLOY_FAILED, e); + return Pair.of(Response.Status.INTERNAL_SERVER_ERROR, makeResponse(e.getMessage())); + + } catch (RuntimeException e) { + logger.warn(DEPLOY_FAILED, e); + return Pair.of(Response.Status.INTERNAL_SERVER_ERROR, makeResponse("request failed")); + } + + + // publish the requests + for (PdpUpdate req : requests) { + requestMap.addRequest(req); + } + } + + return Pair.of(Response.Status.OK, makeResponse(null)); + } + + /** + * Makes a response. + * + * @param errorMsg error message, or {@code null} if there was no error + * @return a new response + */ + public abstract R makeResponse(String errorMsg); + + /** + * Finds a Policy having the given name and version. If the specified version is + * {@code null}, then it finds the matching Policy with the latest version. + * + * @param data session data + * @param desiredPolicy the policy desired, with the "name" and optional + * "policyVersion" populated + * @return the matching Policy type + * @throws PfModelException if a DAO error occurred + * @throws PolicyPapRuntimeException if there is no matching policy type + */ + private ToscaPolicy getPolicy(SessionData data, ToscaPolicyIdentifierOptVersion desiredPolicy) + throws PfModelException { + + if (desiredPolicy.isNullVersion()) { + return data.getPolicyMaxVersion(desiredPolicy.getName()); + + } else { + return data.getPolicy(new ToscaPolicyIdentifier(desiredPolicy.getName(), desiredPolicy.getVersion())); + } + } + + /** + * Process a single policy from the request. + * + * @param data session data + * @param desiredPolicy request policy + * @throws PolicyPapRuntimeException if an error occurs + * @throws PfModelException if a DAO error occurred + */ + protected void processPolicy(SessionData data, ToscaPolicyIdentifierOptVersion desiredPolicy) + throws PfModelException { + + ToscaPolicy policy = getPolicy(data, desiredPolicy); + + Collection<PdpGroup> groups = getGroups(data, policy.getTypeIdentifier()); + if (groups.isEmpty()) { + throw new PolicyPapRuntimeException("policy not supported by any PDP group: " + desiredPolicy.getName() + + " " + desiredPolicy.getVersion()); + } + + BiFunction<PdpGroup, PdpSubGroup, Boolean> updater = makeUpdater(policy); + + for (PdpGroup group : groups) { + upgradeGroup(data, policy, group, updater); + } + } + + /** + * Makes a function to update a subgroup. The function is expected to return + * {@code true} if the subgroup was updated, {@code false} if no update was + * necessary/appropriate. + * + * @param policy policy to be added to or removed from each subgroup + * @return a function to update a subgroup + */ + protected abstract BiFunction<PdpGroup, PdpSubGroup, Boolean> makeUpdater(ToscaPolicy policy); + + /** + * Finds the active PDP group(s) with the highest version that supports the given + * policy type. + * + * @param data session data + * @param policyType the policy type of interest + * @return the matching PDP group, or {@code null} if no active group supports the + * given PDP types + * @throws PfModelException if an error occurs + */ + private Collection<PdpGroup> getGroups(SessionData data, ToscaPolicyTypeIdentifier policyType) + throws PfModelException { + // build a map containing the group with the highest version for each name + Map<String, GroupData> name2data = new HashMap<>(); + + for (PdpGroup group : data.getActivePdpGroupsByPolicyType(policyType)) { + Version vers = Version.makeVersion("PdpGroup", group.getName(), group.getVersion()); + if (vers == null) { + continue; + } + + GroupData grpdata = name2data.get(group.getName()); + + if (grpdata == null) { + // not in the map yet + name2data.put(group.getName(), new GroupData(group, vers)); + + } else if (vers.compareTo(grpdata.version) >= 0) { + // higher version + grpdata.replace(group, vers); + } + } + + return name2data.values().stream().map(grpdata -> grpdata.group).collect(Collectors.toList()); + } + + /** + * Updates a group, assigning a new version number, if it actually changes. + * + * @param data session data + * @param policy policy to be added to or removed from the group + * @param oldGroup the original group, to be updated + * @param updater function to update a group + * @throws PfModelException if a DAO error occurred + */ + private void upgradeGroup(SessionData data, ToscaPolicy policy, PdpGroup oldGroup, + BiFunction<PdpGroup, PdpSubGroup, Boolean> updater) throws PfModelException { + + PdpGroup newGroup = new PdpGroup(oldGroup); + boolean updated = false; + + for (PdpSubGroup subgroup : newGroup.getPdpSubgroups()) { + + if (!updater.apply(newGroup, subgroup)) { + continue; + } + + updated = true; + + /* + * generate an UPDATE for each PDP instance. Since the group is active, we + * assume that the PDP is, too, thus no need for a STATE-CHANGE. + */ + for (Pdp pdpInstance : subgroup.getPdpInstances()) { + data.addUpdate(makeUpdate(data, newGroup, subgroup, pdpInstance)); + } + } + + + if (!updated) { + return; + } + + + // something changed + + if (data.isNewlyCreated(newGroup.getName())) { + /* + * It's already in the list of new groups - update the policies, but not the + * version. + */ + data.updatePdpGroup(newGroup); + + } else { + // haven't seen this group before - update the version + upgradeGroupVersion(data, oldGroup, newGroup); + } + } + + /** + * Makes an UPDATE message for a particular PDP. + * + * @param data session data + * @param group group to which the PDP should belong + * @param subgroup subgroup to which the PDP should belong + * @param pdpInstance identifies the PDP of interest + * @return a new UPDATE message + */ + private PdpUpdate makeUpdate(SessionData data, PdpGroup group, PdpSubGroup subgroup, Pdp pdpInstance) { + + PdpUpdate update = new PdpUpdate(); + + update.setName(pdpInstance.getInstanceId()); + update.setDescription(group.getDescription()); + update.setPdpGroup(group.getName()); + update.setPdpSubgroup(subgroup.getPdpType()); + update.setPolicies(subgroup.getPolicies().stream().map(data::getPolicy).collect(Collectors.toList())); + + return update; + } + + /** + * Upgrades a group's version. Updates the version in the new group, persists the new + * group, and deactivates the old group. + * + * @param data session data + * @param newGroup the new version of the group + * @param oldGroup the original group, to be updated + * @throws PfModelException if a DAO error occurred + */ + private void upgradeGroupVersion(SessionData data, PdpGroup newGroup, PdpGroup oldGroup) throws PfModelException { + + // change versions + newGroup.setVersion(makeNewVersion(data, oldGroup).toString()); + + // create it before we update the old group + newGroup = data.createPdpGroup(newGroup); + + // deactivate the old group + oldGroup.setPdpGroupState(PdpState.PASSIVE); + oldGroup = data.updatePdpGroup(oldGroup); + } + + /** + * Makes a new version for the PDP group. + * + * @param data session data + * @param group current group + * @return a new version + * @throws PfModelException if a DAO error occurred + */ + private Version makeNewVersion(SessionData data, PdpGroup group) throws PfModelException { + PdpGroup group2 = data.getPdpGroupMaxVersion(group.getName()); + Version vers = Version.makeVersion("PdpGroup", group2.getName(), group2.getVersion()); + return vers.newVersion(); + } + + /** + * Data associated with a group. Used to find the group with the maximum version. + */ + private static class GroupData { + private PdpGroup group; + private Version version; + + public GroupData(PdpGroup group, Version version) { + this.group = group; + this.version = version; + } + + public void replace(PdpGroup group, Version version) { + this.group = group; + this.version = version; + } + } +} diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/depundep/SessionData.java b/main/src/main/java/org/onap/policy/pap/main/rest/depundep/SessionData.java new file mode 100644 index 00000000..01dc8f47 --- /dev/null +++ b/main/src/main/java/org/onap/policy/pap/main/rest/depundep/SessionData.java @@ -0,0 +1,214 @@ +/* + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.rest.depundep; + +import java.util.Collection; +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 org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.pdp.concepts.PdpGroup; +import org.onap.policy.models.pdp.concepts.PdpGroupFilter; +import org.onap.policy.models.pdp.concepts.PdpUpdate; +import org.onap.policy.models.provider.PolicyModelsProvider; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyFilter; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; +import org.onap.policy.pap.main.PolicyPapRuntimeException; + +/** + * Data used during a single REST call when updating PDP policies. + */ +public class SessionData { + private final PolicyModelsProvider dao; + + /** + * The names of newly created groups are added to this set to prevent the version + * number from being updated in case the group is re-used during the same REST call. + */ + private final Set<String> newGroups; + + /** + * Maps a PDP name to its most recently generated update request. + */ + private final Map<String, PdpUpdate> updates; + + /** + * Maps a policy's identifier to the policy. + */ + private final Map<ToscaPolicyIdentifier, ToscaPolicy> policyMap; + + + /** + * Constructs the object. + * + * @param dao DAO provider + */ + public SessionData(PolicyModelsProvider dao) { + this.dao = dao; + this.newGroups = new HashSet<>(); + this.updates = new HashMap<>(); + this.policyMap = new HashMap<>(); + } + + /** + * Gets the policy, referenced by an identifier. Loads it from the cache, if possible. + * Otherwise, gets it from the DB. + * + * @param ident policy identifier + * @return the specified policy + * @throws PolicyPapRuntimeException if an error occurs + */ + public ToscaPolicy getPolicy(ToscaPolicyIdentifier ident) { + + return policyMap.computeIfAbsent(ident, key -> { + + try { + List<ToscaPolicy> lst = dao.getPolicyList(ident.getName(), ident.getVersion()); + + if (lst.isEmpty()) { + throw new PolicyPapRuntimeException( + "cannot find policy: " + ident.getName() + " " + ident.getVersion()); + } + + if (lst.size() > 1) { + throw new PolicyPapRuntimeException( + "too many policies match: " + ident.getName() + " " + ident.getVersion()); + } + + return lst.get(0); + + } catch (PfModelException e) { + throw new PolicyPapRuntimeException("cannot get policy: " + ident.getName() + " " + ident.getVersion(), + e); + } + }); + } + + /** + * Adds an update to the set of updates, replacing any previous entry for the given + * PDP. + * + * @param update the update to be added + */ + public void addUpdate(PdpUpdate update) { + updates.put(update.getName(), update); + } + + /** + * Gets the accumulated UPDATE requests. + * + * @return the UPDATE requests + */ + public Collection<PdpUpdate> getUpdates() { + return updates.values(); + } + + /** + * Determines if a group has been newly created as part of this REST call. + * + * @param group name to the group of interest + * @return {@code true} if the group has been newly created, {@code false} otherwise + */ + public boolean isNewlyCreated(String group) { + return newGroups.contains(group); + } + + /** + * Gets the policy having the given name and the maximum version. + * + * @param name name of the desired policy + * @return the desired policy, or {@code null} if there is no policy with given name + * @throws PfModelException if an error occurs + */ + public ToscaPolicy getPolicyMaxVersion(String name) throws PfModelException { + ToscaPolicyFilter filter = ToscaPolicyFilter.builder().name(name).build(); + // TODO setLatest, setActive? + + List<ToscaPolicy> policies = dao.getFilteredPolicyList(filter); + if (policies.isEmpty()) { + throw new PolicyPapRuntimeException("cannot find policy: " + name); + } + + return policies.get(0); + } + + /** + * Gets the group having the given name and the maximum version. + * + * @param name name of the desired group + * @return the desired group, or {@code null} if there is no group with given name + * @throws PfModelException if an error occurs + */ + public PdpGroup getPdpGroupMaxVersion(String name) throws PfModelException { + PdpGroupFilter filter = PdpGroupFilter.builder().name(name).build(); + // TODO setLatest + + List<PdpGroup> groups = dao.getFilteredPdpGroups(filter); + if (groups.isEmpty()) { + throw new PolicyPapRuntimeException("cannot find group: " + name); + } + + return groups.get(0); + } + + /** + * Gets the active groups supporting the given policy. + * + * @param type desired policy type + * @return the active groups supporting the given policy + * @throws PfModelException if an error occurs + */ + public List<PdpGroup> getActivePdpGroupsByPolicyType(ToscaPolicyTypeIdentifier type) throws PfModelException { + + PdpGroupFilter filter = PdpGroupFilter.builder().policyType(type).build(); + // TODO setActive, setHasPdps + + return dao.getFilteredPdpGroups(filter); + } + + /** + * Creates a PDP group. + * + * @param pdpGroup the group to be created + * @return the created group + * @throws PfModelException if an error occurs + */ + public PdpGroup createPdpGroup(PdpGroup pdpGroup) throws PfModelException { + newGroups.add(pdpGroup.getName()); + return dao.createPdpGroups(Collections.singletonList(pdpGroup)).get(0); + } + + /** + * Updates a PDP group. + * + * @param pdpGroup the group to be updated + * @return the updated group + * @throws PfModelException if an error occurs + */ + public PdpGroup updatePdpGroup(PdpGroup pdpGroup) throws PfModelException { + return dao.updatePdpGroups(Collections.singletonList(pdpGroup)).get(0); + } +} diff --git a/main/src/test/java/org/onap/policy/pap/main/comm/PdpModifyRequestMapTest.java b/main/src/test/java/org/onap/policy/pap/main/comm/PdpModifyRequestMapTest.java index 8f064035..c36a7d4b 100644 --- a/main/src/test/java/org/onap/policy/pap/main/comm/PdpModifyRequestMapTest.java +++ b/main/src/test/java/org/onap/policy/pap/main/comm/PdpModifyRequestMapTest.java @@ -42,6 +42,7 @@ import java.util.List; import java.util.Map; import java.util.Queue; import java.util.function.Consumer; +import java.util.stream.Collectors; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -56,7 +57,6 @@ import org.onap.policy.models.pdp.concepts.PdpStatus; 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.pap.main.PapConstants; import org.onap.policy.pap.main.comm.PdpModifyRequestMap.ModifyReqData; import org.onap.policy.pap.main.parameters.PdpModifyRequestMapParams; @@ -133,7 +133,8 @@ public class PdpModifyRequestMapTest { response.setState(PdpState.SAFE); response.setPdpGroup(update.getPdpGroup()); response.setPdpSubgroup(update.getPdpSubgroup()); - response.setPolicies(convertToscaPolicyToToscaPolicyIndentifier()); + response.setPolicies(update.getPolicies().stream().map(ToscaPolicy::getIdentifier) + .collect(Collectors.toList())); map = new PdpModifyRequestMap(makeParameters()) { @@ -327,10 +328,13 @@ public class PdpModifyRequestMapTest { public void testModifyReqDataIsActive() { map.addRequest(update); + ModifyReqData reqdata = getReqData(PDP1); + assertNotNull(reqdata); + + // this should remove it from the map invokeProcessResponse(); - // name should have been removed - assertNull(getReqData(PDP1)); + assertFalse(reqdata.isActive()); } @Test @@ -584,18 +588,4 @@ public class PdpModifyRequestMapTest { return cng; } - - /** - * Converts a ToscaPolicy list to ToscaPolicyIdentifier list. - * - * @return the ToscaPolicyIdentifier list - */ - private List<ToscaPolicyIdentifier> convertToscaPolicyToToscaPolicyIndentifier() { - final List<ToscaPolicy> toscaPolicies = update.getPolicies(); - final List<ToscaPolicyIdentifier> toscaPolicyIdentifiers = new ArrayList<>(); - for (final ToscaPolicy toscaPolicy : toscaPolicies) { - toscaPolicyIdentifiers.add(new ToscaPolicyIdentifier(toscaPolicy.getName(), toscaPolicy.getVersion())); - } - return toscaPolicyIdentifiers; - } } diff --git a/main/src/test/java/org/onap/policy/pap/main/comm/msgdata/UpdateDataTest.java b/main/src/test/java/org/onap/policy/pap/main/comm/msgdata/UpdateDataTest.java index 352b92df..bac85ed0 100644 --- a/main/src/test/java/org/onap/policy/pap/main/comm/msgdata/UpdateDataTest.java +++ b/main/src/test/java/org/onap/policy/pap/main/comm/msgdata/UpdateDataTest.java @@ -72,7 +72,7 @@ public class UpdateDataTest { response.setName(MY_NAME); response.setPdpGroup(update.getPdpGroup()); response.setPdpSubgroup(update.getPdpSubgroup()); - response.setPolicies(convertToscaPolicyToToscaPolicyIndentifier(update.getPolicies())); + response.setPolicies(policyToIdent(update.getPolicies())); data = new MyData(update); } @@ -114,24 +114,26 @@ public class UpdateDataTest { } @Test - public void testUpdateDataCheckResponse_MismatchedPoliciesLength() { - response.setPolicies(convertToscaPolicyToToscaPolicyIndentifier(Arrays.asList(update.getPolicies().get(0)))); - - assertEquals("policies do not match", data.checkResponse(response)); - } - - @Test public void testUpdateDataCheckResponse_MismatchedPolicies() { - ArrayList<ToscaPolicyIdentifier> policies = - new ArrayList<>(convertToscaPolicyToToscaPolicyIndentifier(update.getPolicies())); - policies.set(0, new ToscaPolicyIdentifier(DIFFERENT, "10.0.0")); + ArrayList<ToscaPolicy> policies = new ArrayList<>(update.getPolicies()); + policies.set(0, makePolicy(DIFFERENT, "10.0.0")); - response.setPolicies(policies); + response.setPolicies(policyToIdent(policies)); assertEquals("policies do not match", data.checkResponse(response)); } /** + * Converts a list of policies to their corresponding identifiers. + * + * @param policies policies to be converted + * @return a list of policy identifiers + */ + private List<ToscaPolicyIdentifier> policyToIdent(List<ToscaPolicy> policies) { + return policies.stream().map(ToscaPolicy::getIdentifier).collect(Collectors.toList()); + } + + /** * Makes an update message. * * @return a new update message @@ -184,15 +186,4 @@ public class UpdateDataTest { // do nothing } } - - /** - * Converts a ToscaPolicy list to ToscaPolicyIdentifier list. - * - * @param toscaPolicies the list of ToscaPolicy - * @return the ToscaPolicyIdentifier list - */ - private List<ToscaPolicyIdentifier> convertToscaPolicyToToscaPolicyIndentifier(List<ToscaPolicy> toscaPolicies) { - return toscaPolicies.stream().map(policy -> new ToscaPolicyIdentifier(policy.getName(), policy.getVersion())) - .collect(Collectors.toList()); - } } diff --git a/main/src/test/java/org/onap/policy/pap/main/internal/TestModels.java b/main/src/test/java/org/onap/policy/pap/main/internal/TestModels.java deleted file mode 100644 index 7cdd06ee..00000000 --- a/main/src/test/java/org/onap/policy/pap/main/internal/TestModels.java +++ /dev/null @@ -1,46 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2019 Nordix Foundation. - * Modifications Copyright (C) 2019 AT&T Intellectual Property. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.pap.main.internal; - -import com.openpojo.reflection.filters.FilterPackageInfo; -import com.openpojo.validation.Validator; -import com.openpojo.validation.ValidatorBuilder; -import com.openpojo.validation.test.impl.GetterTester; -import com.openpojo.validation.test.impl.SetterTester; - -import org.junit.Test; -import org.onap.policy.common.utils.validation.ToStringTester; - -/** - * Class to perform unit testing of models. - * - * @author Ram Krishna Verma (ram.krishna.verma@est.tech) - */ -public class TestModels { - - @Test - public void testPapModels() { - final Validator validator = ValidatorBuilder.create().with(new ToStringTester()).with(new SetterTester()) - .with(new GetterTester()).build(); - validator.validate(TestModels.class.getPackage().getName(), new FilterPackageInfo()); - } -} diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/ProviderSuper.java b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/ProviderSuper.java new file mode 100644 index 00000000..3a3673d5 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/ProviderSuper.java @@ -0,0 +1,225 @@ +/* + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.rest.depundep; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import org.junit.Before; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.common.utils.services.Registry; +import org.onap.policy.models.pdp.concepts.PdpGroup; +import org.onap.policy.models.pdp.concepts.PdpUpdate; +import org.onap.policy.models.provider.PolicyModelsProvider; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.pap.main.PapConstants; +import org.onap.policy.pap.main.PolicyModelsProviderFactoryWrapper; +import org.onap.policy.pap.main.comm.PdpModifyRequestMap; + +/** + * Super class for TestPdpGroupDeployProviderXxx classes. + */ +public class ProviderSuper { + private static final Coder coder = new StandardCoder(); + + @Mock + protected PolicyModelsProvider dao; + + /** + * Used to capture input to dao.createPdpGroups(). + */ + @Captor + private ArgumentCaptor<List<PdpGroup>> createCaptor; + + + /** + * Used to capture input to dao.updatePdpGroups(). + */ + @Captor + private ArgumentCaptor<List<PdpGroup>> updateCaptor; + + protected Object lockit; + protected PdpModifyRequestMap reqmap; + protected PolicyModelsProviderFactoryWrapper daofact; + protected ToscaPolicy policy1; + + + /** + * Configures DAO, captors, and various mocks. + */ + @Before + public void setUp() throws Exception { + + Registry.newRegistry(); + + MockitoAnnotations.initMocks(this); + + reqmap = mock(PdpModifyRequestMap.class); + + lockit = new Object(); + daofact = mock(PolicyModelsProviderFactoryWrapper.class); + policy1 = loadFile("policy.json", ToscaPolicy.class); + + when(daofact.create()).thenReturn(dao); + + List<PdpGroup> groups = loadGroups("groups.json"); + + when(dao.getFilteredPdpGroups(any())).thenReturn(groups); + + when(dao.createPdpGroups(any())).thenAnswer(answer -> answer.getArgumentAt(0, List.class)); + when(dao.updatePdpGroups(any())).thenAnswer(answer -> answer.getArgumentAt(0, List.class)); + + Registry.register(PapConstants.REG_PDP_MODIFY_LOCK, lockit); + Registry.register(PapConstants.REG_PDP_MODIFY_MAP, reqmap); + Registry.register(PapConstants.REG_PAP_DAO_FACTORY, daofact); + } + + protected void assertGroup(List<PdpGroup> groups, String name, String version) { + PdpGroup group = groups.remove(0); + + assertEquals(name, group.getName()); + assertEquals(version, group.getVersion()); + } + + protected void assertUpdateIgnorePolicy(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()); + } + + /** + * Gets the input to the method. + * + * @param count the number of times the method is expected to have been called. + * @return the input that was passed to the dao.createPdpGroups() method + * @throws Exception if an error occurred + */ + protected List<List<PdpGroup>> getGroupCreates(int count) throws Exception { + verify(dao, times(count)).createPdpGroups(createCaptor.capture()); + + return copyLists(createCaptor.getAllValues()); + } + + /** + * Gets the input to the method. + * + * @param count the number of times the method is expected to have been called + * @return the input that was passed to the dao.updatePdpGroups() method + * @throws Exception if an error occurred + */ + protected List<List<PdpGroup>> getGroupUpdates(int count) throws Exception { + verify(dao, times(count)).updatePdpGroups(updateCaptor.capture()); + + return copyLists(updateCaptor.getAllValues()); + } + + /** + * Gets the updates that were added to the request map. + * + * @param count the number of times the method is expected to have been called + * @return the updates that were added to the request map + */ + protected List<PdpUpdate> getUpdateRequests(int count) { + ArgumentCaptor<PdpUpdate> captor = ArgumentCaptor.forClass(PdpUpdate.class); + + verify(reqmap, times(count)).addRequest(captor.capture()); + + return new ArrayList<>(captor.getAllValues()); + } + + /** + * Makes a partly deep copy of the list. + * + * @param source source list to copy + * @return a copy of the source list + */ + private List<List<PdpGroup>> copyLists(List<List<PdpGroup>> source) { + List<List<PdpGroup>> target = new ArrayList<>(source.size()); + + for (List<PdpGroup> lst : source) { + target.add(new ArrayList<>(lst)); + } + + return target; + } + + /** + * Loads a list of groups. + * + * @param fileName name of the file from which to load + * @return a list of groups + */ + protected List<PdpGroup> loadGroups(String fileName) { + return loadFile(fileName, org.onap.policy.models.pdp.concepts.PdpGroups.class).getGroups(); + } + + /** + * Loads a list of policies. + * + * @param fileName name of the file from which to load + * @return a list of policies + */ + protected List<ToscaPolicy> loadPolicies(String fileName) { + return loadFile(fileName, PolicyList.class).policies; + } + + /** + * Loads an object from a JSON file. + * + * @param fileName name of the file from which to load + * @param clazz the class of the object to be loaded + * @return the object that was loaded from the file + */ + protected <T> T loadFile(String fileName, Class<T> clazz) { + File propFile = new File(ResourceUtils.getFilePath4Resource("simpleDeploy/" + fileName)); + try { + return coder.decode(propFile, clazz); + + } catch (CoderException e) { + throw new RuntimeException(e); + } + } + + /** + * Wraps a list of policies. The decoder doesn't work with generic lists, so we wrap + * the list and decode it into the wrapper before extracting the list contents. + */ + private static class PolicyList { + private List<ToscaPolicy> policies; + } +} diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupDeployControllerV1.java b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeployControllerV1.java index 09e91a99..73a4f0e5 100644 --- a/main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupDeployControllerV1.java +++ b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeployControllerV1.java @@ -1,4 +1,4 @@ -/*- +/* * ============LICENSE_START======================================================= * Copyright (C) 2019 Nordix Foundation. * Modifications Copyright (C) 2019 AT&T Intellectual Property. @@ -19,10 +19,10 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.pap.main.rest; +package org.onap.policy.pap.main.rest.depundep; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertNotNull; import java.util.Arrays; import javax.ws.rs.client.Entity; @@ -35,6 +35,7 @@ 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.tosca.authorative.concepts.ToscaPolicyIdentifierOptVersion; +import org.onap.policy.pap.main.rest.CommonPapRestServer; public class TestPdpGroupDeployControllerV1 extends CommonPapRestServer { @@ -49,18 +50,18 @@ public class TestPdpGroupDeployControllerV1 extends CommonPapRestServer { @Test public void testDeployGroup() throws Exception { - final Entity<PdpGroup> entgrp = makePdpGroupEntity(); + Entity<PdpGroup> entgrp = makePdpGroupEntity(); - final Invocation.Builder invocationBuilder = sendRequest(DEPLOY_GROUP_ENDPOINT); + Invocation.Builder invocationBuilder = sendRequest(DEPLOY_GROUP_ENDPOINT); Response rawresp = invocationBuilder.post(entgrp); PdpGroupDeployResponse resp = rawresp.readEntity(PdpGroupDeployResponse.class); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); - assertNull(resp.getErrorDetails()); + assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rawresp.getStatus()); + assertNotNull(resp.getErrorDetails()); rawresp = invocationBuilder.post(entgrp); resp = rawresp.readEntity(PdpGroupDeployResponse.class); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); - assertNull(resp.getErrorDetails()); + assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rawresp.getStatus()); + assertNotNull(resp.getErrorDetails()); // verify it fails when no authorization info is included checkUnauthRequest(DEPLOY_GROUP_ENDPOINT, req -> req.post(entgrp)); @@ -68,28 +69,28 @@ public class TestPdpGroupDeployControllerV1 extends CommonPapRestServer { @Test public void testDeployPolicies() throws Exception { - final Entity<PdpDeployPolicies> entgrp = makePdpPoliciesEntity(); + Entity<PdpDeployPolicies> entgrp = makePdpPoliciesEntity(); - final Invocation.Builder invocationBuilder = sendRequest(DEPLOY_POLICIES_ENDPOINT); + Invocation.Builder invocationBuilder = sendRequest(DEPLOY_POLICIES_ENDPOINT); Response rawresp = invocationBuilder.post(entgrp); PdpGroupDeployResponse resp = rawresp.readEntity(PdpGroupDeployResponse.class); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); - assertNull(resp.getErrorDetails()); + assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rawresp.getStatus()); + assertNotNull(resp.getErrorDetails()); rawresp = invocationBuilder.post(entgrp); resp = rawresp.readEntity(PdpGroupDeployResponse.class); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); - assertNull(resp.getErrorDetails()); + assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rawresp.getStatus()); + assertNotNull(resp.getErrorDetails()); // verify it fails when no authorization info is included checkUnauthRequest(DEPLOY_POLICIES_ENDPOINT, req -> req.post(entgrp)); } private Entity<PdpGroup> makePdpGroupEntity() { - final PdpSubGroup subgrp = new PdpSubGroup(); + PdpSubGroup subgrp = new PdpSubGroup(); subgrp.setPdpType("drools"); - final PdpGroup group = new PdpGroup(); + PdpGroup group = new PdpGroup(); group.setName("drools-group"); group.setDescription("my description"); group.setVersion("my-version"); @@ -99,14 +100,10 @@ public class TestPdpGroupDeployControllerV1 extends CommonPapRestServer { } private Entity<PdpDeployPolicies> makePdpPoliciesEntity() { - final ToscaPolicyIdentifierOptVersion pol1 = new ToscaPolicyIdentifierOptVersion(); - pol1.setName("policy-a"); - pol1.setVersion("1"); + ToscaPolicyIdentifierOptVersion pol1 = new ToscaPolicyIdentifierOptVersion("policy-a", "1"); + ToscaPolicyIdentifierOptVersion pol2 = new ToscaPolicyIdentifierOptVersion("policy-b", null); - final ToscaPolicyIdentifierOptVersion pol2 = new ToscaPolicyIdentifierOptVersion(); - pol2.setName("policy-b"); - - final PdpDeployPolicies policies = new PdpDeployPolicies(); + PdpDeployPolicies policies = new PdpDeployPolicies(); policies.setPolicies(Arrays.asList(pol1, pol2)); return Entity.entity(policies, MediaType.APPLICATION_JSON); diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeployProvider.java b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeployProvider.java new file mode 100644 index 00000000..d3ffda84 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestPdpGroupDeployProvider.java @@ -0,0 +1,214 @@ +/* + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.rest.depundep; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +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 static org.onap.policy.pap.main.rest.depundep.ProviderBase.DB_ERROR_MSG; + +import java.util.List; +import javax.ws.rs.core.Response.Status; +import org.apache.commons.lang3.tuple.Pair; +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.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.PdpUpdate; +import org.onap.policy.pap.main.rest.depundep.PdpGroupDeployProvider; + +public class TestPdpGroupDeployProvider extends ProviderSuper { + private static final String EXPECTED_EXCEPTION = "expected exception"; + private static final Object REQUEST_FAILED_MSG = "request failed"; + + private static final String POLICY1_NAME = "policyA"; + private static final String POLICY1_VERSION = "1.2.3"; + private static final String GROUP1_NAME = "groupA"; + private static final String GROUP1_VERSION = "200.2.3"; + private static final String GROUP1_NEW_VERSION = "201.0.0"; + private static final String PDP1_TYPE = "pdpTypeA"; + private static final String PDP2_TYPE = "pdpTypeB"; + private static final String PDP4_TYPE = "pdpTypeD"; + private static final String PDP2 = "pdpB"; + private static final String PDP4 = "pdpD"; + + private PdpGroupDeployProvider prov; + + + @AfterClass + public static void tearDownAfterClass() { + Registry.newRegistry(); + } + + /** + * Configures mocks and objects. + * + * @throws Exception if an error occurs + */ + @Before + public void setUp() throws Exception { + + super.setUp(); + + when(dao.getPolicyList(POLICY1_NAME, POLICY1_VERSION)).thenReturn(loadPolicies("daoPolicyList.json")); + + prov = new PdpGroupDeployProvider(); + } + + @Test + public void testDeployGroup() { + Pair<Status, PdpGroupDeployResponse> pair = prov.deployGroup(new PdpGroups()); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertEquals("not implemented yet", pair.getRight().getErrorDetails()); + } + + @Test + public void testDeployPolicies() { + Pair<Status, PdpGroupDeployResponse> pair = prov.deployPolicies(loadEmptyRequest()); + assertEquals(Status.OK, pair.getLeft()); + assertNull(pair.getRight().getErrorDetails()); + } + + @Test + public void testDeploySimplePolicies() throws Exception { + Pair<Status, PdpGroupDeployResponse> pair = prov.deployPolicies(loadRequest()); + assertEquals(Status.OK, pair.getLeft()); + assertNull(pair.getRight().getErrorDetails()); + } + + @Test + public void testDeploySimplePolicies_DaoEx() throws Exception { + when(dao.getFilteredPdpGroups(any())).thenThrow(new PfModelException(Status.BAD_REQUEST, EXPECTED_EXCEPTION)); + + Pair<Status, PdpGroupDeployResponse> pair = prov.deployPolicies(loadRequest()); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertEquals(DB_ERROR_MSG, pair.getRight().getErrorDetails()); + } + + @Test + public void testDeploySimplePolicies_RuntimeEx() throws Exception { + when(dao.getPolicyList(any(), any())).thenThrow(new RuntimeException(EXPECTED_EXCEPTION)); + + Pair<Status, PdpGroupDeployResponse> pair = prov.deployPolicies(loadRequest()); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertEquals(REQUEST_FAILED_MSG, pair.getRight().getErrorDetails()); + } + + @Test + public void testDeploySimplePolicies_NoGroups() throws Exception { + when(dao.getFilteredPdpGroups(any())).thenReturn(loadGroups("emptyGroups.json")); + + Pair<Status, PdpGroupDeployResponse> pair = prov.deployPolicies(loadRequest()); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertEquals("policy not supported by any PDP group: policyA 1.2.3", pair.getRight().getErrorDetails()); + } + + @Test + public void testMakeUpdater() throws Exception { + /* + * Each subgroup has a different PDP type and name. + * + * Type is not supported by the first subgroup. + * + * Second subgroup matches. + * + * Third subgroup already contains the policy. + * + * Last subgroup matches. + */ + + when(dao.getFilteredPdpGroups(any())).thenReturn(loadGroups("upgradeGroupDao.json")); + + Pair<Status, PdpGroupDeployResponse> pair = prov.deployPolicies(loadRequest()); + assertEquals(Status.OK, pair.getLeft()); + assertNull(pair.getRight().getErrorDetails()); + + assertGroup(getGroupUpdates(1).get(0), GROUP1_NAME, GROUP1_VERSION); + assertGroup(getGroupCreates(1).get(0), GROUP1_NAME, GROUP1_NEW_VERSION); + + List<PdpUpdate> requests = getUpdateRequests(2); + assertUpdate(requests, GROUP1_NAME, PDP2_TYPE, PDP2); + assertUpdate(requests, GROUP1_NAME, PDP4_TYPE, PDP4); + } + + @Test + public void testMakeUpdater_NoPdps() throws Exception { + + // subgroup has no PDPs + when(dao.getFilteredPdpGroups(any())).thenReturn(loadGroups("upgradeGroup_NoPdpsDao.json")); + + Pair<Status, PdpGroupDeployResponse> pair = prov.deployPolicies(loadRequest()); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertEquals("group " + GROUP1_NAME + " subgroup " + PDP1_TYPE + " has no active PDPs", + pair.getRight().getErrorDetails()); + + verify(dao, never()).createPdpGroups(any()); + verify(dao, never()).updatePdpGroups(any()); + verify(reqmap, never()).addRequest(any(PdpUpdate.class)); + } + + + 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)); + } + + /** + * Loads a standard request. + * + * @return a standard request + */ + protected PdpDeployPolicies loadRequest() { + return loadRequest("request.json"); + } + + /** + * Loads a request from a JSON file. + * + * @param fileName name of the file from which to load + * @return the request that was loaded + */ + protected PdpDeployPolicies loadRequest(String fileName) { + return loadFile(fileName, PdpDeployPolicies.class); + } + + /** + * Loads an empty request. + * + * @return an empty request + */ + protected PdpDeployPolicies loadEmptyRequest() { + return loadRequest("emptyRequest.json"); + } +} diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestProviderBase.java b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestProviderBase.java new file mode 100644 index 00000000..f64f77da --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestProviderBase.java @@ -0,0 +1,421 @@ +/* + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.rest.depundep; + +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 static org.onap.policy.pap.main.rest.depundep.ProviderBase.DB_ERROR_MSG; + +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.function.BiFunction; +import javax.ws.rs.core.Response.Status; +import org.apache.commons.lang3.tuple.Pair; +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.pap.concepts.PdpDeployPolicies; +import org.onap.policy.models.pap.concepts.SimpleResponse; +import org.onap.policy.models.pdp.concepts.PdpGroup; +import org.onap.policy.models.pdp.concepts.PdpSubGroup; +import org.onap.policy.models.pdp.concepts.PdpUpdate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifierOptVersion; +import org.onap.policy.pap.main.PolicyPapRuntimeException; +import org.powermock.reflect.Whitebox; + +public class TestProviderBase extends ProviderSuper { + private static final String EXPECTED_EXCEPTION = "expected exception"; + private static final Object REQUEST_FAILED_MSG = "request failed"; + + private static final String POLICY1_NAME = "policyA"; + private static final String POLICY1_VERSION = "1.2.3"; + private static final String GROUP1_NAME = "groupA"; + private static final String GROUP1_VERSION = "200.2.3"; + private static final String GROUP1_NEW_VERSION = "201.0.0"; + private static final String GROUP2_NAME = "groupB"; + private static final String PDP1_TYPE = "pdpTypeA"; + private static final String PDP2_TYPE = "pdpTypeB"; + private static final String PDP3_TYPE = "pdpTypeC"; + private static final String PDP4_TYPE = "pdpTypeD"; + private static final String PDP1 = "pdpA"; + private static final String PDP2 = "pdpB"; + private static final String PDP3 = "pdpC"; + private static final String PDP4 = "pdpD"; + + private MyProvider prov; + + + @AfterClass + public static void tearDownAfterClass() { + Registry.newRegistry(); + } + + /** + * Configures mocks and objects. + * + * @throws Exception if an error occurs + */ + @Before + public void setUp() throws Exception { + + super.setUp(); + + when(dao.getPolicyList(POLICY1_NAME, POLICY1_VERSION)).thenReturn(loadPolicies("daoPolicyList.json")); + + prov = new MyProvider(); + } + + @Test + public void testProviderBase() { + assertSame(lockit, Whitebox.getInternalState(prov, "updateLock")); + assertSame(reqmap, Whitebox.getInternalState(prov, "requestMap")); + assertSame(daofact, Whitebox.getInternalState(prov, "daoFactory")); + } + + @Test + public void testProcess() throws Exception { + Pair<Status, MyResponse> pair = prov.process(loadRequest(), this::handle); + assertEquals(Status.OK, pair.getLeft()); + assertNull(pair.getRight().getErrorDetails()); + + assertGroup(getGroupUpdates(1).get(0), GROUP1_NAME, GROUP1_VERSION); + assertGroup(getGroupCreates(1).get(0), GROUP1_NAME, GROUP1_NEW_VERSION); + + assertUpdate(getUpdateRequests(1), GROUP1_NAME, PDP1_TYPE, PDP1); + } + + @Test + public void testProcess_CreateEx() throws Exception { + when(daofact.create()).thenThrow(new PfModelException(Status.BAD_REQUEST, EXPECTED_EXCEPTION)); + + Pair<Status, MyResponse> pair = prov.process(loadEmptyRequest(), this::handle); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertEquals(DB_ERROR_MSG, pair.getRight().getErrorDetails()); + } + + @Test + public void testProcess_PapEx() throws Exception { + when(daofact.create()).thenThrow(new PolicyPapRuntimeException(EXPECTED_EXCEPTION)); + + Pair<Status, MyResponse> pair = prov.process(loadEmptyRequest(), this::handle); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertEquals(EXPECTED_EXCEPTION, pair.getRight().getErrorDetails()); + } + + @Test + public void testProcess_RuntimeEx() throws Exception { + when(daofact.create()).thenThrow(new RuntimeException(EXPECTED_EXCEPTION)); + + Pair<Status, MyResponse> pair = prov.process(loadEmptyRequest(), this::handle); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertEquals(REQUEST_FAILED_MSG, pair.getRight().getErrorDetails()); + } + + @Test + public void testProcessPolicy_NoGroups() throws Exception { + when(dao.getFilteredPdpGroups(any())).thenReturn(Collections.emptyList()); + + SessionData session = new SessionData(dao); + ToscaPolicyIdentifierOptVersion ident = new ToscaPolicyIdentifierOptVersion(POLICY1_NAME, POLICY1_VERSION); + assertThatThrownBy(() -> prov.processPolicy(session, ident)).isInstanceOf(PolicyPapRuntimeException.class) + .hasMessage("policy not supported by any PDP group: policyA 1.2.3"); + + } + + @Test + public void testGetPolicy() throws Exception { + Pair<Status, MyResponse> pair = prov.process(loadRequest(), this::handle); + assertEquals(Status.OK, pair.getLeft()); + assertNull(pair.getRight().getErrorDetails()); + + verify(dao).getPolicyList(any(), any()); + verify(dao, never()).getFilteredPolicyList(any()); + } + + @Test + public void testGetPolicy_NullVersion() throws Exception { + // only allow this query once + when(dao.getPolicyList(POLICY1_NAME, POLICY1_VERSION)).thenReturn(loadPolicies("daoPolicyList.json")) + .thenThrow(new RuntimeException(EXPECTED_EXCEPTION)); + + when(dao.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyList.json")); + + Pair<Status, MyResponse> pair = prov.process(loadRequest("getPolicyReqNullVersion.json"), this::handle); + assertEquals(Status.OK, pair.getLeft()); + assertNull(pair.getRight().getErrorDetails()); + + verify(dao).getFilteredPolicyList(any()); + verify(dao, never()).getPolicies(any(), any()); + } + + @Test + public void testGetPolicy_NotFound() throws Exception { + when(dao.getPolicyList(any(), any())).thenReturn(Collections.emptyList()); + + Pair<Status, MyResponse> pair = prov.process(loadRequest(), this::handle); + assertEquals(Status.INTERNAL_SERVER_ERROR, pair.getLeft()); + assertEquals("cannot find policy: " + POLICY1_NAME + " " + POLICY1_VERSION, pair.getRight().getErrorDetails()); + } + + @Test + public void testGetGroup() throws Exception { + when(dao.getFilteredPdpGroups(any())).thenReturn(loadGroups("getGroupDao.json")) + .thenReturn(loadGroups("groups.json")); + + Pair<Status, MyResponse> pair = prov.process(loadRequest(), this::handle); + assertEquals(Status.OK, pair.getLeft()); + assertNull(pair.getRight().getErrorDetails()); + + assertGroup(getGroupUpdates(1).get(0), GROUP1_NAME, GROUP1_VERSION); + assertGroup(getGroupCreates(1).get(0), GROUP1_NAME, GROUP1_NEW_VERSION); + } + + @Test + public void testUpgradeGroup() throws Exception { + /* + * Each subgroup has a different PDP type and name. + * + * Type is not supported by the first subgroup. + * + * Second subgroup matches. + * + * Third subgroup already contains the policy. + * + * Last subgroup matches. + */ + + when(dao.getFilteredPdpGroups(any())).thenReturn(loadGroups("upgradeGroupDao.json")); + + prov.clear(); + prov.add(false, true, false, true); + + Pair<Status, MyResponse> pair = prov.process(loadRequest(), this::handle); + assertEquals(Status.OK, pair.getLeft()); + assertNull(pair.getRight().getErrorDetails()); + + assertGroup(getGroupUpdates(1).get(0), GROUP1_NAME, GROUP1_VERSION); + assertGroup(getGroupCreates(1).get(0), GROUP1_NAME, GROUP1_NEW_VERSION); + + List<PdpUpdate> requests = getUpdateRequests(2); + assertUpdate(requests, GROUP1_NAME, PDP2_TYPE, PDP2); + assertUpdate(requests, GROUP1_NAME, PDP4_TYPE, PDP4); + } + + @Test + public void testUpgradeGroup_Multiple() throws Exception { + /* + * Policy data in the DB: policy1=type1, policy2=type2, policy3=type3, + * policy4=type1 + * + * Group data in the DB: group1=(type1=pdp1, type3=pdp3) group2=(type2=pdp2) + * + * Request specifies: policy1, policy2, policy3, policy4 + * + * Should create new versions of group1 and group2. + * + * Should update old versions of group1 and group2. Should also update new version + * of group1 twice. + * + * Should generate updates to pdp1, pdp2, and pdp3. + */ + + when(dao.getPolicyList(POLICY1_NAME, POLICY1_VERSION)).thenReturn(loadPolicies("daoPolicyList.json")); + when(dao.getPolicyList("policyB", POLICY1_VERSION)).thenReturn(loadPolicies("upgradeGroupPolicy2.json")); + when(dao.getPolicyList("policyC", POLICY1_VERSION)).thenReturn(loadPolicies("upgradeGroupPolicy3.json")); + when(dao.getPolicyList("policyD", POLICY1_VERSION)).thenReturn(loadPolicies("upgradeGroupPolicy4.json")); + + List<PdpGroup> groups1 = loadGroups("upgradeGroupGroup1.json"); + List<PdpGroup> groups2 = loadGroups("upgradeGroupGroup2.json"); + + /* + * these are in pairs of (get-group, get-max-group) matching each policy in the + * request + */ + // @formatter:off + when(dao.getFilteredPdpGroups(any())) + .thenReturn(groups1).thenReturn(groups1) + .thenReturn(groups2).thenReturn(groups2) + .thenReturn(groups1).thenReturn(groups1) + .thenReturn(groups1).thenReturn(groups1); + // @formatter:on + + // multiple policies in the request + PdpDeployPolicies request = loadFile("updateGroupReqMultiple.json", PdpDeployPolicies.class); + + Pair<Status, MyResponse> pair = prov.process(request, (data, deploy) -> { + for (ToscaPolicyIdentifierOptVersion policy : deploy.getPolicies()) { + handle(data, policy); + } + }); + + assertEquals(Status.OK, pair.getLeft()); + assertNull(pair.getRight().getErrorDetails()); + + List<List<PdpGroup>> creates = getGroupCreates(2); + assertGroup(creates.get(0), GROUP1_NAME, GROUP1_NEW_VERSION); + assertGroup(creates.get(1), GROUP2_NAME, "301.0.0"); + + List<List<PdpGroup>> updates = getGroupUpdates(4); + assertGroup(updates.get(0), GROUP1_NAME, GROUP1_VERSION); + assertGroup(updates.get(1), GROUP2_NAME, "300.2.3"); + assertGroup(updates.get(2), GROUP1_NAME, GROUP1_NEW_VERSION); + assertGroup(updates.get(3), GROUP1_NAME, GROUP1_NEW_VERSION); + + List<PdpUpdate> requests = getUpdateRequests(3); + assertUpdateIgnorePolicy(requests, GROUP1_NAME, PDP1_TYPE, PDP1); + assertUpdateIgnorePolicy(requests, GROUP2_NAME, PDP2_TYPE, PDP2); + assertUpdateIgnorePolicy(requests, GROUP1_NAME, PDP3_TYPE, PDP3); + } + + @Test + public void testUpgradeGroup_NothingUpdated() throws Exception { + prov.clear(); + prov.add(false); + + Pair<Status, MyResponse> pair = prov.process(loadRequest(), this::handle); + assertEquals(Status.OK, pair.getLeft()); + assertNull(pair.getRight().getErrorDetails()); + + verify(dao, never()).createPdpGroups(any()); + verify(dao, never()).updatePdpGroups(any()); + verify(reqmap, never()).addRequest(any(PdpUpdate.class)); + } + + + 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)); + } + + /** + * Loads a standard request. + * + * @return a standard request + */ + protected ToscaPolicyIdentifierOptVersion loadRequest() { + return loadRequest("requestBase.json"); + } + + /** + * Loads a request from a JSON file. + * + * @param fileName name of the file from which to load + * @return the request that was loaded + */ + protected ToscaPolicyIdentifierOptVersion loadRequest(String fileName) { + return loadFile(fileName, ToscaPolicyIdentifierOptVersion.class); + } + + /** + * Loads an empty request. + * + * @return an empty request + */ + protected ToscaPolicyIdentifierOptVersion loadEmptyRequest() { + return loadRequest("emptyRequestBase.json"); + } + + /** + * Handles a request by invoking the provider's processPolicy method. + * + * @param data session data + * @param request request to be handled + */ + private void handle(SessionData data, ToscaPolicyIdentifierOptVersion request) { + try { + prov.processPolicy(data, request); + + } catch (PfModelException e) { + throw new PolicyPapRuntimeException(e); + } + } + + + private static class MyProvider extends ProviderBase<MyResponse> { + /** + * Used to determine whether or not to make an update when + * {@link #makeUpdater(ToscaPolicy)} is called. The updater function removes an + * item from this queue each time it is invoked. + */ + private final Queue<Boolean> shouldUpdate = new LinkedList<>(); + + /** + * Constructs the object and queues up several successful updates. + */ + public MyProvider() { + for (int x = 0; x < 10; ++x) { + shouldUpdate.add(true); + } + } + + public void clear() { + shouldUpdate.clear(); + } + + public void add(Boolean... update) { + shouldUpdate.addAll(Arrays.asList(update)); + } + + @Override + public MyResponse makeResponse(String errorMsg) { + return new MyResponse(errorMsg); + } + + @Override + protected BiFunction<PdpGroup, PdpSubGroup, Boolean> makeUpdater(ToscaPolicy policy) { + return (group, subgroup) -> { + if (shouldUpdate.remove()) { + // queue indicated that the update should succeed + subgroup.getPolicies().add(policy.getIdentifier()); + return true; + + } else { + // queue indicated that no update should be made this time + return false; + } + }; + } + } + + private static class MyResponse extends SimpleResponse { + public MyResponse(String errorMsg) { + setErrorDetails(errorMsg); + } + } +} diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestSessionData.java b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestSessionData.java new file mode 100644 index 00000000..6be5c8ac --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/rest/depundep/TestSessionData.java @@ -0,0 +1,258 @@ +/* + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.rest.depundep; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import javax.ws.rs.core.Response.Status; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.pdp.concepts.PdpGroup; +import org.onap.policy.models.pdp.concepts.PdpUpdate; +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.PolicyPapRuntimeException; + +public class TestSessionData extends ProviderSuper { + private static final String GROUP_VERSION_PREFIX = "9.8."; + private static final String GROUP_NAME = "group"; + private static final String GROUP_VERSION = GROUP_VERSION_PREFIX + "7"; + private static final String GROUP_NAME2 = "group2"; + private static final String GROUP_VERSION2 = GROUP_VERSION_PREFIX + "6"; + private static final String PDP1 = "pdp_1"; + private static final String PDP2 = "pdp_2"; + private static final String PDP3 = "pdp_3"; + private static final String POLICY_VERSION_PREFIX = "1.2."; + private static final String POLICY_NAME = "myPolicy"; + private static final String POLICY_VERSION = POLICY_VERSION_PREFIX + "3"; + private static final String POLICY_VERSION2 = POLICY_VERSION_PREFIX + "4"; + + private SessionData session; + private ToscaPolicyIdentifier ident; + + /** + * Initializes mocks and a session. + * + * @throws Exception if an error occurs + */ + @Before + public void setUp() throws Exception { + super.setUp(); + + ident = new ToscaPolicyIdentifier(POLICY_NAME, POLICY_VERSION); + + session = new SessionData(dao); + } + + @Test + public void testGetPolicy() throws Exception { + ToscaPolicy policy1 = makePolicy(POLICY_NAME, POLICY_VERSION); + when(dao.getPolicyList(POLICY_NAME, POLICY_VERSION)).thenReturn(Arrays.asList(policy1)); + + ToscaPolicy policy2 = makePolicy(POLICY_NAME, POLICY_VERSION2); + when(dao.getPolicyList(POLICY_NAME, POLICY_VERSION2)).thenReturn(Arrays.asList(policy2)); + + ToscaPolicyIdentifier ident2 = new ToscaPolicyIdentifier(POLICY_NAME, POLICY_VERSION2); + + assertSame(policy1, session.getPolicy(ident)); + assertSame(policy2, session.getPolicy(ident2)); + + // repeat + assertSame(policy1, session.getPolicy(ident)); + assertSame(policy2, session.getPolicy(ident2)); + + assertSame(policy1, session.getPolicy(ident)); + assertSame(policy2, session.getPolicy(ident2)); + + // should have only invoked this once for each policy + verify(dao, times(2)).getPolicyList(any(), any()); + } + + @Test + public void testGetPolicy_NotFound() throws Exception { + when(dao.getPolicyList(any(), any())).thenReturn(Collections.emptyList()); + + assertThatThrownBy(() -> session.getPolicy(ident)).hasMessage("cannot find policy: myPolicy 1.2.3"); + } + + @Test + public void testGetPolicy_TooMany() throws Exception { + ToscaPolicy policy = new ToscaPolicy(); + when(dao.getPolicyList(any(), any())).thenReturn(Arrays.asList(policy, policy)); + + assertThatThrownBy(() -> session.getPolicy(ident)).hasMessage("too many policies match: myPolicy 1.2.3"); + } + + @Test + public void testGetPolicy_DaoEx() throws Exception { + PfModelException ex = new PfModelException(Status.INTERNAL_SERVER_ERROR, "expected exception"); + when(dao.getPolicyList(any(), any())).thenThrow(ex); + + assertThatThrownBy(() -> session.getPolicy(ident)).hasMessage("cannot get policy: myPolicy 1.2.3").hasCause(ex); + } + + @Test + public void testAddUpdate() { + // several different updates, but one duplicate + PdpUpdate update1 = makeUpdate(PDP1); + session.addUpdate(update1); + + PdpUpdate update2 = makeUpdate(PDP2); + session.addUpdate(update2); + + PdpUpdate update3 = makeUpdate(PDP3); + session.addUpdate(update3); + + List<PdpUpdate> lst = sort(session.getUpdates(), this::compare); + assertEquals(Arrays.asList(update1, update2, update3).toString(), lst.toString()); + + // overwrite one + update2 = makeUpdate(PDP2); + session.addUpdate(update2); + + lst = sort(session.getUpdates(), this::compare); + assertEquals(Arrays.asList(update1, update2, update3).toString(), lst.toString()); + } + + private ToscaPolicy makePolicy(String name, String version) { + ToscaPolicy policy = new ToscaPolicy(); + + policy.setName(name); + policy.setVersion(version); + + return policy; + } + + @Test + public void testGetPolicyMaxVersion() throws Exception { + ToscaPolicy policy1 = makePolicy(POLICY_NAME, POLICY_VERSION); + + when(dao.getFilteredPolicyList(any())).thenReturn(Arrays.asList(policy1)); + + assertSame(policy1, session.getPolicyMaxVersion(POLICY_NAME)); + + // no matching policies - should throw an exception + when(dao.getFilteredPolicyList(any())).thenReturn(Collections.emptyList()); + assertThatThrownBy(() -> session.getPolicyMaxVersion(POLICY_NAME)).hasMessage("cannot find policy: myPolicy"); + } + + @Test + public void testIsNewlyCreated_testCreatePdpGroup() throws Exception { + assertFalse(session.isNewlyCreated(GROUP_NAME)); + + PdpGroup group1 = makeGroup(GROUP_NAME, GROUP_VERSION); + when(dao.createPdpGroups(any())).thenReturn(Arrays.asList(group1)); + + session.createPdpGroup(group1); + + assertTrue(session.isNewlyCreated(GROUP_NAME)); + assertFalse(session.isNewlyCreated(GROUP_NAME2)); + + PdpGroup group2 = makeGroup(GROUP_NAME2, GROUP_VERSION2); + when(dao.createPdpGroups(any())).thenReturn(Arrays.asList(group2)); + session.createPdpGroup(group2); + + List<List<PdpGroup>> creates = getGroupCreates(2); + assertEquals(group1, creates.get(0).get(0)); + assertEquals(group2, creates.get(1).get(0)); + + assertTrue(session.isNewlyCreated(GROUP_NAME)); + assertTrue(session.isNewlyCreated(GROUP_NAME2)); + } + + private PdpGroup makeGroup(String name, String version) { + PdpGroup group = new PdpGroup(); + + group.setName(name); + group.setVersion(version); + + return group; + } + + @Test + public void testGetPdpGroupMaxVersion() throws Exception { + PdpGroup group = makeGroup(GROUP_NAME, GROUP_VERSION); + when(dao.getFilteredPdpGroups(any())).thenReturn(Arrays.asList(group)); + + assertEquals(group, session.getPdpGroupMaxVersion(GROUP_NAME)); + + // try empty list + when(dao.getFilteredPdpGroups(any())).thenReturn(Collections.emptyList()); + assertThatThrownBy(() -> session.getPdpGroupMaxVersion(GROUP_NAME)) + .isInstanceOf(PolicyPapRuntimeException.class).hasMessage("cannot find group: group"); + } + + @Test + public void testGetActivePdpGroupsByPolicyType() throws Exception { + List<PdpGroup> groups = + Arrays.asList(makeGroup(GROUP_NAME, GROUP_VERSION), makeGroup(GROUP_NAME2, GROUP_VERSION2)); + when(dao.getFilteredPdpGroups(any())).thenReturn(groups); + + assertEquals(groups, session + .getActivePdpGroupsByPolicyType(new ToscaPolicyTypeIdentifier(POLICY_NAME, POLICY_VERSION))); + } + + @Test + public void testUpdatePdpGroup() throws Exception { + PdpGroup group = makeGroup(GROUP_NAME, GROUP_VERSION); + when(dao.updatePdpGroups(any())).thenReturn(Arrays.asList(group)); + + session.updatePdpGroup(group); + + List<PdpGroup> updates = getGroupUpdates(1).get(0); + assertEquals(group, updates.get(0)); + } + + private PdpUpdate makeUpdate(String pdpName) { + PdpUpdate update = new PdpUpdate(); + + update.setName(pdpName); + + return update; + } + + private <T> List<T> sort(Collection<T> collection, Comparator<T> comparator) { + List<T> lst = new ArrayList<>(collection); + Collections.sort(lst, comparator); + + return lst; + } + + private int compare(PdpUpdate left, PdpUpdate right) { + return left.getName().compareTo(right.getName()); + } +} diff --git a/main/src/test/resources/simpleDeploy/daoPolicyList.json b/main/src/test/resources/simpleDeploy/daoPolicyList.json new file mode 100644 index 00000000..93ee9146 --- /dev/null +++ b/main/src/test/resources/simpleDeploy/daoPolicyList.json @@ -0,0 +1,10 @@ +{ + "policies": [ + { + "name": "policyA", + "version": "1.2.3", + "type": "typeA", + "typeVersion": "100.2.3" + } + ] +} diff --git a/main/src/test/resources/simpleDeploy/emptyGroups.json b/main/src/test/resources/simpleDeploy/emptyGroups.json new file mode 100644 index 00000000..44e05c87 --- /dev/null +++ b/main/src/test/resources/simpleDeploy/emptyGroups.json @@ -0,0 +1,3 @@ +{ + "groups": [] +} diff --git a/main/src/test/resources/simpleDeploy/emptyRequest.json b/main/src/test/resources/simpleDeploy/emptyRequest.json new file mode 100644 index 00000000..4c458a32 --- /dev/null +++ b/main/src/test/resources/simpleDeploy/emptyRequest.json @@ -0,0 +1,3 @@ +{ + "policies": [] +} diff --git a/main/src/test/resources/simpleDeploy/emptyRequestBase.json b/main/src/test/resources/simpleDeploy/emptyRequestBase.json new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/main/src/test/resources/simpleDeploy/emptyRequestBase.json @@ -0,0 +1,2 @@ +{ +} diff --git a/main/src/test/resources/simpleDeploy/getGroupDao.json b/main/src/test/resources/simpleDeploy/getGroupDao.json new file mode 100644 index 00000000..2e74d1bf --- /dev/null +++ b/main/src/test/resources/simpleDeploy/getGroupDao.json @@ -0,0 +1,84 @@ +{ + "groups": [ + { + "name": "groupA", + "version": "0.0.0", + "pdpSubgroups": [ + { + "pdpType": "pdpTypeA", + "supportedPolicyTypes": [ + { + "name": "typeA", + "version": "100.2.3" + } + ], + "pdpInstances": [ + { + "instanceId": "pdpA" + } + ] + } + ] + }, + { + "name": "groupA", + "version": "200.2.3", + "pdpSubgroups": [ + { + "pdpType": "pdpTypeA", + "supportedPolicyTypes": [ + { + "name": "typeA", + "version": "100.2.3" + } + ], + "pdpInstances": [ + { + "instanceId": "pdpA" + } + ] + } + ] + }, + { + "name": "groupA", + "version": "0.0.1", + "pdpSubgroups": [ + { + "pdpType": "pdpTypeA", + "supportedPolicyTypes": [ + { + "name": "typeA", + "version": "100.2.3" + } + ], + "pdpInstances": [ + { + "instanceId": "pdpA" + } + ] + } + ] + }, + { + "name": "groupA", + "version": "non-numeric-version", + "pdpSubgroups": [ + { + "pdpType": "pdpTypeA", + "supportedPolicyTypes": [ + { + "name": "typeA", + "version": "100.2.3" + } + ], + "pdpInstances": [ + { + "instanceId": "pdpA" + } + ] + } + ] + } + ] +} diff --git a/main/src/test/resources/simpleDeploy/getPolicyReqNullVersion.json b/main/src/test/resources/simpleDeploy/getPolicyReqNullVersion.json new file mode 100644 index 00000000..bf2d132b --- /dev/null +++ b/main/src/test/resources/simpleDeploy/getPolicyReqNullVersion.json @@ -0,0 +1,7 @@ +{ + "policies": [ + { + "name": "policyA" + } + ] +} diff --git a/main/src/test/resources/simpleDeploy/groups.json b/main/src/test/resources/simpleDeploy/groups.json new file mode 100644 index 00000000..7fd7684b --- /dev/null +++ b/main/src/test/resources/simpleDeploy/groups.json @@ -0,0 +1,25 @@ +{ + "groups": [ + { + "name": "groupA", + "version": "200.2.3", + "pdpSubgroups": [ + { + "pdpType": "pdpTypeA", + "supportedPolicyTypes": [ + { + "name": "typeA", + "version": "100.2.3" + } + ], + "pdpInstances": [ + { + "instanceId": "pdpA" + } + ], + "policies": [] + } + ] + } + ] +} diff --git a/main/src/test/resources/simpleDeploy/policy.json b/main/src/test/resources/simpleDeploy/policy.json new file mode 100644 index 00000000..7786aab7 --- /dev/null +++ b/main/src/test/resources/simpleDeploy/policy.json @@ -0,0 +1,6 @@ +{ + "name": "policyA", + "version": "1.2.3", + "type": "typeA", + "typeVersion": "100.2.3" +} diff --git a/main/src/test/resources/simpleDeploy/request.json b/main/src/test/resources/simpleDeploy/request.json new file mode 100644 index 00000000..060637cc --- /dev/null +++ b/main/src/test/resources/simpleDeploy/request.json @@ -0,0 +1,8 @@ +{ + "policies": [ + { + "name": "policyA", + "version": "1.2.3" + } + ] +} diff --git a/main/src/test/resources/simpleDeploy/requestBase.json b/main/src/test/resources/simpleDeploy/requestBase.json new file mode 100644 index 00000000..67fcdcb6 --- /dev/null +++ b/main/src/test/resources/simpleDeploy/requestBase.json @@ -0,0 +1,4 @@ +{ + "name": "policyA", + "version": "1.2.3" +} diff --git a/main/src/test/resources/simpleDeploy/updateGroupReqMultiple.json b/main/src/test/resources/simpleDeploy/updateGroupReqMultiple.json new file mode 100644 index 00000000..3d4684cc --- /dev/null +++ b/main/src/test/resources/simpleDeploy/updateGroupReqMultiple.json @@ -0,0 +1,20 @@ +{ + "policies": [ + { + "name": "policyA", + "version": "1.2.3" + }, + { + "name": "policyB", + "version": "1.2.3" + }, + { + "name": "policyC", + "version": "1.2.3" + }, + { + "name": "policyD", + "version": "1.2.3" + } + ] +} diff --git a/main/src/test/resources/simpleDeploy/upgradeGroupDao.json b/main/src/test/resources/simpleDeploy/upgradeGroupDao.json new file mode 100644 index 00000000..278b69a6 --- /dev/null +++ b/main/src/test/resources/simpleDeploy/upgradeGroupDao.json @@ -0,0 +1,72 @@ +{ + "groups": [ + { + "name": "groupA", + "version": "200.2.3", + "pdpSubgroups": [ + { + "pdpType": "pdpTypeA", + "supportedPolicyTypes": [], + "pdpInstances": [ + { + "instanceId": "pdpA" + } + ], + "policies": [] + }, + { + "pdpType": "pdpTypeB", + "supportedPolicyTypes": [ + { + "name": "typeA", + "version": "100.2.3" + } + ], + "pdpInstances": [ + { + "instanceId": "pdpB" + } + ], + "policies": [] + }, + { + "pdpType": "pdpTypeC", + "supportedPolicyTypes": [ + { + "name": "typeA", + "version": "100.2.3" + } + ], + "pdpInstances": [ + { + "instanceId": "pdpC" + } + ], + "policies": [ + { + "name": "policyA", + "version": "1.2.3", + "type": "typeA", + "typeVersion": "100.2.3" + } + ] + }, + { + "pdpType": "pdpTypeD", + "supportedPolicyTypes": [ + { + "name": "typeA", + "version": "100.2.3" + } + ], + "pdpInstances": [ + { + "instanceId": "pdpD" + } + ], + "policies": [] + } + ] + } + ] +} diff --git a/main/src/test/resources/simpleDeploy/upgradeGroupGroup1.json b/main/src/test/resources/simpleDeploy/upgradeGroupGroup1.json new file mode 100644 index 00000000..a63eadd9 --- /dev/null +++ b/main/src/test/resources/simpleDeploy/upgradeGroupGroup1.json @@ -0,0 +1,40 @@ +{ + "groups": [ + { + "name": "groupA", + "version": "200.2.3", + "pdpSubgroups": [ + { + "pdpType": "pdpTypeA", + "supportedPolicyTypes": [ + { + "name": "typeA", + "version": "100.2.3" + } + ], + "pdpInstances": [ + { + "instanceId": "pdpA" + } + ], + "policies": [] + }, + { + "pdpType": "pdpTypeC", + "supportedPolicyTypes": [ + { + "name": "typeC", + "version": "100.2.3" + } + ], + "pdpInstances": [ + { + "instanceId": "pdpC" + } + ], + "policies": [] + } + ] + } + ] +} diff --git a/main/src/test/resources/simpleDeploy/upgradeGroupGroup2.json b/main/src/test/resources/simpleDeploy/upgradeGroupGroup2.json new file mode 100644 index 00000000..d4946579 --- /dev/null +++ b/main/src/test/resources/simpleDeploy/upgradeGroupGroup2.json @@ -0,0 +1,25 @@ +{ + "groups": [ + { + "name": "groupB", + "version": "300.2.3", + "pdpSubgroups": [ + { + "pdpType": "pdpTypeB", + "supportedPolicyTypes": [ + { + "name": "typeB", + "version": "100.2.3" + } + ], + "pdpInstances": [ + { + "instanceId": "pdpB" + } + ], + "policies": [] + } + ] + } + ] +} diff --git a/main/src/test/resources/simpleDeploy/upgradeGroupPolicy2.json b/main/src/test/resources/simpleDeploy/upgradeGroupPolicy2.json new file mode 100644 index 00000000..3a13d0c3 --- /dev/null +++ b/main/src/test/resources/simpleDeploy/upgradeGroupPolicy2.json @@ -0,0 +1,10 @@ +{ + "policies": [ + { + "name": "policyB", + "version": "1.2.3", + "type": "typeB", + "typeVersion": "100.2.3" + } + ] +} diff --git a/main/src/test/resources/simpleDeploy/upgradeGroupPolicy3.json b/main/src/test/resources/simpleDeploy/upgradeGroupPolicy3.json new file mode 100644 index 00000000..bf5602ea --- /dev/null +++ b/main/src/test/resources/simpleDeploy/upgradeGroupPolicy3.json @@ -0,0 +1,10 @@ +{ + "policies": [ + { + "name": "policyC", + "version": "1.2.3", + "type": "typeC", + "typeVersion": "100.2.3" + } + ] +} diff --git a/main/src/test/resources/simpleDeploy/upgradeGroupPolicy4.json b/main/src/test/resources/simpleDeploy/upgradeGroupPolicy4.json new file mode 100644 index 00000000..3c0fb72f --- /dev/null +++ b/main/src/test/resources/simpleDeploy/upgradeGroupPolicy4.json @@ -0,0 +1,10 @@ +{ + "policies": [ + { + "name": "policyD", + "version": "1.2.3", + "type": "typeA", + "typeVersion": "100.2.3" + } + ] +} diff --git a/main/src/test/resources/simpleDeploy/upgradeGroup_NoPdpsDao.json b/main/src/test/resources/simpleDeploy/upgradeGroup_NoPdpsDao.json new file mode 100644 index 00000000..72563d47 --- /dev/null +++ b/main/src/test/resources/simpleDeploy/upgradeGroup_NoPdpsDao.json @@ -0,0 +1,21 @@ +{ + "groups": [ + { + "name": "groupA", + "version": "200.2.3", + "pdpSubgroups": [ + { + "pdpType": "pdpTypeA", + "supportedPolicyTypes": [ + { + "name": "typeA", + "version": "100.2.3" + } + ], + "pdpInstances": [], + "policies": [] + } + ] + } + ] +} diff --git a/main/src/test/resources/simpleDeploy/upgradeGroup_NothingUpdatedDao.json b/main/src/test/resources/simpleDeploy/upgradeGroup_NothingUpdatedDao.json new file mode 100644 index 00000000..60d6a68c --- /dev/null +++ b/main/src/test/resources/simpleDeploy/upgradeGroup_NothingUpdatedDao.json @@ -0,0 +1,25 @@ +{ + "groups": [ + { + "name": "groupA", + "version": "200.2.3", + "pdpSubgroups": [ + { + "pdpType": "pdpTypeB", + "supportedPolicyTypes": [ + { + "name": "typeX", + "version": "100.2.3" + } + ], + "pdpInstances": [ + { + "instanceId": "pdpB" + } + ], + "policies": [] + } + ] + } + ] +} |