diff options
author | Michael Mokry <michael.mokry@att.com> | 2019-04-10 09:53:44 -0500 |
---|---|---|
committer | Pamela Dragosh <pdragosh@research.att.com> | 2019-04-10 23:14:16 -0400 |
commit | a9c7e7322eb09672c8dfba32503653d12e685543 (patch) | |
tree | c655701bb30f1276f3cae5b51fe91eefa3d3d7da | |
parent | bfb8d12818346b96c9ab918e72327e1d13662321 (diff) |
XACML PDP DmaaP Deploy/UnDeploy Function
1. Added PDPUpdate listener
2. Added PDPUpdate Publisher
3. Added code to handle PdpUpdate messages and load policies being
deployed
4. Modified Activator to register listener
5. Provided placeholder code to get policies from pdpx for return
PdpStatus response to the PAP
6. Other minor modifications
7. Fix XacmlPdpApplicationManager to only load policy if supports
policy type.
8. Checkstyle fixes
9. Updated applications to support loadPolicy(ToscaPolicy) and
all the translators, JUnit tests.
10. Consolidated some duplicate code in the applications. Can probably
do more in that area.
11. Fixed bug in Properties not really having a copy constructor.
Change-Id: Ic29ad426061cbdb79c1339314667bb8ff8decb88
Issue-ID: POLICY-1451
Signed-off-by: Michael Mokry <michael.mokry@att.com>
Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
26 files changed, 653 insertions, 826 deletions
diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/TestUtils.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/TestUtils.java new file mode 100644 index 00000000..fa32516d --- /dev/null +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/TestUtils.java @@ -0,0 +1,68 @@ +/*- + * ============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; + +import java.util.Map; +import java.util.Map.Entry; + +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.yaml.snakeyaml.Yaml; + +public class TestUtils { + private static final StandardCoder standardCoder = new StandardCoder(); + + private TestUtils() { + super(); + } + + /** + * Load the policies from a resource file into the given the application. + * + * @param resourceFile resource file + * @param service XacmlApplicationServiceProvider + * @throws CoderException exception if it cannot be decoded + * @throws XacmlApplicationException If the application cannot load the policy + */ + public static void loadPolicies(String resourceFile, XacmlApplicationServiceProvider service) + throws CoderException, XacmlApplicationException { + String policyYaml = ResourceUtils.getResourceAsString(resourceFile); + Yaml yaml = new Yaml(); + Object yamlObject = yaml.load(policyYaml); + String yamlAsJsonString = standardCoder.encode(yamlObject); + ToscaServiceTemplate serviceTemplate = standardCoder.decode(yamlAsJsonString, ToscaServiceTemplate.class); + // + // Get the policies + // + for (Map<String, ToscaPolicy> policies : serviceTemplate.getToscaTopologyTemplate().getPolicies()) { + for (Entry<String, ToscaPolicy> entrySet : policies.entrySet()) { + service.loadPolicy(entrySet.getValue()); + } + } + + } + +} diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyTranslator.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyTranslator.java index f5f77d24..47ff70f6 100644 --- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyTranslator.java +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyTranslator.java @@ -25,24 +25,22 @@ package org.onap.policy.pdp.xacml.application.common; import com.att.research.xacml.api.Request; import com.att.research.xacml.api.Response; -import java.util.List; -import java.util.Map; - 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.models.tosca.authorative.concepts.ToscaPolicy; public interface ToscaPolicyTranslator { /** * Implement this method to translate policies. * - * @param toscaObject Incoming Tosca Policies object - * @return List of translated policies + * @param toscaPolicy Incoming Tosca Policy object + * @return Xacml PolicyType object * @throws ToscaPolicyConversionException Exception */ - List<PolicyType> scanAndConvertPolicies(Map<String, Object> toscaObject) throws ToscaPolicyConversionException; + PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException; /** * Implement this method to convert an ONAP DecisionRequest into diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlApplicationServiceProvider.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlApplicationServiceProvider.java index cf9b15cc..c1682fb7 100644 --- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlApplicationServiceProvider.java +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlApplicationServiceProvider.java @@ -23,10 +23,10 @@ package org.onap.policy.pdp.xacml.application.common; import java.nio.file.Path; import java.util.List; -import java.util.Map; import org.onap.policy.models.decisions.concepts.DecisionRequest; import org.onap.policy.models.decisions.concepts.DecisionResponse; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; /** @@ -79,11 +79,11 @@ public interface XacmlApplicationServiceProvider { boolean canSupportPolicyType(ToscaPolicyTypeIdentifier toscaPolicyId); /** - * Load a Map representation of a Tosca Policy. + * Load a Tosca Policy. * - * @param toscaPolicies Map of Tosca Policy Objects + * @param toscaPolicy object */ - void loadPolicies(Map<String, Object> toscaPolicies) throws XacmlApplicationException; + void loadPolicy(ToscaPolicy toscaPolicy) throws XacmlApplicationException; /** * Makes a decision given the incoming request and returns a response. 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 16798379..20b34006 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 @@ -31,16 +31,11 @@ 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.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; @@ -54,9 +49,11 @@ 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.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.models.decisions.concepts.DecisionRequest; import org.onap.policy.models.decisions.concepts.DecisionResponse; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.onap.policy.pdp.xacml.application.common.ToscaDictionary; import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException; import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator; @@ -72,44 +69,61 @@ public class StdCombinedPolicyResultsTranslator implements ToscaPolicyTranslator super(); } - @SuppressWarnings("unchecked") @Override - public List<PolicyType> scanAndConvertPolicies(Map<String, Object> toscaObject) - throws ToscaPolicyConversionException { + public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException { // - // Our return object + // Set it as the policy ID // - List<PolicyType> scannedPolicies = new ArrayList<>(); + PolicyType newPolicyType = new PolicyType(); + newPolicyType.setPolicyId(toscaPolicy.getMetadata().get("policy-id")); // - // Iterate each of the Policies + // Optional description // - 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); - } + newPolicyType.setDescription(toscaPolicy.getDescription()); + // + // There should be a metadata section + // + this.fillMetadataSection(newPolicyType, toscaPolicy.getMetadata()); + // + // Set the combining rule + // + newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_FIRST_APPLICABLE.stringValue()); + // + // Generate the TargetType + // + TargetType target = this.generateTargetType(toscaPolicy.getMetadata().get("policy-id"), + toscaPolicy.getType(), toscaPolicy.getVersion()); + newPolicyType.setTarget(target); + // + // 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(toscaPolicy.getMetadata().get("policy-id") + ":rule"); + rule.setEffect(EffectType.PERMIT); + rule.setTarget(new TargetType()); + // + // Now represent the policy as Json + // + StandardCoder coder = new StandardCoder(); + String jsonPolicy; + try { + jsonPolicy = coder.encode(toscaPolicy); + } catch (CoderException e) { + LOGGER.error("Failed to encode policy to json", e); + throw new ToscaPolicyConversionException(e); } - - return scannedPolicies; + addObligation(rule, jsonPolicy); + // + // Add the rule to the policy + // + newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule); + // + // Return our new policy + // + return newPolicyType; } @Override @@ -194,99 +208,30 @@ public class StdCombinedPolicyResultsTranslator implements ToscaPolicyTranslator } } - @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("type")) { - throw new ToscaPolicyConversionException(policyName + " missing type value"); - } - if (! policyDefinition.containsKey("version")) { - throw new ToscaPolicyConversionException(policyName + " missing version value"); - } - TargetType target = this.generateTargetType(policyName, - policyDefinition.get("type").toString(), - policyDefinition.get("version").toString()); - newPolicyType.setTarget(target); - // - // 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 + * @param map 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")) { + Map<String, String> map) throws ToscaPolicyConversionException { + if (! map.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")) { + if (! map.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()); + policy.setVersion(map.get("policy-version").toString()); } return policy; } @@ -346,7 +291,7 @@ public class StdCombinedPolicyResultsTranslator implements ToscaPolicyTranslator return target; } - protected RuleType addObligation(RuleType rule, JSONObject jsonPolicy) { + protected RuleType addObligation(RuleType rule, String jsonPolicy) { // // Convert the YAML Policy to JSON Object // @@ -358,7 +303,7 @@ public class StdCombinedPolicyResultsTranslator implements ToscaPolicyTranslator // AttributeValueType value = new AttributeValueType(); value.setDataType(ToscaDictionary.ID_OBLIGATION_POLICY_MONITORING_DATATYPE.stringValue()); - value.getContent().add(jsonPolicy.toString()); + value.getContent().add(jsonPolicy); // // Create our AttributeAssignmentExpression where we will // store the contents of the policy in JSON format. diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchableTranslator.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchableTranslator.java index 6ff1566b..9d3c6264 100644 --- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchableTranslator.java +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdMatchableTranslator.java @@ -32,15 +32,11 @@ 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; @@ -56,9 +52,11 @@ 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.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.models.decisions.concepts.DecisionRequest; import org.onap.policy.models.decisions.concepts.DecisionResponse; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.onap.policy.pdp.xacml.application.common.ToscaDictionary; import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException; import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator; @@ -74,46 +72,6 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { 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); @@ -197,13 +155,12 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { } - @SuppressWarnings("unchecked") - protected PolicyType convertPolicy(Entry<String, Object> entrySet) throws ToscaPolicyConversionException { + @Override + public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException { // // Policy name should be at the root // - String policyName = entrySet.getKey(); - Map<String, Object> policyDefinition = (Map<String, Object>) entrySet.getValue(); + String policyName = toscaPolicy.getMetadata().get("policy-id"); // // Set it as the policy ID // @@ -212,17 +169,11 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { // // Optional description // - if (policyDefinition.containsKey("description")) { - newPolicyType.setDescription(policyDefinition.get("description").toString()); - } + newPolicyType.setDescription(toscaPolicy.getDescription()); // // 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")); + this.fillMetadataSection(newPolicyType, toscaPolicy.getMetadata()); // // Set the combining rule // @@ -230,11 +181,7 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { // // 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"))); + newPolicyType.setTarget(generateTargetType(toscaPolicy.getProperties())); // // Now create the Permit Rule // No target since the policy has a target @@ -248,9 +195,15 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { // // Now represent the policy as Json // - JSONObject jsonObligation = new JSONObject(); - jsonObligation.put(policyName, policyDefinition); - addObligation(rule, jsonObligation); + StandardCoder coder = new StandardCoder(); + String jsonPolicy; + try { + jsonPolicy = coder.encode(toscaPolicy); + } catch (CoderException e) { + LOGGER.error("Failed to encode policy to json", e); + throw new ToscaPolicyConversionException(e); + } + addObligation(rule, jsonPolicy); // // Add the rule to the policy // @@ -265,26 +218,26 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { * 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 + * @param map 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")) { + Map<String, String> map) throws ToscaPolicyConversionException { + if (! map.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")) { + if (! map.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()); + policy.setVersion(map.get("policy-version").toString()); } return policy; } @@ -360,7 +313,7 @@ public class StdMatchableTranslator implements ToscaPolicyTranslator { return anyOf; } - protected RuleType addObligation(RuleType rule, JSONObject jsonPolicy) { + protected RuleType addObligation(RuleType rule, String jsonPolicy) { // // Convert the YAML Policy to JSON Object // diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdXacmlApplicationServiceProvider.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdXacmlApplicationServiceProvider.java index 19d8d829..7f85d2f0 100644 --- a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdXacmlApplicationServiceProvider.java +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/std/StdXacmlApplicationServiceProvider.java @@ -28,6 +28,7 @@ import com.att.research.xacml.api.pdp.PDPEngine; import com.att.research.xacml.api.pdp.PDPEngineFactory; import com.att.research.xacml.api.pdp.PDPException; import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.XACMLPolicyWriter; import java.io.IOException; import java.io.InputStream; @@ -37,19 +38,23 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; 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.models.tosca.authorative.concepts.ToscaPolicy; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; +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.XacmlApplicationException; 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; -public class StdXacmlApplicationServiceProvider implements XacmlApplicationServiceProvider { +public abstract class StdXacmlApplicationServiceProvider implements XacmlApplicationServiceProvider { private static final Logger LOGGER = LoggerFactory.getLogger(StdXacmlApplicationServiceProvider.class); private Path pathForData = null; @@ -115,28 +120,84 @@ public class StdXacmlApplicationServiceProvider implements XacmlApplicationServi @Override public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) { - return false; + throw new UnsupportedOperationException("Please override and implement canSupportPolicyType"); } @Override - public void loadPolicies(Map<String, Object> toscaPolicies) throws XacmlApplicationException { - throw new UnsupportedOperationException("Please override and implement loadPolicies"); + public synchronized void loadPolicy(ToscaPolicy toscaPolicy) { + try { + // + // Convert the policies first + // + PolicyType xacmlPolicy = this.getTranslator().convertPolicy(toscaPolicy); + if (xacmlPolicy == null) { + throw new ToscaPolicyConversionException("Failed to convert policy"); + } + // + // Create a copy of the properties object + // + Properties newProperties = this.getProperties(); + // + // Construct the filename + // + Path refPath = XacmlPolicyUtils.constructUniquePolicyFilename(xacmlPolicy, this.getDataPath()); + // + // Write the policy to disk + // Maybe check for an error + // + XACMLPolicyWriter.writePolicyFile(refPath, xacmlPolicy); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Xacml Policy is {}{}", System.lineSeparator(), new String(Files.readAllBytes(refPath))); + } + // + // 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); + // + // Save the properties + // + this.pdpProperties = newProperties; + } catch (IOException | ToscaPolicyConversionException e) { + LOGGER.error("Failed to loadPolicies {}", e); + } } @Override - public DecisionResponse makeDecision(DecisionRequest request) { + public synchronized DecisionResponse makeDecision(DecisionRequest request) { // - // We should have a standard error response to return + // Convert to a XacmlRequest // - return null; + Request xacmlRequest = this.getTranslator().convertRequest(request); + // + // Now get a decision + // + Response xacmlResponse = this.xacmlDecision(xacmlRequest); + // + // Convert to a DecisionResponse + // + return this.getTranslator().convertResponse(xacmlResponse); } + + protected abstract ToscaPolicyTranslator getTranslator(); + protected synchronized PDPEngine getEngine() { return this.pdpEngine; } protected synchronized Properties getProperties() { - return new Properties(pdpProperties); + Properties newProperties = new Properties(); + newProperties.putAll(pdpProperties); + return newProperties; } protected synchronized Path getDataPath() { @@ -190,7 +251,7 @@ public class StdXacmlApplicationServiceProvider implements XacmlApplicationServi PDPEngine engine = factory.newEngine(properties); if (engine != null) { this.pdpEngine = engine; - this.pdpProperties = new Properties(properties); +// this.pdpProperties = new Properties(properties); } } catch (FactoryException e) { LOGGER.error("Failed to create XACML PDP Engine {}", e); 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 41773ab7..0b3b1542 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 @@ -22,26 +22,12 @@ 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 java.io.IOException; -import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; 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.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; -import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException; -import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException; -import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils; +import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator; import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -99,65 +85,7 @@ public class GuardPdpApplication extends StdXacmlApplicationServiceProvider { } @Override - public void loadPolicies(Map<String, Object> toscaPolicies) throws XacmlApplicationException { - try { - // - // Convert the policies first - // - List<PolicyType> listPolicies = translator.scanAndConvertPolicies(toscaPolicies); - if (listPolicies.isEmpty()) { - throw new XacmlApplicationException("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); - } + protected ToscaPolicyTranslator getTranslator() { + return translator; } - - @Override - public 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/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 index 48861d86..77dbb353 100644 --- 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 @@ -30,15 +30,9 @@ 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; @@ -58,6 +52,7 @@ 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.models.tosca.authorative.concepts.ToscaPolicy; import org.onap.policy.pdp.xacml.application.common.ToscaDictionary; import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException; import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator; @@ -69,8 +64,6 @@ 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"; @@ -78,73 +71,52 @@ public class LegacyGuardTranslator implements ToscaPolicyTranslator { super(); } - @SuppressWarnings("unchecked") @Override - public List<PolicyType> scanAndConvertPolicies(Map<String, Object> toscaObject) - throws ToscaPolicyConversionException { + public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException { // - // Our return object + // Policy name should be at the root // - List<PolicyType> scannedPolicies = new ArrayList<>(); + String policyName = toscaPolicy.getMetadata().get("policy-id"); // - // Find the Policies + // Set it as the policy ID // - 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; - } + PolicyType newPolicyType = new PolicyType(); + newPolicyType.setPolicyId(policyName); // - // Iterate each of the Policies + // Optional description // - 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); - } + newPolicyType.setDescription(toscaPolicy.getDescription()); + // + // There should be a metadata section + // + this.fillMetadataSection(newPolicyType, toscaPolicy.getMetadata()); + // + // Set the combining rule + // + newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_DENY_UNLESS_PERMIT.stringValue()); + // + // Generate the TargetType + // + newPolicyType.setTarget(this.generateTargetType(toscaPolicy.getProperties())); + // + // Now create the Permit Rule + // + RuleType rule = generatePermitRule(policyName, toscaPolicy.getType(), toscaPolicy.getProperties()); + // + // Check if we were able to create the rule + // + if (rule == null) { + LOGGER.warn("Failed to create rule"); + return null; } - - return scannedPolicies; + // + // Add the rule to the policy + // + newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule); + // + // Return our new policy + // + return newPolicyType; } @Override @@ -161,7 +133,6 @@ public class LegacyGuardTranslator implements ToscaPolicyTranslator { return null; } - @Override public DecisionResponse convertResponse(Response xacmlResponse) { LOGGER.debug("Converting Response {}", xacmlResponse); @@ -196,89 +167,31 @@ public class LegacyGuardTranslator implements ToscaPolicyTranslator { 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 + * @param map 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")) { + Map<String, String> map) throws ToscaPolicyConversionException { + if (! map.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")) { + if (! map.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()); + policy.setVersion(map.get("policy-version").toString()); } return policy; } @@ -343,7 +256,8 @@ public class LegacyGuardTranslator implements ToscaPolicyTranslator { return allOf; } - private static RuleType generatePermitRule(String policyName, String policyType, Map<String, Object> properties) { + private static RuleType generatePermitRule(String policyName, String policyType, Map<String, Object> properties) + throws ToscaPolicyConversionException { // // Now determine which policy type we are generating // @@ -352,17 +266,16 @@ public class LegacyGuardTranslator implements ToscaPolicyTranslator { } else if ("onap.policies.controlloop.guard.MinMax".equals(policyType)) { return generateMinMaxPermit(policyName, properties); } + LOGGER.error("Missing policy type in the policy"); return null; } - private static RuleType generateFrequencyPermit(String policyName, Map<String, Object> properties) { + private static RuleType generateFrequencyPermit(String policyName, Map<String, Object> properties) + throws ToscaPolicyConversionException { // // See if its possible to generate a count // - Integer limit = null; - if (properties.containsKey("limit")) { - limit = Integer.decode(properties.get("limit").toString()); - } + Integer limit = parseInteger(properties.get("limit").toString()); if (limit == null) { LOGGER.debug("Must have a limit value for frequency guard policy to be created"); return null; @@ -372,7 +285,11 @@ public class LegacyGuardTranslator implements ToscaPolicyTranslator { // String timeWindow = null; if (properties.containsKey("timeWindow")) { - timeWindow = properties.get("timeWindow").toString(); + Integer intTimeWindow = parseInteger(properties.get("timeWindow").toString()); + if (intTimeWindow == null) { + throw new ToscaPolicyConversionException("timeWindow is not an integer"); + } + timeWindow = intTimeWindow.toString(); } String timeUnits = null; if (properties.containsKey("timeUnits")) { @@ -452,11 +369,11 @@ public class LegacyGuardTranslator implements ToscaPolicyTranslator { // Integer min = null; if (properties.containsKey("min")) { - min = Integer.decode(properties.get("min").toString()); + min = parseInteger(properties.get("min").toString()); } Integer max = null; if (properties.containsKey("max")) { - max = Integer.decode(properties.get("max").toString()); + max = parseInteger(properties.get("max").toString()); } final ApplyType minApply = generateMinCheck(min); final ApplyType maxApply = generateMaxCheck(max); @@ -708,6 +625,23 @@ public class LegacyGuardTranslator implements ToscaPolicyTranslator { return applyLessThanEqual; } + private static Integer parseInteger(String strInteger) { + Integer theInt = null; + try { + theInt = Integer.parseInt(strInteger); + } catch (NumberFormatException e) { + LOGGER.warn("Expecting an integer", e); + try { + Double dblLimit = Double.parseDouble(strInteger); + theInt = dblLimit.intValue(); + } catch (NumberFormatException e1) { + LOGGER.error("Failed to parse expected integer as a double", e); + return null; + } + } + return theInt; + } + private static AdviceExpressionsType generateRequestIdAdvice() { AdviceExpressionType adviceExpression = new AdviceExpressionType(); adviceExpression.setAppliesTo(EffectType.PERMIT); 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 be0ee2db..17917af0 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 @@ -25,10 +25,8 @@ package org.onap.policy.xacml.pdp.application.guard; 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.sql.Date; import java.time.Instant; import java.util.HashMap; @@ -56,12 +54,12 @@ import org.onap.policy.models.decisions.concepts.DecisionRequest; import org.onap.policy.models.decisions.concepts.DecisionResponse; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; import org.onap.policy.pdp.xacml.application.common.OnapOperationsHistoryDbao; +import org.onap.policy.pdp.xacml.application.common.TestUtils; import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException; 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 { @@ -242,17 +240,7 @@ public class GuardPdpApplicationTest { // 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")) { - // - // Have yaml parse it - // - Yaml yaml = new Yaml(); - Map<String, Object> toscaObject = yaml.load(is); - // - // Load the policies - // - service.loadPolicies(toscaObject); - } + TestUtils.loadPolicies("src/test/resources/vDNS.policy.guard.frequency.output.tosca.yaml", service); // // Zero recent actions: should get permit // @@ -283,17 +271,7 @@ public class GuardPdpApplicationTest { // 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); - } + TestUtils.loadPolicies("src/test/resources/vDNS.policy.guard.minmax.output.tosca.yaml", service); // // vfcount=1 below min of 2: should get a Deny // @@ -322,7 +300,8 @@ public class GuardPdpApplicationTest { } @Test - public void test5MissingFields() throws FileNotFoundException, IOException, XacmlApplicationException { + public void test5MissingFields() throws FileNotFoundException, IOException, XacmlApplicationException, + CoderException { LOGGER.info("**************** Running test5 ****************"); // // Most likely we would not get a policy with missing fields passed to @@ -330,52 +309,42 @@ public class GuardPdpApplicationTest { // 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")) { - // - // Have yaml parse it - // - Yaml yaml = new Yaml(); - Map<String, Object> toscaObject = yaml.load(is); - // - // Load the policies - // - service.loadPolicies(toscaObject); - // - // We can create a DecisionRequest on the fly - no need - // to have it in the .json files - // - 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); - // - // Ask for a decision - should get permit - // - DecisionResponse response = service.makeDecision(request); - LOGGER.info("Looking for Permit Decision {}", response); - assertThat(response).isNotNull(); - assertThat(response.getStatus()).isNotNull(); - assertThat(response.getStatus()).isEqualTo("Permit"); - // - // Try a deny - // - 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"); - } + TestUtils.loadPolicies("src/test/resources/guard.policy-minmax-missing-fields1.yaml", service); + // + // We can create a DecisionRequest on the fly - no need + // to have it in the .json files + // + 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); + // + // Ask for a decision - should get permit + // + DecisionResponse response = service.makeDecision(request); + LOGGER.info("Looking for Permit Decision {}", response); + assertThat(response).isNotNull(); + assertThat(response.getStatus()).isNotNull(); + assertThat(response.getStatus()).isEqualTo("Permit"); + // + // Try a deny + // + 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"); } @SuppressWarnings("unchecked") @@ -397,6 +366,7 @@ public class GuardPdpApplicationTest { newEntry.setEndtime(Date.from(Instant.now())); newEntry.setRequestId(UUID.randomUUID().toString()); newEntry.setTarget(properties.get("target").toString()); + LOGGER.info("Inserting {}", newEntry); em.getTransaction().begin(); em.persist(newEntry); em.getTransaction().commit(); diff --git a/applications/guard/src/test/resources/xacml.properties b/applications/guard/src/test/resources/xacml.properties index d429a32e..25dee375 100644 --- a/applications/guard/src/test/resources/xacml.properties +++ b/applications/guard/src/test/resources/xacml.properties @@ -22,7 +22,7 @@ xacml.att.policyFinderFactory=org.onap.policy.pdp.xacml.application.common.OnapP # # Use a root combining algorithm # -xacml.att.policyFinderFactory.combineRootPolicies=urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:permit-unless-deny +xacml.att.policyFinderFactory.combineRootPolicies=urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides xacml.pip.engines=historydb diff --git a/applications/monitoring/src/main/java/org/onap/policy/xacml/pdp/application/monitoring/MonitoringPdpApplication.java b/applications/monitoring/src/main/java/org/onap/policy/xacml/pdp/application/monitoring/MonitoringPdpApplication.java index 0c928b8c..0661b869 100644 --- a/applications/monitoring/src/main/java/org/onap/policy/xacml/pdp/application/monitoring/MonitoringPdpApplication.java +++ b/applications/monitoring/src/main/java/org/onap/policy/xacml/pdp/application/monitoring/MonitoringPdpApplication.java @@ -22,33 +22,12 @@ package org.onap.policy.xacml.pdp.application.monitoring; -import com.att.research.xacml.api.Request; -import com.att.research.xacml.api.Response; -import com.att.research.xacml.util.XACMLPolicyScanner; -import com.att.research.xacml.util.XACMLPolicyWriter; -import com.att.research.xacml.util.XACMLProperties; - -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType; -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.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; -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.ToscaPolicyTranslator; import org.onap.policy.pdp.xacml.application.common.std.StdCombinedPolicyResultsTranslator; import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider; import org.slf4j.Logger; @@ -109,106 +88,7 @@ public class MonitoringPdpApplication extends StdXacmlApplicationServiceProvider } @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"); - } - // - // Get our properties because we are going to update - // - Properties currentProperties = this.getProperties(); - // - // Read in our Root Policy - // - Set<String> roots = XACMLProperties.getRootPolicyIDs(currentProperties); - if (roots.isEmpty()) { - throw new ToscaPolicyConversionException("There are NO root policies defined"); - } - // - // Really only should be one - // - String rootFile = currentProperties.getProperty(roots.iterator().next() + ".file"); - try (InputStream is = new FileInputStream(rootFile)) { - // - // Read the Root Policy into memory - // - Object policyData = XACMLPolicyScanner.readPolicy(is); - // - // Should be a PolicySet - // - if (policyData instanceof PolicySetType) { - // - // Add the referenced policies into a new Root Policy - // - PolicyType[] newPolicies = listPolicies.toArray(new PolicyType[listPolicies.size()]); - PolicySetType newRootPolicy = XacmlPolicyUtils.addPoliciesToXacmlRootPolicy( - (PolicySetType) policyData, newPolicies); - LOGGER.debug("New ROOT Policy"); - try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { - XACMLPolicyWriter.writePolicyFile(os, newRootPolicy); - LOGGER.debug("{}", os); - } catch (IOException e) { - LOGGER.error("Failed to convert {}", e); - } - // - // Save the new Policies to disk - // - for (PolicyType policy : newPolicies) { - // - // Construct the filename - // - Path refPath = XacmlPolicyUtils.constructUniquePolicyFilename(policy, this.getDataPath()); - // - // Write the policy to disk - // Maybe check for an error - // - XACMLPolicyWriter.writePolicyFile(refPath, policy); - // - // Save it off - // - XacmlPolicyUtils.addReferencedPolicy(currentProperties, refPath); - } - // - // Save the root policy to disk - // - XACMLPolicyWriter.writePolicyFile(Paths.get(rootFile), newRootPolicy); - // - // Write the policies to disk - // - XacmlPolicyUtils.storeXacmlProperties(currentProperties, - XacmlPolicyUtils.getPropertiesPath(this.getDataPath())); - // - // Reload the engine - // - this.createEngine(currentProperties); - } else { - throw new ToscaPolicyConversionException("Root policy isn't a PolicySet"); - } - } - } 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); + protected ToscaPolicyTranslator getTranslator() { + return translator; } - } diff --git a/packages/policy-xacmlpdp-tarball/src/main/resources/apps/monitoring/RootMonitoringPolicy.xml b/applications/monitoring/src/main/resources/save/RootMonitoringPolicy.xml index 5578fda9..5578fda9 100644 --- a/packages/policy-xacmlpdp-tarball/src/main/resources/apps/monitoring/RootMonitoringPolicy.xml +++ b/applications/monitoring/src/main/resources/save/RootMonitoringPolicy.xml 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 8099ffdd..cc11dcf6 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 @@ -25,13 +25,8 @@ package org.onap.policy.xacml.pdp.application.monitoring; import static org.assertj.core.api.Assertions.assertThat; import java.io.File; -import java.io.FileInputStream; 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; @@ -47,12 +42,12 @@ 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.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; +import org.onap.policy.pdp.xacml.application.common.TestUtils; import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException; 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 { @@ -156,7 +151,6 @@ public class MonitoringPdpApplicationTest { assertThat(response.getPolicies().size()).isEqualTo(0); } - @SuppressWarnings("unchecked") @Test public void test3AddvDnsPolicy() throws IOException, CoderException, XacmlApplicationException { // @@ -164,52 +158,22 @@ public class MonitoringPdpApplicationTest { // the pdp can support it and have it load // into the PDP. // - 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) { - // - // 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( - new ToscaPolicyTypeIdentifier( - policyDefinition.get("type").toString(), - policyDefinition.get("version").toString()))) - .isTrue(); - } - } - // - // Load the policies - // - service.loadPolicies(toscaObject); - // - // Ask for a decision - // - DecisionResponse response = service.makeDecision(requestSinglePolicy); - LOGGER.info("Decision {}", response); + // + // Now load the optimization policies + // + TestUtils.loadPolicies("src/test/resources/vDNS.policy.input.yaml", service); + // + // 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)); - } + assertThat(response).isNotNull(); + assertThat(response.getPolicies().size()).isEqualTo(1); + // + // Dump it out as Json + // + LOGGER.info(gson.encode(response)); } @Test diff --git a/applications/monitoring/src/test/resources/vDNS.policy.input.yaml b/applications/monitoring/src/test/resources/vDNS.policy.input.yaml index 763af75f..7d8120e5 100644 --- a/applications/monitoring/src/test/resources/vDNS.policy.input.yaml +++ b/applications/monitoring/src/test/resources/vDNS.policy.input.yaml @@ -1,7 +1,8 @@ tosca_definitions_version: tosca_simple_yaml_1_0_0 -policies: - - - onap.scaleout.tca: +topology_template: + policies: + - + onap.scaleout.tca: type: onap.policies.monitoring.cdap.tca.hi.lo.app version: 1.0.0 metadata: diff --git a/applications/monitoring/src/test/resources/xacml.properties b/applications/monitoring/src/test/resources/xacml.properties index 36eac3cd..5ea247cf 100644 --- a/applications/monitoring/src/test/resources/xacml.properties +++ b/applications/monitoring/src/test/resources/xacml.properties @@ -19,8 +19,13 @@ xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctio # xacml.att.policyFinderFactory=org.onap.policy.pdp.xacml.application.common.OnapPolicyFinderFactory -# Policies to load # -xacml.rootPolicies=monitoring -monitoring.file=../../packages/policy-xacmlpdp-tarball/src/main/resources/apps/monitoring/RootMonitoringPolicy.xml +# 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/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplication.java b/applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplication.java index accf7a0c..4bb1da65 100644 --- a/applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplication.java +++ b/applications/optimization/src/main/java/org/onap/policy/xacml/pdp/application/optimization/OptimizationPdpApplication.java @@ -22,26 +22,13 @@ 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 java.io.IOException; -import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; 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.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; -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.ToscaPolicyTranslator; import org.onap.policy.pdp.xacml.application.common.std.StdMatchableTranslator; import org.onap.policy.pdp.xacml.application.common.std.StdXacmlApplicationServiceProvider; import org.slf4j.Logger; @@ -113,65 +100,7 @@ public class OptimizationPdpApplication extends StdXacmlApplicationServiceProvid } @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); - } + protected ToscaPolicyTranslator getTranslator() { + return translator; } - - @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/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 index e593d5fe..046aaa66 100644 --- 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 @@ -25,14 +25,9 @@ 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; @@ -48,12 +43,12 @@ 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.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; +import org.onap.policy.pdp.xacml.application.common.TestUtils; import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException; 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 { @@ -159,59 +154,24 @@ public class OptimizationPdpApplicationTest { assertThat(response.getPolicies().size()).isEqualTo(0); } - @SuppressWarnings("unchecked") @Test public void test3AddOptimizationPolicies() throws CoderException, FileNotFoundException, IOException, XacmlApplicationException { // // 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( - new ToscaPolicyTypeIdentifier( - 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); + TestUtils.loadPolicies("src/test/resources/vCPE.policies.optimization.input.tosca.yaml", service); + // + // 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)); - } + 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 index 2fc7c140..2d21a571 100644 --- a/applications/optimization/src/test/resources/vCPE.policies.optimization.input.tosca.yaml +++ b/applications/optimization/src/test/resources/vCPE.policies.optimization.input.tosca.yaml @@ -1,6 +1,6 @@ tosca_definitions_version: tosca_simple_yaml_1_0_0 topology_template: -policies: + policies: - OSDF_CASABLANCA.Affinity_vCPE_1: type: onap.policies.optimization.AffinityPolicy diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHeartbeatPublisher.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisher.java index fe730208..0dc8bf54 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHeartbeatPublisher.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisher.java @@ -23,31 +23,34 @@ package org.onap.policy.pdpx.main.comm; import java.util.Timer; import java.util.TimerTask; import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; +import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.enums.PdpState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class XacmlPdpHeartbeatPublisher extends TimerTask { +public class XacmlPdpHearbeatPublisher extends TimerTask { - private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpHeartbeatPublisher.class); + private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpHearbeatPublisher.class); - private TopicSinkClient topicSinkClient; private Timer timer; private XacmlPdpMessage heartbeatMessage; - private PdpState pdpState; - + private Object message; + private static TopicSinkClient topicSinkClient; private static volatile boolean alive = false; + public static PdpState pdpState; + /** - * Constructor for instantiating XacmlPdpHeartbeatPublisher. + * Constructor for instantiating XacmlPdpPublisher. * - * @param state of the PDP + * @param message of the PDP * @param topicSinkClient used to send heartbeat message */ - public XacmlPdpHeartbeatPublisher(TopicSinkClient topicSinkClient, PdpState state) { + public XacmlPdpHearbeatPublisher(TopicSinkClient topicSinkClient, PdpStateChange message) { + this.message = message; + this.pdpState = message.getState(); this.topicSinkClient = topicSinkClient; this.heartbeatMessage = new XacmlPdpMessage(); - this.pdpState = state; timer = new Timer(false); timer.scheduleAtFixedRate(this, 0, 60000); // time interval temp hard coded now but will be parameterized setAlive(true); @@ -55,7 +58,7 @@ public class XacmlPdpHeartbeatPublisher extends TimerTask { @Override public void run() { - topicSinkClient.send(heartbeatMessage.formatStatusMessage(pdpState)); + topicSinkClient.send(heartbeatMessage.formatHeartbeatMessage((PdpStateChange) message)); LOGGER.info("Sending Xacml PDP heartbeat to the PAP"); } @@ -69,6 +72,7 @@ public class XacmlPdpHeartbeatPublisher extends TimerTask { } public void updateInternalState(PdpState state) { + ((PdpStateChange) this.message).setState(state); this.pdpState = state; } @@ -79,5 +83,4 @@ public class XacmlPdpHeartbeatPublisher extends TimerTask { public void setAlive(boolean alive) { this.alive = alive; } - } diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpMessage.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpMessage.java index 233bd7f7..809e43d0 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpMessage.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpMessage.java @@ -24,7 +24,9 @@ package org.onap.policy.pdpx.main.comm; import java.net.UnknownHostException; import org.onap.policy.common.utils.network.NetworkUtil; +import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.concepts.PdpStatus; +import org.onap.policy.models.pdp.concepts.PdpUpdate; import org.onap.policy.models.pdp.enums.PdpHealthStatus; import org.onap.policy.models.pdp.enums.PdpState; import org.onap.policy.pdpx.main.rest.XacmlPdpApplicationManager; @@ -42,7 +44,6 @@ public class XacmlPdpMessage { * * @param state of the PDP * @return status message of the PDP - * @throws UnknownHostException if cannot get hostname */ public PdpStatus formatStatusMessage(PdpState state) { PdpStatus status = new PdpStatus(); @@ -63,4 +64,55 @@ public class XacmlPdpMessage { return status; } + + /** + * Method used to format the heartbeat status message. + * + * @param message PdpStateChange message received from the PAP + * @return status message of the PDP + */ + public PdpStatus formatHeartbeatMessage(PdpStateChange message) { + PdpStatus status = new PdpStatus(); + status.setName(NetworkUtil.getHostname()); + + if (XacmlPdpActivator.getCurrent().isAlive()) { + status.setHealthy(PdpHealthStatus.HEALTHY); + } else { + status.setHealthy(PdpHealthStatus.NOT_HEALTHY); + } + + status.setPdpType("xacml"); + status.setState(message.getState()); + status.setPdpGroup(message.getPdpGroup()); + status.setPdpSubgroup(message.getPdpSubgroup()); + status.setSupportedPolicyTypes(XacmlPdpApplicationManager.getToscaPolicyTypeIdents()); + + return status; + } + + /** + * Method used to format the PdpUpdate message. + * + * @param message PdpUpdate message that was received from the PAP + * @return status message of the PDP + */ + public PdpStatus formatPdpUpdateMessage(PdpUpdate message, PdpState state) { + PdpStatus status = new PdpStatus(); + status.setName(NetworkUtil.getHostname()); + + if (XacmlPdpActivator.getCurrent().isAlive()) { + status.setHealthy(PdpHealthStatus.HEALTHY); + } else { + status.setHealthy(PdpHealthStatus.NOT_HEALTHY); + } + + status.setPdpType("xacml"); + status.setState(state); + status.setPdpGroup(message.getPdpGroup()); + status.setPdpSubgroup(message.getPdpSubgroup()); + status.setSupportedPolicyTypes(XacmlPdpApplicationManager.getToscaPolicyTypeIdents()); + status.setPolicies(XacmlPdpApplicationManager.getToscaPolicies()); + + return status; + } } diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisher.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisher.java new file mode 100644 index 00000000..716421c7 --- /dev/null +++ b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisher.java @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pdpx.main.comm; + +import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; +import org.onap.policy.models.pdp.concepts.PdpStatus; +import org.onap.policy.models.pdp.concepts.PdpUpdate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.pdpx.main.rest.XacmlPdpApplicationManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class XacmlPdpUpdatePublisher { + + private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpUpdatePublisher.class); + + private XacmlPdpUpdatePublisher() { + throw new IllegalStateException("Please do not create private instance of XacmlPdpUpdatePublisher"); + } + + /** + * Handle the PDP Update message. + * + * @param message Incoming message + * @param client TopicSinkClient + */ + public static void handlePdpUpdate(PdpUpdate message, TopicSinkClient client) { + + if (!message.getPolicies().isEmpty() || message.getPolicies() != null) { + // Load the policies on PDP applications + for (ToscaPolicy toscaPolicy : message.getPolicies()) { + XacmlPdpApplicationManager.loadDeployedPolicy(toscaPolicy); + } + } + + XacmlPdpMessage updatePdpMessage = new XacmlPdpMessage(); + PdpStatus statusMessage = updatePdpMessage.formatPdpUpdateMessage(message, XacmlPdpHearbeatPublisher.pdpState); + sendPdpUpdate(statusMessage, client); + } + + private static void sendPdpUpdate(PdpStatus status, TopicSinkClient client) { + // Send PdpStatus Change to PAP + if (!client.send(status)) { + LOGGER.error("failed to send to topic sink {}", client.getTopic()); + } + } + +} diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListener.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListener.java index f5b2fbfa..3e24c3fe 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListener.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListener.java @@ -28,7 +28,7 @@ import org.onap.policy.common.utils.coder.StandardCoderObject; import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.concepts.PdpStatus; import org.onap.policy.models.pdp.enums.PdpState; -import org.onap.policy.pdpx.main.comm.XacmlPdpHeartbeatPublisher; +import org.onap.policy.pdpx.main.comm.XacmlPdpHearbeatPublisher; import org.onap.policy.pdpx.main.comm.XacmlPdpMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,7 +39,7 @@ public class XacmlPdpStateChangeListener extends ScoListener<PdpStateChange> { private TopicSinkClient client; - private XacmlPdpHeartbeatPublisher heartbeat; + private XacmlPdpHearbeatPublisher heartbeat; /** * Constructs the object. @@ -48,7 +48,9 @@ public class XacmlPdpStateChangeListener extends ScoListener<PdpStateChange> { */ public XacmlPdpStateChangeListener(TopicSinkClient client) { super(PdpStateChange.class); - heartbeat = new XacmlPdpHeartbeatPublisher(client, PdpState.PASSIVE); + PdpStateChange message = new PdpStateChange(); + message.setState(PdpState.PASSIVE); + heartbeat = new XacmlPdpHearbeatPublisher(client, message); this.client = client; } @@ -66,10 +68,10 @@ public class XacmlPdpStateChangeListener extends ScoListener<PdpStateChange> { } // Update the heartbeat internal state if publisher is running else create new publisher - if (XacmlPdpHeartbeatPublisher.isAlive()) { + if (XacmlPdpHearbeatPublisher.isAlive()) { heartbeat.updateInternalState(message.getState()); } else { - heartbeat = new XacmlPdpHeartbeatPublisher(client, message.getState()); + heartbeat = new XacmlPdpHearbeatPublisher(client, message); } } catch (final Exception e) { diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListener.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListener.java new file mode 100644 index 00000000..69f96a05 --- /dev/null +++ b/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListener.java @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pdpx.main.comm.listeners; + +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; +import org.onap.policy.common.endpoints.listeners.ScoListener; +import org.onap.policy.common.utils.coder.StandardCoderObject; +import org.onap.policy.models.pdp.concepts.PdpUpdate; +import org.onap.policy.pdpx.main.comm.XacmlPdpUpdatePublisher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class XacmlPdpUpdateListener extends ScoListener<PdpUpdate> { + + private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpStateChangeListener.class); + + private TopicSinkClient client; + + /** + * Constructs the object. + * + * @param client used to send back response after receiving state change message + */ + public XacmlPdpUpdateListener(TopicSinkClient client) { + super(PdpUpdate.class); + this.client = client; + } + + @Override + public void onTopicEvent(CommInfrastructure infra, String topic, StandardCoderObject sco, PdpUpdate message) { + + try { + + LOGGER.info("PDP update message has been received from the PAP - {}", message.toString()); + XacmlPdpUpdatePublisher.handlePdpUpdate(message, client); + + } catch (final Exception e) { + LOGGER.error("failed to handle the PDP Update message.", e); + } + + } + +} diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java index a5e1d030..09805593 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java @@ -30,6 +30,8 @@ import java.util.List; import java.util.Map; import java.util.ServiceLoader; import org.onap.policy.models.decisions.concepts.DecisionRequest; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException; import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider; @@ -43,6 +45,7 @@ public class XacmlPdpApplicationManager { private static ServiceLoader<XacmlApplicationServiceProvider> applicationLoader; private static Map<String, XacmlApplicationServiceProvider> providerActionMap = new HashMap<>(); private static List<ToscaPolicyTypeIdentifier> toscaPolicyTypeIdents = new ArrayList<>(); + private static List<ToscaPolicyIdentifier> toscaPolicies = new ArrayList<>(); private XacmlPdpApplicationManager() { super(); @@ -117,6 +120,34 @@ public class XacmlPdpApplicationManager { } /** + * Finds the appropriate application and loads the policy. + * + * @param policy Incoming policy + */ + public static void loadDeployedPolicy(ToscaPolicy policy) { + + for (XacmlApplicationServiceProvider application : applicationLoader) { + try { + // + // There should be only one application per policytype. We can + // put more logic surrounding enforcement of that later. For now, + // just use the first one found. + // + if (application.canSupportPolicyType(policy.getTypeIdentifier())) { + application.loadPolicy(policy); + return; + } + } catch (XacmlApplicationException e) { + LOGGER.error("Failed to load the Tosca Policy", e); + } + } + } + + public static List<ToscaPolicyIdentifier> getToscaPolicies() { + return toscaPolicies; + } + + /** * Returns the current count of policy types supported. This could be misleading a bit * as some applications can support wildcard of policy types. Eg. onap.Monitoring.* as * well as individual types/versions. Nevertheless useful for debugging and testing. diff --git a/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java b/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java index 9695c7b9..330fbd67 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java @@ -38,6 +38,7 @@ import org.onap.policy.pdpx.main.PolicyXacmlPdpRuntimeException; import org.onap.policy.pdpx.main.comm.XacmlPdpMessage; import org.onap.policy.pdpx.main.comm.XacmlPdpPapRegistration; import org.onap.policy.pdpx.main.comm.listeners.XacmlPdpStateChangeListener; +import org.onap.policy.pdpx.main.comm.listeners.XacmlPdpUpdateListener; import org.onap.policy.pdpx.main.parameters.XacmlPdpParameterGroup; import org.onap.policy.pdpx.main.rest.XacmlPdpRestServer; import org.slf4j.Logger; @@ -65,17 +66,21 @@ public class XacmlPdpActivator extends ServiceManagerContainer { /** * Listens for messages on the topic, decodes them into a {@link PdpStatus} message, and then - * dispatches them to {@link #pdpUpdateListener}. + * dispatches them to appropriate listener. */ private final MessageTypeDispatcher msgDispatcher; /** - * Listens for {@link PdpUpdate} messages and then routes them to the listener associated with the - * ID of the originating request. + * Listens for {@link PdpStateChange} messages from the PAP. */ private final XacmlPdpStateChangeListener pdpStateChangeListener; /** + * Listens for {@link PdpUpdate} messages from the PAP. + */ + private final XacmlPdpUpdateListener pdpUpdateListener; + + /** * The current activator. */ private static XacmlPdpActivator current = null; @@ -101,6 +106,7 @@ public class XacmlPdpActivator extends ServiceManagerContainer { this.xacmlPdpParameterGroup = xacmlPdpParameterGroup; this.msgDispatcher = new MessageTypeDispatcher(MSG_TYPE_NAMES); this.pdpStateChangeListener = new XacmlPdpStateChangeListener(sinkClient); + this.pdpUpdateListener = new XacmlPdpUpdateListener(sinkClient); this.register = new XacmlPdpPapRegistration(sinkClient); this.message = new XacmlPdpMessage(); } catch (RuntimeException | TopicSinkClientException e) { @@ -113,10 +119,14 @@ public class XacmlPdpActivator extends ServiceManagerContainer { addAction("XACML PDP parameters", () -> ParameterService.register(xacmlPdpParameterGroup), () -> ParameterService.deregister(xacmlPdpParameterGroup.getName())); - addAction("Request ID Dispatcher", + addAction("PdpStateChange Dispatcher", () -> msgDispatcher.register(PdpMessageType.PDP_STATE_CHANGE.name(), this.pdpStateChangeListener), () -> msgDispatcher.unregister(PdpMessageType.PDP_STATE_CHANGE.name())); + addAction("PdpUpdate Dispatcher", + () -> msgDispatcher.register(PdpMessageType.PDP_UPDATE.name(), this.pdpUpdateListener), + () -> msgDispatcher.unregister(PdpMessageType.PDP_UPDATE.name())); + addAction("Message Dispatcher", () -> registerMsgDispatcher(), () -> unregisterMsgDispatcher()); diff --git a/packages/policy-xacmlpdp-tarball/src/main/resources/apps/monitoring/xacml.properties b/packages/policy-xacmlpdp-tarball/src/main/resources/apps/monitoring/xacml.properties index 8ad5152d..5ea247cf 100644 --- a/packages/policy-xacmlpdp-tarball/src/main/resources/apps/monitoring/xacml.properties +++ b/packages/policy-xacmlpdp-tarball/src/main/resources/apps/monitoring/xacml.properties @@ -19,8 +19,13 @@ xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctio # xacml.att.policyFinderFactory=org.onap.policy.pdp.xacml.application.common.OnapPolicyFinderFactory -# Policies to load # -xacml.rootPolicies=monitoring -monitoring.file=/opt/app/policy/pdpx/apps/monitoring/RootMonitoringPolicy.xml +# 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 |