diff options
author | Pamela Dragosh <pdragosh@research.att.com> | 2020-03-10 07:54:05 -0400 |
---|---|---|
committer | Pamela Dragosh <pdragosh@research.att.com> | 2020-03-10 09:37:44 -0400 |
commit | b0a27abb7d8812d5a73f65645df0bdbf06e4d64d (patch) | |
tree | 966f321e7d7259a6816ebeac28680ca1571752b6 /applications/optimization/src/main/java | |
parent | a0ad29cdb6d6f541aac59f9e265f79d3ad085560 (diff) |
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 <pdragosh@research.att.com>
Diffstat (limited to 'applications/optimization/src/main/java')
3 files changed, 165 insertions, 63 deletions
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<ToscaPolicyTypeIdentifier> 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<DecisionResponse, Response> makeDecision(DecisionRequest request, Map<String, String[]> 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<DecisionResponse, Response> 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<Advice> 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<String>) 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<String>) 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> 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<String, Object> 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<String, Object> mapAdvice) { + if (values instanceof Collection) { + List<String> valueList = new ArrayList<>(); + ((Collection<Object>) 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<String, Object> subscriberProperties) throws ToscaPolicyConversionException { @@ -132,50 +184,63 @@ public class OptimizationPdpApplicationTranslator extends StdMatchableTranslator } @SuppressWarnings("unchecked") - private static AdviceExpressionsType generateSubscriberAdvice(ToscaPolicy toscaPolicy, - Map<String, Object> subscriberProperties) throws ToscaPolicyConversionException { + private static AdviceExpressionsType generateSubscriberAdvice(Map<String, Object> 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<Object>) 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<Object>) provision : Arrays.asList(role)); + // + // Add it to the overall expressions // - generateSubscriberRoleAdvice(adviceExpression, role instanceof Collection ? (List<Object>) 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<Object> subscriberRoles) { - for (Object subscriberRole : subscriberRoles) { + private static AdviceExpressionType generateSubscriberAdviceAttributes(AdviceExpressionType adviceExpression, + Identifier attributeId, Collection<Object> 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<String, Object> contexts = decisionRequest.getContext(); for (Entry<String, Object> 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); |