diff options
author | Pamela Dragosh <pdragosh@research.att.com> | 2019-12-11 10:00:21 -0500 |
---|---|---|
committer | Pamela Dragosh <pdragosh@research.att.com> | 2019-12-23 13:33:19 +0000 |
commit | 85744c81b27a833db4a8089c90a4faeb98d8f349 (patch) | |
tree | 290b6c6f6dfcc7c108182c6af44116e7bcfae581 | |
parent | 4ff3b261231274ec9f3cd957ba50108fef3e0eb5 (diff) |
Add optimization subscriber request
Adding support for a preliminary request to pull subscriber details.
The returned decision adds scope attributes for the original request.
Fixed some checkstyle issues due to new checkstyle requirements.
Issue-ID: POLICY-2066
Change-Id: Ief02d896ce33e4864bb20e9185b0d0f5eb254bfd
Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
10 files changed, 515 insertions, 30 deletions
diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaDictionary.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaDictionary.java index 1a899971..c8dab3a8 100644 --- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaDictionary.java +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaDictionary.java @@ -106,6 +106,22 @@ public final class ToscaDictionary { new IdentifierImpl(ID_URN_ONAP, "guard:advice:request-id"); /* + * These id's are specifically for optimization subscriber policies + */ + public static final Identifier ID_SUBJECT_OPTIMIZATION_SUBSCRIBER_NAME = + new IdentifierImpl(ID_URN_ONAP, "optimization:subscriber:name"); + + /* + * These ids are specifically for optimization advice + */ + public static final Identifier ID_ADVICE_OPTIMIZATION_SUBSCRIBER = + new IdentifierImpl(ID_URN_ONAP, "optimization:advice:subscriber"); + public static final Identifier ID_ADVICE_OPTIMIZATION_SUBSCRIBER_ROLE = + new IdentifierImpl(ID_URN_ONAP, "optimization:advice:subscriber:role"); + public static final Identifier ID_ADVICE_OPTIMIZATION_SUBSCRIBER_STATUS = + new IdentifierImpl(ID_URN_ONAP, "optimization:advice:subscriber:status"); + + /* * Obligation specific ID's */ diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchablePolicyRequest.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchablePolicyRequest.java index b478e8c1..2d83b897 100644 --- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchablePolicyRequest.java +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchablePolicyRequest.java @@ -163,7 +163,7 @@ public class StdMatchablePolicyRequest { return mutableRequest; } - private static StdMutableRequestAttributes addResources(StdMutableRequestAttributes attributes, + protected static StdMutableRequestAttributes addResources(StdMutableRequestAttributes attributes, Collection<Object> values, String id) throws DataTypeException { DataTypeFactory factory = getDataTypeFactory(); diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdXacmlApplicationServiceProvider.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdXacmlApplicationServiceProvider.java index 5aea3457..e43e6519 100644 --- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdXacmlApplicationServiceProvider.java +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdXacmlApplicationServiceProvider.java @@ -121,8 +121,7 @@ public abstract class StdXacmlApplicationServiceProvider implements XacmlApplica // // Convert the policies first // - PolicyType xacmlPolicy = this.getTranslator(toscaPolicy.getType()) - .convertPolicy(toscaPolicy); + PolicyType xacmlPolicy = this.getTranslator(toscaPolicy.getType()).convertPolicy(toscaPolicy); if (xacmlPolicy == null) { throw new ToscaPolicyConversionException("Failed to convert policy"); } diff --git a/applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplication.java b/applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplication.java index c5a9e7cf..e921dce8 100644 --- a/applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplication.java +++ b/applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplication.java @@ -22,16 +22,27 @@ package org.onap.policy.xacml.pdp.application.optimization; +import com.att.research.xacml.api.Advice; +import com.att.research.xacml.api.AttributeAssignment; +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.Response; +import com.att.research.xacml.api.Result; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; +import org.apache.commons.lang3.tuple.Pair; import org.onap.policy.common.endpoints.parameters.RestServerParameters; +import org.onap.policy.models.decisions.concepts.DecisionRequest; +import org.onap.policy.models.decisions.concepts.DecisionResponse; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; +import org.onap.policy.pdp.xacml.application.common.ToscaDictionary; import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator; import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException; -import org.onap.policy.pdp.xacml.application.common.std.StdMatchableTranslator; import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,8 +51,9 @@ public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvid private static final Logger LOGGER = LoggerFactory.getLogger(OptimizationPdpApplication.class); private static final String STRING_VERSION100 = "1.0.0"; + private static final String RESOURCE_SUBSCRIBERNAME = "subscriberName"; - private StdMatchableTranslator translator = new StdMatchableTranslator(); + private OptimizationPdpApplicationTranslator translator = new OptimizationPdpApplicationTranslator(); private List<ToscaPolicyTypeIdentifier> supportedPolicyTypes = new ArrayList<>(); /** @@ -118,6 +130,63 @@ public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvid } @Override + public Pair<DecisionResponse, Response> makeDecision(DecisionRequest request, + Map<String, String[]> requestQueryParams) { + // + // Check if there are subject attributes for subscriber + // + if (hasSubscriberAttributes(request)) { + // + // We must do an initial request to pull subscriber attributes + // + LOGGER.info("Request Subscriber attributes"); + // + // Convert the request + // + DecisionRequest subscriberRequest = new DecisionRequest(request); + // + // Override the PolicyType to ensure we are only looking at Subscriber Policies + // + if (subscriberRequest.getResource().containsKey("policy-type")) { + subscriberRequest.getResource().remove("policy-type"); + } + subscriberRequest.getResource().put("policy-type", "onap.policies.optimization.service.SubscriberPolicy"); + // + // Convert to a XacmlRequest and get a decision + // + Response xacmlResponse = null; + try { + xacmlResponse = this.xacmlDecision(OptimizationSubscriberRequest.createInstance(subscriberRequest)); + } catch (XacmlApplicationException e) { + LOGGER.error("Could not create subscriberName request {}", e); + } + // + // Check the response for subscriber attributes and add them + // to the initial request. + // + if (! addSubscriberAttributes(xacmlResponse, request)) { + LOGGER.error("Failed to get subscriber attributes"); + // + // Convert to a DecisionResponse + // + return Pair.of(this.getTranslator().convertResponse(xacmlResponse), xacmlResponse); + } + } + // + // Convert to a XacmlRequest + // + Request xacmlRequest = this.getTranslator().convertRequest(request); + // + // Now get a decision + // + Response xacmlResponse = this.xacmlDecision(xacmlRequest); + // + // Convert to a DecisionResponse + // + return Pair.of(this.getTranslator().convertResponse(xacmlResponse), xacmlResponse); + } + + @Override protected ToscaPolicyTranslator getTranslator(String type) { // // Return translator @@ -125,4 +194,63 @@ public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvid return translator; } + @SuppressWarnings("unchecked") + private boolean hasSubscriberAttributes(DecisionRequest request) { + return request.getContext() != null + && request.getContext().containsKey(RESOURCE_SUBSCRIBERNAME) + && request.getContext().get(RESOURCE_SUBSCRIBERNAME) instanceof List + && ! ((List<String>) request.getContext().get(RESOURCE_SUBSCRIBERNAME)).isEmpty(); + } + + private boolean addSubscriberAttributes(Response xacmlResponse, DecisionRequest initialRequest) { + // + // Should only be one result + // + for (Result result : xacmlResponse.getResults()) { + // + // Check the result + // + if (result.getStatus().isOk() && result.getDecision().equals(Decision.PERMIT)) { + // + // Pull out the advice which has attributes + // + scanAdvice(result.getAssociatedAdvice(), initialRequest); + // + // PLD this is an assumption + // + return true; + } else { + LOGGER.error("XACML result not ok {} or Permit {}", result.getStatus(), result.getDecision()); + } + } + return false; + } + + @SuppressWarnings("unchecked") + private void scanAdvice(Collection<Advice> adviceCollection, DecisionRequest initialRequest) { + // + // There really should only be one advice object + // + for (Advice advice : adviceCollection) { + // + // Look for the optimization specific advice + // + if (ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER.equals(advice.getId())) { + // + // Get the attributes and add them + for (AttributeAssignment attribute : advice.getAttributeAssignments()) { + // + // If this is subscriber role + // + if (ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER_ROLE.equals(attribute.getAttributeId())) { + ((List<String>) initialRequest.getResource().get("scope")).add(attribute.getAttributeValue() + .getValue().toString()); + } + } + } else { + LOGGER.error("Unsupported advice id {}", advice.getId()); + } + } + } + } diff --git a/applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplicationTranslator.java b/applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplicationTranslator.java new file mode 100644 index 00000000..7ec8f676 --- /dev/null +++ b/applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplicationTranslator.java @@ -0,0 +1,185 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * 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.xacml.pdp.application.optimization; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.util.XACMLPolicyWriter; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; +import org.apache.commons.lang3.StringUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.pdp.xacml.application.common.ToscaDictionary; +import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException; +import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslatorUtils; +import org.onap.policy.pdp.xacml.application.common.std.StdMatchableTranslator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class OptimizationPdpApplicationTranslator extends StdMatchableTranslator { + private static final Logger LOGGER = LoggerFactory.getLogger(OptimizationPdpApplicationTranslator.class); + + private static final String OPTIMIZATION_POLICYTYPE_SUBSCRIBER = + "onap.policies.optimization.service.SubscriberPolicy"; + + @SuppressWarnings("unchecked") + @Override + public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException { + // + // Have our superclass do the work + // + PolicyType policy = super.convertPolicy(toscaPolicy); + // + // Check if this is the subscriber policy + // + if (OPTIMIZATION_POLICYTYPE_SUBSCRIBER.equals(toscaPolicy.getType())) { + // + // Ensure the policy has the subscriber properties + // + Map<String, Object> subscriberProperties = (Map<String, Object>) toscaPolicy.getProperties() + .get("subscriberProperties"); + if (subscriberProperties == null) { + throw new ToscaPolicyConversionException("Missing subscriberProperties from subscriber policy"); + } + // + // Add subscriber name to the target so the policy + // only matches for the given subscriberName. + // + addSubscriberNameIntoTarget(policy, subscriberProperties); + // + // Add subscriber advice + // + policy.setAdviceExpressions(generateSubscriberAdvice(toscaPolicy, subscriberProperties)); + // + // Dump our revised policy out + // + try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { + XACMLPolicyWriter.writePolicyFile(os, policy); + LOGGER.info("{}", os); + } catch (IOException e) { + LOGGER.error("Failed to create byte array stream", e); + } + } + return policy; + } + + @SuppressWarnings("unchecked") + private static PolicyType addSubscriberNameIntoTarget(PolicyType policy, + Map<String, Object> subscriberProperties) throws ToscaPolicyConversionException { + // + // Find the subscriber names + // + Object subscriberNames = subscriberProperties.get("subscriberName"); + if (subscriberNames == null) { + throw new ToscaPolicyConversionException("Missing subscriberName property"); + } + // + // Iterate through all the subscriber names + // + AnyOfType anyOf = new AnyOfType(); + for (Object subscriberName : subscriberNames instanceof Collection ? (List<Object>) subscriberNames : + Arrays.asList(subscriberNames)) { + + MatchType match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator( + XACML3.ID_FUNCTION_STRING_EQUAL, + subscriberName, + XACML3.ID_DATATYPE_STRING, + ToscaDictionary.ID_SUBJECT_OPTIMIZATION_SUBSCRIBER_NAME, + XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT); + + anyOf.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(match)); + } + // + // Add to the target + // + policy.getTarget().getAnyOf().add(anyOf); + // + // Return for convenience + // + return policy; + } + + @SuppressWarnings("unchecked") + private static AdviceExpressionsType generateSubscriberAdvice(ToscaPolicy toscaPolicy, + Map<String, Object> subscriberProperties) throws ToscaPolicyConversionException { + // + // Get the subscriber role + // + Object role = subscriberProperties.get("subscriberRole"); + if (role == null || StringUtils.isBlank(role.toString())) { + throw new ToscaPolicyConversionException("Missing subscriberRole"); + } + // + // Get the provision status + // TODO + // + // Our subscriber Advice expression holds all the attribute assignments + // + AdviceExpressionType adviceExpression = new AdviceExpressionType(); + adviceExpression.setAppliesTo(EffectType.PERMIT); + adviceExpression.setAdviceId(ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER.stringValue()); + // + // Add in subscriber role + // + generateSubscriberRoleAdvice(adviceExpression, role instanceof Collection ? (List<Object>) role : + Arrays.asList(role)); + + AdviceExpressionsType adviceExpressions = new AdviceExpressionsType(); + adviceExpressions.getAdviceExpression().add(adviceExpression); + + return adviceExpressions; + } + + private static AdviceExpressionType generateSubscriberRoleAdvice(AdviceExpressionType adviceExpression, + Collection<Object> subscriberRoles) { + for (Object subscriberRole : subscriberRoles) { + AttributeValueType value = new AttributeValueType(); + value.setDataType(XACML3.ID_DATATYPE_STRING.stringValue()); + value.getContent().add(subscriberRole.toString()); + + AttributeAssignmentExpressionType assignment = new AttributeAssignmentExpressionType(); + assignment.setAttributeId(ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER_ROLE.stringValue()); + assignment.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue()); + assignment.setExpression(new ObjectFactory().createAttributeValue(value)); + + adviceExpression.getAttributeAssignmentExpression().add(assignment); + + } + // + // Return for convenience + // + return adviceExpression; + } +} diff --git a/applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationSubscriberRequest.java b/applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationSubscriberRequest.java new file mode 100644 index 00000000..b1028e89 --- /dev/null +++ b/applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationSubscriberRequest.java @@ -0,0 +1,113 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * 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.xacml.pdp.application.optimization; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.DataTypeException; +import com.att.research.xacml.api.DataTypeFactory; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdMutableAttribute; +import com.att.research.xacml.std.StdMutableRequest; +import com.att.research.xacml.std.StdMutableRequestAttributes; +import com.att.research.xacml.std.annotations.XACMLSubject; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import org.onap.policy.models.decisions.concepts.DecisionRequest; +import org.onap.policy.pdp.xacml.application.common.ToscaDictionary; +import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException; +import org.onap.policy.pdp.xacml.application.common.std.StdMatchablePolicyRequest; + +public class OptimizationSubscriberRequest extends StdMatchablePolicyRequest { + + @XACMLSubject(attributeId = "urn:org:onap:optimization:subscriber:name", includeInResults = true) + List<String> subscriberRoles; + + /** + * Create an instance of xacml request. + * + * @param decisionRequest Incoming DecisionRequest object + * @return XACML request + * @throws XacmlApplicationException XacmlApplicationException + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + public static Request createInstance(DecisionRequest decisionRequest) throws XacmlApplicationException { + Request request = StdMatchablePolicyRequest.createInstance(decisionRequest); + + // + // Add in the context attributes + // + StdMutableRequest mutableRequest = new StdMutableRequest(request); + StdMutableRequestAttributes contextAttributes = new StdMutableRequestAttributes(); + contextAttributes.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT); + // + // Add the context attributes + // + Map<String, Object> contexts = decisionRequest.getContext(); + for (Entry<String, Object> entrySet : contexts.entrySet()) { + try { + if (entrySet.getValue() instanceof Collection) { + addSubject(contextAttributes, (Collection) entrySet.getValue(), + ToscaDictionary.ID_SUBJECT_OPTIMIZATION_SUBSCRIBER_NAME); + } else { + addSubject(contextAttributes, Arrays.asList(entrySet.getValue().toString()), + ToscaDictionary.ID_SUBJECT_OPTIMIZATION_SUBSCRIBER_NAME); + } + } catch (DataTypeException e) { + throw new XacmlApplicationException("Failed to add resource ", e); + } + } + mutableRequest.add(contextAttributes); + return mutableRequest; + } + + protected static StdMutableRequestAttributes addSubject(StdMutableRequestAttributes attributes, + Collection<Object> values, Identifier id) throws DataTypeException { + + DataTypeFactory factory = getDataTypeFactory(); + if (factory == null) { + return null; + } + for (Object value : values) { + StdMutableAttribute mutableAttribute = new StdMutableAttribute(); + mutableAttribute.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT); + mutableAttribute.setAttributeId(id); + mutableAttribute.setIncludeInResults(true); + + DataType<?> dataTypeExtended = factory.getDataType(XACML3.ID_DATATYPE_STRING); + AttributeValue<?> attributeValue = dataTypeExtended.createAttributeValue(value); + Collection<AttributeValue<?>> attributeValues = new ArrayList<>(); + attributeValues.add(attributeValue); + mutableAttribute.setValues(attributeValues); + + attributes.add(mutableAttribute); + } + return attributes; + } +} diff --git a/applications/optimization/src/test/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplicationTest.java b/applications/optimization/src/test/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplicationTest.java index 1cb8f32a..e457e2f2 100644 --- a/applications/optimization/src/test/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplicationTest.java +++ b/applications/optimization/src/test/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplicationTest.java @@ -30,8 +30,6 @@ import static org.mockito.Mockito.when; import com.att.research.xacml.api.Response; import com.google.common.collect.Lists; import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Collection; @@ -162,6 +160,9 @@ public class OptimizationPdpApplicationTest { service.initialize(propertiesFile.toPath().getParent(), clientParams); } + /** + * Simply test some of the simple methods for the application. + */ @Test public void test01Basics() { // @@ -169,7 +170,7 @@ public class OptimizationPdpApplicationTest { // assertThat(service.applicationName()).isNotEmpty(); // - // Decisions + // Does it return the correct decisions // assertThat(service.actionDecisionsSupported().size()).isEqualTo(1); assertThat(service.actionDecisionsSupported()).contains("optimize"); @@ -185,6 +186,11 @@ public class OptimizationPdpApplicationTest { "onap.foobar", "1.0.0"))).isFalse(); } + /** + * With no policies loaded, there should be 0 policies returned. + * + * @throws CoderException CoderException + */ @Test public void test02NoPolicies() throws CoderException { // @@ -198,9 +204,13 @@ public class OptimizationPdpApplicationTest { assertThat(decision.getKey().getPolicies().size()).isEqualTo(0); } + /** + * Should return ONLY default policies. + * + * @throws XacmlApplicationException could not load policies + */ @Test - public void test03OptimizationDefault() throws CoderException, FileNotFoundException, IOException, - XacmlApplicationException { + public void test03OptimizationDefault() throws XacmlApplicationException { // // Now load all the optimization policies // @@ -218,10 +228,12 @@ public class OptimizationPdpApplicationTest { validateDecision(response, baseRequest); } + /** + * Should only return default HPA policy type. + */ @SuppressWarnings("unchecked") @Test - public void test04OptimizationDefaultHpa() throws CoderException, FileNotFoundException, IOException, - XacmlApplicationException { + public void test04OptimizationDefaultHpa() { // // Add in policy type // @@ -244,6 +256,9 @@ public class OptimizationPdpApplicationTest { validateDecision(response, baseRequest); } + /** + * Refine for US only policies. + */ @SuppressWarnings("unchecked") @Test public void test05OptimizationDefaultGeography() throws CoderException { @@ -267,9 +282,12 @@ public class OptimizationPdpApplicationTest { validateDecision(response, baseRequest); } + /** + * Add more refinement for service. + */ @SuppressWarnings("unchecked") @Test - public void test06OptimizationDefaultGeographyAndService() throws CoderException { + public void test06OptimizationDefaultGeographyAndService() { // // Add vCPE to the service list // @@ -280,16 +298,19 @@ public class OptimizationPdpApplicationTest { DecisionResponse response = makeDecision(); assertThat(response).isNotNull(); - assertThat(response.getPolicies().size()).isEqualTo(5); + assertThat(response.getPolicies().size()).isEqualTo(3); // // Validate it // validateDecision(response, baseRequest); } + /** + * Add more refinement for specific resource. + */ @SuppressWarnings("unchecked") @Test - public void test07OptimizationDefaultGeographyAndServiceAndResource() throws CoderException { + public void test07OptimizationDefaultGeographyAndServiceAndResource() { // // Add vG to the resource list // @@ -300,75 +321,91 @@ public class OptimizationPdpApplicationTest { DecisionResponse response = makeDecision(); assertThat(response).isNotNull(); - assertThat(response.getPolicies().size()).isEqualTo(8); + assertThat(response.getPolicies().size()).isEqualTo(6); // // Validate it // validateDecision(response, baseRequest); } + /** + * Now we need to add in subscriberName in order to get scope for gold. + */ @SuppressWarnings("unchecked") @Test - public void test08OptimizationGeographyAndServiceAndResourceAndScope() throws CoderException { + public void test08OptimizationGeographyAndServiceAndResourceAndScopeIsGoldSubscriber() { // // Add gold as a scope // - ((List<String>)baseRequest.getResource().get("scope")).add("gold"); + //((List<String>)baseRequest.getResource().get("scope")).add("gold"); + ((List<String>)baseRequest.getContext().get("subscriberName")).add("subscriber_a"); // // Ask for a decision for specific US vCPE vG gold // DecisionResponse response = makeDecision(); assertThat(response).isNotNull(); - assertThat(response.getPolicies().size()).isEqualTo(8); + assertThat(response.getPolicies().size()).isEqualTo(6); // // Validate it // validateDecision(response, baseRequest); } + /** + * Add a subscriber that should be platinum. + */ @SuppressWarnings("unchecked") @Test - public void test09OptimizationGeographyAndServiceAndResourceAndScopeIsGoldOrPlatinum() throws CoderException { + public void test09OptimizationGeographyAndServiceAndResourceAndScopeGoldOrPlatinumSubscriber() { // // Add platinum to the scope list: this is now gold OR platinum // - ((List<String>)baseRequest.getResource().get("scope")).add("platinum"); + ((List<String>)baseRequest.getResource().get("scope")).remove("gold"); + ((List<String>)baseRequest.getContext().get("subscriberName")).add("subscriber_x"); // // Ask for a decision for specific US vCPE vG (gold or platinum) // DecisionResponse response = makeDecision(); assertThat(response).isNotNull(); - assertThat(response.getPolicies().size()).isEqualTo(10); + assertThat(response.getPolicies().size()).isEqualTo(8); // // Validate it // validateDecision(response, baseRequest); } + /** + * Remove gold subscriber, keep the platinum one. + */ @SuppressWarnings("unchecked") @Test - public void test10OptimizationGeographyAndServiceAndResourceAndScopeNotGold() throws CoderException { + public void test10OptimizationGeographyAndServiceAndResourceAndScopeNotGoldStillPlatinum() { // // Add gold as a scope // ((List<String>)baseRequest.getResource().get("scope")).remove("gold"); + ((List<String>)baseRequest.getResource().get("scope")).remove("platinum"); + ((List<String>)baseRequest.getContext().get("subscriberName")).remove("subscriber_a"); // // Ask for a decision for specific US vCPE vG gold // DecisionResponse response = makeDecision(); assertThat(response).isNotNull(); - assertThat(response.getPolicies().size()).isEqualTo(9); + assertThat(response.getPolicies().size()).isEqualTo(7); // // Validate it // validateDecision(response, baseRequest); } + /** + * Filter by Affinity policy. + */ @Test - public void test11OptimizationPolicyTypeDefault() throws CoderException { + public void test11OptimizationPolicyTypeDefault() { // // Add in policy type // @@ -387,9 +424,12 @@ public class OptimizationPdpApplicationTest { validateDecision(response, baseRequest); } + /** + * Now filter by HPA policy type. + */ @SuppressWarnings("unchecked") @Test - public void test12OptimizationPolicyTypeDefault() throws CoderException { + public void test12OptimizationPolicyTypeDefault() { // // Add in another policy type // diff --git a/applications/optimization/src/test/resources/decision.optimization.input.json b/applications/optimization/src/test/resources/decision.optimization.input.json index 3872ca90..523b9d5d 100644 --- a/applications/optimization/src/test/resources/decision.optimization.input.json +++ b/applications/optimization/src/test/resources/decision.optimization.input.json @@ -2,6 +2,9 @@ "ONAPName": "OOF", "ONAPComponent": "OOF-component", "ONAPInstance": "OOF-component-instance", + "context" : { + "subscriberName": [] + }, "action": "optimize", "resource": { "scope": [], diff --git a/applications/optimization/src/test/resources/vCPE.policies.optimization.input.tosca.yaml b/applications/optimization/src/test/resources/vCPE.policies.optimization.input.tosca.yaml index 3eedac95..fb848637 100644 --- a/applications/optimization/src/test/resources/vCPE.policies.optimization.input.tosca.yaml +++ b/applications/optimization/src/test/resources/vCPE.policies.optimization.input.tosca.yaml @@ -291,7 +291,7 @@ topology_template: scope: [] services: [vCPE] identity: subscriber_vCPE - properties: + subscriberProperties: subscriberName: [subscriber_x, subscriber_y] subscriberRole: [platinum] provStatus: [CAPPED] @@ -307,7 +307,7 @@ topology_template: scope: [] services: [vCPE] identity: subscriber_vCPE - properties: + subscriberProperties: subscriberName: [subscriber_a, subscriber_b] subscriberRole: [gold] provStatus: [CAPPED] diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/DecisionProvider.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/DecisionProvider.java index a5141b90..b6a4e5a0 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/DecisionProvider.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/DecisionProvider.java @@ -39,9 +39,10 @@ public class DecisionProvider { /** * Retrieves the policy decision for the specified parameters. - * @param body * - * @return the Decision object + * @param request DecisionRequest + * @param queryParams Map of parameters + * @return DecisionResponse */ public DecisionResponse fetchDecision(DecisionRequest request, Map<String, String[]> queryParams) { LOGGER.debug("Fetching decision {}", request); |