diff options
author | Pamela Dragosh <pdragosh@research.att.com> | 2019-08-30 15:21:05 -0400 |
---|---|---|
committer | Pamela Dragosh <pdragosh@research.att.com> | 2019-09-09 15:27:30 -0400 |
commit | 85b5178017e89c815af7792826f52a90814f5dba (patch) | |
tree | 1cc49f6763f1af2cab372bb75ae6b9e5391c3ad7 /applications/common/src/main | |
parent | dc68da3c00c0a814110e0f7529365d695bff571b (diff) |
Integrate using Policy Type to find Matchable
Utilize's Jim's helper class to pull from API policy types
definitions so that Xacml PDP can determine which properties
are "matchable".
Override initialize to set translator parameters.
Utilize the metadata section of ToscaProperties to store
the matchable field.
Updated Matchable Request to be dynamic with respect to the
incoming resource attributes.
Stored the policy types as JSON.
Issue-ID: POLICY-1899
Change-Id: Icff3605495b0a34ebfcdfa54346095ce2d8468a4
Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
Diffstat (limited to 'applications/common/src/main')
6 files changed, 410 insertions, 92 deletions
diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/TestUtils.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/TestUtils.java index c48dd360..f720fec4 100644 --- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/TestUtils.java +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/TestUtils.java @@ -31,6 +31,7 @@ import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.common.utils.resources.ResourceUtils; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.yaml.snakeyaml.Yaml; @@ -64,11 +65,20 @@ public class TestUtils { Yaml yaml = new Yaml(); Object yamlObject = yaml.load(policyYaml); String yamlAsJsonString = standardCoder.encode(yamlObject); + // + // Serialize it into a class + // ToscaServiceTemplate serviceTemplate = standardCoder.decode(yamlAsJsonString, ToscaServiceTemplate.class); // + // Make sure all the fields are setup properly + // + JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate(); + jtst.fromAuthorative(serviceTemplate); + ToscaServiceTemplate completedJtst = jtst.toAuthorative(); + // // Get the policies // - for (Map<String, ToscaPolicy> policies : serviceTemplate.getToscaTopologyTemplate().getPolicies()) { + for (Map<String, ToscaPolicy> policies : completedJtst.getToscaTopologyTemplate().getPolicies()) { for (ToscaPolicy policy : policies.values()) { if (service.loadPolicy(policy)) { loadedPolicies.add(policy); 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 21820b99..500be2e6 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 @@ -58,14 +58,10 @@ public final class ToscaDictionary { new IdentifierImpl(ID_URN_ONAP, "onap-instance"); /* - * These 2 ID's are for Optimization policies + * These ID's are for Matchable Attributes */ - public static final Identifier ID_RESOURCE_POLICY_SCOPE_PROPERTY = - new IdentifierImpl(ID_URN_ONAP, "policy-scope-property"); - - public static final Identifier ID_RESOURCE_POLICY_TYPE_PROPERTY = - new IdentifierImpl(ID_URN_ONAP, "policy-type-property"); + public static final String ID_RESOURCE_MATCHABLE = URN_ONAP + ":matchable:"; /* * These ID's are for Legacy Guard Policies diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlApplicationServiceProvider.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlApplicationServiceProvider.java index b20ce32f..c3d66255 100644 --- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlApplicationServiceProvider.java +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlApplicationServiceProvider.java @@ -27,6 +27,7 @@ import java.nio.file.Path; import java.util.List; 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.ToscaPolicy; @@ -60,10 +61,13 @@ public interface XacmlApplicationServiceProvider { /** * Initializes the application and gives it a Path for storing its * data. The Path may be already populated with previous data. + * Also gives api rest parameters if needed. * * @param pathForData Local Path + * @param policyApiParameters API rest parameters */ - void initialize(Path pathForData) throws XacmlApplicationException; + void initialize(Path pathForData, RestServerParameters policyApiParameters) + throws XacmlApplicationException; /** * Returns a list of supported Tosca Policy Types. 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 0e5edf84..c32eeca4 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 @@ -22,21 +22,33 @@ package org.onap.policy.pdp.xacml.application.common.std; +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.Request; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.IdentifierImpl; +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.RequestParser; import com.att.research.xacml.std.annotations.XACMLAction; import com.att.research.xacml.std.annotations.XACMLRequest; -import com.att.research.xacml.std.annotations.XACMLResource; import com.att.research.xacml.std.annotations.XACMLSubject; - +import com.att.research.xacml.util.FactoryException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Map; import java.util.Map.Entry; - import lombok.Getter; import lombok.Setter; import lombok.ToString; - import org.onap.policy.models.decisions.concepts.DecisionRequest; +import org.onap.policy.pdp.xacml.application.common.ToscaDictionary; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Getter @Setter @@ -44,8 +56,7 @@ import org.onap.policy.models.decisions.concepts.DecisionRequest; @XACMLRequest(ReturnPolicyIdList = true) public class StdMatchablePolicyRequest { - public static final String POLICY_TYPE_KEY = "policyType"; - public static final String POLICY_SCOPE_KEY = "policyScope"; + private static final Logger LOGGER = LoggerFactory.getLogger(StdMatchablePolicyRequest.class); @XACMLSubject(includeInResults = true) private String onapName; @@ -59,29 +70,38 @@ public class StdMatchablePolicyRequest { @XACMLAction() private String action; - // - // Unfortunately the annotations won't take an object.toString() - // So I could not use the ToscaDictionary class to put these id's - // into the annotations. - // - @XACMLResource(attributeId = "urn:org:onap:policy-scope-property", includeInResults = true) - Collection<String> policyScopes = new ArrayList<>(); - - @XACMLResource(attributeId = "urn:org:onap:policy-type-property", includeInResults = true) - Collection<String> policyTypes = new ArrayList<>(); - public StdMatchablePolicyRequest() { super(); } + protected static DataTypeFactory dataTypeFactory = null; + + protected static synchronized DataTypeFactory getDataTypeFactory() { + try { + if (dataTypeFactory != null) { + return dataTypeFactory; + } + dataTypeFactory = DataTypeFactory.newInstance(); + if (dataTypeFactory == null) { + LOGGER.error("Could not create data type factory"); + } + } catch (FactoryException e) { + LOGGER.error("Can't get Data type Factory: {}", e); + } + return dataTypeFactory; + } + /** * Parses the DecisionRequest into a MonitoringRequest. * * @param decisionRequest Input DecisionRequest - * @return MonitoringRequest + * @return Request XACML Request object + * @throws DataTypeException DataType exception + * @throws IllegalAccessException Illegal access exception */ @SuppressWarnings({"rawtypes", "unchecked"}) - public static StdMatchablePolicyRequest createInstance(DecisionRequest decisionRequest) { + public static Request createInstance(DecisionRequest decisionRequest) throws IllegalAccessException, + DataTypeException { // // Create our request object // @@ -97,48 +117,58 @@ public class StdMatchablePolicyRequest { // request.action = decisionRequest.getAction(); // + // Parse the request - we use the annotations to create a + // basic XACML request. + // + Request xacmlRequest = RequestParser.parseRequest(request); + // + // Create an object we can add to + // + StdMutableRequest mutableRequest = new StdMutableRequest(xacmlRequest); + StdMutableRequestAttributes resourceAttributes = new StdMutableRequestAttributes(); + resourceAttributes.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + // // Add the resource attributes // Map<String, Object> resources = decisionRequest.getResource(); for (Entry<String, Object> entrySet : resources.entrySet()) { // - // Making an assumption that these two fields are matchable. + // Making an assumption that these fields are matchable. // Its possible we may have to load the policy type model - // and use that to find the fields that are matchable. + // and use that to validate the fields that are matchable. // - if (POLICY_SCOPE_KEY.equals(entrySet.getKey())) { - if (entrySet.getValue() instanceof Collection) { - addPolicyScopes(request, (Collection) entrySet.getValue()); - } else if (entrySet.getValue() instanceof String) { - request.policyScopes.add(entrySet.getValue().toString()); - } - continue; - } - if (POLICY_TYPE_KEY.equals(entrySet.getKey())) { - if (entrySet.getValue() instanceof Collection) { - addPolicyTypes(request, (Collection) entrySet.getValue()); - } - if (entrySet.getValue() instanceof String) { - request.policyTypes.add(entrySet.getValue().toString()); - } + if (entrySet.getValue() instanceof Collection) { + addResources(resourceAttributes, (Collection) entrySet.getValue(), entrySet.getKey()); + } else { + addResources(resourceAttributes, Arrays.asList(entrySet.getValue().toString()), entrySet.getKey()); } } - return request; + mutableRequest.add(resourceAttributes); + return mutableRequest; } - private static StdMatchablePolicyRequest addPolicyScopes(StdMatchablePolicyRequest request, - Collection<Object> scopes) { - for (Object scope : scopes) { - request.policyScopes.add(scope.toString()); - } - return request; - } + private static StdMutableRequestAttributes addResources(StdMutableRequestAttributes attributes, + Collection<Object> values, String id) throws DataTypeException { - private static StdMatchablePolicyRequest addPolicyTypes(StdMatchablePolicyRequest request, - Collection<Object> types) { - for (Object type : types) { - request.policyTypes.add(type.toString()); + DataTypeFactory factory = getDataTypeFactory(); + if (factory == null) { + return null; } - return request; + for (Object value : values) { + StdMutableAttribute mutableAttribute = new StdMutableAttribute(); + mutableAttribute.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + mutableAttribute.setAttributeId(new IdentifierImpl(ToscaDictionary.ID_RESOURCE_MATCHABLE + 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/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchableTranslator.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchableTranslator.java index dd44af7a..1c69c7a6 100644 --- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchableTranslator.java +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchableTranslator.java @@ -31,15 +31,25 @@ import com.att.research.xacml.api.Request; import com.att.research.xacml.api.Response; import com.att.research.xacml.api.Result; import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.IdentifierImpl; import com.att.research.xacml.std.annotations.RequestParser; +import com.att.research.xacml.util.XACMLPolicyWriter; import com.google.gson.Gson; - +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Map.Entry; - +import lombok.Setter; 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; @@ -51,12 +61,19 @@ import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionsType; import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType; import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType; - +import org.onap.policy.common.endpoints.parameters.RestServerParameters; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.models.decisions.concepts.DecisionRequest; import org.onap.policy.models.decisions.concepts.DecisionResponse; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; +import org.onap.policy.pdp.xacml.application.common.PolicyApiCaller; +import org.onap.policy.pdp.xacml.application.common.PolicyApiException; 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.ToscaPolicyTranslator; @@ -64,10 +81,24 @@ import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslatorUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * This standard matchable translator uses Policy Types that contain "matchable" field in order + * to translate policies. + * + * @author pameladragosh + * + */ public class StdMatchableTranslator implements ToscaPolicyTranslator { private static final Logger LOGGER = LoggerFactory.getLogger(StdMatchableTranslator.class); private static final String POLICY_ID = "policy-id"; + private static final StandardCoder standardCoder = new StandardCoder(); + + private final Map<ToscaPolicyTypeIdentifier, ToscaPolicyType> matchablePolicyTypes = new HashMap<>(); + @Setter + private RestServerParameters apiRestParameters; + @Setter + private Path pathForData; public StdMatchableTranslator() { super(); @@ -77,7 +108,7 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { public Request convertRequest(DecisionRequest request) { LOGGER.info("Converting Request {}", request); try { - return RequestParser.parseRequest(StdMatchablePolicyRequest.createInstance(request)); + return StdMatchablePolicyRequest.createInstance(request); } catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) { LOGGER.error("Failed to convert DecisionRequest: {}", e); } @@ -162,6 +193,18 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { @Override public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException { // + // Get the TOSCA Policy Type for this policy + // + Collection<ToscaPolicyType> policyTypes = this.getPolicyTypes(toscaPolicy.getTypeIdentifier()); + // + // If we don't have any policy types, then we cannot know + // which properties are matchable. + // + if (policyTypes.isEmpty()) { + throw new ToscaPolicyConversionException( + "Cannot retrieve Policy Type definition for policy " + toscaPolicy.getName()); + } + // // Policy name should be at the root // String policyName = toscaPolicy.getMetadata().get(POLICY_ID); @@ -185,7 +228,7 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { // // Generate the TargetType // - newPolicyType.setTarget(generateTargetType(toscaPolicy.getProperties())); + newPolicyType.setTarget(generateTargetType(toscaPolicy.getProperties(), policyTypes)); // // Now create the Permit Rule // No target since the policy has a target @@ -214,6 +257,12 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { // // Return our new policy // + try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { + XACMLPolicyWriter.writePolicyFile(os, newPolicyType); + LOGGER.info("{}", os); + } catch (IOException e) { + LOGGER.error("Failed to create byte array stream", e); + } return newPolicyType; } @@ -246,46 +295,37 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { } /** - * For generating target type, we are making an assumption that the - * policyScope and policyType are the fields that OOF wants to match on. - * - * <P>In the future, we would need to receive the Policy Type specification - * from the PAP so we can dynamically see which fields are matchable. - * - * <P>Note: I am making an assumption that the matchable fields are what - * the OOF wants to query a policy on. + * For generating target type, we are scan for matchable properties + * and use those to build the policy. * * @param properties Properties section of policy + * @param policyTypes Collection of policy Type to find matchable metadata * @return TargetType object */ @SuppressWarnings("unchecked") - protected TargetType generateTargetType(Map<String, Object> properties) { + protected TargetType generateTargetType(Map<String, Object> properties, Collection<ToscaPolicyType> policyTypes) { TargetType targetType = new TargetType(); // // Iterate the properties // for (Entry<String, Object> entrySet : properties.entrySet()) { // - // Find policyScope and policyType + // Find matchable properties // - if (entrySet.getKey().equals("policyScope")) { - LOGGER.info("Found policyScope: {}", entrySet.getValue()); + if (isMatchable(entrySet.getKey(), policyTypes)) { + LOGGER.info("Found matchable property {}", entrySet.getValue()); if (entrySet.getValue() instanceof Collection) { - targetType.getAnyOf().add(generateMatches((Collection<Object>) entrySet.getValue(), - ToscaDictionary.ID_RESOURCE_POLICY_SCOPE_PROPERTY)); - } else if (entrySet.getValue() instanceof String) { - targetType.getAnyOf().add(generateMatches(Arrays.asList(entrySet.getValue()), - ToscaDictionary.ID_RESOURCE_POLICY_SCOPE_PROPERTY)); - } - } - if (entrySet.getKey().equals("policyType")) { - LOGGER.info("Found policyType: {}", entrySet.getValue()); - if (entrySet.getValue() instanceof Collection) { - targetType.getAnyOf().add(generateMatches((Collection<Object>) entrySet.getValue(), - ToscaDictionary.ID_RESOURCE_POLICY_TYPE_PROPERTY)); - } else if (entrySet.getValue() instanceof String) { - targetType.getAnyOf().add(generateMatches(Arrays.asList(entrySet.getValue()), - ToscaDictionary.ID_RESOURCE_POLICY_TYPE_PROPERTY)); + AnyOfType anyOf = generateMatches((Collection<Object>) entrySet.getValue(), + new IdentifierImpl(ToscaDictionary.ID_RESOURCE_MATCHABLE + entrySet.getKey())); + if (! anyOf.getAllOf().isEmpty()) { + targetType.getAnyOf().add(anyOf); + } + } else { + AnyOfType anyOf = generateMatches(Arrays.asList(entrySet.getValue()), + new IdentifierImpl(ToscaDictionary.ID_RESOURCE_MATCHABLE + entrySet.getKey())); + if (! anyOf.getAllOf().isEmpty()) { + targetType.getAnyOf().add(anyOf); + } } } } @@ -293,6 +333,23 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { return targetType; } + protected boolean isMatchable(String propertyName, Collection<ToscaPolicyType> policyTypes) { + for (ToscaPolicyType policyType : policyTypes) { + for (Entry<String, ToscaProperty> propertiesEntry : policyType.getProperties().entrySet()) { + if (! propertiesEntry.getKey().equals(propertyName) + || propertiesEntry.getValue().getMetadata() == null) { + continue; + } + for (Entry<String, String> entrySet : propertiesEntry.getValue().getMetadata().entrySet()) { + if (entrySet.getKey().equals("matchable") && entrySet.getValue().equals("true")) { + return true; + } + } + } + } + return false; + } + protected AnyOfType generateMatches(Collection<Object> matchables, Identifier attributeId) { // // This is our outer AnyOf - which is an OR @@ -300,12 +357,33 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { AnyOfType anyOf = new AnyOfType(); for (Object matchable : matchables) { // + // Default to string + // + Identifier idFunction = XACML3.ID_FUNCTION_STRING_EQUAL; + Identifier idDatatype = XACML3.ID_DATATYPE_STRING; + // + // See if we are another datatype + // + // TODO We should add datetime support. But to do that we need + // probably more metadata to describe how that would be translated. + // + if (matchable instanceof Integer) { + idFunction = XACML3.ID_FUNCTION_INTEGER_EQUAL; + idDatatype = XACML3.ID_DATATYPE_INTEGER; + } else if (matchable instanceof Double) { + idFunction = XACML3.ID_FUNCTION_DOUBLE_EQUAL; + idDatatype = XACML3.ID_DATATYPE_DOUBLE; + } else if (matchable instanceof Boolean) { + idFunction = XACML3.ID_FUNCTION_BOOLEAN_EQUAL; + idDatatype = XACML3.ID_DATATYPE_BOOLEAN; + } + // // Create a match for this // MatchType match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator( - XACML3.ID_FUNCTION_STRING_EQUAL, + idFunction, matchable.toString(), - XACML3.ID_DATATYPE_STRING, + idDatatype, attributeId, XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); // @@ -353,4 +431,195 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { return rule; } + + /** + * Get Policy Type definitions. This could be previously loaded, or could be + * stored in application path, or may need to be pulled from the API. + * + * + * @param policyTypeId Policy Type Id + * @return A list of PolicyTypes + */ + private List<ToscaPolicyType> getPolicyTypes(ToscaPolicyTypeIdentifier policyTypeId) { + // + // Create identifier from the policy + // + ToscaPolicyTypeIdentifier typeId = new ToscaPolicyTypeIdentifier(policyTypeId); + // + // Find the Policy Type + // + ToscaPolicyType policyType = findPolicyType(typeId); + if (policyType == null) { + return Collections.emptyList(); + } + // + // Create our return object + // + List<ToscaPolicyType> listTypes = new ArrayList<>(); + listTypes.add(policyType); + // + // Look for parent policy types that could also contain matchable properties + // + ToscaPolicyType childPolicyType = policyType; + while (! childPolicyType.getDerivedFrom().startsWith("tosca.policies.Root")) { + // + // Create parent policy type id. + // + // We will have to assume the same version between child and the + // parent policy type it derives from. + // + // Or do we assume 1.0.0? + // + String strDerivedFrom = childPolicyType.getDerivedFrom(); + // + // Hack that fixes policy/models appending 0.0.0 to the derivedFrom name + // + if (strDerivedFrom.endsWith("0.0.0")) { + strDerivedFrom = strDerivedFrom.substring(0, strDerivedFrom.length() - "0.0.0".length() - 1); + } + ToscaPolicyTypeIdentifier parentId = new ToscaPolicyTypeIdentifier(strDerivedFrom, "1.0.0"); + // + // Find the policy type + // + ToscaPolicyType parentPolicyType = findPolicyType(parentId); + if (parentPolicyType == null) { + // + // Probably would be best to throw an exception and + // return nothing back. + // + // But instead we will log a warning + // + LOGGER.warn("Missing parent policy type - proceeding anyway {}", parentId); + // + // Break the loop + // + break; + } + // + // Great save it + // + listTypes.add(parentPolicyType); + // + // Move to the next parent + // + childPolicyType = parentPolicyType; + } + + + return listTypes; + } + + private ToscaPolicyType findPolicyType(ToscaPolicyTypeIdentifier policyTypeId) { + // + // Is it loaded in memory? + // + ToscaPolicyType policyType = this.matchablePolicyTypes.get(policyTypeId); + if (policyType == null) { + // + // Load the policy + // + policyType = this.loadPolicyType(policyTypeId); + } + // + // Yep return it + // + return policyType; + } + + private ToscaPolicyType loadPolicyType(ToscaPolicyTypeIdentifier policyTypeId) { + // + // Construct what the file name should be + // + Path policyTypePath = this.constructLocalFilePath(policyTypeId); + // + // See if it exists + // + byte[] bytes; + try { + // + // If it exists locally, read the bytes in + // + bytes = Files.readAllBytes(policyTypePath); + } catch (IOException e) { + // + // Does not exist locally, so let's GET it from the policy api + // + LOGGER.error("PolicyType not found in data area yet {}", policyTypePath, e); + // + // So let's pull it from API REST call and save it locally + // + return this.pullPolicyType(policyTypeId, policyTypePath); + } + LOGGER.info("Read in local policy type {}", policyTypePath.toAbsolutePath()); + try { + ToscaServiceTemplate serviceTemplate = standardCoder.decode(new String(bytes, StandardCharsets.UTF_8), + ToscaServiceTemplate.class); + JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate(); + jtst.fromAuthorative(serviceTemplate); + ToscaServiceTemplate completedJtst = jtst.toAuthorative(); + // + // Search for our Policy Type, there really only should be one but + // this is returned as a map. + // + for ( Entry<String, ToscaPolicyType> entrySet : completedJtst.getPolicyTypes().entrySet()) { + ToscaPolicyType entryPolicyType = entrySet.getValue(); + if (policyTypeId.getName().equals(entryPolicyType.getName()) + && policyTypeId.getVersion().equals(entryPolicyType.getVersion())) { + LOGGER.info("Found existing local policy type {} {}", entryPolicyType.getName(), + entryPolicyType.getVersion()); + // + // Just simply return the policy type right here + // + return entryPolicyType; + } else { + LOGGER.warn("local policy type contains different name version {} {}", entryPolicyType.getName(), + entryPolicyType.getVersion()); + } + } + // + // This would be an error, if the file stored does not match what its supposed to be + // + LOGGER.error("Existing policy type file does not contain right name and version"); + } catch (CoderException e) { + LOGGER.error("Failed to decode tosca template for {}", policyTypePath, e); + } + // + // Hopefully we never get here + // + LOGGER.error("Failed to find/load policy type {}", policyTypeId); + return null; + } + + private synchronized ToscaPolicyType pullPolicyType(ToscaPolicyTypeIdentifier policyTypeId, Path policyTypePath) { + // + // This is what we return + // + ToscaPolicyType policyType = null; + try { + PolicyApiCaller api = new PolicyApiCaller(this.apiRestParameters); + + policyType = api.getPolicyType(policyTypeId); + } catch (PolicyApiException e) { + LOGGER.error("Failed to make API call", e); + LOGGER.error("parameters: {} ", this.apiRestParameters); + return null; + } + // + // Store it locally + // + try { + standardCoder.encode(policyTypePath.toFile(), policyType); + } catch (CoderException e) { + LOGGER.error("Failed to store {} locally to {}", policyTypeId, policyTypePath, e); + } + // + // Done return the policy type + // + return policyType; + } + + private Path constructLocalFilePath(ToscaPolicyTypeIdentifier policyTypeId) { + return Paths.get(this.pathForData.toAbsolutePath().toString(), policyTypeId.getName() + "-" + + policyTypeId.getVersion() + ".json"); + } } 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 89299567..17119858 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 @@ -37,8 +37,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; +import lombok.Getter; import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; 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.ToscaPolicy; @@ -55,6 +57,8 @@ public abstract class StdXacmlApplicationServiceProvider implements XacmlApplica private static final Logger LOGGER = LoggerFactory.getLogger(StdXacmlApplicationServiceProvider.class); private Path pathForData = null; + @Getter + private RestServerParameters policyApiParameters; private Properties pdpProperties = null; private PDPEngine pdpEngine = null; private Map<ToscaPolicy, Path> mapLoadedPolicies = new HashMap<>(); @@ -74,13 +78,18 @@ public abstract class StdXacmlApplicationServiceProvider implements XacmlApplica } @Override - public void initialize(Path pathForData) throws XacmlApplicationException { + public void initialize(Path pathForData, RestServerParameters policyApiParameters) + throws XacmlApplicationException { // // Save our path // this.pathForData = pathForData; LOGGER.info("New Path is {}", this.pathForData.toAbsolutePath()); // + // Save our params + // + this.policyApiParameters = policyApiParameters; + // // Look for and load the properties object // try { |