aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPamela Dragosh <pdragosh@research.att.com>2019-03-22 14:12:52 -0400
committerPamela Dragosh <pdragosh@research.att.com>2019-03-25 13:54:56 -0400
commit2c847e0855b316c162c9fd31456fdf8e338a5dba (patch)
treeceb330604ec28a2cde721ebc0774508a533a1e56
parentd5c3b36247605392b4f75b2e44296922559baac6 (diff)
Adding optimization application finish guard
Created Optimization application and created a translator for it. The translator makes an assumption that OOF wants to query on policyScope and policyType properties. Rearranged some of the test code for re-usability. Guard policies are now creating for frequency limiter and min max. Probably could use some clean up. Upgraded to xacml 2.0.1 to include a fix for handling null attribute values. Added some code to test missing values. Issue-ID: POLICY-1273 Change-Id: Ia3dbfa992bbe0cbb5aa294c38aa2aff430a3230a Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
-rw-r--r--applications/common/pom.xml2
-rw-r--r--applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/OnapPolicyFinderFactory.java53
-rw-r--r--applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaDictionary.java64
-rw-r--r--applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlPolicyUtils.java129
-rw-r--r--applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdCombinedPolicyRequest.java87
-rw-r--r--applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdCombinedPolicyResultsTranslator.java75
-rw-r--r--applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchablePolicyRequest.java141
-rw-r--r--applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchableTranslator.java400
-rw-r--r--applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMetadataTranslator.java110
-rw-r--r--applications/guard/pom.xml9
-rw-r--r--applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java40
-rw-r--r--applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardPolicyRequest.java163
-rw-r--r--applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardTranslator.java740
-rw-r--r--applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java354
-rw-r--r--applications/guard/src/test/resources/guard.policy-minmax-missing-fields1.yaml19
-rw-r--r--applications/guard/src/test/resources/vDNS.policy.guard.frequency.output.tosca.yaml20
-rw-r--r--applications/guard/src/test/resources/vDNS.policy.guard.minmax.output.tosca.yaml19
-rw-r--r--applications/guard/src/test/resources/xacml.properties13
-rw-r--r--applications/monitoring/pom.xml9
-rw-r--r--applications/monitoring/src/main/java/org/onap/policy/xacml/pdp/application/monitoring/MonitoringRequest.java78
-rw-r--r--applications/monitoring/src/test/java/org/onap/policy/xacml/pdp/application/monitoring/MonitoringPdpApplicationTest.java298
-rw-r--r--applications/monitoring/src/test/resources/vDNS.policy.decision.payload.json0
-rw-r--r--applications/monitoring/src/test/resources/xacml.properties8
-rw-r--r--applications/optimization/pom.xml43
-rw-r--r--applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplication.java164
-rw-r--r--applications/optimization/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider1
-rw-r--r--applications/optimization/src/test/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplicationTest.java211
-rw-r--r--applications/optimization/src/test/resources/vCPE.policies.optimization.input.tosca.yaml137
-rw-r--r--applications/optimization/src/test/resources/xacml.properties31
-rw-r--r--applications/pom.xml1
-rw-r--r--main/pom.xml5
-rw-r--r--main/src/test/resources/decisions/decision.guard.shoulddeny.input.json7
-rw-r--r--main/src/test/resources/decisions/decision.guard.shoulddeny.input2.json15
-rw-r--r--main/src/test/resources/decisions/decision.guard.shoulddeny.output.json3
-rw-r--r--main/src/test/resources/decisions/decision.guard.shouldpermit.input.json8
-rw-r--r--main/src/test/resources/decisions/decision.guard.shouldpermit.output.json3
-rw-r--r--main/src/test/resources/decisions/decision.optimization.affinity.input.json10
-rw-r--r--pom.xml6
38 files changed, 2881 insertions, 595 deletions
diff --git a/applications/common/pom.xml b/applications/common/pom.xml
index 30017302..1e75e0dc 100644
--- a/applications/common/pom.xml
+++ b/applications/common/pom.xml
@@ -45,7 +45,7 @@
<dependency>
<groupId>com.att.research.xacml</groupId>
<artifactId>xacml-pdp</artifactId>
- <version>2.0.0</version>
+ <version>2.0.1</version>
</dependency>
</dependencies>
</project>
diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/OnapPolicyFinderFactory.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/OnapPolicyFinderFactory.java
index 7da455c0..66352010 100644
--- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/OnapPolicyFinderFactory.java
+++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/OnapPolicyFinderFactory.java
@@ -20,16 +20,24 @@
package org.onap.policy.pdp.xacml.application.common;
+import com.att.research.xacml.std.IdentifierImpl;
import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.StdVersion;
import com.att.research.xacml.std.dom.DOMStructureException;
import com.att.research.xacml.util.FactoryException;
import com.att.research.xacml.util.XACMLProperties;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory;
import com.att.research.xacmlatt.pdp.policy.Policy;
import com.att.research.xacmlatt.pdp.policy.PolicyDef;
import com.att.research.xacmlatt.pdp.policy.PolicyFinder;
import com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+import com.att.research.xacmlatt.pdp.policy.Target;
import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef;
import com.att.research.xacmlatt.pdp.std.StdPolicyFinder;
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
@@ -43,6 +51,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
+import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -212,7 +221,49 @@ public class OnapPolicyFinderFactory extends PolicyFinderFactory {
protected synchronized void init() {
if (this.needsInit) {
logger.debug("Initializing OnapPolicyFinderFactory Properties ");
- this.rootPolicies = this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES);
+
+ //
+ // Check for property that combines root policies into one policyset
+ //
+ String combiningAlgorithm = properties.getProperty(
+ ATTPDPProperties.PROP_POLICYFINDERFACTORY_COMBINEROOTPOLICIES);
+ if (combiningAlgorithm != null) {
+ try {
+ logger.info("Combining root policies with {}", combiningAlgorithm);
+ //
+ // Find the combining algorithm
+ //
+ CombiningAlgorithm<PolicySetChild> algorithm = CombiningAlgorithmFactory.newInstance()
+ .getPolicyCombiningAlgorithm(new IdentifierImpl(combiningAlgorithm));
+ //
+ // Create our root policy
+ //
+ PolicySet root = new PolicySet();
+ root.setIdentifier(new IdentifierImpl(UUID.randomUUID().toString()));
+ root.setVersion(StdVersion.newInstance("1.0"));
+ root.setTarget(new Target());
+ //
+ // Set the algorithm
+ //
+ root.setPolicyCombiningAlgorithm(algorithm);
+ //
+ // Load all our root policies
+ //
+ for (PolicyDef policy : this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES)) {
+ root.addChild(policy);
+ }
+ //
+ // Set this policy as the root
+ //
+ this.rootPolicies = new ArrayList<>();
+ this.rootPolicies.add(root);
+ } catch (Exception e) {
+ logger.error("Failed to load Combining Algorithm Factory: {}", e.getLocalizedMessage());
+ }
+ } else {
+ logger.info("Loading root policies");
+ this.rootPolicies = this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES);
+ }
this.referencedPolicies = this.getPolicyDefs(XACMLProperties.PROP_REFERENCEDPOLICIES);
logger.debug("Root Policies: {}", this.rootPolicies.size());
logger.debug("Referenced Policies: {}", this.referencedPolicies.size());
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 352e51d8..0dcafa00 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
@@ -43,6 +43,68 @@ public final class ToscaDictionary {
public static final Identifier ID_RESOURCE_POLICY_TYPE_VERSION =
new IdentifierImpl(URN_ONAP, "policy-type-version");
+ /*
+ * These ID's are for identifying Subjects
+ */
+
+ public static final Identifier ID_SUBJECT_ONAP_NAME =
+ XACML3.ID_SUBJECT_SUBJECT_ID;
+
+ public static final Identifier ID_SUBJECT_ONAP_COMPONENT =
+ new IdentifierImpl(URN_ONAP, "onap-component");
+
+ public static final Identifier ID_SUBJECT_ONAP_INSTANCE =
+ new IdentifierImpl(URN_ONAP, "onap-instance");
+
+ /*
+ * These 2 ID's are for Optimization policies
+ */
+
+ public static final Identifier ID_RESOURCE_POLICY_SCOPE_PROPERTY =
+ new IdentifierImpl(URN_ONAP, "policy-scope-property");
+
+ public static final Identifier ID_RESOURCE_POLICY_TYPE_PROPERTY =
+ new IdentifierImpl(URN_ONAP, "policy-type-property");
+
+ /*
+ * These ID's are for Legacy Guard Policies
+ */
+ public static final Identifier ID_RESOURCE_GUARD_ACTOR =
+ new IdentifierImpl(URN_ONAP, "guard:actor:actor-id");
+ public static final Identifier ID_RESOURCE_GUARD_RECIPE =
+ new IdentifierImpl(URN_ONAP, "guard:operation:operation-id");
+ public static final Identifier ID_RESOURCE_GUARD_CLNAME =
+ new IdentifierImpl(URN_ONAP, "guard:clname:clname-id");
+ public static final Identifier ID_RESOURCE_GUARD_TARGETID =
+ new IdentifierImpl(URN_ONAP, "guard:target:target-id");
+ public static final Identifier ID_SUBJECT_GUARD_REQUESTID =
+ new IdentifierImpl(URN_ONAP, "guard:request:request-id");
+ public static final Identifier ID_RESOURCE_GUARD_VFCOUNT =
+ new IdentifierImpl(URN_ONAP, "guard:target:vf-count");
+ public static final Identifier ID_RESOURCE_GUARD_MIN =
+ new IdentifierImpl(URN_ONAP, "guard:target:min");
+ public static final Identifier ID_RESOURCE_GUARD_MAX =
+ new IdentifierImpl(URN_ONAP, "guard:target:max");
+
+ /*
+ * This id specifically for guard is provided by the
+ * operational history database PIP.
+ */
+ public static final Identifier ID_RESOURCE_GUARD_OPERATIONCOUNT =
+ new IdentifierImpl(URN_ONAP, "guard:operation:operation-count");
+
+ /*
+ * This id is specifically for advice returned from guard
+ */
+ public static final Identifier ID_ADVICE_GUARD =
+ new IdentifierImpl(URN_ONAP, "guard:advice");
+ public static final Identifier ID_ADVICE_GUARD_REQUESTID =
+ new IdentifierImpl(URN_ONAP, "guard:advice:request-id");
+
+ /*
+ * Obligation specific ID's
+ */
+
public static final Identifier ID_OBLIGATION_REST_BODY =
new IdentifierImpl(URN_ONAP, "rest:body");
@@ -61,6 +123,8 @@ public final class ToscaDictionary {
public static final Identifier ID_OBLIGATION_MONITORING_ISSUER =
new IdentifierImpl(URN_ONAP, "issuer:monitoring");
+
+
private ToscaDictionary() {
super();
}
diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlPolicyUtils.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlPolicyUtils.java
index ca327b90..46742af9 100644
--- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlPolicyUtils.java
+++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlPolicyUtils.java
@@ -23,11 +23,11 @@
package org.onap.policy.pdp.xacml.application.common;
import com.att.research.xacml.api.Identifier;
-import com.att.research.xacml.api.pdp.PDPEngine;
-import com.att.research.xacml.api.pdp.PDPEngineFactory;
-import com.att.research.xacml.util.FactoryException;
import com.att.research.xacml.util.XACMLProperties;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -146,6 +146,40 @@ public class XacmlPolicyUtils {
}
/**
+ * Adds in the root policy to the PDP properties object.
+ *
+ * @param properties Input properties
+ * @param rootPolicyPath Path to the root policy file
+ * @return Properties object
+ */
+ public static Properties addRootPolicy(Properties properties, Path rootPolicyPath) {
+ //
+ // Get the current set of referenced policy ids
+ //
+ Set<String> rootPolicies = XACMLProperties.getRootPolicyIDs(properties);
+ //
+ // Construct a unique id
+ //
+ int id = 1;
+ while (true) {
+ String refId = "ref" + id;
+ if (rootPolicies.contains(refId)) {
+ id++;
+ } else {
+ rootPolicies.add(refId);
+ properties.put(refId + DOT_FILE_SUFFIX, rootPolicyPath.toAbsolutePath().toString());
+ break;
+ }
+ }
+ //
+ // Set the new comma separated list
+ //
+ properties.setProperty(XACMLProperties.PROP_ROOTPOLICIES,
+ rootPolicies.stream().collect(Collectors.joining(",")));
+ return properties;
+ }
+
+ /**
* Adds in the referenced policy to the PDP properties object.
*
* @param properties Input properties
@@ -318,23 +352,90 @@ public class XacmlPolicyUtils {
return Paths.get(rootPath.toAbsolutePath().toString(), "xacml.properties");
}
+ public interface FileCreator {
+ public File createAFile(String filename) throws IOException;
+
+ }
/**
- * Creates an instance of PDP engine given the Properties object.
+ * Copies a xacml.properties file to another location and all the policies defined within it.
*
- * @param properties Incoming Properties object
- * @return PDPEngine instance or null if failed
+ * @param propertiesPath Path to an existing properties file
+ * @param properties Properties object
+ * @param creator A callback that can create files. Allows JUnit test to pass Temporary folder
+ * @return File object that points to new Properties file
+ * @throws IOException Could not read/write files
*/
- public static PDPEngine createEngine(Properties properties) {
+ public static File copyXacmlPropertiesContents(String propertiesPath, Properties properties,
+ FileCreator creator) throws IOException {
//
- // Now initialize the XACML PDP Engine
+ // Open the properties file
//
- try {
- PDPEngineFactory factory = PDPEngineFactory.newInstance();
- return factory.newEngine(properties);
- } catch (FactoryException e) {
- LOGGER.error("Failed to create XACML PDP Engine {}", e);
+ try (InputStream is = new FileInputStream(propertiesPath)) {
+ //
+ // Load in the properties
+ //
+ properties.load(is);
+ //
+ // Now we create a new xacml.properties in the temporary folder location
+ //
+ File propertiesFile = creator.createAFile("xacml.properties");
+ //
+ // Iterate through any root policies defined
+ //
+ for (String root : XACMLProperties.getRootPolicyIDs(properties)) {
+ //
+ // Get a file
+ //
+ Path rootPath = Paths.get(properties.getProperty(root + DOT_FILE_SUFFIX));
+ LOGGER.debug("Root file {} {}", rootPath, rootPath.getFileName());
+ //
+ // Construct new path for the root policy
+ //
+ File newRootPath = creator.createAFile(rootPath.getFileName().toString());
+ //
+ // Copy the policy file to the temporary folder
+ //
+ com.google.common.io.Files.copy(rootPath.toFile(), newRootPath);
+ //
+ // Change the properties object to point to where the new policy is
+ // in the temporary folder
+ //
+ properties.setProperty(root + DOT_FILE_SUFFIX, newRootPath.getAbsolutePath());
+ }
+ //
+ // Iterate through any referenced policies defined
+ //
+ for (String referenced : XACMLProperties.getReferencedPolicyIDs(properties)) {
+ //
+ // Get a file
+ //
+ Path refPath = Paths.get(properties.getProperty(referenced + DOT_FILE_SUFFIX));
+ LOGGER.debug("Referenced file {} {}", refPath, refPath.getFileName());
+ //
+ // Construct new path for the root policy
+ //
+ File newReferencedPath = creator.createAFile(refPath.getFileName().toString());
+ //
+ // Copy the policy file to the temporary folder
+ //
+ com.google.common.io.Files.copy(refPath.toFile(), newReferencedPath);
+ //
+ // Change the properties object to point to where the new policy is
+ // in the temporary folder
+ //
+ properties.setProperty(referenced + DOT_FILE_SUFFIX, newReferencedPath.getAbsolutePath());
+ }
+ //
+ // Save the new properties file to the temporary folder
+ //
+ try (OutputStream os = new FileOutputStream(propertiesFile.getAbsolutePath())) {
+ properties.store(os, "");
+ }
+ //
+ // Return the new path to the properties folder
+ //
+ return propertiesFile;
}
- return null;
}
}
diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdCombinedPolicyRequest.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdCombinedPolicyRequest.java
index 3914ba60..3038b651 100644
--- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdCombinedPolicyRequest.java
+++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdCombinedPolicyRequest.java
@@ -27,27 +27,41 @@ 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 java.util.ArrayList;
+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;
+@Getter
+@Setter
+@ToString
@XACMLRequest(ReturnPolicyIdList = true)
public class StdCombinedPolicyRequest {
- public StdCombinedPolicyRequest() {
- super();
- }
-
@XACMLSubject(includeInResults = true)
- String onapName = "DCAE";
+ private String onapName;
- @XACMLResource(includeInResults = true)
- String resource = "onap.policies.Monitoring";
+ @XACMLSubject(attributeId = "urn:org:onap:onap-component", includeInResults = true)
+ private String onapComponent;
+
+ @XACMLSubject(attributeId = "urn:org:onap:onap-instance", includeInResults = true)
+ private String onapInstance;
@XACMLAction()
- String action = "configure";
+ private String action;
+
+ @XACMLResource(includeInResults = true)
+ private Collection<String> resource = new ArrayList<>();
+ public StdCombinedPolicyRequest() {
+ super();
+ }
/**
* Parses the DecisionRequest into a MonitoringRequest.
@@ -55,30 +69,57 @@ public class StdCombinedPolicyRequest {
* @param decisionRequest Input DecisionRequest
* @return MonitoringRequest
*/
+ @SuppressWarnings({"unchecked", "rawtypes"})
public static StdCombinedPolicyRequest createInstance(DecisionRequest decisionRequest) {
+ //
+ // Create our request object
+ //
StdCombinedPolicyRequest request = new StdCombinedPolicyRequest();
+ //
+ // Add the subject attributes
+ //
request.onapName = decisionRequest.getOnapName();
+ request.onapComponent = decisionRequest.getOnapComponent();
+ request.onapInstance = decisionRequest.getOnapInstance();
+ //
+ // Add the action attribute
+ //
request.action = decisionRequest.getAction();
-
+ //
+ // Add the resource attributes
+ //
Map<String, Object> resources = decisionRequest.getResource();
- for (Entry<String, Object> entry : resources.entrySet()) {
- if ("policy-id".equals(entry.getKey())) {
- //
- // TODO handle lists of policies
- //
- request.resource = entry.getValue().toString();
+ for (Entry<String, Object> entrySet : resources.entrySet()) {
+ if ("policy-id".equals(entrySet.getKey())) {
+ if (entrySet.getValue() instanceof Collection) {
+ addPolicyIds(request, (Collection) entrySet.getValue());
+ } else if (entrySet.getValue() instanceof String) {
+ request.resource.add(entrySet.getValue().toString());
+ }
continue;
}
- if ("policy-type".equals(entry.getKey())) {
- //
- // TODO handle lists of policies
- //
- request.resource = entry.getValue().toString();
+ if ("policy-type".equals(entrySet.getKey())) {
+ if (entrySet.getValue() instanceof Collection) {
+ addPolicyTypes(request, (Collection) entrySet.getValue());
+ } else if (entrySet.getValue() instanceof String) {
+ request.resource.add(entrySet.getValue().toString());
+ }
}
}
- //
- // TODO handle a bad incoming request. Do that here?
- //
+ return request;
+ }
+
+ private static StdCombinedPolicyRequest addPolicyIds(StdCombinedPolicyRequest request, Collection<Object> ids) {
+ for (Object id : ids) {
+ request.resource.add(id.toString());
+ }
+ return request;
+ }
+
+ private static StdCombinedPolicyRequest addPolicyTypes(StdCombinedPolicyRequest request, Collection<Object> types) {
+ for (Object type : types) {
+ request.resource.add(type.toString());
+ }
return request;
}
}
diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdCombinedPolicyResultsTranslator.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdCombinedPolicyResultsTranslator.java
index b39c2e60..16798379 100644
--- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdCombinedPolicyResultsTranslator.java
+++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdCombinedPolicyResultsTranslator.java
@@ -37,6 +37,7 @@ import com.google.gson.Gson;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -144,40 +145,55 @@ public class StdCombinedPolicyResultsTranslator implements ToscaPolicyTranslator
//
// Go through obligations
//
- for (Obligation obligation : xacmlResult.getObligations()) {
- LOGGER.debug("Obligation: {}", obligation);
- for (AttributeAssignment assignment : obligation.getAttributeAssignments()) {
- LOGGER.debug("Attribute Assignment: {}", assignment);
- //
- // We care about the content attribute
- //
- if (ToscaDictionary.ID_OBLIGATION_POLICY_MONITORING_CONTENTS
- .equals(assignment.getAttributeId())) {
- //
- // The contents are in Json form
- //
- Object stringContents = assignment.getAttributeValue().getValue();
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("DCAE contents: {}{}", System.lineSeparator(), stringContents);
- }
- //
- // Let's parse it into a map using Gson
- //
- Gson gson = new Gson();
- @SuppressWarnings("unchecked")
- Map<String, Object> result = gson.fromJson(stringContents.toString() ,Map.class);
- decisionResponse.getPolicies().add(result);
- }
- }
- }
- } else {
- decisionResponse.setErrorMessage("A better error message");
+ scanObligations(xacmlResult.getObligations(), decisionResponse);
+ }
+ if (xacmlResult.getDecision() == Decision.NOTAPPLICABLE) {
+ //
+ // There is no policy
+ //
+ decisionResponse.setPolicies(new ArrayList<>());
+ }
+ if (xacmlResult.getDecision() == Decision.DENY
+ || xacmlResult.getDecision() == Decision.INDETERMINATE) {
+ //
+ // TODO we have to return an ErrorResponse object instead
+ //
+ decisionResponse.setStatus("A better error message");
}
}
return decisionResponse;
}
+ protected void scanObligations(Collection<Obligation> obligations, DecisionResponse decisionResponse) {
+ for (Obligation obligation : obligations) {
+ LOGGER.debug("Obligation: {}", obligation);
+ for (AttributeAssignment assignment : obligation.getAttributeAssignments()) {
+ LOGGER.debug("Attribute Assignment: {}", assignment);
+ //
+ // We care about the content attribute
+ //
+ if (ToscaDictionary.ID_OBLIGATION_POLICY_MONITORING_CONTENTS
+ .equals(assignment.getAttributeId())) {
+ //
+ // The contents are in Json form
+ //
+ Object stringContents = assignment.getAttributeValue().getValue();
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("DCAE contents: {}{}", System.lineSeparator(), stringContents);
+ }
+ //
+ // Let's parse it into a map using Gson
+ //
+ Gson gson = new Gson();
+ @SuppressWarnings("unchecked")
+ Map<String, Object> result = gson.fromJson(stringContents.toString() ,Map.class);
+ decisionResponse.getPolicies().add(result);
+ }
+ }
+ }
+ }
+
@SuppressWarnings("unchecked")
protected PolicyType convertPolicy(Entry<String, Object> entrySet) throws ToscaPolicyConversionException {
//
@@ -211,9 +227,6 @@ public class StdCombinedPolicyResultsTranslator implements ToscaPolicyTranslator
//
// Generate the TargetType
//
- //
- // There should be a metadata section
- //
if (! policyDefinition.containsKey("type")) {
throw new ToscaPolicyConversionException(policyName + " missing type value");
}
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
new file mode 100644
index 00000000..086d21db
--- /dev/null
+++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchablePolicyRequest.java
@@ -0,0 +1,141 @@
+/*-
+ * ============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.pdp.xacml.application.common.std;
+
+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 java.util.ArrayList;
+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;
+
+@Getter
+@Setter
+@ToString
+@XACMLRequest(ReturnPolicyIdList = true)
+public class StdMatchablePolicyRequest {
+
+ @XACMLSubject(includeInResults = true)
+ private String onapName;
+
+ @XACMLSubject(attributeId = "urn:org:onap:onap-component", includeInResults = true)
+ private String onapComponent;
+
+ @XACMLSubject(attributeId = "urn:org:onap:onap-instance", includeInResults = true)
+ private String onapInstance;
+
+ @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();
+ }
+
+ /**
+ * Parses the DecisionRequest into a MonitoringRequest.
+ *
+ * @param decisionRequest Input DecisionRequest
+ * @return MonitoringRequest
+ */
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public static StdMatchablePolicyRequest createInstance(DecisionRequest decisionRequest) {
+ //
+ // Create our request object
+ //
+ StdMatchablePolicyRequest request = new StdMatchablePolicyRequest();
+ //
+ // Add the subject attributes
+ //
+ request.onapName = decisionRequest.getOnapName();
+ request.onapComponent = decisionRequest.getOnapComponent();
+ request.onapInstance = decisionRequest.getOnapInstance();
+ //
+ // Add the action attribute
+ //
+ request.action = decisionRequest.getAction();
+ //
+ // 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.
+ // Its possible we may have to load the policy type model
+ // and use that to find the fields that are matchable.
+ //
+ if ("policyScope".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 ("policyType".equals(entrySet.getKey())) {
+ if (entrySet.getValue() instanceof Collection) {
+ addPolicyTypes(request, (Collection) entrySet.getValue());
+ }
+ if (entrySet.getValue() instanceof String) {
+ request.policyTypes.add(entrySet.getValue().toString());
+ }
+ }
+ }
+ return request;
+ }
+
+ private static StdMatchablePolicyRequest addPolicyScopes(StdMatchablePolicyRequest request,
+ Collection<Object> scopes) {
+ for (Object scope : scopes) {
+ request.policyScopes.add(scope.toString());
+ }
+ return request;
+ }
+
+ private static StdMatchablePolicyRequest addPolicyTypes(StdMatchablePolicyRequest request,
+ Collection<Object> types) {
+ for (Object type : types) {
+ request.policyTypes.add(type.toString());
+ }
+ return request;
+ }
+}
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
new file mode 100644
index 00000000..8550b12e
--- /dev/null
+++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchableTranslator.java
@@ -0,0 +1,400 @@
+/*-
+ * ============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.pdp.xacml.application.common.std;
+
+import com.att.research.xacml.api.AttributeAssignment;
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Obligation;
+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.annotations.RequestParser;
+import com.att.research.xacml.util.XACMLPolicyWriter;
+import com.google.gson.Gson;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+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 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.ObligationExpressionType;
+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.json.JSONObject;
+import org.onap.policy.models.decisions.concepts.DecisionRequest;
+import org.onap.policy.models.decisions.concepts.DecisionResponse;
+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;
+import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslatorUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class StdMatchableTranslator implements ToscaPolicyTranslator {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(StdMatchableTranslator.class);
+
+ public StdMatchableTranslator() {
+ super();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<PolicyType> scanAndConvertPolicies(Map<String, Object> toscaObject)
+ throws ToscaPolicyConversionException {
+ //
+ // Our return object
+ //
+ List<PolicyType> scannedPolicies = new ArrayList<>();
+ //
+ // Iterate each of the Policies
+ //
+ List<Object> policies = (List<Object>) toscaObject.get("policies");
+ for (Object policyObject : policies) {
+ //
+ // Get the contents
+ //
+ LOGGER.debug("Found policy {}", policyObject.getClass());
+ Map<String, Object> policyContents = (Map<String, Object>) policyObject;
+ for (Entry<String, Object> entrySet : policyContents.entrySet()) {
+ LOGGER.debug("Entry set {}", entrySet);
+ //
+ // Convert this policy
+ //
+ PolicyType policy = this.convertPolicy(entrySet);
+ try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+ XACMLPolicyWriter.writePolicyFile(os, policy);
+ LOGGER.debug("{}", os);
+ } catch (IOException e) {
+ LOGGER.error("Failed to convert {}", e);
+ }
+ //
+ // Convert and add in the new policy
+ //
+ scannedPolicies.add(policy);
+ }
+ }
+
+ return scannedPolicies;
+ }
+
+ @Override
+ public Request convertRequest(DecisionRequest request) {
+ LOGGER.debug("Converting Request {}", request);
+ try {
+ return RequestParser.parseRequest(StdMatchablePolicyRequest.createInstance(request));
+ } catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) {
+ LOGGER.error("Failed to convert DecisionRequest: {}", e);
+ }
+ //
+ // TODO throw exception
+ //
+ return null;
+ }
+
+ @Override
+ public DecisionResponse convertResponse(Response xacmlResponse) {
+ LOGGER.debug("Converting Response {}", xacmlResponse);
+ DecisionResponse decisionResponse = new DecisionResponse();
+ //
+ // Iterate through all the results
+ //
+ for (Result xacmlResult : xacmlResponse.getResults()) {
+ //
+ // Check the result
+ //
+ if (xacmlResult.getDecision() == Decision.PERMIT) {
+ //
+ // Setup policies
+ //
+ decisionResponse.setPolicies(new ArrayList<>());
+ //
+ // Go through obligations
+ //
+ scanObligations(xacmlResult.getObligations(), decisionResponse);
+ }
+ if (xacmlResult.getDecision() == Decision.NOTAPPLICABLE) {
+ //
+ // There is no policy
+ //
+ decisionResponse.setPolicies(new ArrayList<>());
+ }
+ if (xacmlResult.getDecision() == Decision.DENY
+ || xacmlResult.getDecision() == Decision.INDETERMINATE) {
+ //
+ // TODO we have to return an ErrorResponse object instead
+ //
+ decisionResponse.setStatus("A better error message");
+ }
+ }
+
+ return decisionResponse;
+ }
+
+ protected void scanObligations(Collection<Obligation> obligations, DecisionResponse decisionResponse) {
+ for (Obligation obligation : obligations) {
+ LOGGER.debug("Obligation: {}", obligation);
+ for (AttributeAssignment assignment : obligation.getAttributeAssignments()) {
+ LOGGER.debug("Attribute Assignment: {}", assignment);
+ //
+ // We care about the content attribute
+ //
+ if (ToscaDictionary.ID_OBLIGATION_POLICY_MONITORING_CONTENTS
+ .equals(assignment.getAttributeId())) {
+ //
+ // The contents are in Json form
+ //
+ Object stringContents = assignment.getAttributeValue().getValue();
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("DCAE contents: {}{}", System.lineSeparator(), stringContents);
+ }
+ //
+ // Let's parse it into a map using Gson
+ //
+ Gson gson = new Gson();
+ @SuppressWarnings("unchecked")
+ Map<String, Object> result = gson.fromJson(stringContents.toString() ,Map.class);
+ decisionResponse.getPolicies().add(result);
+ }
+ }
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ protected PolicyType convertPolicy(Entry<String, Object> entrySet) throws ToscaPolicyConversionException {
+ //
+ // Policy name should be at the root
+ //
+ String policyName = entrySet.getKey();
+ Map<String, Object> policyDefinition = (Map<String, Object>) entrySet.getValue();
+ //
+ // Set it as the policy ID
+ //
+ PolicyType newPolicyType = new PolicyType();
+ newPolicyType.setPolicyId(policyName);
+ //
+ // Optional description
+ //
+ if (policyDefinition.containsKey("description")) {
+ newPolicyType.setDescription(policyDefinition.get("description").toString());
+ }
+ //
+ // There should be a metadata section
+ //
+ if (! policyDefinition.containsKey("metadata")) {
+ throw new ToscaPolicyConversionException(policyName + " missing metadata section");
+ }
+ this.fillMetadataSection(newPolicyType,
+ (Map<String, Object>) policyDefinition.get("metadata"));
+ //
+ // Set the combining rule
+ //
+ newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_FIRST_APPLICABLE.stringValue());
+ //
+ // Generate the TargetType
+ //
+ if (! policyDefinition.containsKey("properties")) {
+ throw new ToscaPolicyConversionException(policyName + " missing properties section");
+ }
+ policyDefinition.get("properties");
+ newPolicyType.setTarget(generateTargetType((Map<String, Object>) policyDefinition.get("properties")));
+ //
+ // Now create the Permit Rule
+ // No target since the policy has a target
+ // With obligations.
+ //
+ RuleType rule = new RuleType();
+ rule.setDescription("Default is to PERMIT if the policy matches.");
+ rule.setRuleId(policyName + ":rule");
+ rule.setEffect(EffectType.PERMIT);
+ rule.setTarget(new TargetType());
+ //
+ // Now represent the policy as Json
+ //
+ JSONObject jsonObligation = new JSONObject();
+ jsonObligation.put(policyName, policyDefinition);
+ addObligation(rule, jsonObligation);
+ //
+ // Add the rule to the policy
+ //
+ newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
+ //
+ // Return our new policy
+ //
+ return newPolicyType;
+ }
+
+ /**
+ * From the TOSCA metadata section, pull in values that are needed into the XACML policy.
+ *
+ * @param policy Policy Object to store the metadata
+ * @param metadata The Metadata TOSCA Map
+ * @return Same Policy Object
+ * @throws ToscaPolicyConversionException If there is something missing from the metadata
+ */
+ protected PolicyType fillMetadataSection(PolicyType policy,
+ Map<String, Object> metadata) throws ToscaPolicyConversionException {
+ if (! metadata.containsKey("policy-id")) {
+ throw new ToscaPolicyConversionException(policy.getPolicyId() + " missing metadata policy-id");
+ } else {
+ //
+ // Do nothing here - the XACML PolicyId is used from TOSCA Policy Name field
+ //
+ }
+ if (! metadata.containsKey("policy-version")) {
+ throw new ToscaPolicyConversionException(policy.getPolicyId() + " missing metadata policy-version");
+ } else {
+ //
+ // Add in the Policy Version
+ //
+ policy.setVersion(metadata.get("policy-version").toString());
+ }
+ return policy;
+ }
+
+ /**
+ * 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.
+ *
+ * @param properties Properties section of policy
+ * @return TargetType object
+ */
+ @SuppressWarnings("unchecked")
+ protected TargetType generateTargetType(Map<String, Object> properties) {
+ TargetType targetType = new TargetType();
+ //
+ // Iterate the properties
+ //
+ for (Entry<String, Object> entrySet : properties.entrySet()) {
+ //
+ // Find policyScope and policyType
+ //
+ if (entrySet.getKey().equals("policyScope")) {
+ LOGGER.debug("Found policyScope: {}", 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.debug("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));
+ }
+ }
+ }
+
+ return targetType;
+ }
+
+ protected AnyOfType generateMatches(Collection<Object> matchables, Identifier attributeId) {
+ //
+ // This is our outer AnyOf - which is an OR
+ //
+ AnyOfType anyOf = new AnyOfType();
+ for (Object matchable : matchables) {
+ //
+ // Create a match for this
+ //
+ MatchType match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+ XACML3.ID_FUNCTION_STRING_EQUAL,
+ matchable.toString(),
+ XACML3.ID_DATATYPE_STRING,
+ attributeId,
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
+ //
+ // Now create an anyOf (OR)
+ //
+ anyOf.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(match));
+ }
+ return anyOf;
+ }
+
+ protected RuleType addObligation(RuleType rule, JSONObject jsonPolicy) {
+ //
+ // Convert the YAML Policy to JSON Object
+ //
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("JSON Optimization Policy {}{}", System.lineSeparator(), jsonPolicy);
+ }
+ //
+ // Create an AttributeValue for it
+ //
+ AttributeValueType value = new AttributeValueType();
+ value.setDataType(ToscaDictionary.ID_OBLIGATION_POLICY_MONITORING_DATATYPE.stringValue());
+ value.getContent().add(jsonPolicy.toString());
+ //
+ // Create our AttributeAssignmentExpression where we will
+ // store the contents of the policy in JSON format.
+ //
+ AttributeAssignmentExpressionType expressionType = new AttributeAssignmentExpressionType();
+ expressionType.setAttributeId(ToscaDictionary.ID_OBLIGATION_POLICY_MONITORING_CONTENTS.stringValue());
+ ObjectFactory factory = new ObjectFactory();
+ expressionType.setExpression(factory.createAttributeValue(value));
+ //
+ // Create an ObligationExpression for it
+ //
+ ObligationExpressionType obligation = new ObligationExpressionType();
+ obligation.setFulfillOn(EffectType.PERMIT);
+ obligation.setObligationId(ToscaDictionary.ID_OBLIGATION_REST_BODY.stringValue());
+ obligation.getAttributeAssignmentExpression().add(expressionType);
+ //
+ // Now we can add it into the rule
+ //
+ ObligationExpressionsType obligations = new ObligationExpressionsType();
+ obligations.getObligationExpression().add(obligation);
+ rule.setObligationExpressions(obligations);
+ return rule;
+ }
+
+}
diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMetadataTranslator.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMetadataTranslator.java
deleted file mode 100644
index 11651f4f..00000000
--- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMetadataTranslator.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*-
- * ============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.pdp.xacml.application.common.std;
-
-import com.att.research.xacml.api.Request;
-import com.att.research.xacml.api.Response;
-import com.att.research.xacml.util.XACMLPolicyWriter;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
-
-import org.onap.policy.models.decisions.concepts.DecisionRequest;
-import org.onap.policy.models.decisions.concepts.DecisionResponse;
-import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
-import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class StdMetadataTranslator implements ToscaPolicyTranslator {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(StdMetadataTranslator.class);
-
- public StdMetadataTranslator() {
- super();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public List<PolicyType> scanAndConvertPolicies(Map<String, Object> toscaObject)
- throws ToscaPolicyConversionException {
- //
- // Our return object
- //
- List<PolicyType> scannedPolicies = new ArrayList<>();
- //
- // Iterate each of the Policies
- //
- List<Object> policies = (List<Object>) toscaObject.get("policies");
- for (Object policyObject : policies) {
- //
- // Get the contents
- //
- LOGGER.debug("Found policy {}", policyObject.getClass());
- Map<String, Object> policyContents = (Map<String, Object>) policyObject;
- for (Entry<String, Object> entrySet : policyContents.entrySet()) {
- LOGGER.debug("Entry set {}", entrySet);
- //
- // Convert this policy
- //
- PolicyType policy = this.convertPolicy(entrySet);
- try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
- XACMLPolicyWriter.writePolicyFile(os, policy);
- LOGGER.debug("{}", os);
- } catch (IOException e) {
- LOGGER.error("Failed to convert {}", e);
- }
- //
- // Convert and add in the new policy
- //
- scannedPolicies.add(policy);
- }
- }
-
- return scannedPolicies;
- }
-
- @Override
- public Request convertRequest(DecisionRequest request) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public DecisionResponse convertResponse(Response xacmlResponse) {
- // TODO Auto-generated method stub
- return null;
- }
-
- private PolicyType convertPolicy(Entry<String, Object> entrySet) throws ToscaPolicyConversionException {
-
- return null;
- }
-
-}
diff --git a/applications/guard/pom.xml b/applications/guard/pom.xml
index 7ee3da08..6696e55e 100644
--- a/applications/guard/pom.xml
+++ b/applications/guard/pom.xml
@@ -34,15 +34,6 @@
<dependencies>
<dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- </dependency>
- <dependency>
- <groupId>org.onap.policy.common</groupId>
- <artifactId>common-parameters</artifactId>
- <version>${policy.common.version}</version>
- </dependency>
- <dependency>
<groupId>org.onap.policy.xacml-pdp.applications</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
diff --git a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java
index 18385239..1b12fca8 100644
--- a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java
+++ b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java
@@ -24,19 +24,23 @@ package org.onap.policy.xacml.pdp.application.guard;
import com.att.research.xacml.api.Request;
import com.att.research.xacml.api.Response;
+import com.att.research.xacml.util.XACMLPolicyWriter;
import com.google.common.collect.Lists;
+import java.io.IOException;
+import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
import org.onap.policy.models.decisions.concepts.DecisionRequest;
import org.onap.policy.models.decisions.concepts.DecisionResponse;
import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
-import org.onap.policy.pdp.xacml.application.common.std.StdMetadataTranslator;
+import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -52,7 +56,7 @@ public class GuardPdpApplication extends StdXacmlApplicationServiceProvider {
private static final Logger LOGGER = LoggerFactory.getLogger(GuardPdpApplication.class);
private static final String STRING_VERSION100 = "1.0.0";
private Map<String, String> supportedPolicyTypes = new HashMap<>();
- private StdMetadataTranslator translator = new StdMetadataTranslator();
+ private LegacyGuardTranslator translator = new LegacyGuardTranslator();
/** Constructor.
*
@@ -103,9 +107,37 @@ public class GuardPdpApplication extends StdXacmlApplicationServiceProvider {
throw new ToscaPolicyConversionException("Converted 0 policies");
}
//
- // TODO update properties, save to disk, etc.
+ // Create a copy of the properties object
//
- } catch (ToscaPolicyConversionException e) {
+ Properties newProperties = this.getProperties();
+ //
+ // Iterate through the policies
+ //
+ for (PolicyType newPolicy : listPolicies) {
+ //
+ // Construct the filename
+ //
+ Path refPath = XacmlPolicyUtils.constructUniquePolicyFilename(newPolicy, this.getDataPath());
+ //
+ // Write the policy to disk
+ // Maybe check for an error
+ //
+ XACMLPolicyWriter.writePolicyFile(refPath, newPolicy);
+ //
+ // Add root policy to properties object
+ //
+ XacmlPolicyUtils.addRootPolicy(newProperties, refPath);
+ }
+ //
+ // Write the properties to disk
+ //
+ XacmlPolicyUtils.storeXacmlProperties(newProperties,
+ XacmlPolicyUtils.getPropertiesPath(this.getDataPath()));
+ //
+ // Reload the engine
+ //
+ this.createEngine(newProperties);
+ } catch (IOException | ToscaPolicyConversionException e) {
LOGGER.error("Failed to loadPolicies {}", e);
}
}
diff --git a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardPolicyRequest.java b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardPolicyRequest.java
new file mode 100644
index 00000000..0b5b5675
--- /dev/null
+++ b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardPolicyRequest.java
@@ -0,0 +1,163 @@
+/*-
+ * ============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.guard;
+
+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 java.util.Map;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+import org.onap.policy.models.decisions.concepts.DecisionRequest;
+
+@Getter
+@Setter
+@ToString
+@XACMLRequest(ReturnPolicyIdList = true)
+public class LegacyGuardPolicyRequest {
+
+ private static final String STR_GUARD = "guard";
+
+ @XACMLSubject(includeInResults = true)
+ private String onapName;
+
+ @XACMLSubject(includeInResults = true, attributeId = "urn:org:onap:onap-component")
+ private String onapComponent;
+
+ @XACMLSubject(includeInResults = true, attributeId = "urn:org:onap:onap-instance")
+ private String onapInstance;
+
+ @XACMLSubject(includeInResults = true, attributeId = "urn:org:onap:guard:request:request-id")
+ private String requestId;
+
+ @XACMLAction
+ private String action = STR_GUARD;
+
+ @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:clname:clname-id")
+ private String clnameId;
+
+ @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:actor:actor-id")
+ private String actorId;
+
+ @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:operation:operation-id")
+ private String operationId;
+
+ @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:target:target-id")
+ private String targetId;
+
+ @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:target:vf-count")
+ private Integer vfCount;
+
+ @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:target:min")
+ private Integer min;
+
+ @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:target:max")
+ private Integer max;
+
+ @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:operation:operation-count")
+ private Integer operationCount;
+
+ public LegacyGuardPolicyRequest() {
+ super();
+ }
+
+ /**
+ * Parses the DecisionRequest into a StdMetadataPolicyRequest.
+ *
+ * @param decisionRequest Input DecisionRequest
+ * @return StdMetadataPolicyRequest
+ */
+ @SuppressWarnings("unchecked")
+ public static LegacyGuardPolicyRequest createInstance(DecisionRequest decisionRequest) {
+ //
+ // Create our return object
+ //
+ LegacyGuardPolicyRequest request = new LegacyGuardPolicyRequest();
+ //
+ // Add the subject attributes
+ //
+ request.onapName = decisionRequest.getOnapName();
+ request.onapComponent = decisionRequest.getOnapComponent();
+ request.onapInstance = decisionRequest.getOnapInstance();
+ request.requestId = decisionRequest.getRequestId();
+ //
+ // Now pull from the resources
+ //
+ Map<String, Object> resources = decisionRequest.getResource();
+ //
+ // Just in case nothing is in there
+ //
+ if (resources == null || resources.isEmpty() || ! resources.containsKey(STR_GUARD)) {
+ //
+ // Perhaps we throw an exception and then caller
+ // can put together a response
+ //
+ return request;
+ }
+ Map<String, Object> guard = (Map<String, Object>) resources.get(STR_GUARD);
+ if (guard == null || guard.isEmpty()) {
+ //
+ // again, same problem throw an exception?
+ //
+ return request;
+ }
+ //
+ // Find our fields
+ //
+ if (guard.containsKey("actor")) {
+ request.actorId = guard.get("actor").toString();
+ }
+ if (guard.containsKey("recipe")) {
+ request.operationId = guard.get("recipe").toString();
+ }
+ if (guard.containsKey("clname")) {
+ request.clnameId = guard.get("clname").toString();
+ }
+ if (guard.containsKey("targets")) {
+ request.targetId = guard.get("targets").toString();
+ }
+ if (guard.containsKey("vfCount")) {
+ request.vfCount = Integer.decode(guard.get("vfCount").toString());
+ }
+ if (guard.containsKey("min")) {
+ request.min = Integer.decode(guard.get("min").toString());
+ }
+ if (guard.containsKey("max")) {
+ request.max = Integer.decode(guard.get("max").toString());
+ }
+ //
+ // TODO - remove this when the PIP is hooked up
+ //
+ if (guard.containsKey("operationCount")) {
+ request.operationCount = Integer.decode(guard.get("operationCount").toString());
+ }
+
+ return request;
+ }
+
+}
diff --git a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardTranslator.java b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardTranslator.java
new file mode 100644
index 00000000..81340b4d
--- /dev/null
+++ b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardTranslator.java
@@ -0,0 +1,740 @@
+/*-
+ * ============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.guard;
+
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+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.annotations.RequestParser;
+import com.att.research.xacml.util.XACMLPolicyWriter;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+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.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
+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 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.models.decisions.concepts.DecisionRequest;
+import org.onap.policy.models.decisions.concepts.DecisionResponse;
+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;
+import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslatorUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LegacyGuardTranslator implements ToscaPolicyTranslator {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(LegacyGuardTranslator.class);
+
+ private static final String FIELD_POLICIES = "policies";
+ private static final String FIELD_TOPOLOGY_TEMPLATE = "topology_template";
+ private static final String FIELD_GUARD_ACTIVE_START = "guardActiveStart";
+ private static final String FIELD_GUARD_ACTIVE_END = "guardActiveEnd";
+
+ public LegacyGuardTranslator() {
+ super();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<PolicyType> scanAndConvertPolicies(Map<String, Object> toscaObject)
+ throws ToscaPolicyConversionException {
+ //
+ // Our return object
+ //
+ List<PolicyType> scannedPolicies = new ArrayList<>();
+ //
+ // Find the Policies
+ //
+ List<Object> policies;
+
+ if (toscaObject.containsKey(FIELD_POLICIES)) {
+ policies = (List<Object>) toscaObject.get(FIELD_POLICIES);
+ } else if (toscaObject.containsKey(FIELD_TOPOLOGY_TEMPLATE)) {
+ Map<String, Object> topologyTemplate = (Map<String, Object>) toscaObject.get(FIELD_TOPOLOGY_TEMPLATE);
+ if (topologyTemplate.containsKey(FIELD_POLICIES)) {
+ policies = (List<Object>) topologyTemplate.get(FIELD_POLICIES);
+ } else {
+ LOGGER.warn("topologyTemplate does not contain policies");
+ return scannedPolicies;
+ }
+ } else {
+ LOGGER.warn("Failed to find policies or topologyTemplate");
+ return scannedPolicies;
+ }
+ //
+ // Iterate each of the Policies
+ //
+ for (Object policyObject : policies) {
+ //
+ // Get the contents
+ //
+ LOGGER.debug("Found policy {}", policyObject.getClass());
+ Map<String, Object> policyContents = (Map<String, Object>) policyObject;
+ for (Entry<String, Object> entrySet : policyContents.entrySet()) {
+ LOGGER.debug("Entry set {}", entrySet);
+ //
+ // Convert this policy
+ //
+ PolicyType policy = this.convertPolicy(entrySet);
+ if (policy == null) {
+ //
+ // Somehow there wasn't enough information to create
+ // a policy
+ //
+ LOGGER.debug("Failed to convert policy");
+ continue;
+ }
+ //
+ // Debug dump this
+ //
+ try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+ XACMLPolicyWriter.writePolicyFile(os, policy);
+ LOGGER.debug("{}", os);
+ } catch (IOException e) {
+ LOGGER.error("Failed to convert {}", e);
+ }
+ //
+ // Convert and add in the new policy
+ //
+ scannedPolicies.add(policy);
+ }
+ }
+
+ return scannedPolicies;
+ }
+
+ @Override
+ public Request convertRequest(DecisionRequest request) {
+ LOGGER.debug("Converting Request {}", request);
+ try {
+ return RequestParser.parseRequest(LegacyGuardPolicyRequest.createInstance(request));
+ } catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) {
+ LOGGER.error("Failed to convert DecisionRequest: {}", e);
+ }
+ //
+ // TODO throw exception
+ //
+ return null;
+ }
+
+
+ @Override
+ public DecisionResponse convertResponse(Response xacmlResponse) {
+ LOGGER.debug("Converting Response {}", xacmlResponse);
+ DecisionResponse decisionResponse = new DecisionResponse();
+ //
+ // Iterate through all the results
+ //
+ for (Result xacmlResult : xacmlResponse.getResults()) {
+ //
+ // Check the result
+ //
+ if (xacmlResult.getDecision() == Decision.PERMIT) {
+ //
+ // Just simply return a Permit response
+ //
+ decisionResponse.setStatus(Decision.PERMIT.toString());
+ }
+ if (xacmlResult.getDecision() == Decision.DENY) {
+ //
+ // Just simply return a Deny response
+ //
+ decisionResponse.setStatus(Decision.DENY.toString());
+ }
+ if (xacmlResult.getDecision() == Decision.NOTAPPLICABLE) {
+ //
+ // There is no guard policy, so we return a permit
+ //
+ decisionResponse.setStatus(Decision.PERMIT.toString());
+ }
+ }
+
+ return decisionResponse;
+ }
+
+ @SuppressWarnings("unchecked")
+ private PolicyType convertPolicy(Entry<String, Object> entrySet) throws ToscaPolicyConversionException {
+ //
+ // Policy name should be at the root
+ //
+ String policyName = entrySet.getKey();
+ Map<String, Object> policyDefinition = (Map<String, Object>) entrySet.getValue();
+ //
+ // Set it as the policy ID
+ //
+ PolicyType newPolicyType = new PolicyType();
+ newPolicyType.setPolicyId(policyName);
+ //
+ // Optional description
+ //
+ if (policyDefinition.containsKey("description")) {
+ newPolicyType.setDescription(policyDefinition.get("description").toString());
+ }
+ //
+ // There should be a metadata section
+ //
+ if (! policyDefinition.containsKey("metadata")) {
+ throw new ToscaPolicyConversionException(policyName + " missing metadata section");
+ }
+ this.fillMetadataSection(newPolicyType,
+ (Map<String, Object>) policyDefinition.get("metadata"));
+ //
+ // Set the combining rule
+ //
+ newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_DENY_UNLESS_PERMIT.stringValue());
+ //
+ // Generate the TargetType
+ //
+ if (! policyDefinition.containsKey("properties")) {
+ throw new ToscaPolicyConversionException(policyName + " missing properties section");
+ }
+ newPolicyType.setTarget(this.generateTargetType((Map<String, Object>) policyDefinition.get("properties")));
+ //
+ // Now create the Permit Rule
+ //
+ RuleType rule = generatePermitRule(policyName, policyDefinition.get("type").toString(),
+ (Map<String, Object>) policyDefinition.get("properties"));
+ //
+ // Check if we were able to create the rule
+ //
+ if (rule == null) {
+ LOGGER.warn("Failed to create rule");
+ return null;
+ }
+ //
+ // Add the rule to the policy
+ //
+ newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
+ //
+ // Return our new policy
+ //
+ return newPolicyType;
+ }
+
+ /**
+ * From the TOSCA metadata section, pull in values that are needed into the XACML policy.
+ *
+ * @param policy Policy Object to store the metadata
+ * @param metadata The Metadata TOSCA Map
+ * @return Same Policy Object
+ * @throws ToscaPolicyConversionException If there is something missing from the metadata
+ */
+ protected PolicyType fillMetadataSection(PolicyType policy,
+ Map<String, Object> metadata) throws ToscaPolicyConversionException {
+ if (! metadata.containsKey("policy-id")) {
+ throw new ToscaPolicyConversionException(policy.getPolicyId() + " missing metadata policy-id");
+ } else {
+ //
+ // Do nothing here - the XACML PolicyId is used from TOSCA Policy Name field
+ //
+ }
+ if (! metadata.containsKey("policy-version")) {
+ throw new ToscaPolicyConversionException(policy.getPolicyId() + " missing metadata policy-version");
+ } else {
+ //
+ // Add in the Policy Version
+ //
+ policy.setVersion(metadata.get("policy-version").toString());
+ }
+ return policy;
+ }
+
+ protected TargetType generateTargetType(Map<String, Object> properties) {
+ //
+ // Go through potential properties
+ //
+ AllOfType allOf = new AllOfType();
+ if (properties.containsKey("actor")) {
+ addMatch(allOf, properties.get("actor"), ToscaDictionary.ID_RESOURCE_GUARD_ACTOR);
+ }
+ if (properties.containsKey("recipe")) {
+ addMatch(allOf, properties.get("recipe"), ToscaDictionary.ID_RESOURCE_GUARD_RECIPE);
+ }
+ if (properties.containsKey("targets")) {
+ addMatch(allOf, properties.get("targets"), ToscaDictionary.ID_RESOURCE_GUARD_TARGETID);
+ }
+ if (properties.containsKey("clname")) {
+ addMatch(allOf, properties.get("clname"), ToscaDictionary.ID_RESOURCE_GUARD_CLNAME);
+ }
+ if (properties.containsKey("targets")) {
+ addMatch(allOf, properties.get("targets"), ToscaDictionary.ID_RESOURCE_GUARD_TARGETID);
+ }
+ //
+ // Create target
+ //
+ TargetType target = new TargetType();
+ AnyOfType anyOf = new AnyOfType();
+ anyOf.getAllOf().add(allOf);
+ target.getAnyOf().add(anyOf);
+ return target;
+ }
+
+ private static AllOfType addMatch(AllOfType allOf, Object value, Identifier attributeId) {
+ if (value instanceof String) {
+ if (".*".equals(value.toString())) {
+ //
+ // There's no point to even have a match
+ //
+ return allOf;
+ } else {
+ //
+ // Exact match
+ //
+ MatchType match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+ XACML3.ID_FUNCTION_STRING_EQUAL,
+ value,
+ XACML3.ID_DATATYPE_STRING,
+ attributeId,
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
+
+ allOf.getMatch().add(match);
+ }
+ return allOf;
+ }
+ if (value instanceof Collection) {
+ //
+ // TODO support a collection of that attribute
+ //
+ }
+ return allOf;
+ }
+
+ private static RuleType generatePermitRule(String policyName, String policyType, Map<String, Object> properties) {
+ //
+ // Now determine which policy type we are generating
+ //
+ if ("onap.policies.controlloop.guard.FrequencyLimiter".equals(policyType)) {
+ return generateFrequencyPermit(policyName, properties);
+ } else if ("onap.policies.controlloop.guard.MinMax".equals(policyType)) {
+ return generateMinMaxPermit(policyName, properties);
+ }
+ return null;
+ }
+
+ private static RuleType generateFrequencyPermit(String policyName, Map<String, Object> properties) {
+ //
+ // See if its possible to generate a count
+ //
+ Integer limit = null;
+ if (properties.containsKey("limit")) {
+ limit = Integer.decode(properties.get("limit").toString());
+ }
+ if (limit == null) {
+ LOGGER.debug("Must have a limit value for frequency guard policy to be created");
+ return null;
+ }
+ //
+ // Get the properties that are common among guards
+ //
+ String timeWindow = null;
+ if (properties.containsKey("timeWindow")) {
+ timeWindow = properties.get("timeWindow").toString();
+ }
+ String timeUnits = null;
+ if (properties.containsKey("timeUnits")) {
+ timeUnits = properties.get("timeUnits").toString();
+ }
+ String guardActiveStart = null;
+ if (properties.containsKey(FIELD_GUARD_ACTIVE_START)) {
+ guardActiveStart = properties.get(FIELD_GUARD_ACTIVE_START).toString();
+ }
+ String guardActiveEnd = null;
+ if (properties.containsKey(FIELD_GUARD_ACTIVE_END)) {
+ guardActiveEnd = properties.get(FIELD_GUARD_ACTIVE_END).toString();
+ }
+ //
+ // Generate the time in range
+ //
+ final ApplyType timeRange = generateTimeInRange(guardActiveStart, guardActiveEnd);
+ //
+ // Generate a count
+ //
+ final ApplyType countCheck = generateCountCheck(limit, timeWindow, timeUnits);
+ //
+ // Now combine into an And
+ //
+ ApplyType applyAnd = new ApplyType();
+ applyAnd.setDescription("return true if all the apply's are true.");
+ applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
+ applyAnd.getExpression().add(new ObjectFactory().createApply(timeRange));
+ applyAnd.getExpression().add(new ObjectFactory().createApply(countCheck));
+ //
+ // And create an outer negation of the And
+ //
+ ApplyType applyNot = new ApplyType();
+ applyNot.setDescription("Negate the and");
+ applyNot.setFunctionId(XACML3.ID_FUNCTION_NOT.stringValue());
+ applyNot.getExpression().add(new ObjectFactory().createApply(applyAnd));
+
+ //
+ // Create our condition
+ //
+ final ConditionType condition = new ConditionType();
+ condition.setExpression(new ObjectFactory().createApply(applyNot));
+
+ //
+ // Now we can create our rule
+ //
+ RuleType permit = new RuleType();
+ permit.setDescription("Default is to PERMIT if the policy matches.");
+ permit.setRuleId(policyName + ":rule");
+ permit.setEffect(EffectType.PERMIT);
+ permit.setTarget(new TargetType());
+ //
+ // Add the condition
+ //
+ permit.setCondition(condition);
+ //
+ // TODO Add the advice - Is the request id needed to be returned?
+ //
+ // permit.setAdviceExpressions(adviceExpressions);
+ //
+ // Done
+ //
+ return permit;
+ }
+
+ private static RuleType generateMinMaxPermit(String policyName, Map<String, Object> properties) {
+ //
+ // Get the properties that are common among guards
+ //
+ String guardActiveStart = null;
+ if (properties.containsKey(FIELD_GUARD_ACTIVE_START)) {
+ guardActiveStart = properties.get(FIELD_GUARD_ACTIVE_START).toString();
+ }
+ String guardActiveEnd = null;
+ if (properties.containsKey(FIELD_GUARD_ACTIVE_END)) {
+ guardActiveEnd = properties.get(FIELD_GUARD_ACTIVE_END).toString();
+ }
+ //
+ // Generate the time in range
+ //
+ final ApplyType timeRange = generateTimeInRange(guardActiveStart, guardActiveEnd);
+ //
+ // See if its possible to generate a count
+ //
+ Integer min = null;
+ if (properties.containsKey("min")) {
+ min = Integer.decode(properties.get("min").toString());
+ }
+ Integer max = null;
+ if (properties.containsKey("max")) {
+ max = Integer.decode(properties.get("max").toString());
+ }
+ final ApplyType minApply = generateMinCheck(min);
+ final ApplyType maxApply = generateMaxCheck(max);
+ //
+ // Make sure we have at least something to check here,
+ // otherwise there really is no point to this policy.
+ //
+ if (timeRange == null && minApply == null && maxApply == null) {
+ return null;
+ }
+ //
+ // Create our rule
+ //
+ RuleType permit = new RuleType();
+ permit.setDescription("Default is to PERMIT if the policy matches.");
+ permit.setRuleId(policyName + ":rule");
+ permit.setEffect(EffectType.PERMIT);
+ permit.setTarget(new TargetType());
+ //
+ // Create our condition
+ //
+ final ConditionType condition = new ConditionType();
+ //
+ // Check if we have all the fields (this can be a little
+ // ugly) but the ultimate goal is to simplify the policy
+ // condition to only check for necessary attributes.
+ //
+ ObjectFactory factory = new ObjectFactory();
+ if (timeRange != null && minApply != null && maxApply != null) {
+ //
+ // All 3 must apply
+ //
+ ApplyType applyAnd = new ApplyType();
+ applyAnd.setDescription("return true if all the apply's are true.");
+ applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
+ applyAnd.getExpression().add(factory.createApply(timeRange));
+ applyAnd.getExpression().add(factory.createApply(minApply));
+ applyAnd.getExpression().add(factory.createApply(maxApply));
+ //
+ // Add into the condition
+ //
+ condition.setExpression(factory.createApply(applyAnd));
+ } else {
+ //
+ // At least one of these applies is null. We need at least
+ // two to require the And apply. Otherwise there is no need
+ // for an outer And apply as the single condition can work
+ // on its own.
+ //
+ if (timeRange != null && minApply == null && maxApply == null) {
+ //
+ // Only the time range check is necessary
+ //
+ condition.setExpression(factory.createApply(timeRange));
+ } else if (timeRange == null && minApply != null && maxApply == null) {
+ //
+ // Only the min check is necessary
+ //
+ condition.setExpression(factory.createApply(minApply));
+ } else if (timeRange == null && minApply == null) {
+ //
+ // Only the max check is necessary
+ //
+ condition.setExpression(factory.createApply(maxApply));
+ } else {
+ //
+ // Ok we will need an outer And and have at least the
+ // time range and either min or max check
+ //
+ ApplyType applyAnd = new ApplyType();
+ applyAnd.setDescription("return true if all the apply's are true.");
+ applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue());
+ if (timeRange != null) {
+ applyAnd.getExpression().add(factory.createApply(timeRange));
+ }
+ if (minApply != null) {
+ applyAnd.getExpression().add(factory.createApply(minApply));
+ }
+ if (maxApply != null) {
+ applyAnd.getExpression().add(factory.createApply(maxApply));
+ }
+ //
+ // Add into the condition
+ //
+ condition.setExpression(factory.createApply(applyAnd));
+ }
+ }
+ //
+ // Add the condition
+ //
+ permit.setCondition(condition);
+ //
+ // TODO Add the advice - Is the request id needed to be returned?
+ //
+ // permit.setAdviceExpressions(adviceExpressions);
+ //
+ // Done
+ //
+ return permit;
+ }
+
+ private static ApplyType generateTimeInRange(String start, String end) {
+ if (start == null || end == null) {
+ LOGGER.warn("Missing time range start {} end {}", start, end);
+ return null;
+ }
+ if (start.isEmpty() || end.isEmpty()) {
+ LOGGER.warn("Empty time range start {} end {}", start, end);
+ return null;
+ }
+
+ AttributeDesignatorType designator = new AttributeDesignatorType();
+ designator.setAttributeId(XACML3.ID_ENVIRONMENT_CURRENT_TIME.stringValue());
+ designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_ENVIRONMENT.stringValue());
+ designator.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
+
+ AttributeValueType valueStart = new AttributeValueType();
+ valueStart.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
+ valueStart.getContent().add(start);
+
+ AttributeValueType valueEnd = new AttributeValueType();
+ valueEnd.setDataType(XACML3.ID_DATATYPE_TIME.stringValue());
+ valueEnd.getContent().add(end);
+
+ ObjectFactory factory = new ObjectFactory();
+
+ ApplyType applyOneAndOnly = new ApplyType();
+ applyOneAndOnly.setDescription("Unbag the current time");
+ applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_TIME_ONE_AND_ONLY.stringValue());
+ applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
+
+ ApplyType applyTimeInRange = new ApplyType();
+ applyTimeInRange.setDescription("return true if current time is in range.");
+ applyTimeInRange.setFunctionId(XACML3.ID_FUNCTION_TIME_IN_RANGE.stringValue());
+ applyTimeInRange.getExpression().add(factory.createApply(applyOneAndOnly));
+ applyTimeInRange.getExpression().add(factory.createAttributeValue(valueStart));
+ applyTimeInRange.getExpression().add(factory.createAttributeValue(valueEnd));
+
+ return applyTimeInRange;
+ }
+
+ private static ApplyType generateCountCheck(Integer limit, String timeWindow, String timeUnits) {
+ AttributeDesignatorType designator = new AttributeDesignatorType();
+ designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_OPERATIONCOUNT.stringValue());
+ designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
+ designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
+ //
+ // TODO Add this back in when the operational database PIP is configured.
+ // The issuer indicates that the PIP will be providing this attribute during
+ // the decision making.
+ //
+ // Right now I am faking the count value by re-using the request-id field
+ //
+ //String issuer = "org:onap:xacml:guard:historydb:tw:" + timeWindow + ":" + timeUnits;
+ //designator.setIssuer(issuer);
+
+ AttributeValueType valueLimit = new AttributeValueType();
+ valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
+ //
+ // Yes really use toString(), the marshaller will
+ // throw an exception if this is an integer object
+ // and not a string.
+ //
+ valueLimit.getContent().add(limit.toString());
+
+ ObjectFactory factory = new ObjectFactory();
+
+ ApplyType applyOneAndOnly = new ApplyType();
+ applyOneAndOnly.setDescription("Unbag the limit");
+ applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
+ applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
+
+ ApplyType applyGreaterThanEqual = new ApplyType();
+ applyGreaterThanEqual.setDescription("return true if current count is greater than or equal.");
+ applyGreaterThanEqual.setFunctionId(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL.stringValue());
+ applyGreaterThanEqual.getExpression().add(factory.createApply(applyOneAndOnly));
+ applyGreaterThanEqual.getExpression().add(factory.createAttributeValue(valueLimit));
+
+ return applyGreaterThanEqual;
+ }
+
+ private static ApplyType generateMinCheck(Integer min) {
+ if (min == null) {
+ return null;
+ }
+ AttributeDesignatorType designator = new AttributeDesignatorType();
+ designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.stringValue());
+ designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
+ designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
+ //
+ //
+ //
+ AttributeValueType valueLimit = new AttributeValueType();
+ valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
+ //
+ // Yes really use toString(), the marshaller will
+ // throw an exception if this is an integer object
+ // and not a string.
+ //
+ valueLimit.getContent().add(min.toString());
+ ObjectFactory factory = new ObjectFactory();
+
+ ApplyType applyOneAndOnly = new ApplyType();
+ applyOneAndOnly.setDescription("Unbag the min");
+ applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
+ applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
+
+ ApplyType applyGreaterThanEqual = new ApplyType();
+ applyGreaterThanEqual.setDescription("return true if current count is greater than or equal.");
+ applyGreaterThanEqual.setFunctionId(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL.stringValue());
+ applyGreaterThanEqual.getExpression().add(factory.createApply(applyOneAndOnly));
+ applyGreaterThanEqual.getExpression().add(factory.createAttributeValue(valueLimit));
+
+ return applyGreaterThanEqual;
+ }
+
+ private static ApplyType generateMaxCheck(Integer max) {
+ if (max == null) {
+ return null;
+ }
+ AttributeDesignatorType designator = new AttributeDesignatorType();
+ designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.stringValue());
+ designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
+ designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
+ //
+ //
+ //
+ AttributeValueType valueLimit = new AttributeValueType();
+ valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
+ //
+ // Yes really use toString(), the marshaller will
+ // throw an exception if this is an integer object
+ // and not a string.
+ //
+ valueLimit.getContent().add(max.toString());
+ ObjectFactory factory = new ObjectFactory();
+
+ ApplyType applyOneAndOnly = new ApplyType();
+ applyOneAndOnly.setDescription("Unbag the min");
+ applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
+ applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
+
+ ApplyType applyGreaterThanEqual = new ApplyType();
+ applyGreaterThanEqual.setDescription("return true if current count is less than or equal.");
+ applyGreaterThanEqual.setFunctionId(XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL.stringValue());
+ applyGreaterThanEqual.getExpression().add(factory.createApply(applyOneAndOnly));
+ applyGreaterThanEqual.getExpression().add(factory.createAttributeValue(valueLimit));
+
+ return applyGreaterThanEqual;
+ }
+
+ private static AdviceExpressionsType generateRequestIdAdvice() {
+ AdviceExpressionType adviceExpression = new AdviceExpressionType();
+ adviceExpression.setAppliesTo(EffectType.PERMIT);
+ adviceExpression.setAdviceId(ToscaDictionary.ID_ADVICE_GUARD.stringValue());
+
+ AttributeDesignatorType designator = new AttributeDesignatorType();
+ designator.setAttributeId(ToscaDictionary.ID_SUBJECT_GUARD_REQUESTID.stringValue());
+ designator.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue());
+ designator.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
+
+ AttributeAssignmentExpressionType assignment = new AttributeAssignmentExpressionType();
+ assignment.setAttributeId(ToscaDictionary.ID_ADVICE_GUARD_REQUESTID.stringValue());
+ assignment.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue());
+ assignment.setExpression(new ObjectFactory().createAttributeDesignator(designator));
+
+ adviceExpression.getAttributeAssignmentExpression().add(assignment);
+
+ AdviceExpressionsType adviceExpressions = new AdviceExpressionsType();
+ adviceExpressions.getAdviceExpression().add(adviceExpression);
+
+ return adviceExpressions;
+ }
+}
diff --git a/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java b/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java
index ae4193d3..ff137e13 100644
--- a/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java
+++ b/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java
@@ -23,168 +23,300 @@
package org.onap.policy.xacml.pdp.application.guard;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-
-import com.att.research.xacml.util.XACMLProperties;
-import com.google.common.io.Files;
-import com.google.gson.Gson;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.file.Path;
-import java.nio.file.Paths;
+import java.util.HashMap;
import java.util.Iterator;
+import java.util.Map;
import java.util.Properties;
import java.util.ServiceLoader;
+import java.util.UUID;
-import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.ClassRule;
+import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
+import org.junit.runners.MethodSorters;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
import org.onap.policy.common.utils.resources.TextFileUtils;
import org.onap.policy.models.decisions.concepts.DecisionRequest;
-import org.onap.policy.models.decisions.serialization.DecisionRequestMessageBodyHandler;
-import org.onap.policy.models.decisions.serialization.DecisionResponseMessageBodyHandler;
+import org.onap.policy.models.decisions.concepts.DecisionResponse;
import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
+import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.yaml.snakeyaml.Yaml;
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class GuardPdpApplicationTest {
private static final Logger LOGGER = LoggerFactory.getLogger(GuardPdpApplicationTest.class);
private static Properties properties = new Properties();
private static File propertiesFile;
private static XacmlApplicationServiceProvider service;
- private static DecisionRequest requestSinglePolicy;
-
- private static Gson gsonDecisionRequest;
- private static Gson gsonDecisionResponse;
+ private static DecisionRequest requestGuardPermit;
+ private static DecisionRequest requestGuardDeny;
+ private static DecisionRequest requestGuardDeny2;
+ private static StandardCoder gson = new StandardCoder();
@ClassRule
public static final TemporaryFolder policyFolder = new TemporaryFolder();
- @Before
- public void setUp() throws Exception {
+ /**
+ * Copies the xacml.properties and policies files into
+ * temporary folder and loads the service provider saving
+ * instance of provider off for other tests to use.
+ */
+ @BeforeClass
+ public static void setUp() throws Exception {
+ //
+ // Setup our temporary folder
+ //
+ XacmlPolicyUtils.FileCreator myCreator = (String filename) -> policyFolder.newFile(filename);
+ propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents("src/test/resources/xacml.properties",
+ properties, myCreator);
+ //
+ // Load service
+ //
+ ServiceLoader<XacmlApplicationServiceProvider> applicationLoader =
+ ServiceLoader.load(XacmlApplicationServiceProvider.class);
+ //
+ // Find the guard service application and save for use in all the tests
+ //
+ StringBuilder strDump = new StringBuilder("Loaded applications:" + System.lineSeparator());
+ Iterator<XacmlApplicationServiceProvider> iterator = applicationLoader.iterator();
+ while (iterator.hasNext()) {
+ XacmlApplicationServiceProvider application = iterator.next();
+ //
+ // Is it our service?
+ //
+ if (application instanceof GuardPdpApplication) {
+ //
+ // Should be the first and only one
+ //
+ assertThat(service).isNull();
+ service = application;
+ }
+ strDump.append(application.applicationName());
+ strDump.append(" supports ");
+ strDump.append(application.supportedPolicyTypes());
+ strDump.append(System.lineSeparator());
+ }
+ LOGGER.debug("{}", strDump);
+ //
+ // Tell it to initialize based on the properties file
+ // we just built for it.
+ //
+ service.initialize(propertiesFile.toPath().getParent());
+ }
+ @Test
+ public void test1Basics() throws CoderException, IOException {
+ //
+ // Load Single Decision Request
+ //
+ requestGuardPermit = gson.decode(
+ TextFileUtils.getTextFileAsString(
+ "../../main/src/test/resources/decisions/decision.guard.shouldpermit.input.json"),
+ DecisionRequest.class);
+ //
+ // Load Single Decision Request
+ //
+ requestGuardDeny = gson.decode(TextFileUtils.getTextFileAsString(
+ "../../main/src/test/resources/decisions/decision.guard.shoulddeny.input.json"),
+ DecisionRequest.class);
+ //
+ // Load Single Decision Request
+ //
+ requestGuardDeny2 = gson.decode(TextFileUtils.getTextFileAsString(
+ "../../main/src/test/resources/decisions/decision.guard.shoulddeny.input2.json"),
+ DecisionRequest.class);
+ //
+ // Make sure there's an application name
+ //
+ assertThat(service.applicationName()).isNotEmpty();
+ //
+ // Decisions
+ //
+ assertThat(service.actionDecisionsSupported().size()).isEqualTo(1);
+ assertThat(service.actionDecisionsSupported()).contains("guard");
+ //
+ // Ensure it has the supported policy types and
+ // can support the correct policy types.
+ //
+ assertThat(service.supportedPolicyTypes()).isNotEmpty();
+ assertThat(service.supportedPolicyTypes().size()).isEqualTo(2);
+ assertThat(service.canSupportPolicyType("onap.policies.controlloop.guard.FrequencyLimiter", "1.0.0"))
+ .isTrue();
+ assertThat(service.canSupportPolicyType("onap.policies.controlloop.guard.FrequencyLimiter", "1.0.1"))
+ .isFalse();
+ assertThat(service.canSupportPolicyType("onap.policies.controlloop.guard.MinMax", "1.0.0")).isTrue();
+ assertThat(service.canSupportPolicyType("onap.policies.controlloop.guard.MinMax", "1.0.1")).isFalse();
+ assertThat(service.canSupportPolicyType("onap.foo", "1.0.1")).isFalse();
}
@Test
- public void testBasics() {
- assertThatCode(() -> {
+ public void test2NoPolicies() {
+ //
+ // Ask for a decision
+ //
+ DecisionResponse response = service.makeDecision(requestGuardPermit);
+ LOGGER.info("Decision {}", response);
+
+ assertThat(response).isNotNull();
+ assertThat(response.getStatus()).isEqualTo("Permit");
+ }
+
+ @Test
+ public void test3FrequencyLimiter() throws CoderException, FileNotFoundException, IOException {
+ //
+ // Now load the vDNS frequency limiter Policy - make sure
+ // the pdp can support it and have it load
+ // into the PDP.
+ //
+ try (InputStream is = new FileInputStream("src/test/resources/vDNS.policy.guard.frequency.output.tosca.yaml")) {
//
- // Create our Gson builder
+ // Have yaml parse it
//
- gsonDecisionRequest = new DecisionRequestMessageBodyHandler().getGson();
- gsonDecisionResponse = new DecisionResponseMessageBodyHandler().getGson();
+ Yaml yaml = new Yaml();
+ Map<String, Object> toscaObject = yaml.load(is);
//
- // Load Single Decision Request
+ // Load the policies
//
- requestSinglePolicy = gsonDecisionRequest.fromJson(
- TextFileUtils
- .getTextFileAsString("../../main/src/test/resources/decisions/decision.single.input.json"),
- DecisionRequest.class);
+ service.loadPolicies(toscaObject);
//
- // Copy all the properties and root policies to the temporary folder
+ // Ask for a decision - should get permit
//
- try (InputStream is = new FileInputStream("src/test/resources/xacml.properties")) {
- //
- // Load it in
- //
- properties.load(is);
- propertiesFile = policyFolder.newFile("xacml.properties");
- //
- // Copy the root policies
- //
- for (String root : XACMLProperties.getRootPolicyIDs(properties)) {
- //
- // Get a file
- //
- Path rootPath = Paths.get(properties.getProperty(root + ".file"));
- LOGGER.debug("Root file {} {}", rootPath, rootPath.getFileName());
- //
- // Construct new file name
- //
- File newRootPath = policyFolder.newFile(rootPath.getFileName().toString());
- //
- // Copy it
- //
- Files.copy(rootPath.toFile(), newRootPath);
- assertThat(newRootPath).exists();
- //
- // Point to where the new policy is in the temp dir
- //
- properties.setProperty(root + ".file", newRootPath.getAbsolutePath());
- }
- try (OutputStream os = new FileOutputStream(propertiesFile.getAbsolutePath())) {
- properties.store(os, "");
- assertThat(propertiesFile).exists();
- }
- }
+ DecisionResponse response = service.makeDecision(requestGuardPermit);
+ LOGGER.info("Looking for Permit Decision {}", response);
+
+ assertThat(response).isNotNull();
+ assertThat(response.getStatus()).isNotNull();
+ assertThat(response.getStatus()).isEqualTo("Permit");
//
- // Load service
+ // Dump it out as Json
//
- ServiceLoader<XacmlApplicationServiceProvider> applicationLoader =
- ServiceLoader.load(XacmlApplicationServiceProvider.class);
+ LOGGER.info(gson.encode(response));
//
- // Iterate through them - I could store the object as
- // XacmlApplicationServiceProvider pointer.
+ // Ask for a decision - should get deny
//
- // Try this later.
+ response = service.makeDecision(requestGuardDeny2);
+ LOGGER.info("Looking for Deny Decision {}", response);
+ assertThat(response).isNotNull();
+ assertThat(response.getStatus()).isNotNull();
+ assertThat(response.getStatus()).isEqualTo("Deny");
//
- StringBuilder strDump = new StringBuilder("Loaded applications:" + System.lineSeparator());
- Iterator<XacmlApplicationServiceProvider> iterator = applicationLoader.iterator();
- while (iterator.hasNext()) {
- XacmlApplicationServiceProvider application = iterator.next();
- //
- // Is it our service?
- //
- if (application instanceof GuardPdpApplication) {
- //
- // Should be the first and only one
- //
- assertThat(service).isNull();
- service = application;
- }
- strDump.append(application.applicationName());
- strDump.append(" supports ");
- strDump.append(application.supportedPolicyTypes());
- strDump.append(System.lineSeparator());
- }
- LOGGER.debug("{}", strDump);
+ // Dump it out as Json
+ //
+ LOGGER.info(gson.encode(response));
+ }
+ }
+
+ @Test
+ public void test4MinMax() throws CoderException, FileNotFoundException, IOException {
+ //
+ // Now load the vDNS min max Policy - make sure
+ // the pdp can support it and have it load
+ // into the PDP.
+ //
+ try (InputStream is = new FileInputStream("src/test/resources/vDNS.policy.guard.minmax.output.tosca.yaml")) {
+ //
+ // Have yaml parse it
+ //
+ Yaml yaml = new Yaml();
+ Map<String, Object> toscaObject = yaml.load(is);
+ //
+ // Load the policies
+ //
+ service.loadPolicies(toscaObject);
+ //
+ // Ask for a decision - should get permit
+ //
+ DecisionResponse response = service.makeDecision(requestGuardPermit);
+ LOGGER.info("Looking for Permit Decision {}", response);
+
+ assertThat(response).isNotNull();
+ assertThat(response.getStatus()).isNotNull();
+ assertThat(response.getStatus()).isEqualTo("Permit");
+ //
+ // Dump it out as Json
+ //
+ LOGGER.info(gson.encode(response));
+ //
+ // Ask for a decision - should get deny
+ //
+ response = service.makeDecision(requestGuardDeny);
+ LOGGER.info("Looking for Deny Decision {}", response);
+ assertThat(response).isNotNull();
+ assertThat(response.getStatus()).isNotNull();
+ assertThat(response.getStatus()).isEqualTo("Deny");
+ //
+ // Dump it out as Json
+ //
+ LOGGER.info(gson.encode(response));
+ }
+ }
+
+ @Test
+ public void test5MissingFields() throws FileNotFoundException, IOException {
+ LOGGER.debug("Running test5");
+ //
+ // Most likely we would not get a policy with missing fields passed to
+ // us from the API. But in case that happens, or we decide that some fields
+ // will be optional due to re-working of how the XACML policies are built,
+ // let's add support in for that.
+ //
+ try (InputStream is = new FileInputStream("src/test/resources/guard.policy-minmax-missing-fields1.yaml")) {
//
- // Tell it to initialize based on the properties file
- // we just built for it.
+ // Have yaml parse it
//
- service.initialize(propertiesFile.toPath().getParent());
+ Yaml yaml = new Yaml();
+ Map<String, Object> toscaObject = yaml.load(is);
//
- // Make sure there's an application name
+ // Load the policies
//
- assertThat(service.applicationName()).isNotEmpty();
+ service.loadPolicies(toscaObject);
//
- // Decisions
+ // We can create a DecisionRequest on the fly - no need
+ // to have it in the .json files
//
- assertThat(service.actionDecisionsSupported().size()).isEqualTo(1);
- assertThat(service.actionDecisionsSupported()).contains("guard");
+ DecisionRequest request = new DecisionRequest();
+ request.setOnapName("JUnit");
+ request.setOnapComponent("test5MissingFields");
+ request.setRequestId(UUID.randomUUID().toString());
+ request.setAction("guard");
+ Map<String, Object> guard = new HashMap<>();
+ guard.put("actor", "FOO");
+ guard.put("recipe", "bar");
+ guard.put("vfCount", "4");
+ Map<String, Object> resource = new HashMap<>();
+ resource.put("guard", guard);
+ request.setResource(resource);
//
- // Ensure it has the supported policy types and
- // can support the correct policy types.
+ // Ask for a decision - should get permit
//
- assertThat(service.supportedPolicyTypes()).isNotEmpty();
- assertThat(service.supportedPolicyTypes().size()).isEqualTo(2);
- assertThat(service.canSupportPolicyType("onap.policies.controlloop.guard.FrequencyLimiter", "1.0.0"))
- .isTrue();
- assertThat(service.canSupportPolicyType("onap.policies.controlloop.guard.FrequencyLimiter", "1.0.1"))
- .isFalse();
- assertThat(service.canSupportPolicyType("onap.policies.controlloop.guard.MinMax", "1.0.0")).isTrue();
- assertThat(service.canSupportPolicyType("onap.policies.controlloop.guard.MinMax", "1.0.1")).isFalse();
- assertThat(service.canSupportPolicyType("onap.foo", "1.0.1")).isFalse();
+ DecisionResponse response = service.makeDecision(request);
+ LOGGER.info("Looking for Permit Decision {}", response);
+ assertThat(response).isNotNull();
+ assertThat(response.getStatus()).isNotNull();
+ assertThat(response.getStatus()).isEqualTo("Permit");
//
- // Ensure it supports decisions
+ // Try a deny
//
- assertThat(service.actionDecisionsSupported()).contains("guard");
- }).doesNotThrowAnyException();
+ guard.put("vfCount", "10");
+ resource.put("guard", guard);
+ request.setResource(resource);
+ response = service.makeDecision(request);
+ LOGGER.info("Looking for Deny Decision {}", response);
+ assertThat(response).isNotNull();
+ assertThat(response.getStatus()).isNotNull();
+ assertThat(response.getStatus()).isEqualTo("Deny");
+ }
}
}
diff --git a/applications/guard/src/test/resources/guard.policy-minmax-missing-fields1.yaml b/applications/guard/src/test/resources/guard.policy-minmax-missing-fields1.yaml
new file mode 100644
index 00000000..6a441182
--- /dev/null
+++ b/applications/guard/src/test/resources/guard.policy-minmax-missing-fields1.yaml
@@ -0,0 +1,19 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+topology_template:
+ policies:
+ -
+ guard.minmax.missing1:
+ type: onap.policies.controlloop.guard.MinMax
+ version: 1.0.0
+ metadata:
+ policy-id : guard.minmax.scaleout
+ policy-version: 1
+ properties:
+ actor: FOO
+ recipe: bar
+# targets: *.
+# clname: ControlLoop-Foo-Bar
+ min: 1
+ max: 5
+# guardActiveStart: 00:00:01-05:00
+# guardActiveEnd: 23:59:59-05:00
diff --git a/applications/guard/src/test/resources/vDNS.policy.guard.frequency.output.tosca.yaml b/applications/guard/src/test/resources/vDNS.policy.guard.frequency.output.tosca.yaml
new file mode 100644
index 00000000..03afd5e2
--- /dev/null
+++ b/applications/guard/src/test/resources/vDNS.policy.guard.frequency.output.tosca.yaml
@@ -0,0 +1,20 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+topology_template:
+ policies:
+ -
+ guard.frequency.scaleout:
+ type: onap.policies.controlloop.guard.FrequencyLimiter
+ version: 1.0.0
+ metadata:
+ policy-id: guard.frequency.scaleout
+ policy-version: 1
+ properties:
+ actor: SO
+ recipe: scaleOut
+ targets: .*
+ clname: ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3
+ limit: 1
+ timeWindow: 10
+ timeUnits: minute
+ guardActiveStart: 00:00:01-05:00
+ guardActiveEnd: 23:59:59-05:00
diff --git a/applications/guard/src/test/resources/vDNS.policy.guard.minmax.output.tosca.yaml b/applications/guard/src/test/resources/vDNS.policy.guard.minmax.output.tosca.yaml
new file mode 100644
index 00000000..5ac76015
--- /dev/null
+++ b/applications/guard/src/test/resources/vDNS.policy.guard.minmax.output.tosca.yaml
@@ -0,0 +1,19 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+topology_template:
+ policies:
+ -
+ guard.minmax.scaleout:
+ type: onap.policies.controlloop.guard.MinMax
+ version: 1.0.0
+ metadata:
+ policy-id : guard.minmax.scaleout
+ policy-version: 1
+ properties:
+ actor: SO
+ recipe: scaleOut
+ targets: .*
+ clname: ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3
+ min: 1
+ max: 5
+ guardActiveStart: 00:00:01-05:00
+ guardActiveEnd: 23:59:59-05:00
diff --git a/applications/guard/src/test/resources/xacml.properties b/applications/guard/src/test/resources/xacml.properties
index b32a936c..9bd7bfb8 100644
--- a/applications/guard/src/test/resources/xacml.properties
+++ b/applications/guard/src/test/resources/xacml.properties
@@ -20,18 +20,13 @@ xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctio
xacml.att.policyFinderFactory=org.onap.policy.pdp.xacml.application.common.OnapPolicyFinderFactory
#
-# ONAP Implementation Factories
+# Use a root combining algorithm
#
-#xacml.att.policyFinderFactory=org.onap.policy.pdp.xacml.application.common.OnapApplicationPolicyFinder
+xacml.att.policyFinderFactory.combineRootPolicies=urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:permit-unless-deny
-#
-# NOTE: If you are testing against a RESTful PDP, then the PDP must be configured with the
-# policies and PIP configuration as defined below. Otherwise, this is the configuration that
-# the embedded PDP uses.
-#
# Policies to load
#
-xacml.rootPolicies=guard
-guard.file=src/main/resources/RootGuardPolicy.xml
+#xacml.rootPolicies=guard
+#guard.file=src/main/resources/RootGuardPolicy.xml
diff --git a/applications/monitoring/pom.xml b/applications/monitoring/pom.xml
index 018c3722..d477bee7 100644
--- a/applications/monitoring/pom.xml
+++ b/applications/monitoring/pom.xml
@@ -34,15 +34,6 @@
<dependencies>
<dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- </dependency>
- <dependency>
- <groupId>org.onap.policy.common</groupId>
- <artifactId>common-parameters</artifactId>
- <version>${policy.common.version}</version>
- </dependency>
- <dependency>
<groupId>org.onap.policy.xacml-pdp.applications</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
diff --git a/applications/monitoring/src/main/java/org/onap/policy/xacml/pdp/application/monitoring/MonitoringRequest.java b/applications/monitoring/src/main/java/org/onap/policy/xacml/pdp/application/monitoring/MonitoringRequest.java
deleted file mode 100644
index ce0bd3f2..00000000
--- a/applications/monitoring/src/main/java/org/onap/policy/xacml/pdp/application/monitoring/MonitoringRequest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * ONAP Policy Decision Models
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.xacml.pdp.application.monitoring;
-
-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 java.util.Map;
-import java.util.Map.Entry;
-
-import org.onap.policy.models.decisions.concepts.DecisionRequest;
-
-@XACMLRequest(ReturnPolicyIdList = true)
-public class MonitoringRequest {
-
- @XACMLSubject(includeInResults = true)
- String onapName = "DCAE";
-
- @XACMLResource(includeInResults = true)
- String resource = "onap.policies.Monitoring";
-
- @XACMLAction()
- String action = "configure";
-
-
- /**
- * Parses the DecisionRequest into a MonitoringRequest.
- *
- * @param decisionRequest Input DecisionRequest
- * @return MonitoringRequest
- */
- public static MonitoringRequest createInstance(DecisionRequest decisionRequest) {
- MonitoringRequest request = new MonitoringRequest();
- request.onapName = decisionRequest.getOnapName();
- request.action = decisionRequest.getAction();
-
- Map<String, Object> resources = decisionRequest.getResource();
- for (Entry<String, Object> entry : resources.entrySet()) {
- if ("policy-id".equals(entry.getKey())) {
- //
- // TODO handle lists of policies
- //
- request.resource = entry.getValue().toString();
- continue;
- }
- if ("policy-type".equals(entry.getKey())) {
- //
- // TODO handle lists of policies
- //
- request.resource = entry.getValue().toString();
- }
- }
- //
- // TODO handle a bad incoming request. Do that here?
- //
- return request;
- }
-}
diff --git a/applications/monitoring/src/test/java/org/onap/policy/xacml/pdp/application/monitoring/MonitoringPdpApplicationTest.java b/applications/monitoring/src/test/java/org/onap/policy/xacml/pdp/application/monitoring/MonitoringPdpApplicationTest.java
index d3624a64..4af4bac4 100644
--- a/applications/monitoring/src/test/java/org/onap/policy/xacml/pdp/application/monitoring/MonitoringPdpApplicationTest.java
+++ b/applications/monitoring/src/test/java/org/onap/policy/xacml/pdp/application/monitoring/MonitoringPdpApplicationTest.java
@@ -23,20 +23,11 @@
package org.onap.policy.xacml.pdp.application.monitoring;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-
-import com.att.research.xacml.util.XACMLProperties;
-import com.google.common.io.Files;
-import com.google.gson.Gson;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -46,19 +37,22 @@ import java.util.ServiceLoader;
import org.junit.BeforeClass;
import org.junit.ClassRule;
+import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
+import org.junit.runners.MethodSorters;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
import org.onap.policy.common.utils.resources.TextFileUtils;
import org.onap.policy.models.decisions.concepts.DecisionRequest;
import org.onap.policy.models.decisions.concepts.DecisionResponse;
-import org.onap.policy.models.decisions.serialization.DecisionRequestMessageBodyHandler;
-import org.onap.policy.models.decisions.serialization.DecisionResponseMessageBodyHandler;
-import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
+import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MonitoringPdpApplicationTest {
private static final Logger LOGGER = LoggerFactory.getLogger(MonitoringPdpApplicationTest.class);
@@ -67,210 +61,166 @@ public class MonitoringPdpApplicationTest {
private static XacmlApplicationServiceProvider service;
private static DecisionRequest requestSinglePolicy;
- private static Gson gsonDecisionRequest;
- private static Gson gsonDecisionResponse;
+ private static StandardCoder gson = new StandardCoder();
@ClassRule
public static final TemporaryFolder policyFolder = new TemporaryFolder();
/**
- * Load a test engine.
+ * Copies the xacml.properties and policies files into
+ * temporary folder and loads the service provider saving
+ * instance of provider off for other tests to use.
*/
@BeforeClass
- public static void setup() {
- assertThatCode(() -> {
- //
- // Create our Gson builder
- //
- gsonDecisionRequest = new DecisionRequestMessageBodyHandler().getGson();
- gsonDecisionResponse = new DecisionResponseMessageBodyHandler().getGson();
- //
- // Load Single Decision Request
- //
- requestSinglePolicy = gsonDecisionRequest.fromJson(
- TextFileUtils
- .getTextFileAsString("../../main/src/test/resources/decisions/decision.single.input.json"),
- DecisionRequest.class);
- //
- // Copy all the properties and root policies to the temporary folder
- //
- try (InputStream is = new FileInputStream("src/test/resources/xacml.properties")) {
- //
- // Load it in
- //
- properties.load(is);
- propertiesFile = policyFolder.newFile("xacml.properties");
- //
- // Copy the root policies
- //
- for (String root : XACMLProperties.getRootPolicyIDs(properties)) {
- //
- // Get a file
- //
- Path rootPath = Paths.get(properties.getProperty(root + ".file"));
- LOGGER.debug("Root file {} {}", rootPath, rootPath.getFileName());
- //
- // Construct new file name
- //
- File newRootPath = policyFolder.newFile(rootPath.getFileName().toString());
- //
- // Copy it
- //
- Files.copy(rootPath.toFile(), newRootPath);
- assertThat(newRootPath).exists();
- //
- // Point to where the new policy is in the temp dir
- //
- properties.setProperty(root + ".file", newRootPath.getAbsolutePath());
- }
- try (OutputStream os = new FileOutputStream(propertiesFile.getAbsolutePath())) {
- properties.store(os, "");
- assertThat(propertiesFile).exists();
- }
- }
- //
- // Load service
- //
- ServiceLoader<XacmlApplicationServiceProvider> applicationLoader =
- ServiceLoader.load(XacmlApplicationServiceProvider.class);
- //
- // Iterate through them - I could store the object as
- // XacmlApplicationServiceProvider pointer.
+ public static void setup() throws Exception {
+ //
+ // Load Single Decision Request
+ //
+ requestSinglePolicy = gson.decode(
+ TextFileUtils
+ .getTextFileAsString("../../main/src/test/resources/decisions/decision.single.input.json"),
+ DecisionRequest.class);
+ //
+ // Setup our temporary folder
+ //
+ XacmlPolicyUtils.FileCreator myCreator = (String filename) -> policyFolder.newFile(filename);
+ propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents("src/test/resources/xacml.properties",
+ properties, myCreator);
+ //
+ // Load XacmlApplicationServiceProvider service
+ //
+ ServiceLoader<XacmlApplicationServiceProvider> applicationLoader =
+ ServiceLoader.load(XacmlApplicationServiceProvider.class);
+ //
+ // Look for our class instance and save it
+ //
+ StringBuilder strDump = new StringBuilder("Loaded applications:" + System.lineSeparator());
+ Iterator<XacmlApplicationServiceProvider> iterator = applicationLoader.iterator();
+ while (iterator.hasNext()) {
+ XacmlApplicationServiceProvider application = iterator.next();
//
- // Try this later.
+ // Is it our service?
//
- StringBuilder strDump = new StringBuilder("Loaded applications:" + System.lineSeparator());
- Iterator<XacmlApplicationServiceProvider> iterator = applicationLoader.iterator();
- while (iterator.hasNext()) {
- XacmlApplicationServiceProvider application = iterator.next();
+ if (application instanceof MonitoringPdpApplication) {
//
- // Is it our service?
+ // Should be the first and only one
//
- if (application instanceof MonitoringPdpApplication) {
- //
- // Should be the first and only one
- //
- assertThat(service).isNull();
- service = application;
- }
- strDump.append(application.applicationName());
- strDump.append(" supports ");
- strDump.append(application.supportedPolicyTypes());
- strDump.append(System.lineSeparator());
+ assertThat(service).isNull();
+ service = application;
}
- LOGGER.debug("{}", strDump);
- //
- // Tell it to initialize based on the properties file
- // we just built for it.
- //
- service.initialize(propertiesFile.toPath().getParent());
- //
- // Make sure there's an application name
- //
- assertThat(service.applicationName()).isNotEmpty();
- //
- // Ensure it has the supported policy types and
- // can support the correct policy types.
- //
- assertThat(service.canSupportPolicyType("onap.Monitoring", "1.0.0")).isTrue();
- assertThat(service.canSupportPolicyType("onap.Monitoring", "1.5.0")).isTrue();
- assertThat(service.canSupportPolicyType("onap.policies.monitoring.foobar", "1.0.1")).isTrue();
- assertThat(service.canSupportPolicyType("onap.foobar", "1.0.0")).isFalse();
- assertThat(service.supportedPolicyTypes()).contains("onap.Monitoring");
- //
- // Ensure it supports decisions
- //
- assertThat(service.actionDecisionsSupported()).contains("configure");
- }).doesNotThrowAnyException();
+ strDump.append(application.applicationName());
+ strDump.append(" supports ");
+ strDump.append(application.supportedPolicyTypes());
+ strDump.append(System.lineSeparator());
+ }
+ LOGGER.debug("{}", strDump);
+ //
+ // Tell it to initialize based on the properties file
+ // we just built for it.
+ //
+ service.initialize(propertiesFile.toPath().getParent());
}
@Test
- public void testNoPolicies() {
+ public void test1Basics() {
//
- // Make a simple decision - NO policies are loaded
+ // Make sure there's an application name
//
- assertThatCode(() -> {
- //
- // Ask for a decision
- //
- DecisionResponse response = service.makeDecision(requestSinglePolicy);
- LOGGER.info("Decision {}", response);
+ assertThat(service.applicationName()).isNotEmpty();
+ //
+ // Ensure it has the supported policy types and
+ // can support the correct policy types.
+ //
+ assertThat(service.canSupportPolicyType("onap.Monitoring", "1.0.0")).isTrue();
+ assertThat(service.canSupportPolicyType("onap.Monitoring", "1.5.0")).isTrue();
+ assertThat(service.canSupportPolicyType("onap.policies.monitoring.foobar", "1.0.1")).isTrue();
+ assertThat(service.canSupportPolicyType("onap.foobar", "1.0.0")).isFalse();
+ assertThat(service.supportedPolicyTypes()).contains("onap.Monitoring");
+ //
+ // Ensure it supports decisions
+ //
+ assertThat(service.actionDecisionsSupported()).contains("configure");
+ }
- assertThat(response).isNotNull();
- assertThat(response.getErrorMessage()).isNullOrEmpty();
- assertThat(response.getPolicies().size()).isEqualTo(0);
+ @Test
+ public void test2NoPolicies() {
+ //
+ // Ask for a decision
+ //
+ DecisionResponse response = service.makeDecision(requestSinglePolicy);
+ LOGGER.info("Decision {}", response);
- }).doesNotThrowAnyException();
+ assertThat(response).isNotNull();
+ assertThat(response.getPolicies().size()).isEqualTo(0);
}
@SuppressWarnings("unchecked")
@Test
- public void testvDnsPolicy() {
+ public void test3AddvDnsPolicy() throws IOException, CoderException {
//
// Now load the vDNS Policy - make sure
// the pdp can support it and have it load
// into the PDP.
//
- assertThatCode(() -> {
- try (InputStream is = new FileInputStream("src/test/resources/vDNS.policy.input.yaml")) {
- Yaml yaml = new Yaml();
- Map<String, Object> toscaObject = yaml.load(is);
- List<Object> policies = (List<Object>) toscaObject.get("policies");
- //
- // What we should really do is split the policies out from the ones that
- // are not supported to ones that are. And then load these.
+ try (InputStream is = new FileInputStream("src/test/resources/vDNS.policy.input.yaml")) {
+ //
+ // Have yaml parse it
+ //
+ Yaml yaml = new Yaml();
+ Map<String, Object> toscaObject = yaml.load(is);
+ List<Object> policies = (List<Object>) toscaObject.get("policies");
+ //
+ // Sanity check to ensure the policy type and version are supported
+ //
+ for (Object policyObject : policies) {
//
- // In another future review....
+ // Get the contents
//
- for (Object policyObject : policies) {
+ Map<String, Object> policyContents = (Map<String, Object>) policyObject;
+ for (Entry<String, Object> entrySet : policyContents.entrySet()) {
+ LOGGER.info("Entry set {}", entrySet.getKey());
+ Map<String, Object> policyDefinition = (Map<String, Object>) entrySet.getValue();
//
- // Get the contents
+ // Find the type and make sure the engine supports it
//
- Map<String, Object> policyContents = (Map<String, Object>) policyObject;
- for (Entry<String, Object> entrySet : policyContents.entrySet()) {
- LOGGER.info("Entry set {}", entrySet.getKey());
- Map<String, Object> policyDefinition = (Map<String, Object>) entrySet.getValue();
- //
- // Find the type and make sure the engine supports it
- //
- assertThat(policyDefinition.containsKey("type")).isTrue();
- assertThat(service.canSupportPolicyType(
- policyDefinition.get("type").toString(),
- policyDefinition.get("version").toString()))
- .isTrue();
- }
+ assertThat(policyDefinition.containsKey("type")).isTrue();
+ assertThat(service.canSupportPolicyType(
+ policyDefinition.get("type").toString(),
+ policyDefinition.get("version").toString()))
+ .isTrue();
}
- //
- // Just go ahead and load them all for now
- //
- // Assuming all are supported etc.
- //
- service.loadPolicies(toscaObject);
- //
- // Ask for a decision
- //
- DecisionResponse response = service.makeDecision(requestSinglePolicy);
- LOGGER.info("Decision {}", response);
-
- assertThat(response).isNotNull();
- assertThat(response.getPolicies().size()).isEqualTo(1);
- //
- // Dump it out as Json
- //
- LOGGER.info(gsonDecisionResponse.toJson(response));
}
- }).doesNotThrowAnyException();
+ //
+ // Load the policies
+ //
+ service.loadPolicies(toscaObject);
+ //
+ // Ask for a decision
+ //
+ DecisionResponse response = service.makeDecision(requestSinglePolicy);
+ LOGGER.info("Decision {}", response);
+
+ assertThat(response).isNotNull();
+ assertThat(response.getPolicies().size()).isEqualTo(1);
+ //
+ // Dump it out as Json
+ //
+ LOGGER.info(gson.encode(response));
+ }
}
@Test
- public void testBadPolicies() {
+ public void test4BadPolicies() {
+ /*
+ *
+ * THESE TEST SHOULD BE MOVED INTO THE API PROJECT
+ *
//
// No need for service, just test some of the methods
// for bad policies
//
MonitoringPdpApplication onapPdpEngine = new MonitoringPdpApplication();
- /*
assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() -> {
try (InputStream is =
new FileInputStream("src/test/resources/test.monitoring.policy.missingmetadata.yaml")) {
diff --git a/applications/monitoring/src/test/resources/vDNS.policy.decision.payload.json b/applications/monitoring/src/test/resources/vDNS.policy.decision.payload.json
deleted file mode 100644
index e69de29b..00000000
--- a/applications/monitoring/src/test/resources/vDNS.policy.decision.payload.json
+++ /dev/null
diff --git a/applications/monitoring/src/test/resources/xacml.properties b/applications/monitoring/src/test/resources/xacml.properties
index 9b5330dc..56a92d69 100644
--- a/applications/monitoring/src/test/resources/xacml.properties
+++ b/applications/monitoring/src/test/resources/xacml.properties
@@ -19,14 +19,6 @@ xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctio
#
xacml.att.policyFinderFactory=org.onap.policy.pdp.xacml.application.common.OnapPolicyFinderFactory
-#
-# NOTE: If you are testing against a RESTful PDP, then the PDP must be configured with the
-# policies and PIP configuration as defined below. Otherwise, this is the configuration that
-# the embedded PDP uses.
-#
-
-policytypes=onap.Monitoring, onap.policies.monitoring.cdap.tca.hi.lo.app
-
# Policies to load
#
xacml.rootPolicies=monitoring
diff --git a/applications/optimization/pom.xml b/applications/optimization/pom.xml
new file mode 100644
index 00000000..0723ec5e
--- /dev/null
+++ b/applications/optimization/pom.xml
@@ -0,0 +1,43 @@
+<!--
+ ============LICENSE_START=======================================================
+ ONAP Policy Engine - XACML PDP
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onap.policy.xacml-pdp.applications</groupId>
+ <artifactId>applications</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>optimization</artifactId>
+
+ <name>${project.artifactId}</name>
+ <description>This modules contains applications that implement policy-types for XACML PDP.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.policy.xacml-pdp.applications</groupId>
+ <artifactId>common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
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
new file mode 100644
index 00000000..4a4a6046
--- /dev/null
+++ b/applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplication.java
@@ -0,0 +1,164 @@
+/*-
+ * ============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.Request;
+import com.att.research.xacml.api.Response;
+import com.att.research.xacml.util.XACMLPolicyWriter;
+import com.google.common.collect.Lists;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+
+import org.onap.policy.models.decisions.concepts.DecisionRequest;
+import org.onap.policy.models.decisions.concepts.DecisionResponse;
+import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
+import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
+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;
+
+public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvider {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(OptimizationPdpApplication.class);
+ private static final String STRING_VERSION100 = "1.0.0";
+
+ private StdMatchableTranslator translator = new StdMatchableTranslator();
+ private Map<String, String> supportedPolicyTypes = new HashMap<>();
+
+ /**
+ * Constructor.
+ */
+ public OptimizationPdpApplication() {
+ this.supportedPolicyTypes.put("onap.policies.optimization.AffinityPolicy", STRING_VERSION100);
+ this.supportedPolicyTypes.put("onap.policies.optimization.DistancePolicy", STRING_VERSION100);
+ this.supportedPolicyTypes.put("onap.policies.optimization.HpaPolicy", STRING_VERSION100);
+ this.supportedPolicyTypes.put("onap.policies.optimization.OptimizationPolicy", STRING_VERSION100);
+ this.supportedPolicyTypes.put("onap.policies.optimization.PciPolicy", STRING_VERSION100);
+ this.supportedPolicyTypes.put("onap.policies.optimization.QueryPolicy", STRING_VERSION100);
+ this.supportedPolicyTypes.put("onap.policies.optimization.SubscriberPolicy", STRING_VERSION100);
+ this.supportedPolicyTypes.put("onap.policies.optimization.Vim_fit", STRING_VERSION100);
+ this.supportedPolicyTypes.put("onap.policies.optimization.VnfPolicy", STRING_VERSION100);
+ }
+
+ @Override
+ public String applicationName() {
+ return "Optimization Application";
+ }
+
+ @Override
+ public List<String> actionDecisionsSupported() {
+ return Arrays.asList("optimize");
+ }
+
+ @Override
+ public synchronized List<String> supportedPolicyTypes() {
+ return Lists.newArrayList(supportedPolicyTypes.keySet());
+ }
+
+ @Override
+ public boolean canSupportPolicyType(String policyType, String policyTypeVersion) {
+ //
+ // For the time being, restrict this if the version isn't known.
+ // Could be too difficult to support changing of versions dynamically.
+ //
+ if (! this.supportedPolicyTypes.containsKey(policyType)) {
+ return false;
+ }
+ //
+ // Must match version exactly
+ //
+ return this.supportedPolicyTypes.get(policyType).equals(policyTypeVersion);
+ }
+
+ @Override
+ public synchronized void loadPolicies(Map<String, Object> toscaPolicies) {
+ try {
+ //
+ // Convert the policies first
+ //
+ List<PolicyType> listPolicies = translator.scanAndConvertPolicies(toscaPolicies);
+ if (listPolicies.isEmpty()) {
+ throw new ToscaPolicyConversionException("Converted 0 policies");
+ }
+ //
+ // Create a copy of the properties object
+ //
+ Properties newProperties = this.getProperties();
+ //
+ // Iterate through the policies
+ //
+ for (PolicyType newPolicy : listPolicies) {
+ //
+ // Construct the filename
+ //
+ Path refPath = XacmlPolicyUtils.constructUniquePolicyFilename(newPolicy, this.getDataPath());
+ //
+ // Write the policy to disk
+ // Maybe check for an error
+ //
+ XACMLPolicyWriter.writePolicyFile(refPath, newPolicy);
+ //
+ // Add root policy to properties object
+ //
+ XacmlPolicyUtils.addRootPolicy(newProperties, refPath);
+ }
+ //
+ // Write the properties to disk
+ //
+ XacmlPolicyUtils.storeXacmlProperties(newProperties,
+ XacmlPolicyUtils.getPropertiesPath(this.getDataPath()));
+ //
+ // Reload the engine
+ //
+ this.createEngine(newProperties);
+ } catch (IOException | ToscaPolicyConversionException e) {
+ LOGGER.error("Failed to loadPolicies {}", e);
+ }
+ }
+
+ @Override
+ public synchronized DecisionResponse makeDecision(DecisionRequest request) {
+ //
+ // Convert to a XacmlRequest
+ //
+ Request xacmlRequest = translator.convertRequest(request);
+ //
+ // Now get a decision
+ //
+ Response xacmlResponse = this.xacmlDecision(xacmlRequest);
+ //
+ // Convert to a DecisionResponse
+ //
+ return translator.convertResponse(xacmlResponse);
+ }
+
+}
diff --git a/applications/optimization/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider b/applications/optimization/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider
new file mode 100644
index 00000000..ffb7e802
--- /dev/null
+++ b/applications/optimization/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider
@@ -0,0 +1 @@
+org.onap.policy.xacml.pdp.application.optimization.OptimizationPdpApplication \ No newline at end of file
diff --git a/applications/optimization/src/test/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplicationTest.java b/applications/optimization/src/test/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplicationTest.java
new file mode 100644
index 00000000..efbf730c
--- /dev/null
+++ b/applications/optimization/src/test/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplicationTest.java
@@ -0,0 +1,211 @@
+/*-
+ * ============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 static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.ServiceLoader;
+
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runners.MethodSorters;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.resources.TextFileUtils;
+import org.onap.policy.models.decisions.concepts.DecisionRequest;
+import org.onap.policy.models.decisions.concepts.DecisionResponse;
+import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
+import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.yaml.snakeyaml.Yaml;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class OptimizationPdpApplicationTest {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(OptimizationPdpApplicationTest.class);
+ private static Properties properties = new Properties();
+ private static File propertiesFile;
+ private static XacmlApplicationServiceProvider service;
+ private static StandardCoder gson = new StandardCoder();
+ private static DecisionRequest requestAffinity;
+
+ @ClassRule
+ public static final TemporaryFolder policyFolder = new TemporaryFolder();
+
+ /**
+ * Copies the xacml.properties and policies files into
+ * temporary folder and loads the service provider saving
+ * instance of provider off for other tests to use.
+ */
+ @BeforeClass
+ public static void setUp() throws Exception {
+ //
+ // Load Single Decision Request
+ //
+ requestAffinity = gson.decode(
+ TextFileUtils
+ .getTextFileAsString(
+ "../../main/src/test/resources/decisions/decision.optimization.affinity.input.json"),
+ DecisionRequest.class);
+ //
+ // Setup our temporary folder
+ //
+ XacmlPolicyUtils.FileCreator myCreator = (String filename) -> policyFolder.newFile(filename);
+ propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents("src/test/resources/xacml.properties",
+ properties, myCreator);
+ //
+ // Load service
+ //
+ ServiceLoader<XacmlApplicationServiceProvider> applicationLoader =
+ ServiceLoader.load(XacmlApplicationServiceProvider.class);
+ //
+ // Iterate through Xacml application services and find
+ // the optimization service. Save it for use throughout
+ // all the Junit tests.
+ //
+ StringBuilder strDump = new StringBuilder("Loaded applications:" + System.lineSeparator());
+ Iterator<XacmlApplicationServiceProvider> iterator = applicationLoader.iterator();
+ while (iterator.hasNext()) {
+ XacmlApplicationServiceProvider application = iterator.next();
+ //
+ // Is it our service?
+ //
+ if (application instanceof OptimizationPdpApplication) {
+ //
+ // Should be the first and only one
+ //
+ assertThat(service).isNull();
+ service = application;
+ }
+ strDump.append(application.applicationName());
+ strDump.append(" supports ");
+ strDump.append(application.supportedPolicyTypes());
+ strDump.append(System.lineSeparator());
+ }
+ LOGGER.debug("{}", strDump);
+ //
+ // Tell it to initialize based on the properties file
+ // we just built for it.
+ //
+ service.initialize(propertiesFile.toPath().getParent());
+ }
+
+ @Test
+ public void test1Basics() {
+ //
+ // Make sure there's an application name
+ //
+ assertThat(service.applicationName()).isNotEmpty();
+ //
+ // Decisions
+ //
+ assertThat(service.actionDecisionsSupported().size()).isEqualTo(1);
+ assertThat(service.actionDecisionsSupported()).contains("optimize");
+ //
+ // Ensure it has the supported policy types and
+ // can support the correct policy types.
+ //
+ assertThat(service.canSupportPolicyType("onap.policies.optimization.AffinityPolicy", "1.0.0")).isTrue();
+ assertThat(service.canSupportPolicyType("onap.foobar", "1.0.0")).isFalse();
+ }
+
+ @Test
+ public void test2NoPolicies() {
+ //
+ // Ask for a decision
+ //
+ DecisionResponse response = service.makeDecision(requestAffinity);
+ LOGGER.info("Decision {}", response);
+
+ assertThat(response).isNotNull();
+ assertThat(response.getPolicies().size()).isEqualTo(0);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void test3AddOptimizationPolicies() throws CoderException, FileNotFoundException, IOException {
+ //
+ // Now load the optimization policies
+ //
+ try (InputStream is = new FileInputStream("src/test/resources/vCPE.policies.optimization.input.tosca.yaml")) {
+ //
+ // Have yaml parse it
+ //
+ Yaml yaml = new Yaml();
+ Map<String, Object> toscaObject = yaml.load(is);
+ List<Object> policies = (List<Object>) toscaObject.get("policies");
+ //
+ // Sanity check to ensure the policy type and version are supported
+ //
+ for (Object policyObject : policies) {
+ //
+ // Get the contents
+ //
+ Map<String, Object> policyContents = (Map<String, Object>) policyObject;
+ for (Entry<String, Object> entrySet : policyContents.entrySet()) {
+ LOGGER.info("Entry set {}", entrySet.getKey());
+ Map<String, Object> policyDefinition = (Map<String, Object>) entrySet.getValue();
+ //
+ // Find the type and make sure the engine supports it
+ //
+ assertThat(policyDefinition.containsKey("type")).isTrue();
+ assertThat(service.canSupportPolicyType(
+ policyDefinition.get("type").toString(),
+ policyDefinition.get("version").toString()))
+ .isTrue();
+ }
+ }
+ //
+ // Load the policies
+ //
+ service.loadPolicies(toscaObject);
+ //
+ // Ask for a decision
+ //
+ DecisionResponse response = service.makeDecision(requestAffinity);
+ LOGGER.info("Decision {}", response);
+
+ assertThat(response).isNotNull();
+ assertThat(response.getPolicies().size()).isEqualTo(1);
+ //
+ // Dump it out as Json
+ //
+ LOGGER.info(gson.encode(response));
+ }
+ }
+
+}
diff --git a/applications/optimization/src/test/resources/vCPE.policies.optimization.input.tosca.yaml b/applications/optimization/src/test/resources/vCPE.policies.optimization.input.tosca.yaml
new file mode 100644
index 00000000..2fc7c140
--- /dev/null
+++ b/applications/optimization/src/test/resources/vCPE.policies.optimization.input.tosca.yaml
@@ -0,0 +1,137 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+topology_template:
+policies:
+ -
+ OSDF_CASABLANCA.Affinity_vCPE_1:
+ type: onap.policies.optimization.AffinityPolicy
+ version: 1.0.0
+ metadata:
+ policy-id: OSDF_CASABLANCA.Affinity_vCPE_1
+ policy-version: 1
+ properties:
+ identity: affinity_vCPE
+ policyScope: [vCPE, US, INTERNATIONAL, ip, vGMuxInfra, vG]
+ affinityProperties:
+ qualifier: same
+ category: complex
+ policyType: zone
+ resources: [vGMuxInfra, vG]
+ -
+ OSDF_CASABLANCA.Capacity_vG_1:
+ type: onap.policies.optimization.Vim_fit
+ version: 1.0.0
+ metadata:
+ policy-id: OSDF_CASABLANCA.Capacity_vG_1
+ policy-version: 1
+ properties:
+ identity: capacity_vG
+ policyScope: [VCPE, US, INTERNATIONAL, ip, vG]
+ resources: [vG]
+ capacityProperty:
+ controller: multicloud
+ request: "{\"vCPU\": 10, \"Memory\": {\"quantity\": {\"get_param\": \"REQUIRED_MEM\"}, \"unit\": \"GB\"}, \"Storage\": {\"quantity\": {\"get_param\": \"REQUIRED_DISK\"}, \"unit\": \"GB\"}}"
+ policyType: vim_fit
+ applicableResources: any
+ -
+ OSDF_CASABLANCA.Distance_vG_1:
+ type: onap.policies.optimization.DistancePolicy
+ version: 1.0.0
+ metadata:
+ policy-id: OSDF_CASABLANCA.Distance_vG_1
+ policy-version: 1
+ properties:
+ distanceProperties:
+ locationInfo: customer_loc
+ distance:
+ value: 1500
+ operator: "<"
+ unit: km
+ identity: "distance-vG"
+ resources: [vG]
+ policyScope: [vCPE, US, INTERNATIONAL, ip, vG]
+ policyType: distance_to_location
+ applicableResources: any
+ -
+ OSDF_CASABLANCA.hpa_policy_vG_1:
+ type: onap.policies.optimization.HpaPolicy
+ version: 1.0.0
+ metadata:
+ policy-id: OSDF_CASABLANCA.hpa_policy_vG_1
+ policy-version: 1
+ properties:
+ resources: [vG]
+ identity: "hpa-vG"
+ policyScope: [vCPE, US, INTERNATIONAL, ip, vG]
+ policyType: hpa
+ # NONE OF THE FLAVORFEATURES CAME OUT RIGHT
+ -
+ OSDF_CASABLANCA.queryPolicy_vCPE:
+ type: onap.policies.optimization.QueryPolicy
+ version: 1.0.0
+ metadata:
+ policy-id: OSDF_CASABLANCA.queryPolicy_vCPE
+ policy-version: 1
+ properties:
+ queryProperties:
+ -
+ attribute: locationId
+ attribute_location: customerLocation
+ value: ""
+ -
+ attribute: id
+ attribute_location: "vpnInfo.vpnId"
+ value: ""
+ -
+ attribute: upstreamBW
+ attribute_location: "vpnInfo.upstreamBW"
+ value: ""
+ -
+ attribute: customerLatitude
+ attribute_location: customerLatitude
+ value: 1.1
+ -
+ attribute: customerLongitude
+ attribute_location: customerLongitude
+ value: 2.2
+ serviceName: vCPE
+ policyScope: [vCPE, US, INTERNATIONAL, ip, vGMuxInfra, vG]
+ policyType: request_param_query
+ identity: vCPE_Query_Policy
+
+ -
+ OSDF_CASABLANCA.SubscriberPolicy_v1:
+ type: onap.policies.optimization.SubscriberPolicy
+ version: 1.0.0
+ metadata:
+ policy-id: OSDF_CASABLANCA.SubscriberPolicy_v1
+ policy-version: 1
+ properties:
+ identity: subscriber_vCPE
+ policyScope: [vCPE, subscriber_x, subscriber_y, subscriberPolicy]
+ properties:
+ subscriberName: [subscriber_x, subscriber_y]
+ subscriberRole: ["PVT Homing"]
+ provStatus: [CAPPED]
+ policyType: subscriberPolicy
+ serviceName: vCPE
+ -
+ OSDF_CASABLANCA.vnfPolicy_vG:
+ type: onap.policies.optimization.VnfPolicy
+ version: 1.0.0
+ metadata:
+ policy-id: OSDF_CASABLANCA.vnfPolicy_vG
+ policy-version: 1
+ properties:
+ identity: vnf_vG
+ policyScope: [vCPE, US, INTERNATIONAL, ip, vG]
+ policyType: vnfPolicy
+ resources: [vG]
+ applicableResources: any
+ vnfProperties:
+ -
+ inventoryProvider: aai
+ serviceType: ""
+ inventoryType: cloud
+ customerId: ""
+ orchestrationStatus: ""
+ equipmentRole: "" \ No newline at end of file
diff --git a/applications/optimization/src/test/resources/xacml.properties b/applications/optimization/src/test/resources/xacml.properties
new file mode 100644
index 00000000..5ea247cf
--- /dev/null
+++ b/applications/optimization/src/test/resources/xacml.properties
@@ -0,0 +1,31 @@
+#
+# Properties that the embedded PDP engine uses to configure and load
+#
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory
+#
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+#
+# ONAP PDP Implementation Factories
+#
+xacml.att.policyFinderFactory=org.onap.policy.pdp.xacml.application.common.OnapPolicyFinderFactory
+
+#
+# Use a root combining algorithm
+#
+xacml.att.policyFinderFactory.combineRootPolicies=urn:com:att:xacml:3.0:policy-combining-algorithm:combined-permit-overrides
+
+#
+# Policies to load
+#
+xacml.rootPolicies=
+xacml.referencedPolicies= \ No newline at end of file
diff --git a/applications/pom.xml b/applications/pom.xml
index 8d5d4b28..0a1cac02 100644
--- a/applications/pom.xml
+++ b/applications/pom.xml
@@ -35,6 +35,7 @@
<module>common</module>
<module>monitoring</module>
<module>guard</module>
+ <module>optimization</module>
</modules>
diff --git a/main/pom.xml b/main/pom.xml
index f4b0c9f4..872a5a0e 100644
--- a/main/pom.xml
+++ b/main/pom.xml
@@ -71,6 +71,11 @@
<artifactId>guard</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.onap.policy.xacml-pdp.applications</groupId>
+ <artifactId>optimization</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
<build>
diff --git a/main/src/test/resources/decisions/decision.guard.shoulddeny.input.json b/main/src/test/resources/decisions/decision.guard.shoulddeny.input.json
index ba9b5543..65d40c0a 100644
--- a/main/src/test/resources/decisions/decision.guard.shoulddeny.input.json
+++ b/main/src/test/resources/decisions/decision.guard.shoulddeny.input.json
@@ -1,14 +1,15 @@
{
"ONAPName": "Policy",
- "ONAPComponent": "DCAE",
- "ONAPInstance": "optional-tbd",
+ "ONAPComponent": "drools-pdp",
+ "ONAPInstance": "usecase-template",
+ "requestId": "unique-request-id-2",
"action": "guard",
"resource": {
"guard": {
"actor": "SO",
"recipe": "scaleOut",
"clname": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3",
- "vfcount" : "5"
+ "operationCount" : "1"
}
}
} \ No newline at end of file
diff --git a/main/src/test/resources/decisions/decision.guard.shoulddeny.input2.json b/main/src/test/resources/decisions/decision.guard.shoulddeny.input2.json
new file mode 100644
index 00000000..29dfc3dc
--- /dev/null
+++ b/main/src/test/resources/decisions/decision.guard.shoulddeny.input2.json
@@ -0,0 +1,15 @@
+{
+ "ONAPName": "Policy",
+ "ONAPComponent": "drools-pdp",
+ "ONAPInstance": "usecase-template",
+ "requestId": "unique-request-id-2",
+ "action": "guard",
+ "resource": {
+ "guard": {
+ "actor": "SO",
+ "recipe": "scaleOut",
+ "clname": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3",
+ "vfCount" : "6"
+ }
+ }
+} \ No newline at end of file
diff --git a/main/src/test/resources/decisions/decision.guard.shoulddeny.output.json b/main/src/test/resources/decisions/decision.guard.shoulddeny.output.json
deleted file mode 100644
index 3752fe47..00000000
--- a/main/src/test/resources/decisions/decision.guard.shoulddeny.output.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "status": "deny"
-} \ No newline at end of file
diff --git a/main/src/test/resources/decisions/decision.guard.shouldpermit.input.json b/main/src/test/resources/decisions/decision.guard.shouldpermit.input.json
index 324d495a..92e933f7 100644
--- a/main/src/test/resources/decisions/decision.guard.shouldpermit.input.json
+++ b/main/src/test/resources/decisions/decision.guard.shouldpermit.input.json
@@ -1,14 +1,16 @@
{
"ONAPName": "Policy",
- "ONAPComponent": "DCAE",
- "ONAPInstance": "optional-tbd",
+ "ONAPComponent": "drools-pdp",
+ "ONAPInstance": "usecase-template",
+ "requestId": "unique-request-id-1",
"action": "guard",
"resource": {
"guard": {
"actor": "SO",
"recipe": "scaleOut",
"clname": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3",
- "vfcount" : "1"
+ "operationCount": "0",
+ "vfCount": "1"
}
}
} \ No newline at end of file
diff --git a/main/src/test/resources/decisions/decision.guard.shouldpermit.output.json b/main/src/test/resources/decisions/decision.guard.shouldpermit.output.json
deleted file mode 100644
index a1939262..00000000
--- a/main/src/test/resources/decisions/decision.guard.shouldpermit.output.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "status": "permit"
-} \ No newline at end of file
diff --git a/main/src/test/resources/decisions/decision.optimization.affinity.input.json b/main/src/test/resources/decisions/decision.optimization.affinity.input.json
new file mode 100644
index 00000000..1794acea
--- /dev/null
+++ b/main/src/test/resources/decisions/decision.optimization.affinity.input.json
@@ -0,0 +1,10 @@
+{
+ "ONAPName": "OOF",
+ "ONAPComponent": "OOF-component",
+ "ONAPInstance": "OOF-component-instance",
+ "action": "optimize",
+ "resource": {
+ "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra", "vG"],
+ "policyType": "zone"
+ }
+} \ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 77838654..1559f963 100644
--- a/pom.xml
+++ b/pom.xml
@@ -100,13 +100,17 @@
<version>1.24</version>
</dependency>
<dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180813</version>
</dependency>
<dependency>
<groupId>org.onap.policy.models</groupId>
- <artifactId>models-decisions</artifactId>
+ <artifactId>policy-models-decisions</artifactId>
<version>${policy.models.version}</version>
</dependency>
<dependency>