summaryrefslogtreecommitdiffstats
path: root/applications/optimization/src/main
diff options
context:
space:
mode:
authorPamela Dragosh <pdragosh@research.att.com>2019-12-11 10:00:21 -0500
committerPamela Dragosh <pdragosh@research.att.com>2019-12-23 13:33:19 +0000
commit85744c81b27a833db4a8089c90a4faeb98d8f349 (patch)
tree290b6c6f6dfcc7c108182c6af44116e7bcfae581 /applications/optimization/src/main
parent4ff3b261231274ec9f3cd957ba50108fef3e0eb5 (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>
Diffstat (limited to 'applications/optimization/src/main')
-rw-r--r--applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplication.java132
-rw-r--r--applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplicationTranslator.java185
-rw-r--r--applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationSubscriberRequest.java113
3 files changed, 428 insertions, 2 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 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;
+ }
+}