diff options
Diffstat (limited to 'applications/common')
11 files changed, 722 insertions, 113 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 { diff --git a/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchablePolicyRequestTest.java b/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchablePolicyRequestTest.java index 00c86f25..1c844621 100644 --- a/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchablePolicyRequestTest.java +++ b/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchablePolicyRequestTest.java @@ -20,14 +20,17 @@ package org.onap.policy.pdp.xacml.application.common.std; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; -import java.util.Collection; -import java.util.Collections; +import com.att.research.xacml.api.DataTypeException; +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.RequestAttributes; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.IdentifierImpl; +import java.util.Arrays; +import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import org.junit.Before; @@ -35,21 +38,24 @@ import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.onap.policy.models.decisions.concepts.DecisionRequest; +import org.onap.policy.pdp.xacml.application.common.ToscaDictionary; public class StdMatchablePolicyRequestTest { private static final String ACTION = "my-action"; private static final String ONAP_NAME = "my-name"; private static final String ONAP_INSTANCE = "my-instance"; private static final String ONAP_COMPONENT = "my-component"; - private static final String POLICY_SCOPE = "my-scope"; - private static final String POLICY_TYPE = "my-type"; + private static final String RESOURCE1 = "my-scope"; + private static final String RESOURCE2 = "my-service"; + private static final String RESOURCE3 = "my-geography1"; + private static final String RESOURCE4 = "my-geography2"; @Mock private DecisionRequest decreq; private Map<String, Object> resources; - private StdMatchablePolicyRequest stdreq; + private Request stdreq; /** * Initializes objects. @@ -68,23 +74,29 @@ public class StdMatchablePolicyRequestTest { } @Test - public void testCreateInstance() { - resources.put(StdMatchablePolicyRequest.POLICY_SCOPE_KEY, 100); - resources.put(StdMatchablePolicyRequest.POLICY_TYPE_KEY, 101); + public void testCreateInstance() throws IllegalAccessException, DataTypeException { + resources.put("resource1", RESOURCE1); + resources.put("resource2", RESOURCE2); + resources.put("resource3", Arrays.asList(RESOURCE3, RESOURCE4)); stdreq = StdMatchablePolicyRequest.createInstance(decreq); assertNotNull(stdreq); - assertEquals(ACTION, stdreq.getAction()); - assertEquals(ONAP_COMPONENT, stdreq.getOnapComponent()); - assertEquals(ONAP_INSTANCE, stdreq.getOnapInstance()); - assertEquals(ONAP_NAME, stdreq.getOnapName()); + assertTrue(stdreq.getRequestAttributes(XACML3.ID_ATTRIBUTE_CATEGORY_ACTION).hasNext()); + assertTrue(stdreq.getRequestAttributes(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT).hasNext()); + + + Iterator<RequestAttributes> iterResources = stdreq.getRequestAttributes(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + assertTrue(iterResources.hasNext()); + while (iterResources.hasNext()) { + RequestAttributes attrs = iterResources.next(); + assertTrue(attrs.hasAttributes(new IdentifierImpl(ToscaDictionary.ID_RESOURCE_MATCHABLE + "resource1"))); + } - assertTrue(stdreq.getPolicyScopes().isEmpty()); - assertTrue(stdreq.getPolicyTypes().isEmpty()); } + /* @Test public void testCreateInstance_StringValues() { resources.put(StdMatchablePolicyRequest.POLICY_SCOPE_KEY, POLICY_SCOPE); @@ -117,5 +129,6 @@ public class StdMatchablePolicyRequestTest { assertFalse(res.isEmpty()); assertEquals(POLICY_TYPE, res.iterator().next()); } +*/ } diff --git a/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchableTranslatorTest.java b/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchableTranslatorTest.java new file mode 100644 index 00000000..3e690882 --- /dev/null +++ b/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchableTranslatorTest.java @@ -0,0 +1,215 @@ +/*- + * ============LICENSE_START======================================================= + * 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.pdp.xacml.application.common.std; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.onap.policy.common.endpoints.http.server.HttpServletServer; +import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance; +import org.onap.policy.common.endpoints.parameters.RestServerParameters; +import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; +import org.onap.policy.common.gson.GsonMessageBodyHandler; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.network.NetworkUtil; +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.ToscaPolicyType; +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.ToscaPolicyConversionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; + +public class StdMatchableTranslatorTest { + + private static final Logger logger = LoggerFactory.getLogger(StdMatchableTranslatorTest.class); + private static final String CLIENT_NAME = "policy-api"; + private static final StandardCoder standardCoder = new StandardCoder(); + private static int port; + private static RestServerParameters clientParams; + private static ToscaPolicyType testPolicyType; + + @ClassRule + public static final TemporaryFolder policyFolder = new TemporaryFolder(); + + /** + * Initializes {@link #clientParams} and starts a simple REST server to handle the + * test requests. + * + * @throws IOException if an error occurs + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog"); + System.setProperty("org.eclipse.jetty.LEVEL", "OFF"); + // + // Setup our api server simulator + // + port = NetworkUtil.allocPort(); + + clientParams = mock(RestServerParameters.class); + when(clientParams.getHost()).thenReturn("localhost"); + when(clientParams.getPort()).thenReturn(port); + + Properties props = new Properties(); + props.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES, CLIENT_NAME); + + final String svcpfx = + PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + CLIENT_NAME; + + props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX, clientParams.getHost()); + props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX, + Integer.toString(clientParams.getPort())); + props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_REST_CLASSES_SUFFIX, + ApiRestController.class.getName()); + props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX, "true"); + props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX, "false"); + props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_AAF_SUFFIX, "false"); + props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER, + GsonMessageBodyHandler.class.getName()); + + HttpServletServerFactoryInstance.getServerFactory().build(props).forEach(HttpServletServer::start); + + assertTrue(NetworkUtil.isTcpPortOpen(clientParams.getHost(), clientParams.getPort(), 100, 100)); + // + // Load our test policy type + // + String policyYaml = ResourceUtils.getResourceAsString("matchable/onap.policies.Test-1.0.0.yaml"); + 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(); + // + // Find the Policy Type - SHOULD only be one + // + assertEquals(1, completedJtst.getPolicyTypes().size()); + testPolicyType = completedJtst.getPolicyTypes().get("onap.policies.Test"); + assertNotNull(testPolicyType); + logger.info("Test Policy Type {}{}", System.lineSeparator(), testPolicyType); + } + + @AfterClass + public static void tearDownAfterClass() { + HttpServletServerFactoryInstance.getServerFactory().destroy(); + } + + @Test + public void test() throws CoderException, ToscaPolicyConversionException { + // + // Create our translator + // + StdMatchableTranslator translator = new StdMatchableTranslator(); + assertNotNull(translator); + // + // Set it up + // + translator.setPathForData(policyFolder.getRoot().toPath()); + translator.setApiRestParameters(clientParams); + // + // Load policies to test + // + String policyYaml = ResourceUtils.getResourceAsString( + "src/test/resources/matchable/test.policies.input.tosca.yaml"); + 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 : completedJtst.getToscaTopologyTemplate().getPolicies()) { + for (ToscaPolicy policy : policies.values()) { + PolicyType translatedPolicy = translator.convertPolicy(policy); + assertNotNull(translatedPolicy); + logger.info("Translated policy {} {}", System.lineSeparator(), translatedPolicy); + } + } + } + + /** + * Simple REST server to handle test requests. + */ + + @Path("/policy/api/v1") + @Produces({"application/json", "application/yaml"}) + @Consumes({"application/json", "application/yaml"}) + public static class ApiRestController { + + /** + * Retrieves the specified version of a particular policy type. + * + * @param policyTypeId ID of desired policy type + * @param versionId version of desired policy type + * @param requestId optional request ID + * + * @return the Response object containing the results of the API operation + */ + @GET + @Path("/policytypes/{policyTypeId}/versions/{versionId}") + public Response getSpecificVersionOfPolicyType(@PathParam("policyTypeId") String policyTypeId, + @PathParam("versionId") String versionId, @HeaderParam("X-ONAP-RequestID") UUID requestId) { + logger.info("request for policy type={} version={}", policyTypeId, versionId); + return Response.status(Response.Status.OK).entity(testPolicyType).build(); + + } + } +} diff --git a/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/std/StdXacmlApplicationServiceProviderTest.java b/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/std/StdXacmlApplicationServiceProviderTest.java index 8f44dedb..30419daf 100644 --- a/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/std/StdXacmlApplicationServiceProviderTest.java +++ b/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/std/StdXacmlApplicationServiceProviderTest.java @@ -54,6 +54,7 @@ import org.junit.BeforeClass; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +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; @@ -76,6 +77,7 @@ public class StdXacmlApplicationServiceProviderTest { private static final String POLICY_NAME = "my-name"; private static final String POLICY_VERSION = "1.2.3"; private static final String POLICY_TYPE = "my-type"; + private static final RestServerParameters apiRestParameters = new RestServerParameters(); @Mock private ToscaPolicyTranslator trans; @@ -162,7 +164,7 @@ public class StdXacmlApplicationServiceProviderTest { @Test public void testInitialize_testGetXxx() throws XacmlApplicationException { - prov.initialize(TEMP_PATH); + prov.initialize(TEMP_PATH, apiRestParameters); assertEquals(TEMP_PATH, prov.getDataPath()); assertNotNull(prov.getEngine()); @@ -173,7 +175,7 @@ public class StdXacmlApplicationServiceProviderTest { @Test public void testInitialize_Ex() throws XacmlApplicationException { - assertThatThrownBy(() -> prov.initialize(new File(TEMP_DIR_NAME + "-nonExistent").toPath())) + assertThatThrownBy(() -> prov.initialize(new File(TEMP_DIR_NAME + "-nonExistent").toPath(), apiRestParameters)) .isInstanceOf(XacmlApplicationException.class).hasMessage("Failed to load xacml.properties"); } @@ -196,7 +198,7 @@ public class StdXacmlApplicationServiceProviderTest { @Test public void testLoadPolicy_testUnloadPolicy() throws Exception { - prov.initialize(TEMP_PATH); + prov.initialize(TEMP_PATH, apiRestParameters); PROP_FILE.delete(); final Set<String> set = XACMLProperties.getRootPolicyIDs(prov.getProperties()); @@ -243,7 +245,7 @@ public class StdXacmlApplicationServiceProviderTest { @Test public void testUnloadPolicy_NotDeployed() throws Exception { - prov.initialize(TEMP_PATH); + prov.initialize(TEMP_PATH, apiRestParameters); assertFalse(prov.unloadPolicy(policy)); @@ -309,7 +311,7 @@ public class StdXacmlApplicationServiceProviderTest { engineFactory = null; prov = new MyProv(); - prov.initialize(TEMP_PATH); + prov.initialize(TEMP_PATH, apiRestParameters); assertNotNull(prov.getEngine()); } diff --git a/applications/common/src/test/resources/matchable/onap.policies.Test-1.0.0.yaml b/applications/common/src/test/resources/matchable/onap.policies.Test-1.0.0.yaml new file mode 100644 index 00000000..089aad66 --- /dev/null +++ b/applications/common/src/test/resources/matchable/onap.policies.Test-1.0.0.yaml @@ -0,0 +1,38 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +policy_types: + onap.policies.Test: + derived_from: tosca.policies.Root + version: 1.0.0 + properties: + nonmatachableString: + type: string + matchableString: + type: string + metadata: + matchable: true + nonmatachableInteger: + type: integer + metadata: + matchable: false + matachableInteger: + type: integer + metadata: + matchable: true + nonmatachableDouble: + type: double + matchableDouble: + type: double + metadata: + matchable: true + nonmatachableBoolean: + type: boolean + matachableBoolean: + type: boolean + metadata: + matchable: true + matchableListString: + type: list + metadata: + matchable: true + entry_schema: + type: string
\ No newline at end of file diff --git a/applications/common/src/test/resources/matchable/test.policies.input.tosca.yaml b/applications/common/src/test/resources/matchable/test.policies.input.tosca.yaml new file mode 100644 index 00000000..434f7a97 --- /dev/null +++ b/applications/common/src/test/resources/matchable/test.policies.input.tosca.yaml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +topology_template: + policies: + - + Test.policy: + type: onap.policies.Test + type_version: 1.0.0 + version: 1.0.0 + metadata: + policy-id: Test.policy + policy-version: 1 + properties: + nonmatachableString: "I am NON matchable" + matchableString: "I should be matched" + nonmatachableInteger: 0 + matachableInteger: 1000 + nonmatachableDouble: 0.0 + matchableDouble: 1.1 + nonmatachableBoolean: false + matachableBoolean: true + matchableListString: + - match A + - match B
\ No newline at end of file |