From b0a27abb7d8812d5a73f65645df0bdbf06e4d64d Mon Sep 17 00:00:00 2001 From: Pamela Dragosh Date: Tue, 10 Mar 2020 07:54:05 -0400 Subject: Fix optimization bug add coverage plus Fix a NPE bug and add more code coverage. Also is missing returning of context details for subscriber policies. This code is a bit ad-hoc and there is a separate JIRA POLICY-2147 to support re-factoring this codebase. Added scanning for advice to be returned. For optimization, because of the need for some changes in XACML github dependency, we are stuck with a little narly code to get it to fully work. POLICY-2417 is created to address this in Guilen. Upgraded to released XACML artifact - this has been tested locally for a few weeks with naming, guard and this optimzation code. It removed Jackson in lieu of Json, cleaned up some security fixes, upgraded dependencies, and added more code coverage. Issue-ID: POLICY-2066 Change-Id: I3cae99de265c815200ec2ce71e471338772bdb5b Signed-off-by: Pamela Dragosh --- .../optimization/OptimizationPdpApplication.java | 117 +++++++++++++-------- .../OptimizationPdpApplicationTranslator.java | 105 ++++++++++++++---- .../OptimizationSubscriberRequest.java | 6 +- 3 files changed, 165 insertions(+), 63 deletions(-) (limited to 'applications/optimization/src/main') 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 e921dce8..d0f4b1eb 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 @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 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. @@ -52,6 +52,18 @@ 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 static final String RESOURCE_POLICYTYPE = "policy-type"; + private static final String RESOURCE_SCOPE = "scope"; + + public static final String POLICYTYPE_AFFINITY = "onap.policies.optimization.resource.AffinityPolicy"; + public static final String POLICYTYPE_SUBSCRIBER = "onap.policies.optimization.service.SubscriberPolicy"; + public static final String POLICYTYPE_DISTANCE = "onap.policies.optimization.resource.DistancePolicy"; + public static final String POLICYTYPE_HPA = "onap.policies.optimization.resource.HpaPolicy"; + public static final String POLICYTYPE_OPTIMIZATION = "onap.policies.optimization.resource.OptimizationPolicy"; + public static final String POLICYTYPE_PCI = "onap.policies.optimization.resource.PciPolicy"; + public static final String POLICYTYPE_QUERY = "onap.policies.optimization.service.QueryPolicy"; + public static final String POLICYTYPE_VIMFIT = "onap.policies.optimization.resource.Vim_fit"; + public static final String POLICYTYPE_VNF = "onap.policies.optimization.resource.VnfPolicy"; private OptimizationPdpApplicationTranslator translator = new OptimizationPdpApplicationTranslator(); private List supportedPolicyTypes = new ArrayList<>(); @@ -60,24 +72,15 @@ public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvid * Constructor. */ public OptimizationPdpApplication() { - this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier( - "onap.policies.optimization.resource.AffinityPolicy", STRING_VERSION100)); - this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier( - "onap.policies.optimization.resource.DistancePolicy", STRING_VERSION100)); - this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier( - "onap.policies.optimization.resource.HpaPolicy", STRING_VERSION100)); - this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier( - "onap.policies.optimization.resource.OptimizationPolicy", STRING_VERSION100)); - this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier( - "onap.policies.optimization.resource.PciPolicy", STRING_VERSION100)); - this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier( - "onap.policies.optimization.service.QueryPolicy", STRING_VERSION100)); - this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier( - "onap.policies.optimization.service.SubscriberPolicy", STRING_VERSION100)); - this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier( - "onap.policies.optimization.resource.Vim_fit", STRING_VERSION100)); - this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier( - "onap.policies.optimization.resource.VnfPolicy", STRING_VERSION100)); + this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_AFFINITY, STRING_VERSION100)); + this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_DISTANCE, STRING_VERSION100)); + this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_HPA, STRING_VERSION100)); + this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_OPTIMIZATION, STRING_VERSION100)); + this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_PCI, STRING_VERSION100)); + this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_QUERY, STRING_VERSION100)); + this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_SUBSCRIBER, STRING_VERSION100)); + this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_VIMFIT, STRING_VERSION100)); + this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier(POLICYTYPE_VNF, STRING_VERSION100)); } @Override @@ -133,6 +136,10 @@ public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvid public Pair makeDecision(DecisionRequest request, Map requestQueryParams) { // + // In case we have a subcriber policy + // + Response xacmlSubscriberResponse = null; + // // Check if there are subject attributes for subscriber // if (hasSubscriberAttributes(request)) { @@ -147,16 +154,16 @@ public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvid // // Override the PolicyType to ensure we are only looking at Subscriber Policies // - if (subscriberRequest.getResource().containsKey("policy-type")) { - subscriberRequest.getResource().remove("policy-type"); + if (subscriberRequest.getResource().containsKey(RESOURCE_POLICYTYPE)) { + subscriberRequest.getResource().remove(RESOURCE_POLICYTYPE); } - subscriberRequest.getResource().put("policy-type", "onap.policies.optimization.service.SubscriberPolicy"); + subscriberRequest.getResource().put(RESOURCE_POLICYTYPE, POLICYTYPE_SUBSCRIBER); // // Convert to a XacmlRequest and get a decision // - Response xacmlResponse = null; try { - xacmlResponse = this.xacmlDecision(OptimizationSubscriberRequest.createInstance(subscriberRequest)); + xacmlSubscriberResponse = + this.xacmlDecision(OptimizationSubscriberRequest.createInstance(subscriberRequest)); } catch (XacmlApplicationException e) { LOGGER.error("Could not create subscriberName request {}", e); } @@ -164,12 +171,12 @@ public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvid // Check the response for subscriber attributes and add them // to the initial request. // - if (! addSubscriberAttributes(xacmlResponse, request)) { - LOGGER.error("Failed to get subscriber attributes"); + if (xacmlSubscriberResponse != null && ! addSubscriberAttributes(xacmlSubscriberResponse, request)) { + LOGGER.error("Failed to get subscriber role attributes"); // // Convert to a DecisionResponse // - return Pair.of(this.getTranslator().convertResponse(xacmlResponse), xacmlResponse); + return Pair.of(this.getTranslator().convertResponse(xacmlSubscriberResponse), xacmlSubscriberResponse); } } // @@ -183,7 +190,15 @@ public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvid // // Convert to a DecisionResponse // - return Pair.of(this.getTranslator().convertResponse(xacmlResponse), xacmlResponse); + Pair returnPair = Pair.of(this.getTranslator().convertResponse(xacmlResponse), + xacmlResponse); + // + // Add back in advice from subscriber + // + if (xacmlSubscriberResponse != null) { + addSubscriberAdvice(xacmlSubscriberResponse, returnPair.getLeft()); + } + return returnPair; } @Override @@ -204,7 +219,9 @@ public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvid private boolean addSubscriberAttributes(Response xacmlResponse, DecisionRequest initialRequest) { // - // Should only be one result + // This has multiple results right now because of how the attributes were added to the + // request. That will have to be fixed in the future, for now find the Permit result + // and add the role attributes as they will be used in the next request. // for (Result result : xacmlResponse.getResults()) { // @@ -216,7 +233,7 @@ public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvid // scanAdvice(result.getAssociatedAdvice(), initialRequest); // - // PLD this is an assumption + // PLD this is an assumption that all is good // return true; } else { @@ -226,6 +243,21 @@ public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvid return false; } + private void addSubscriberAdvice(Response xacmlResponse, DecisionResponse response) { + // + // Again find the Permit result + // + for (Result result : xacmlResponse.getResults()) { + // + // Check the result + // + if (result.getStatus().isOk() && Decision.PERMIT.equals(result.getDecision())) { + this.translator.scanAdvice(result.getAssociatedAdvice(), response); + } + } + } + + @SuppressWarnings("unchecked") private void scanAdvice(Collection adviceCollection, DecisionRequest initialRequest) { // @@ -235,20 +267,21 @@ public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvid // // Look for the optimization specific advice // - if (ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER.equals(advice.getId())) { + if (! ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER.equals(advice.getId())) { + LOGGER.error("Unsupported advice id {}", advice.getId()); + continue; + } + // + // Get the attributes and add them + // + for (AttributeAssignment attribute : advice.getAttributeAssignments()) { // - // 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) initialRequest.getResource().get("scope")).add(attribute.getAttributeValue() - .getValue().toString()); - } + // If this is subscriber role + // + if (ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER_ROLE.equals(attribute.getAttributeId())) { + ((List) initialRequest.getResource().get(RESOURCE_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 index 7ec8f676..d56b73ae 100644 --- 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 @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 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. @@ -22,12 +22,17 @@ 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.Identifier; 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.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Map; import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType; @@ -40,6 +45,7 @@ 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.decisions.concepts.DecisionResponse; 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; @@ -54,6 +60,9 @@ public class OptimizationPdpApplicationTranslator extends StdMatchableTranslator private static final String OPTIMIZATION_POLICYTYPE_SUBSCRIBER = "onap.policies.optimization.service.SubscriberPolicy"; + private static final String FIELD_SUBSCRIBER_ROLE = "subscriberRole"; + private static final String FIELD_PROV_STATUS = "provStatus"; + @SuppressWarnings("unchecked") @Override public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException { @@ -81,7 +90,7 @@ public class OptimizationPdpApplicationTranslator extends StdMatchableTranslator // // Add subscriber advice // - policy.setAdviceExpressions(generateSubscriberAdvice(toscaPolicy, subscriberProperties)); + policy.setAdviceExpressions(generateSubscriberAdvice(subscriberProperties)); // // Dump our revised policy out // @@ -95,6 +104,49 @@ public class OptimizationPdpApplicationTranslator extends StdMatchableTranslator return policy; } + @Override + protected void scanAdvice(Collection advice, DecisionResponse decisionResponse) { + for (Advice adv : advice) { + if (! ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER.equals(adv.getId())) { + LOGGER.warn("Unknown advice id {}", adv.getId()); + continue; + } + // + // Get the existing advice if any, we are appending to it. + // + Map mapAdvice = decisionResponse.getAdvice(); + // + // If there's nothing, create a map + // + if (mapAdvice == null) { + mapAdvice = new HashMap<>(); + } + for (AttributeAssignment assignment : adv.getAttributeAssignments()) { + if (ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER_ROLE.equals(assignment.getAttributeId())) { + addValuesToMap(assignment.getAttributeValue().getValue(), FIELD_SUBSCRIBER_ROLE, mapAdvice); + } else if (ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER_STATUS.equals( + assignment.getAttributeId())) { + addValuesToMap(assignment.getAttributeValue().getValue(), FIELD_PROV_STATUS, mapAdvice); + } + } + if (! mapAdvice.isEmpty()) { + decisionResponse.setAdvice(mapAdvice); + } + } + } + + @SuppressWarnings("unchecked") + private static void addValuesToMap(Object values, String key, Map mapAdvice) { + if (values instanceof Collection) { + List valueList = new ArrayList<>(); + ((Collection) values).forEach(val -> valueList.add(val.toString())); + mapAdvice.put(key, valueList); + } else { + mapAdvice.put(key, values.toString()); + } + + } + @SuppressWarnings("unchecked") private static PolicyType addSubscriberNameIntoTarget(PolicyType policy, Map subscriberProperties) throws ToscaPolicyConversionException { @@ -132,50 +184,63 @@ public class OptimizationPdpApplicationTranslator extends StdMatchableTranslator } @SuppressWarnings("unchecked") - private static AdviceExpressionsType generateSubscriberAdvice(ToscaPolicy toscaPolicy, - Map subscriberProperties) throws ToscaPolicyConversionException { + private static AdviceExpressionsType generateSubscriberAdvice(Map subscriberProperties) + throws ToscaPolicyConversionException { // // Get the subscriber role // - Object role = subscriberProperties.get("subscriberRole"); + Object role = subscriberProperties.get(FIELD_SUBSCRIBER_ROLE); 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 + // Create our subscriber advice expression // AdviceExpressionType adviceExpression = new AdviceExpressionType(); adviceExpression.setAppliesTo(EffectType.PERMIT); adviceExpression.setAdviceId(ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER.stringValue()); // - // Add in subscriber role + // Add in subscriber role advice attributes + // + generateSubscriberAdviceAttributes( + adviceExpression, + ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER_ROLE, + role instanceof Collection ? (List) role : Arrays.asList(role)); + // + // Get the provision status + // + Object provision = subscriberProperties.get(FIELD_PROV_STATUS); + if (provision == null || StringUtils.isBlank(provision.toString())) { + throw new ToscaPolicyConversionException("Missing provStatus"); + } + adviceExpression = generateSubscriberAdviceAttributes( + adviceExpression, + ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER_STATUS, + role instanceof Collection ? (List) provision : Arrays.asList(role)); + // + // Add it to the overall expressions // - generateSubscriberRoleAdvice(adviceExpression, role instanceof Collection ? (List) role : - Arrays.asList(role)); - AdviceExpressionsType adviceExpressions = new AdviceExpressionsType(); adviceExpressions.getAdviceExpression().add(adviceExpression); - + // + // Done return our advice expressions + // return adviceExpressions; } - private static AdviceExpressionType generateSubscriberRoleAdvice(AdviceExpressionType adviceExpression, - Collection subscriberRoles) { - for (Object subscriberRole : subscriberRoles) { + private static AdviceExpressionType generateSubscriberAdviceAttributes(AdviceExpressionType adviceExpression, + Identifier attributeId, Collection adviceAttribute) { + for (Object attribute : adviceAttribute) { AttributeValueType value = new AttributeValueType(); value.setDataType(XACML3.ID_DATATYPE_STRING.stringValue()); - value.getContent().add(subscriberRole.toString()); + value.getContent().add(attribute.toString()); AttributeAssignmentExpressionType assignment = new AttributeAssignmentExpressionType(); - assignment.setAttributeId(ToscaDictionary.ID_ADVICE_OPTIMIZATION_SUBSCRIBER_ROLE.stringValue()); + assignment.setAttributeId(attributeId.stringValue()); assignment.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue()); assignment.setExpression(new ObjectFactory().createAttributeValue(value)); adviceExpression.getAttributeAssignmentExpression().add(assignment); - } // // Return for convenience 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 index b1028e89..263c6540 100644 --- 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 @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 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. @@ -72,6 +72,10 @@ public class OptimizationSubscriberRequest extends StdMatchablePolicyRequest { Map contexts = decisionRequest.getContext(); for (Entry entrySet : contexts.entrySet()) { try { + // + // Should always be a collection, but in case someone changes + // the class without checking this repo. + // if (entrySet.getValue() instanceof Collection) { addSubject(contextAttributes, (Collection) entrySet.getValue(), ToscaDictionary.ID_SUBJECT_OPTIMIZATION_SUBSCRIBER_NAME); -- cgit 1.2.3-korg