diff options
22 files changed, 830 insertions, 71 deletions
diff --git a/models-examples/src/main/resources/policies/sdnc.policy.naming.input.tosca.yaml b/models-examples/src/main/resources/policies/sdnc.policy.naming.input.tosca.yaml index 825e95dea..f17e9096b 100644 --- a/models-examples/src/main/resources/policies/sdnc.policy.naming.input.tosca.yaml +++ b/models-examples/src/main/resources/policies/sdnc.policy.naming.input.tosca.yaml @@ -4,6 +4,7 @@ topology_template: - SDNC_Policy.ONAP_VNF_NAMING_TIMESTAMP: type: onap.policies.Naming version: 1.0.0 + type_version: 1.0.0 properties: policy-instance-name: ONAP_VNF_NAMING_TIMESTAMP naming-models: @@ -46,4 +47,4 @@ topology_template: start-value: 1 length: 3 increment: 1 - sequence-type: alpha-numeric
\ No newline at end of file + sequence-type: alpha-numeric diff --git a/models-examples/src/main/resources/policytypes/onap.policies.Optimization.yaml b/models-examples/src/main/resources/policytypes/onap.policies.Optimization.yaml index f88239d73..2cd391ff0 100644 --- a/models-examples/src/main/resources/policytypes/onap.policies.Optimization.yaml +++ b/models-examples/src/main/resources/policytypes/onap.policies.Optimization.yaml @@ -13,22 +13,6 @@ policy_types: required: true entry_schema: type: string - services: - description: One or more services that the policy applies to. - type: list - metadata: - matchable: true - required: true - entry_schema: - type: string - resources: - description: One or more VNF resources that the policy applies to. - type: list - metadata: - matchable: true - required: true - entry_schema: - type: string geography: description: One or more geographic regions type: list diff --git a/models-examples/src/main/resources/policytypes/onap.policies.optimization.Resource.yaml b/models-examples/src/main/resources/policytypes/onap.policies.optimization.Resource.yaml new file mode 100644 index 000000000..1d8135162 --- /dev/null +++ b/models-examples/src/main/resources/policytypes/onap.policies.optimization.Resource.yaml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +policy_types: + onap.policies.optimization.Resource: + derived_from: onap.policies.Optimization + version: 1.0.0 + description: The base policy type for all policies that govern optimization for a Resource in a Service. + properties: + services: + description: One or more services that the policy applies to. + type: list + metadata: + matchable: true + required: true + entry_schema: + type: string + resources: + description: One or more VNF resources that the policy applies to. + type: list + metadata: + matchable: true + required: true + entry_schema: + type: string
\ No newline at end of file diff --git a/models-examples/src/main/resources/policytypes/onap.policies.optimization.Service.yaml b/models-examples/src/main/resources/policytypes/onap.policies.optimization.Service.yaml new file mode 100644 index 000000000..8e7b724da --- /dev/null +++ b/models-examples/src/main/resources/policytypes/onap.policies.optimization.Service.yaml @@ -0,0 +1,15 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +policy_types: + onap.policies.optimization.Service: + derived_from: onap.policies.Optimization + version: 1.0.0 + description: The base policy type for all policies that govern optimization for a Service. + properties: + services: + description: One or more services that the policy applies to. + type: list + metadata: + matchable: true + required: true + entry_schema: + type: string
\ No newline at end of file diff --git a/models-examples/src/main/resources/policytypes/onap.policies.optimization.AffinityPolicy.yaml b/models-examples/src/main/resources/policytypes/onap.policies.optimization.resource.AffinityPolicy.yaml index abac21922..173691f21 100644 --- a/models-examples/src/main/resources/policytypes/onap.policies.optimization.AffinityPolicy.yaml +++ b/models-examples/src/main/resources/policytypes/onap.policies.optimization.resource.AffinityPolicy.yaml @@ -1,7 +1,7 @@ tosca_definitions_version: tosca_simple_yaml_1_0_0 policy_types: - onap.policies.optimization.AffinityPolicy: - derived_from: onap.policies.Optimization + onap.policies.optimization.resource.AffinityPolicy: + derived_from: onap.policies.optimization.Resource version: 1.0.0 properties: applicableResources: diff --git a/models-examples/src/main/resources/policytypes/onap.policies.optimization.DistancePolicy.yaml b/models-examples/src/main/resources/policytypes/onap.policies.optimization.resource.DistancePolicy.yaml index 3c9150d9e..060c4f97c 100644 --- a/models-examples/src/main/resources/policytypes/onap.policies.optimization.DistancePolicy.yaml +++ b/models-examples/src/main/resources/policytypes/onap.policies.optimization.resource.DistancePolicy.yaml @@ -1,7 +1,7 @@ tosca_definitions_version: tosca_simple_yaml_1_0_0 policy_types: - onap.policies.optimization.DistancePolicy: - derived_from: onap.policies.Optimization + onap.policies.optimization.resource.DistancePolicy: + derived_from: onap.policies.optimization.Resource version: 1.0.0 properties: applicableResources: diff --git a/models-examples/src/main/resources/policytypes/onap.policies.optimization.HpaPolicy.yaml b/models-examples/src/main/resources/policytypes/onap.policies.optimization.resource.HpaPolicy.yaml index dbb5e9ef1..d35552f10 100644 --- a/models-examples/src/main/resources/policytypes/onap.policies.optimization.HpaPolicy.yaml +++ b/models-examples/src/main/resources/policytypes/onap.policies.optimization.resource.HpaPolicy.yaml @@ -1,7 +1,7 @@ tosca_definitions_version: tosca_simple_yaml_1_0_0 policy_types: - onap.policies.optimization.HpaPolicy: - derived_from: onap.policies.Optimization + onap.policies.optimization.resource.HpaPolicy: + derived_from: onap.policies.optimization.Resource version: 1.0.0 properties: flavorFeatures: diff --git a/models-examples/src/main/resources/policytypes/onap.policies.optimization.OptimizationPolicy.yaml b/models-examples/src/main/resources/policytypes/onap.policies.optimization.resource.OptimizationPolicy.yaml index e03ceeea6..abc329ccd 100644 --- a/models-examples/src/main/resources/policytypes/onap.policies.optimization.OptimizationPolicy.yaml +++ b/models-examples/src/main/resources/policytypes/onap.policies.optimization.resource.OptimizationPolicy.yaml @@ -1,7 +1,7 @@ tosca_definitions_version: tosca_simple_yaml_1_0_0 policy_types: - onap.policies.optimization.OptimizationPolicy: - derived_from: onap.policies.Optimization + onap.policies.optimization.resource.OptimizationPolicy: + derived_from: onap.policies.optimization.Resource version: 1.0.0 properties: objective: diff --git a/models-examples/src/main/resources/policytypes/onap.policies.optimization.PciPolicy.yaml b/models-examples/src/main/resources/policytypes/onap.policies.optimization.resource.PciPolicy.yaml index 097a5f173..887e372df 100644 --- a/models-examples/src/main/resources/policytypes/onap.policies.optimization.PciPolicy.yaml +++ b/models-examples/src/main/resources/policytypes/onap.policies.optimization.resource.PciPolicy.yaml @@ -1,7 +1,7 @@ tosca_definitions_version: tosca_simple_yaml_1_0_0 policy_types: - onap.policies.optimization.PciPolicy: - derived_from: onap.policies.Optimization + onap.policies.optimization.resource.PciPolicy: + derived_from: onap.policies.optimization.Resource version: 1.0.0 properties: pciProperties: diff --git a/models-examples/src/main/resources/policytypes/onap.policies.optimization.Vim_fit.yaml b/models-examples/src/main/resources/policytypes/onap.policies.optimization.resource.Vim_fit.yaml index b70dddb2f..fd851248f 100644 --- a/models-examples/src/main/resources/policytypes/onap.policies.optimization.Vim_fit.yaml +++ b/models-examples/src/main/resources/policytypes/onap.policies.optimization.resource.Vim_fit.yaml @@ -1,7 +1,7 @@ tosca_definitions_version: tosca_simple_yaml_1_0_0 policy_types: - onap.policies.optimization.Vim_fit: - derived_from: onap.policies.Optimization + onap.policies.optimization.resource.Vim_fit: + derived_from: onap.policies.optimization.Resource version: 1.0.0 properties: applicableResources: diff --git a/models-examples/src/main/resources/policytypes/onap.policies.optimization.VnfPolicy.yaml b/models-examples/src/main/resources/policytypes/onap.policies.optimization.resource.VnfPolicy.yaml index 18a0ccfd0..960ee15f4 100644 --- a/models-examples/src/main/resources/policytypes/onap.policies.optimization.VnfPolicy.yaml +++ b/models-examples/src/main/resources/policytypes/onap.policies.optimization.resource.VnfPolicy.yaml @@ -1,7 +1,7 @@ tosca_definitions_version: tosca_simple_yaml_1_0_0 policy_types: - onap.policies.optimization.VnfPolicy: - derived_from: onap.policies.Optimization + onap.policies.optimization.resource.VnfPolicy: + derived_from: onap.policies.optimization.Resource version: 1.0.0 properties: applicableResources: diff --git a/models-examples/src/main/resources/policytypes/onap.policies.optimization.QueryPolicy.yaml b/models-examples/src/main/resources/policytypes/onap.policies.optimization.service.QueryPolicy.yaml index 41b923ad7..68c6636b4 100644 --- a/models-examples/src/main/resources/policytypes/onap.policies.optimization.QueryPolicy.yaml +++ b/models-examples/src/main/resources/policytypes/onap.policies.optimization.service.QueryPolicy.yaml @@ -1,7 +1,7 @@ tosca_definitions_version: tosca_simple_yaml_1_0_0 policy_types: - onap.policies.optimization.QueryPolicy: - derived_from: onap.policies.Optimization + onap.policies.optimization.service.QueryPolicy: + derived_from: onap.policies.optimization.Service version: 1.0.0 properties: queryProperties: diff --git a/models-examples/src/main/resources/policytypes/onap.policies.optimization.SubscriberPolicy.yaml b/models-examples/src/main/resources/policytypes/onap.policies.optimization.service.SubscriberPolicy.yaml index 010a1534b..b6327c87b 100644 --- a/models-examples/src/main/resources/policytypes/onap.policies.optimization.SubscriberPolicy.yaml +++ b/models-examples/src/main/resources/policytypes/onap.policies.optimization.service.SubscriberPolicy.yaml @@ -1,7 +1,7 @@ tosca_definitions_version: tosca_simple_yaml_1_0_0 policy_types: - onap.policies.optimization.SubscriberPolicy: - derived_from: onap.policies.Optimization + onap.policies.optimization.service.SubscriberPolicy: + derived_from: onap.policies.optimization.Service version: 1.0.0 properties: subscriberProperties: diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/DeploymentGroup.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/DeploymentGroup.java new file mode 100644 index 000000000..d98f6ed30 --- /dev/null +++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/DeploymentGroup.java @@ -0,0 +1,116 @@ +/*- + * ============LICENSE_START======================================================= + * 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.models.pdp.concepts; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.ObjectValidationResult; +import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.parameters.ValidationStatus; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.pdp.concepts.DeploymentSubGroup.Action; + +/** + * Batch modification of a deployment group, which groups multiple DeploymentSubGroup + * entities together for a particular domain. + */ +@Data +@NoArgsConstructor +public class DeploymentGroup { + private static final String SUBGROUP_FIELD = "deploymentSubgroups"; + + private String name; + private List<DeploymentSubGroup> deploymentSubgroups; + + /** + * Constructs the object, making a deep copy from the source. + * + * @param source source from which to copy fields + */ + public DeploymentGroup(@NonNull DeploymentGroup source) { + this.name = source.name; + this.deploymentSubgroups = + PfUtils.mapList(source.deploymentSubgroups, DeploymentSubGroup::new, new ArrayList<>(0)); + } + + /** + * Validates that appropriate fields are populated for an incoming call to the PAP + * REST API. + * + * @return the validation result + */ + public ValidationResult validatePapRest() { + BeanValidationResult result = new BeanValidationResult("group", this); + + result.validateNotNull("name", name); + result.validateNotNullList(SUBGROUP_FIELD, deploymentSubgroups, DeploymentSubGroup::validatePapRest); + + if (deploymentSubgroups != null && deploymentSubgroups.isEmpty()) { + result.addResult(new ObjectValidationResult(SUBGROUP_FIELD, deploymentSubgroups, ValidationStatus.INVALID, + "is empty")); + } + + checkDuplicateSubgroups(result); + + return result; + } + + /** + * Checks for duplicate subgroups. + * + * @param result where to place validation results + */ + private void checkDuplicateSubgroups(BeanValidationResult result) { + if (deploymentSubgroups == null || !result.isValid()) { + return; + } + + /* + * Verify that if a subgroup appears more than once, then the second appearance is + * not a PATCH, as that would overwrite anything that has appeared before. + */ + Map<String, Action> pdpType2action = new HashMap<>(); + + for (DeploymentSubGroup subgrp : deploymentSubgroups) { + Action action = subgrp.getAction(); + + pdpType2action.compute(subgrp.getPdpType(), (pdpType, curact) -> { + + if (curact != null && action == Action.PATCH) { + BeanValidationResult subResult = new BeanValidationResult(pdpType, pdpType); + subResult.addResult(new ObjectValidationResult("action", action, ValidationStatus.INVALID, + "incompatible with previous action: " + curact)); + BeanValidationResult subResult2 = new BeanValidationResult(SUBGROUP_FIELD, subgrp); + subResult2.addResult(subResult); + result.addResult(subResult2); + } + + return action; + }); + } + } +} diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/DeploymentGroups.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/DeploymentGroups.java new file mode 100644 index 000000000..0d810d210 --- /dev/null +++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/DeploymentGroups.java @@ -0,0 +1,73 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Models + * ================================================================================ + * 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.models.pdp.concepts; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.ObjectValidationResult; +import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.parameters.ValidationStatus; + +/** + * Batch modification of a deployment groups via the PDP Group deployment REST API. + */ +@Getter +@Setter +@ToString +public class DeploymentGroups { + private static final String GROUPS_FIELD = "groups"; + + private List<DeploymentGroup> groups; + + /** + * Validates that appropriate fields are populated for an incoming call to the PAP + * REST API. + * + * @return the validation result + */ + public ValidationResult validatePapRest() { + BeanValidationResult result = new BeanValidationResult(GROUPS_FIELD, this); + + result.validateNotNullList(GROUPS_FIELD, groups, DeploymentGroup::validatePapRest); + if (!result.isValid()) { + return result; + } + + // verify that the same group doesn't appear more than once + Set<String> sawGroup = new HashSet<>(); + for (DeploymentGroup group : groups) { + String name = group.getName(); + if (sawGroup.contains(name)) { + return new ObjectValidationResult(GROUPS_FIELD, name, ValidationStatus.INVALID, "duplicate group name"); + + } else { + sawGroup.add(name); + } + } + + return result; + } +} diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/DeploymentSubGroup.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/DeploymentSubGroup.java new file mode 100644 index 000000000..1a1fe228d --- /dev/null +++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/DeploymentSubGroup.java @@ -0,0 +1,82 @@ +/*- + * ============LICENSE_START======================================================= + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.pdp.concepts; + +import java.util.ArrayList; +import java.util.List; +import lombok.Data; +import lombok.NonNull; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; + +/** + * A deployment (i.e., set of policies) for all PDPs of the same pdp type running within a + * particular domain. + */ +@Data +public class DeploymentSubGroup { + + public enum Action { + POST, // all listed policies are to be added + DELETE, // all listed policies are to be deleted + PATCH // update the deployment so that the policies match exactly + } + + private String pdpType; + private Action action; + private List<ToscaPolicyIdentifier> policies; + + /** + * Constructs the object. + */ + public DeploymentSubGroup() { + super(); + } + + /** + * Constructs the object, making a deep copy from the source. + * + * @param source source from which to copy fields + */ + public DeploymentSubGroup(@NonNull final DeploymentSubGroup source) { + this.pdpType = source.pdpType; + this.action = source.action; + this.policies = PfUtils.mapList(source.policies, ToscaPolicyIdentifier::new, new ArrayList<>(0)); + } + + /** + * Validates that appropriate fields are populated for an incoming call to the PAP + * REST API. + * + * @return the validation result + */ + public ValidationResult validatePapRest() { + BeanValidationResult result = new BeanValidationResult("group", this); + + result.validateNotNull("pdpType", pdpType); + result.validateNotNull("action", action); + result.validateNotNullList("policies", policies, ToscaPolicyIdentifier::validatePapRest); + + return result; + } +} diff --git a/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/DeploymentGroupTest.java b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/DeploymentGroupTest.java new file mode 100644 index 000000000..a74029e10 --- /dev/null +++ b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/DeploymentGroupTest.java @@ -0,0 +1,194 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP Policy Models + * ================================================================================ + * 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.models.pdp.concepts; + +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.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import org.junit.Test; +import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.models.pdp.concepts.DeploymentSubGroup.Action; + +/** + * Test methods not tested by {@link ModelsTest}. + */ +public class DeploymentGroupTest { + private static final String NAME = "my-name"; + private static final String PDP_TYPE1 = "type-1"; + private static final String PDP_TYPE2 = "type-2"; + private static final String PDP_TYPE3 = "type-3"; + + @Test + public void testCopyConstructor() { + assertThatThrownBy(() -> new DeploymentGroup(null)).isInstanceOf(NullPointerException.class); + + DeploymentGroup orig = new DeploymentGroup(); + + // verify with null values + assertEquals("DeploymentGroup(name=null, deploymentSubgroups=[])", new DeploymentGroup(orig).toString()); + + // verify with all values + orig.setName(NAME); + + DeploymentSubGroup sub1 = new DeploymentSubGroup(); + DeploymentSubGroup sub2 = new DeploymentSubGroup(); + orig.setDeploymentSubgroups(Arrays.asList(sub1, sub2)); + + assertEquals("DeploymentGroup(name=my-name, " + + "deploymentSubgroups=[DeploymentSubGroup(pdpType=null, action=null, policies=[]), " + + "DeploymentSubGroup(pdpType=null, action=null, policies=[])])", + new DeploymentGroup(orig).toString()); + } + + @Test + public void testHashCode() { + DeploymentGroup group = new DeploymentGroup(); + group.setName("A"); + int hash = group.hashCode(); + + assertEquals(hash, group.hashCode()); + + group.setName("B"); + assertTrue(hash != group.hashCode()); + } + + @Test + public void testValidatePapRest() { + DeploymentGroup group = new DeploymentGroup(); + group.setName(NAME); + + DeploymentSubGroup subgroup1 = new DeploymentSubGroup(); + subgroup1.setPdpType(PDP_TYPE1); + subgroup1.setAction(Action.PATCH); + subgroup1.setPolicies(Collections.emptyList()); + + DeploymentSubGroup subgroup2 = new DeploymentSubGroup(subgroup1); + subgroup2.setPdpType(PDP_TYPE2); + + DeploymentSubGroup subgroup3 = new DeploymentSubGroup(subgroup1); + subgroup3.setPdpType(PDP_TYPE3); + + group.setDeploymentSubgroups(Arrays.asList(subgroup1, subgroup2, subgroup3)); + + // valid + assertValid(group); + + // null name + DeploymentGroup group2 = new DeploymentGroup(group); + group2.setName(null); + assertInvalid(group2); + + // null subgroup list + group2 = new DeploymentGroup(group); + group2.setDeploymentSubgroups(null); + assertInvalid(group2); + + // empty subgroup list + group2 = new DeploymentGroup(group); + group2.setDeploymentSubgroups(Collections.emptyList()); + assertInvalid(group2); + + // null subgroup + group2 = new DeploymentGroup(group); + group2.setDeploymentSubgroups(Arrays.asList(subgroup1, null)); + assertInvalid(group2); + + // invalid subgroup + group2 = new DeploymentGroup(group); + DeploymentSubGroup subgroupX = new DeploymentSubGroup(subgroup1); + subgroupX.setPdpType(null); + group2.setDeploymentSubgroups(Arrays.asList(subgroupX)); + assertInvalid(group2); + } + + @Test + public void testCheckDuplicateSubgroups() { + DeploymentGroup group = new DeploymentGroup(); + group.setName(NAME); + + DeploymentSubGroup subgroup1 = new DeploymentSubGroup(); + subgroup1.setPdpType(PDP_TYPE1); + subgroup1.setAction(Action.POST); + subgroup1.setPolicies(Collections.emptyList()); + + DeploymentSubGroup subgroup2 = new DeploymentSubGroup(subgroup1); + subgroup2.setPdpType(PDP_TYPE2); + subgroup2.setAction(Action.PATCH); + + DeploymentSubGroup subgroup3 = new DeploymentSubGroup(subgroup1); + subgroup3.setPdpType(PDP_TYPE3); + subgroup3.setAction(Action.DELETE); + + group.setDeploymentSubgroups(Arrays.asList(subgroup1, subgroup2, subgroup3)); + + // no duplicates + assertValid(group); + + /* + * Allowed duplicates + */ + DeploymentSubGroup subgroup1b = new DeploymentSubGroup(subgroup1); + subgroup1b.setAction(Action.POST); + + DeploymentSubGroup subgroup1c = new DeploymentSubGroup(subgroup1); + subgroup1c.setAction(Action.DELETE); + + DeploymentSubGroup subgroup1d = new DeploymentSubGroup(subgroup1); + subgroup1d.setAction(Action.DELETE); + + group.setDeploymentSubgroups( + Arrays.asList(subgroup1, subgroup2, subgroup3, subgroup1b, subgroup1c, subgroup1d)); + + // still ok + assertValid(group); + + /* + * Not allowed + */ + DeploymentSubGroup subgroup1e = new DeploymentSubGroup(subgroup1); + subgroup1e.setAction(Action.PATCH); + + group.setDeploymentSubgroups( + Arrays.asList(subgroup1, subgroup2, subgroup3, subgroup1b, subgroup1c, subgroup1d, subgroup1e)); + + assertInvalid(group); + } + + private void assertValid(DeploymentGroup group) { + ValidationResult result = group.validatePapRest(); + assertNotNull(result); + assertNull(result.getResult()); + assertTrue(result.isValid()); + } + + private void assertInvalid(DeploymentGroup group) { + ValidationResult result = group.validatePapRest(); + assertNotNull(result); + assertFalse(result.isValid()); + assertNotNull(result.getResult()); + } +} diff --git a/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/DeploymentGroupsTest.java b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/DeploymentGroupsTest.java new file mode 100644 index 000000000..18b13759a --- /dev/null +++ b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/DeploymentGroupsTest.java @@ -0,0 +1,89 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Models + * ================================================================================ + * 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.models.pdp.concepts; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import org.junit.Test; +import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.models.pdp.concepts.DeploymentSubGroup.Action; + +public class DeploymentGroupsTest { + + @Test + public void testValidatePapRest_toMapList() { + DeploymentGroup group1 = new DeploymentGroup(); + group1.setName("group-1"); + + DeploymentSubGroup subgrp = new DeploymentSubGroup(); + subgrp.setPdpType("pdp-type"); + subgrp.setAction(Action.DELETE); + subgrp.setPolicies(Collections.emptyList()); + + group1.setDeploymentSubgroups(Arrays.asList(subgrp)); + + DeploymentGroup group2 = new DeploymentGroup(); + group2.setName("group-2"); + group2.setDeploymentSubgroups(Arrays.asList(subgrp)); + + DeploymentGroups groups = new DeploymentGroups(); + groups.setGroups(Arrays.asList(group1, group2)); + + // valid + ValidationResult result = groups.validatePapRest(); + assertNotNull(result); + assertNull(result.getResult()); + assertTrue(result.isValid()); + + // null group list + groups = new DeploymentGroups(); + groups.setGroups(null); + assertInvalid(groups); + + // null group + groups = new DeploymentGroups(); + groups.setGroups(Arrays.asList(group1, null)); + assertInvalid(groups); + + // invalid group + DeploymentGroup groupX = new DeploymentGroup(group1); + groupX.setName(null); + groups.setGroups(Arrays.asList(group1, groupX)); + assertInvalid(groups); + + // duplicate groups + groups = new DeploymentGroups(); + groups.setGroups(Arrays.asList(group1, group2, group1)); + assertInvalid(groups); + } + + private void assertInvalid(DeploymentGroups groups) { + ValidationResult result = groups.validatePapRest(); + assertNotNull(result); + assertFalse(result.isValid()); + assertNotNull(result.getResult()); + } +} diff --git a/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/DeploymentSubGroupTest.java b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/DeploymentSubGroupTest.java new file mode 100644 index 000000000..511d88f27 --- /dev/null +++ b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/DeploymentSubGroupTest.java @@ -0,0 +1,152 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP Policy Models + * ================================================================================ + * 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.models.pdp.concepts; + +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.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import org.junit.Test; +import org.onap.policy.common.parameters.ValidationResult; +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.models.pdp.concepts.DeploymentSubGroup.Action; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; + +/** + * Test methods not tested by {@link ModelsTest}. + */ +public class DeploymentSubGroupTest { + private static final String VERSION_300 = "3.0.0"; + private static final Coder coder = new StandardCoder(); + + @Test + public void testCopyConstructor() { + assertThatThrownBy(() -> new DeploymentSubGroup(null)).isInstanceOf(NullPointerException.class); + + final DeploymentSubGroup orig = new DeploymentSubGroup(); + + // verify with null values + assertEquals("DeploymentSubGroup(pdpType=null, action=null, policies=[])", + new DeploymentSubGroup(orig).toString()); + + orig.setPdpType("my-type"); + orig.setAction(Action.POST); + + final ToscaPolicyIdentifier pol1 = new ToscaPolicyIdentifier(); + pol1.setName("policy-A"); + pol1.setVersion("1.0.0"); + final ToscaPolicyIdentifier pol2 = new ToscaPolicyIdentifier(); + pol2.setName("policy-B"); + pol1.setVersion("2.0.0"); + orig.setPolicies(Arrays.asList(pol1, pol2)); + + assertEquals(orig.toString(), new DeploymentSubGroup(orig).toString()); + } + + @Test + public void testValidatePapRest() throws Exception { + DeploymentSubGroup subgrp = new DeploymentSubGroup(); + + subgrp.setPdpType("pdp-type"); + subgrp.setAction(Action.PATCH); + subgrp.setPolicies(Arrays.asList(makeIdent("policy-X", "4.0.0", ToscaPolicyIdentifier.class))); + + // valid + ValidationResult result = subgrp.validatePapRest(); + assertNotNull(result); + assertTrue(result.isValid()); + assertNull(result.getResult()); + + // null pdp type + DeploymentSubGroup sub2 = new DeploymentSubGroup(subgrp); + sub2.setPdpType(null); + assertInvalid(sub2); + + // null action + sub2 = new DeploymentSubGroup(subgrp); + sub2.setAction(null); + assertInvalid(sub2); + + // null policies + sub2 = new DeploymentSubGroup(subgrp); + sub2.setPolicies(null); + assertInvalid(sub2); + + // null policy item + sub2 = new DeploymentSubGroup(subgrp); + sub2.getPolicies().set(0, null); + assertInvalid(sub2); + + // invalid policy item + sub2 = new DeploymentSubGroup(subgrp); + sub2.getPolicies().set(0, makeIdent(null, VERSION_300, ToscaPolicyIdentifier.class)); + assertInvalid(sub2); + } + + private void assertInvalid(DeploymentSubGroup sub2) { + ValidationResult result = sub2.validatePapRest(); + assertNotNull(result); + assertFalse(result.isValid()); + assertNotNull(result.getResult()); + } + + /** + * Makes an identifier. Uses JSON which does no error checking. + * + * @param name name to put into the identifier + * @param version version to put into the identifier + * @param clazz type of identifier to create + * @return a new identifier + * @throws CoderException if the JSON cannot be decoded + */ + private <T> T makeIdent(String name, String version, Class<T> clazz) throws CoderException { + StringBuilder bldr = new StringBuilder(); + bldr.append("{"); + + if (name != null) { + bldr.append("'name':'"); + bldr.append(name); + bldr.append("'"); + } + + if (version != null) { + if (name != null) { + bldr.append(','); + } + + bldr.append("'version':'"); + bldr.append(version); + bldr.append("'"); + } + + bldr.append("}"); + + String json = bldr.toString().replace('\'', '"'); + + return coder.decode(json, clazz); + } +} diff --git a/models-provider/src/test/java/org/onap/policy/models/provider/impl/PolicyTypePersistenceTest.java b/models-provider/src/test/java/org/onap/policy/models/provider/impl/PolicyTypePersistenceTest.java index 2ccf215c9..75f21d2f8 100644 --- a/models-provider/src/test/java/org/onap/policy/models/provider/impl/PolicyTypePersistenceTest.java +++ b/models-provider/src/test/java/org/onap/policy/models/provider/impl/PolicyTypePersistenceTest.java @@ -64,17 +64,17 @@ public class PolicyTypePersistenceTest { // @formatter:off private String[] policyTypeResourceNames = { "policytypes/onap.policies.controlloop.Operational.yaml", - "policytypes/onap.policies.optimization.DistancePolicy.yaml", - "policytypes/onap.policies.optimization.VnfPolicy.yaml", - "policytypes/onap.policies.optimization.PciPolicy.yaml", - "policytypes/onap.policies.optimization.OptimizationPolicy.yaml", + "policytypes/onap.policies.optimization.resource.DistancePolicy.yaml", + "policytypes/onap.policies.optimization.resource.VnfPolicy.yaml", + "policytypes/onap.policies.optimization.resource.PciPolicy.yaml", + "policytypes/onap.policies.optimization.resource.OptimizationPolicy.yaml", "policytypes/onap.policies.controlloop.guard.Blacklist.yaml", "policytypes/onap.policies.monitoring.dcaegen2.collectors.datafile.datafile-app-server.yaml", - "policytypes/onap.policies.optimization.HpaPolicy.yaml", - "policytypes/onap.policies.optimization.Vim_fit.yaml", - "policytypes/onap.policies.optimization.SubscriberPolicy.yaml", - "policytypes/onap.policies.optimization.AffinityPolicy.yaml", - "policytypes/onap.policies.optimization.QueryPolicy.yaml", + "policytypes/onap.policies.optimization.resource.HpaPolicy.yaml", + "policytypes/onap.policies.optimization.resource.Vim_fit.yaml", + "policytypes/onap.policies.optimization.service.SubscriberPolicy.yaml", + "policytypes/onap.policies.optimization.resource.AffinityPolicy.yaml", + "policytypes/onap.policies.optimization.service.QueryPolicy.yaml", "policytypes/onap.policies.controlloop.guard.MinMax.yaml", "policytypes/onap.policies.controlloop.guard.FrequencyLimiter.yaml", "policytypes/onap.policies.controlloop.guard.coordination.FirstBlocksSecond.yaml", diff --git a/models-tosca/src/test/java/org/onap/policy/models/tosca/authorative/concepts/ToscaPolicyTypeFilterTest.java b/models-tosca/src/test/java/org/onap/policy/models/tosca/authorative/concepts/ToscaPolicyTypeFilterTest.java index d9ffec566..f4f822c20 100644 --- a/models-tosca/src/test/java/org/onap/policy/models/tosca/authorative/concepts/ToscaPolicyTypeFilterTest.java +++ b/models-tosca/src/test/java/org/onap/policy/models/tosca/authorative/concepts/ToscaPolicyTypeFilterTest.java @@ -27,12 +27,10 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import com.google.gson.GsonBuilder; - import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; - import org.junit.BeforeClass; import org.junit.Test; import org.onap.policy.common.utils.coder.CoderException; @@ -59,17 +57,17 @@ public class ToscaPolicyTypeFilterTest { // @formatter:off private static final String[] policyTypeResourceNames = { "policytypes/onap.policies.controlloop.Operational.yaml", - "policytypes/onap.policies.optimization.DistancePolicy.yaml", - "policytypes/onap.policies.optimization.VnfPolicy.yaml", - "policytypes/onap.policies.optimization.PciPolicy.yaml", - "policytypes/onap.policies.optimization.OptimizationPolicy.yaml", + "policytypes/onap.policies.optimization.resource.DistancePolicy.yaml", + "policytypes/onap.policies.optimization.resource.VnfPolicy.yaml", + "policytypes/onap.policies.optimization.resource.PciPolicy.yaml", + "policytypes/onap.policies.optimization.resource.OptimizationPolicy.yaml", "policytypes/onap.policies.controlloop.guard.Blacklist.yaml", "policytypes/onap.policies.monitoring.dcaegen2.collectors.datafile.datafile-app-server.yaml", - "policytypes/onap.policies.optimization.HpaPolicy.yaml", - "policytypes/onap.policies.optimization.Vim_fit.yaml", - "policytypes/onap.policies.optimization.SubscriberPolicy.yaml", - "policytypes/onap.policies.optimization.AffinityPolicy.yaml", - "policytypes/onap.policies.optimization.QueryPolicy.yaml", + "policytypes/onap.policies.optimization.resource.HpaPolicy.yaml", + "policytypes/onap.policies.optimization.resource.Vim_fit.yaml", + "policytypes/onap.policies.optimization.service.SubscriberPolicy.yaml", + "policytypes/onap.policies.optimization.resource.AffinityPolicy.yaml", + "policytypes/onap.policies.optimization.service.QueryPolicy.yaml", "policytypes/onap.policies.controlloop.guard.MinMax.yaml", "policytypes/onap.policies.controlloop.guard.FrequencyLimiter.yaml", "policytypes/onap.policies.controlloop.guard.coordination.FirstBlocksSecond.yaml", diff --git a/models-tosca/src/test/java/org/onap/policy/models/tosca/simple/serialization/OptimizationPolicyTypeSerializationTest.java b/models-tosca/src/test/java/org/onap/policy/models/tosca/simple/serialization/OptimizationPolicyTypeSerializationTest.java index 9f9906930..e710faa31 100644 --- a/models-tosca/src/test/java/org/onap/policy/models/tosca/simple/serialization/OptimizationPolicyTypeSerializationTest.java +++ b/models-tosca/src/test/java/org/onap/policy/models/tosca/simple/serialization/OptimizationPolicyTypeSerializationTest.java @@ -44,7 +44,10 @@ public class OptimizationPolicyTypeSerializationTest { private static final String TYPE_ROOT = "tosca.policies.Root"; private static final String VERSION = "1.0.0"; - private static final String INPUT_YAML = "policytypes/onap.policies.Optimization.yaml"; + private static final String INPUT_OPTIMIZATION_YAML = "policytypes/onap.policies.Optimization.yaml"; + private static final String INPUT_OPTIMIZATION_RESOURCE_YAML = + "policytypes/onap.policies.optimization.Resource.yaml"; + private static final String INPUT_OPTIMIZATION_SERVICE_YAML = "policytypes/onap.policies.optimization.Service.yaml"; private StandardCoder coder; @@ -54,13 +57,39 @@ public class OptimizationPolicyTypeSerializationTest { } @Test - public void test() throws CoderException { - JpaToscaServiceTemplate svctmpl = loadYaml(INPUT_YAML); - validate("initial object", svctmpl); + public void testOptimization() throws CoderException { + JpaToscaServiceTemplate svctmpl = loadYaml(INPUT_OPTIMIZATION_YAML); + validate("initial object", svctmpl, TYPE_ROOT, "onap.policies.Optimization", false, false); String ser = serialize(svctmpl); JpaToscaServiceTemplate svctmpl2 = deserialize(ser); - validate("copy", svctmpl2); + validate("copy", svctmpl2, TYPE_ROOT, "onap.policies.Optimization", false, false); + + assertEquals(svctmpl, svctmpl2); + } + + @Test + public void testOptimizationResource() throws CoderException { + JpaToscaServiceTemplate svctmpl = loadYaml(INPUT_OPTIMIZATION_RESOURCE_YAML); + validate("initial object", svctmpl, "onap.policies.Optimization", "onap.policies.optimization.Resource", true, + true); + + String ser = serialize(svctmpl); + JpaToscaServiceTemplate svctmpl2 = deserialize(ser); + validate("copy", svctmpl2, "onap.policies.Optimization", "onap.policies.optimization.Resource", true, true); + + assertEquals(svctmpl, svctmpl2); + } + + @Test + public void testOptimizationService() throws CoderException { + JpaToscaServiceTemplate svctmpl = loadYaml(INPUT_OPTIMIZATION_SERVICE_YAML); + validate("initial object", svctmpl, "onap.policies.Optimization", "onap.policies.optimization.Service", false, + true); + + String ser = serialize(svctmpl); + JpaToscaServiceTemplate svctmpl2 = deserialize(ser); + validate("copy", svctmpl2, "onap.policies.Optimization", "onap.policies.optimization.Service", false, true); assertEquals(svctmpl, svctmpl2); } @@ -86,29 +115,32 @@ public class OptimizationPolicyTypeSerializationTest { return coder.encode(auth); } - private void validate(String testnm, JpaToscaServiceTemplate svctmpl) { + private void validate(String testnm, JpaToscaServiceTemplate svctmpl, String derivedFrom, + String typeName, boolean checkResource, boolean checkService) { JpaToscaPolicyTypes policyTypes = svctmpl.getPolicyTypes(); assertEquals(testnm + " type count", 1, policyTypes.getConceptMap().size()); JpaToscaPolicyType policyType = policyTypes.getConceptMap().values().iterator().next(); - assertEquals(testnm + " name", "onap.policies.Optimization", policyType.getName()); + assertEquals(testnm + " name", typeName, policyType.getName()); assertEquals(testnm + " version", VERSION, policyType.getVersion()); assertNotNull(testnm + " derived from", policyType.getDerivedFrom()); - assertEquals(testnm + " derived from name", TYPE_ROOT, policyType.getDerivedFrom().getName()); - - assertEquals(testnm + " description", "The base policy type for all policies that govern optimization", - policyType.getDescription()); + assertEquals(testnm + " derived from name", derivedFrom, policyType.getDerivedFrom().getName()); Map<String, JpaToscaProperty> props = policyType.getProperties(); assertNotNull(testnm + " properties", props); - validateScope(testnm, props.get("scope")); - validateServices(testnm, props.get("services")); - validateResources(testnm, props.get("resources")); - validateGeography(testnm, props.get("geography")); - validateIdentity(testnm, props.get("identity")); + if (checkResource && checkService) { + validateResources(testnm, props.get("resources")); + validateServices(testnm, props.get("services")); + } else if (checkService && !checkResource) { + validateServices(testnm, props.get("services")); + } else { + validateScope(testnm, props.get("scope")); + validateGeography(testnm, props.get("geography")); + validateIdentity(testnm, props.get("identity")); + } } // only need to validate deep match of one of these; geography is the most interesting |