From b909b14fe88c5fe8f096cf8b471a2aa799d84739 Mon Sep 17 00:00:00 2001 From: Pamela Dragosh Date: Sat, 9 Mar 2019 11:48:44 -0500 Subject: [PATCH] Monitoring policy creation foundation Upgrde to xacml v2.0.0 release artifact. Some re-arrangement of classes. New class to support a common dictionary among the monitoring applications. I may move it to a common under the main since some of the values are shareable. Created application service provider, so the XACML main knows what policy types are pre-loaded and can report them back to the PAP. struggled with cucumber, which does not create TemporaryFolder although the documentation says its supported. Added a new Policy Finder specific to ONAP which does quicker job to load policies. Issue-ID: POLICY-1273 Change-Id: I4af15a64da3b42d48f29809710421b1649625adc Signed-off-by: Pamela Dragosh --- applications/common/pom.xml | 46 ++ .../common/OnapPolicyFinderFactory.java | 252 ++++++++++ .../xacml/application/common/ToscaDictionary.java | 69 +++ .../common/ToscaPolicyConversionException.java | 50 ++ .../application/common/ToscaPolicyConverter.java | 36 ++ .../common/ToscaPolicyConverterUtils.java | 102 ++++ .../common/XacmlApplicationServiceProvider.java | 98 ++++ .../application/common/XacmlUpdatePolicyUtils.java | 88 ++++ .../application/common/ToscaDictionaryTest.java | 56 +++ .../common/ToscaPolicyConversionExceptionTest.java | 35 ++ .../common/ToscaPolicyConverterUtilsTest.java | 42 ++ .../common/XacmlUpdatePolicyUtilsTest.java | 226 +++++++++ .../common/src/test/resources/test.properties | 32 ++ applications/guard/pom.xml | 52 +++ .../pdp/application/guard/GuardPdpApplication.java | 107 +++++ .../application/guard/GuardPdpApplicationTest.java | 96 ++++ .../guard/src/test/resources/xacml.properties | 37 ++ applications/monitoring/pom.xml | 5 + .../xacml/pdp/engine/OnapXacmlPdpEngine.java | 514 ++++++++++++++++++++- ...lication.common.XacmlApplicationServiceProvider | 1 + .../src/main/resources/RootMonitoringPolicy.xml | 40 +- .../src/test/java/cucumber/Stepdefs.java | 203 +++++++- .../xacml/pdp/engine/OnapXacmlPdpEngineTest.java | 296 ++++++++++++ .../src/test/resources/cucumber/decisions.feature | 14 +- .../test/resources/cucumber/load_policy.feature | 35 ++ .../test.monitoring.policy.badmetadata.1.yaml | 10 + .../test.monitoring.policy.badmetadata.2.yaml | 10 + .../test.monitoring.policy.missingmetadata.yaml | 9 + .../test.monitoring.policy.missingproperties.yaml | 9 + .../test.monitoring.policy.missingtype.yaml | 11 + .../test.monitoring.policy.missingversion.yaml | 11 + .../src/test/resources/unsupportedpolicytype.yaml | 11 + .../resources/vDNS.policy.decision.payload.json | 0 .../src/test/resources/vDNS.policy.input.yaml | 1 + .../monitoring/src/test/resources/vDNS.policy.xml | 44 ++ .../monitoring/src/test/resources/xacml.properties | 34 ++ applications/pom.xml | 2 + main/pom.xml | 10 + .../policy/pdpx/main/rest/XacmlPdpRestServer.java | 43 +- .../pdpx/main/rest/XacmlPdpStatisticsManager.java | 22 + .../onap/policy/pdpx/main/rest/model/Decision.java | 10 +- .../pdpx/main/rest/model/StatisticsReport.java | 21 + .../main/rest/provider/StatisticsProvider.java | 1 + .../parameters/TestXacmlPdpParameterHandler.java | 2 +- .../pdpx/main/rest/TestXacmlPdpRestServer.java | 11 + .../pdpx/main/rest/TestXacmlPdpStatistics.java | 9 + .../onap/policy/pdpx/main/startstop/TestMain.java | 11 + pom.xml | 15 + 48 files changed, 2792 insertions(+), 47 deletions(-) create mode 100644 applications/common/pom.xml create mode 100644 applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/OnapPolicyFinderFactory.java create mode 100644 applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaDictionary.java create mode 100644 applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConversionException.java create mode 100644 applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConverter.java create mode 100644 applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConverterUtils.java create mode 100644 applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlApplicationServiceProvider.java create mode 100644 applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlUpdatePolicyUtils.java create mode 100644 applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/ToscaDictionaryTest.java create mode 100644 applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConversionExceptionTest.java create mode 100644 applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConverterUtilsTest.java create mode 100644 applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/XacmlUpdatePolicyUtilsTest.java create mode 100644 applications/common/src/test/resources/test.properties create mode 100644 applications/guard/pom.xml create mode 100644 applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java create mode 100644 applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java create mode 100644 applications/guard/src/test/resources/xacml.properties create mode 100644 applications/monitoring/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider create mode 100644 applications/monitoring/src/test/java/org/onap/policy/xacml/pdp/engine/OnapXacmlPdpEngineTest.java create mode 100644 applications/monitoring/src/test/resources/cucumber/load_policy.feature create mode 100644 applications/monitoring/src/test/resources/test.monitoring.policy.badmetadata.1.yaml create mode 100644 applications/monitoring/src/test/resources/test.monitoring.policy.badmetadata.2.yaml create mode 100644 applications/monitoring/src/test/resources/test.monitoring.policy.missingmetadata.yaml create mode 100644 applications/monitoring/src/test/resources/test.monitoring.policy.missingproperties.yaml create mode 100644 applications/monitoring/src/test/resources/test.monitoring.policy.missingtype.yaml create mode 100644 applications/monitoring/src/test/resources/test.monitoring.policy.missingversion.yaml create mode 100644 applications/monitoring/src/test/resources/unsupportedpolicytype.yaml create mode 100644 applications/monitoring/src/test/resources/vDNS.policy.decision.payload.json create mode 100644 applications/monitoring/src/test/resources/vDNS.policy.xml create mode 100644 applications/monitoring/src/test/resources/xacml.properties diff --git a/applications/common/pom.xml b/applications/common/pom.xml new file mode 100644 index 00000000..9d83f3d5 --- /dev/null +++ b/applications/common/pom.xml @@ -0,0 +1,46 @@ + + + + 4.0.0 + + org.onap.policy.xacml-pdp.applications + applications + 2.0.0-SNAPSHOT + + + common + + + + junit + junit + test + + + org.onap.policy.common + utils-test + ${policy.common.version} + + + 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 new file mode 100644 index 00000000..1e47c5b5 --- /dev/null +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/OnapPolicyFinderFactory.java @@ -0,0 +1,252 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + + +package org.onap.policy.pdp.xacml.application.common; + +import com.att.research.xacml.std.StdStatusCode; +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.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.dom.DOMPolicyDef; +import com.att.research.xacmlatt.pdp.std.StdPolicyFinder; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implements ONAP specific ability to find Policies for XACML PDP engine. + * + * @author pameladragosh + * + */ +public class OnapPolicyFinderFactory extends PolicyFinderFactory { + + public static final String PROP_FILE = ".file"; + public static final String PROP_URL = ".url"; + + private static Logger logger = LoggerFactory.getLogger(OnapPolicyFinderFactory.class); + private List rootPolicies; + private List referencedPolicies; + private boolean needsInit = true; + + private Properties properties = null; + + /** + * Empty constructor. + */ + public OnapPolicyFinderFactory() { + logger.debug("Constructed without properties"); + // + // Here we differ from the StdPolicyFinderFactory in that we initialize right away. + // We do not wait for a policy request to happen to look for and load policies. + // + this.init(); + } + + /** + * Constructor with properties passed. This will be preferred. + * + * @param properties Properties object + */ + public OnapPolicyFinderFactory(Properties properties) { + super(properties); + logger.debug("Constructed using properties {}", properties); + // + // Save our properties + // + this.properties = properties; + // + // Here we differ from the StdPolicyFinderFactory in that we initialize right away. + // We do not wait for a policy request to happen to look for and load policies. + // + this.init(); + } + + /** + * Loads the PolicyDef for the given String identifier by looking first + * for a ".file" property associated with the ID and using that to load from a File and + * looking for a ".url" property associated with the ID and using that to load from a URL. + * + * @param policyId the String identifier for the policy + * @return a PolicyDef loaded from the given identifier + */ + protected PolicyDef loadPolicyDef(String policyId) { + String propLocation = null; + if (this.properties == null) { + propLocation = XACMLProperties.getProperty(policyId + PROP_FILE); + } else { + propLocation = this.properties.getProperty(policyId + PROP_FILE); + } + if (propLocation != null) { + // + // Try to load it from the file + // + PolicyDef policy = this.loadPolicyFileDef(propLocation); + if (policy != null) { + return policy; + } + } + if (this.properties == null) { + propLocation = XACMLProperties.getProperty(policyId + PROP_URL); + } else { + propLocation = this.properties.getProperty(policyId + PROP_URL); + } + if (propLocation != null) { + PolicyDef policy = this.loadPolicyUrlDef(propLocation); + if (policy != null) { + return policy; + } + } + + logger.error("No known location for Policy {}", policyId); + return null; + } + + protected PolicyDef loadPolicyFileDef(String propLocation) { + File fileLocation = new File(propLocation); + if (!fileLocation.exists()) { + logger.error("Policy file {} does not exist.", fileLocation.getAbsolutePath()); + return null; + } + if (!fileLocation.canRead()) { + logger.error("Policy file {} cannot be read.", fileLocation.getAbsolutePath()); + return null; + } + try { + logger.info("Loading policy file {}", fileLocation); + PolicyDef policyDef = DOMPolicyDef.load(fileLocation); + if (policyDef != null) { + return policyDef; + } + return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "DOM Could not load policy"); + } catch (DOMStructureException ex) { + logger.error("Error loading policy file {}: {}", fileLocation.getAbsolutePath(), ex); + return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + } + } + + protected PolicyDef loadPolicyUrlDef(String propLocation) { + InputStream is = null; + try { + URL url = new URL(propLocation); + URLConnection urlConnection = url.openConnection(); + OnapPolicyFinderFactory.logger.info("Loading policy file {}", url); + is = urlConnection.getInputStream(); + PolicyDef policyDef = DOMPolicyDef.load(is); + if (policyDef != null) { + return policyDef; + } + } catch (MalformedURLException ex) { + logger.error("Invalid URL " + propLocation + ": " + ex.getMessage(), ex); + } catch (IOException ex) { + logger.error("IOException opening URL {}: {}{}", + propLocation, ex.getMessage(), ex); + } catch (DOMStructureException ex) { + logger.error("Invalid Policy " + propLocation + ": " + ex.getMessage(), ex); + return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + logger.error("Exception closing InputStream for GET of url {}: {}", + propLocation, e.getMessage() + " (May be memory leak)", e); + } + } + } + return null; + } + + /** + * Finds the identifiers for all of the policies referenced by the given property name in the + * XACMLProperties and loads them using the requested loading method. + * + * @param propertyName the String name of the property containing the list of policy identifiers + * @return a List of PolicyDefs loaded from the given property name + */ + protected List getPolicyDefs(String propertyName) { + String policyIds; + if (this.properties != null) { + policyIds = this.properties.getProperty(propertyName); + } else { + policyIds = XACMLProperties.getProperty(propertyName); + } + if (Strings.isNullOrEmpty(policyIds)) { + return Collections.emptyList(); + } + + Iterable policyIdArray = Splitter.on(',').trimResults().omitEmptyStrings().split(policyIds); + if (policyIdArray == null) { + return Collections.emptyList(); + } + + List listPolicyDefs = new ArrayList<>(); + for (String policyId : policyIdArray) { + PolicyDef policyDef = this.loadPolicyDef(policyId); + if (policyDef != null) { + listPolicyDefs.add(policyDef); + } + } + return listPolicyDefs; + } + + protected synchronized void init() { + if (this.needsInit) { + logger.debug("Initializing OnapPolicyFinderFactory Properties "); + 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()); + this.needsInit = false; + } + } + + @Override + public PolicyFinder getPolicyFinder() throws FactoryException { + // + // Force using any properties that were passed upon construction + // + return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, this.properties); + } + + @Override + public PolicyFinder getPolicyFinder(Properties properties) throws FactoryException { + return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, properties); + } + +} 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 new file mode 100644 index 00000000..c65d7a17 --- /dev/null +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaDictionary.java @@ -0,0 +1,69 @@ +/*- + * ============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 com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.IdentifierImpl; + +public final class ToscaDictionary { + + private ToscaDictionary() { + super(); + } + + /* + * These are the ID's for various TOSCA Policy Types we are supporting in the Applications. + */ + public static final Identifier URN_ONAP = + new IdentifierImpl("urn:org:onap"); + + public static final Identifier ID_RESOURCE_POLICY_ID = + XACML3.ID_RESOURCE_RESOURCE_ID; + + public static final Identifier ID_RESOURCE_POLICY_TYPE = + new IdentifierImpl(URN_ONAP, "policy-type"); + + public static final Identifier ID_RESOURCE_POLICY_TYPE_VERSION = + new IdentifierImpl(URN_ONAP, "policy-type-version"); + + public static final Identifier ID_OBLIGATION_REST_BODY = + new IdentifierImpl(URN_ONAP, "rest:body"); + + public static final Identifier ID_OBLIGATION_POLICY_MONITORING = + new IdentifierImpl(URN_ONAP, ":obligation:monitoring"); + + public static final Identifier ID_OBLIGATION_POLICY_MONITORING_CONTENTS = + new IdentifierImpl(URN_ONAP, ":obligation:monitoring:contents"); + + public static final Identifier ID_OBLIGATION_POLICY_MONITORING_CATEGORY = + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE; + + public static final Identifier ID_OBLIGATION_POLICY_MONITORING_DATATYPE = + XACML3.ID_DATATYPE_STRING; + + public static final Identifier ID_OBLIGATION_ISSUER = + new IdentifierImpl(URN_ONAP, "issuer:monitoring"); + + +} diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConversionException.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConversionException.java new file mode 100644 index 00000000..071a14e1 --- /dev/null +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConversionException.java @@ -0,0 +1,50 @@ +/*- + * ============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; + +public class ToscaPolicyConversionException extends Exception { + + private static final long serialVersionUID = 1L; + + public ToscaPolicyConversionException() { + super(); + } + + public ToscaPolicyConversionException(String message) { + super(message); + } + + public ToscaPolicyConversionException(Throwable cause) { + super(cause); + } + + public ToscaPolicyConversionException(String message, Throwable cause) { + super(message, cause); + } + + public ToscaPolicyConversionException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConverter.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConverter.java new file mode 100644 index 00000000..f6f75a4c --- /dev/null +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConverter.java @@ -0,0 +1,36 @@ +/*- + * ============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.io.InputStream; +import java.util.List; +import java.util.Map; + +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; + +public interface ToscaPolicyConverter { + + List convertPolicies(InputStream isToscaPolicy) throws ToscaPolicyConversionException; + + List convertPolicies(Map toscaObject) throws ToscaPolicyConversionException; +} diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConverterUtils.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConverterUtils.java new file mode 100644 index 00000000..cd197935 --- /dev/null +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConverterUtils.java @@ -0,0 +1,102 @@ +/*- + * ============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 com.att.research.xacml.api.Identifier; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType; +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.MatchType; + +/** + * This class contains static methods of helper classes to convert TOSCA policies + * into XACML policies. + * + * @author pameladragosh + * + */ +public final class ToscaPolicyConverterUtils { + + private ToscaPolicyConverterUtils() { + super(); + } + + /** + * This method builds a MatchType for TargetType object for AttributeValue and AttributeDesignator + * combination. + * + * @param Incoming value could be any object + * @param function Function for the Match + * @param value Attribute value used + * @param datatype Datatype for attribute value and AttributeDesignator + * @param designatorId ID for the AttributeDesignator + * @param designatorCategory Category ID for the AttributeDesignator + * @return The MatchType object + */ + public static MatchType buildMatchTypeDesignator(Identifier function, + T value, + Identifier datatype, + Identifier designatorId, + Identifier designatorCategory) { + // + // Create the MatchType object and set its function + // + MatchType match = new MatchType(); + match.setMatchId(function.stringValue()); + // + // Add in the AttributeValue object + // + AttributeValueType valueType = new AttributeValueType(); + valueType.setDataType(datatype.stringValue()); + valueType.getContent().add(value); + + match.setAttributeValue(valueType); + // + // Add in the AttributeDesignator object + // + AttributeDesignatorType designator = new AttributeDesignatorType(); + designator.setAttributeId(designatorId.stringValue()); + designator.setCategory(designatorCategory.stringValue()); + designator.setDataType(datatype.stringValue()); + + match.setAttributeDesignator(designator); + // + // Done + // + return match; + } + + /** + * Builds an AllOfType (AND) with one or more MatchType objects. + * + * @param matches A list of one or more MatchType + * @return The AllOf object + */ + public static AllOfType buildAllOf(MatchType... matches) { + AllOfType allOf = new AllOfType(); + for (MatchType match : matches) { + allOf.getMatch().add(match); + } + return allOf; + } +} 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 new file mode 100644 index 00000000..65648ea8 --- /dev/null +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlApplicationServiceProvider.java @@ -0,0 +1,98 @@ +/* ============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.nio.file.Path; +import java.util.List; +import java.util.Map; + +import org.json.JSONObject; + +/** + * This interface is how the XACML REST controller can communicate + * with Policy Type implementation applications. + * Applications should register themselves as this service provider + * and implement these methods. + * + * @author pameladragosh + * + */ +public interface XacmlApplicationServiceProvider { + + /** + * Name of the application for auditing and organization of its data. + * + * @return String + */ + String applicationName(); + + /** + * Returns a list of action decisions supported by the application. + * + * @return List of String (eg. "configure", "placement", "naming") + */ + List actionDecisionsSupported(); + + /** + * Initializes the application and gives it a Path for storing its + * data. The Path may be already populated with previous data. + * + * @param pathForData Local Path + */ + void initialize(Path pathForData); + + /** + * Returns a list of supported Tosca Policy Types. + * + * @return List of Strings (eg. "onap.policy.foo.bar") + */ + List supportedPolicyTypes(); + + /** + * Asks whether the application can support the incoming + * Tosca Policy Type and version. + * + * @param policyType String Tosca Policy Type + * @param policyTypeVersion String of the Tosca Policy Type version + * @return true if supported + */ + boolean canSupportPolicyType(String policyType, String policyTypeVersion); + + /** + * Load a Map representation of a Tosca Policy. + * + * @param toscaPolicies Map of Tosca Policy Objects + */ + void loadPolicies(Map toscaPolicies); + + /** + * Makes a decision given the incoming request and returns a response. + * + *

NOTE: I may want to change this to an object that represents the + * schema. + * + * @param jsonSchema Incoming Json + * @return response + */ + JSONObject makeDecision(JSONObject jsonSchema); + +} diff --git a/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlUpdatePolicyUtils.java b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlUpdatePolicyUtils.java new file mode 100644 index 00000000..957242c5 --- /dev/null +++ b/applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/XacmlUpdatePolicyUtils.java @@ -0,0 +1,88 @@ +/*- + * ============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 oasis.names.tc.xacml._3_0.core.schema.wd_17.IdReferenceType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; + +public class XacmlUpdatePolicyUtils { + + private XacmlUpdatePolicyUtils() { + super(); + } + + /** + * This method updates a root PolicySetType by adding in a PolicyType as a reference. + * + * @param rootPolicy Root PolicySet being updated + * @param referencedPolicies A list of PolicyType being added as a references + * @return the rootPolicy PolicySet object + */ + public static PolicySetType updateXacmlRootPolicy(PolicySetType rootPolicy, PolicyType... referencedPolicies) { + ObjectFactory factory = new ObjectFactory(); + // + // Iterate each policy + // + for (PolicyType referencedPolicy : referencedPolicies) { + IdReferenceType reference = new IdReferenceType(); + reference.setValue(referencedPolicy.getPolicyId()); + // + // Add it in + // + rootPolicy.getPolicySetOrPolicyOrPolicySetIdReference().add(factory.createPolicySetIdReference(reference)); + } + // + // Return the updated object + // + return rootPolicy; + } + + /** + * This method updates a root PolicySetType by adding in a PolicyType as a reference. + * + * @param rootPolicy Root PolicySet being updated + * @param referencedPolicySets A list of PolicySetType being added as a references + * @return the rootPolicy PolicySet object + */ + public static PolicySetType updateXacmlRootPolicy(PolicySetType rootPolicy, PolicySetType... referencedPolicySets) { + ObjectFactory factory = new ObjectFactory(); + // + // Iterate each policy + // + for (PolicySetType referencedPolicySet : referencedPolicySets) { + IdReferenceType reference = new IdReferenceType(); + reference.setValue(referencedPolicySet.getPolicySetId()); + // + // Add it in + // + rootPolicy.getPolicySetOrPolicyOrPolicySetIdReference().add(factory.createPolicySetIdReference(reference)); + } + // + // Return the updated object + // + return rootPolicy; + } + +} diff --git a/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/ToscaDictionaryTest.java b/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/ToscaDictionaryTest.java new file mode 100644 index 00000000..d427982f --- /dev/null +++ b/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/ToscaDictionaryTest.java @@ -0,0 +1,56 @@ +/*- + * ============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 static org.assertj.core.api.Assertions.assertThatCode; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; + +import org.junit.Test; + +public class ToscaDictionaryTest { + + @Test + public void testConstructorIsProtected() throws Exception { + // + // Ensure that this is static class + // + final Constructor constructor = ToscaDictionary.class.getDeclaredConstructor(); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + // + // Trying to get 100% code coverage + // + assertThatCode(() -> { + constructor.setAccessible(true); + constructor.newInstance(); + }).doesNotThrowAnyException(); + // + // Probably don't need these as these ID's are used by other components + // + assertNotNull(ToscaDictionary.ID_OBLIGATION_ISSUER); + } + +} diff --git a/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConversionExceptionTest.java b/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConversionExceptionTest.java new file mode 100644 index 00000000..bee4ba3d --- /dev/null +++ b/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConversionExceptionTest.java @@ -0,0 +1,35 @@ +/* + * ============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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pdp.xacml.application.common; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.onap.policy.common.utils.test.ExceptionsTester; + +public class ToscaPolicyConversionExceptionTest { + + @Test + public void test() { + assertEquals(5, new ExceptionsTester().test(ToscaPolicyConversionException.class)); + } + +} diff --git a/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConverterUtilsTest.java b/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConverterUtilsTest.java new file mode 100644 index 00000000..cc1787c3 --- /dev/null +++ b/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyConverterUtilsTest.java @@ -0,0 +1,42 @@ +/*- + * ============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 static org.junit.Assert.assertTrue; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; + +import org.junit.Test; + +public class ToscaPolicyConverterUtilsTest { + + @Test + public void test() throws NoSuchMethodException, SecurityException { + final Constructor constructor + = ToscaPolicyConverterUtils.class.getDeclaredConstructor(); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + + } + +} diff --git a/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/XacmlUpdatePolicyUtilsTest.java b/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/XacmlUpdatePolicyUtilsTest.java new file mode 100644 index 00000000..84fefa5c --- /dev/null +++ b/applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/XacmlUpdatePolicyUtilsTest.java @@ -0,0 +1,226 @@ +/*- + * ============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 static org.assertj.core.api.Assertions.assertThatCode; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.util.XACMLPolicyWriter; +import com.att.research.xacml.util.XACMLProperties; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map.Entry; +import java.util.Properties; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType; +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.PolicySetType; +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.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utility methods for storing policies to disk and updating Properties objects + * that reference policies. + * + * @author pameladragosh + * + */ +public class XacmlUpdatePolicyUtilsTest { + private static final Logger LOGGER = LoggerFactory.getLogger(XacmlUpdatePolicyUtilsTest.class); + + static Properties properties; + + static PolicySetType rootPolicy = new PolicySetType(); + + static Path rootPath; + + static PolicyType policy1 = new PolicyType(); + static PolicyType policy2 = new PolicyType(); + + static PolicySetType policySet3 = new PolicySetType(); + + static Path path1; + static Path path2; + + static Path policySetPath; + + /** + * Temporary folder where we will store newly created policies. + */ + @ClassRule + public static TemporaryFolder policyFolder = new TemporaryFolder(); + + /** + * Setup the JUnit tests. + * + * @throws Exception thrown + */ + @BeforeClass + public static void setUp() throws Exception { + assertThatCode(() -> { + // + // Load our test property object + // + try (InputStream is = new FileInputStream("src/test/resources/test.properties")) { + properties = new Properties(); + properties.load(is); + } + // + // Create a very basic Root policy + // + rootPolicy.setPolicySetId("root"); + rootPolicy.setTarget(new TargetType()); + rootPolicy.setPolicyCombiningAlgId(XACML3.ID_POLICY_FIRST_APPLICABLE.stringValue()); + File rootFile = policyFolder.newFile("root.xml"); + LOGGER.info("Creating Root Policy {}", rootFile.getAbsolutePath()); + rootPath = XACMLPolicyWriter.writePolicyFile(rootFile.toPath(), rootPolicy); + // + // Create policies + // + path1 = createPolicy(policy1, "policy1", "resource1"); + LOGGER.info(new String(Files.readAllBytes(path1))); + path2 = createPolicy(policy2, "policy2", "resource2"); + LOGGER.info(new String(Files.readAllBytes(path2))); + // + // Create another PolicySet + // + policySet3.setPolicySetId("policyset1"); + policySet3.setTarget(new TargetType()); + policySet3.setPolicyCombiningAlgId(XACML3.ID_POLICY_FIRST_APPLICABLE.stringValue()); + ObjectFactory factory = new ObjectFactory(); + + policySet3.getPolicySetOrPolicyOrPolicySetIdReference().add(factory.createPolicy(policy1)); + policySet3.getPolicySetOrPolicyOrPolicySetIdReference().add(factory.createPolicy(policy2)); + File policySetFile = policyFolder.newFile("policySet1.xml"); + LOGGER.info("Creating PolicySet {}", policySetFile.getAbsolutePath()); + policySetPath = XACMLPolicyWriter.writePolicyFile(policySetFile.toPath(), policySet3); + + }).doesNotThrowAnyException(); + } + + private static Path createPolicy(PolicyType policy, String id, String resource) throws IOException { + // + // Create Policy 1 + // + policy.setPolicyId(id); + MatchType matchPolicyId = ToscaPolicyConverterUtils.buildMatchTypeDesignator( + XACML3.ID_FUNCTION_STRING_EQUAL, + resource, + XACML3.ID_DATATYPE_STRING, + XACML3.ID_RESOURCE_RESOURCE_ID, + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + // + // This is our outer AnyOf - which is an OR + // + AnyOfType anyOf = new AnyOfType(); + // + // Create AllOf (AND) of just Policy Id + // + anyOf.getAllOf().add(ToscaPolicyConverterUtils.buildAllOf(matchPolicyId)); + TargetType target = new TargetType(); + target.getAnyOf().add(anyOf); + policy.setTarget(target); + RuleType rule = new RuleType(); + rule.setRuleId(policy.getPolicyId() + ":rule"); + rule.setEffect(EffectType.PERMIT); + rule.setTarget(new TargetType()); + // + // Add the rule to the policy + // + policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule); + // + // Create a file + // + File file = policyFolder.newFile(policy.getPolicyId() + ".xml"); + LOGGER.info("Creating Policy {}", file.getAbsolutePath()); + return XACMLPolicyWriter.writePolicyFile(file.toPath(), policy); + } + + @Test + public void test() { + assertThatCode(() -> { + // + // Just update root and policies + // + XacmlUpdatePolicyUtils.updateXacmlRootPolicy(rootPolicy, policy1, policy2); + try (OutputStream os = new ByteArrayOutputStream()) { + XACMLPolicyWriter.writePolicyFile(os, rootPolicy); + LOGGER.debug("New Root Policy:{}{}", System.lineSeparator(), os.toString()); + } + // + // Test updating the properties + // + XACMLProperties.setXacmlRootProperties(properties, rootPath); + XACMLProperties.setXacmlReferencedProperties(properties, path1, path2); + // + // Dump this out so I can see what I'm doing + // + for (Entry entry : properties.entrySet()) { + LOGGER.info("{}={}", entry.getKey(), entry.getValue()); + } + LOGGER.info("Properties {}", properties.toString()); + // + // Somehow I have to figure out how to test this in assertj + // + // + // Just update root and PolicySet + // + XacmlUpdatePolicyUtils.updateXacmlRootPolicy(rootPolicy, policySet3); + try (OutputStream os = new ByteArrayOutputStream()) { + XACMLPolicyWriter.writePolicyFile(os, rootPolicy); + LOGGER.debug("New Root Policy:{}{}", System.lineSeparator(), os.toString()); + } + // + // Test updating the properties + // + XACMLProperties.setXacmlRootProperties(properties, rootPath); + XACMLProperties.setXacmlReferencedProperties(properties, policySetPath); + // + // Dump this out so I can see what I'm doing + // + for (Entry entry : properties.entrySet()) { + LOGGER.info("{}={}", entry.getKey(), entry.getValue()); + } + LOGGER.info("Properties {}", properties.toString()); + // + // Somehow I have to figure out how to test this in assertj + // + + }).doesNotThrowAnyException(); + } +} diff --git a/applications/common/src/test/resources/test.properties b/applications/common/src/test/resources/test.properties new file mode 100644 index 00000000..efe90d82 --- /dev/null +++ b/applications/common/src/test/resources/test.properties @@ -0,0 +1,32 @@ +# +# 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 + +# +# +# +xacml.rootPolicies=rootstart +rootstart.file=src/test/resources/root.xml + +xacml.referencedPolicies=refstart1,refstart2,refstart3,refstart4 +refstart1.file=src/test/resources/ref1.xml +refstart2.file=src/test/resources/ref2.xml +refstart3.file=src/test/resources/ref3.xml +refstart4.file=src/test/resources/ref4.xml diff --git a/applications/guard/pom.xml b/applications/guard/pom.xml new file mode 100644 index 00000000..7ee3da08 --- /dev/null +++ b/applications/guard/pom.xml @@ -0,0 +1,52 @@ + + + + 4.0.0 + + org.onap.policy.xacml-pdp.applications + applications + 2.0.0-SNAPSHOT + + + guard + + ${project.artifactId} + This modules contain an application that implements onap.Guard policy-types for XACML PDP. + + + + com.google.code.gson + gson + + + org.onap.policy.common + common-parameters + ${policy.common.version} + + + org.onap.policy.xacml-pdp.applications + common + ${project.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 new file mode 100644 index 00000000..e8a51136 --- /dev/null +++ b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java @@ -0,0 +1,107 @@ +/*- + * ============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.google.common.collect.Lists; + +import java.nio.file.Path; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.json.JSONObject; +import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class implements the onap.policies.controlloop.Guard policy implementations. + * + * @author pameladragosh + * + */ +public class GuardPdpApplication implements XacmlApplicationServiceProvider { + + private static final Logger LOGGER = LoggerFactory.getLogger(GuardPdpApplication.class); + private static final String STRING_VERSION100 = "1.0.0"; + private Map supportedPolicyTypes = new HashMap<>(); + private Path pathForData; + + /** Constructor. + * + */ + public GuardPdpApplication() { + this.supportedPolicyTypes.put("onap.policies.controlloop.guard.FrequencyLimiter", STRING_VERSION100); + this.supportedPolicyTypes.put("onap.policies.controlloop.guard.MinMax", STRING_VERSION100); + } + + @Override + public String applicationName() { + return "Guard Application"; + } + + @Override + public List actionDecisionsSupported() { + return Arrays.asList("guard"); + } + + @Override + public void initialize(Path pathForData) { + // + // Save the path + // + this.pathForData = pathForData; + LOGGER.debug("New Path is {}", this.pathForData.toAbsolutePath()); + } + + @Override + public List 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 void loadPolicies(Map toscaPolicies) { + } + + @Override + public JSONObject makeDecision(JSONObject jsonSchema) { + return null; + } + +} 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 new file mode 100644 index 00000000..656c7275 --- /dev/null +++ b/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java @@ -0,0 +1,96 @@ +/*- + * ============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 static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; + +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 org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +public class GuardPdpApplicationTest { + + @ClassRule + public static final TemporaryFolder policyFolder = new TemporaryFolder(); + + /** + * This is a simple annotation class to simulate + * requests coming in. + */ + @XACMLRequest(ReturnPolicyIdList = true) + public class MyXacmlRequest { + + @XACMLSubject(includeInResults = true) + String onapName = "Drools"; + + @XACMLResource(includeInResults = true) + String resource = "onap.policies.Guard"; + + @XACMLAction() + String action = "guard"; + } + + @Before + public void setUp() throws Exception { + + } + + @Test + public void testBasics() { + assertThatCode(() -> { + GuardPdpApplication guard = new GuardPdpApplication(); + // + // Set the path + // + guard.initialize(policyFolder.getRoot().toPath()); + // + // Application name + // + assertThat(guard.applicationName()).isNotEmpty(); + // + // Decisions + // + assertThat(guard.actionDecisionsSupported().size()).isEqualTo(1); + assertThat(guard.actionDecisionsSupported()).contains("guard"); + // + // Supported policy types + // + assertThat(guard.supportedPolicyTypes()).isNotEmpty(); + assertThat(guard.supportedPolicyTypes().size()).isEqualTo(2); + assertThat(guard.canSupportPolicyType("onap.policies.controlloop.guard.FrequencyLimiter", "1.0.0")) + .isTrue(); + assertThat(guard.canSupportPolicyType("onap.policies.controlloop.guard.FrequencyLimiter", "1.0.1")) + .isFalse(); + assertThat(guard.canSupportPolicyType("onap.policies.controlloop.guard.MinMax", "1.0.0")).isTrue(); + assertThat(guard.canSupportPolicyType("onap.policies.controlloop.guard.MinMax", "1.0.1")).isFalse(); + assertThat(guard.canSupportPolicyType("onap.foo", "1.0.1")).isFalse(); + }).doesNotThrowAnyException(); + } +} diff --git a/applications/guard/src/test/resources/xacml.properties b/applications/guard/src/test/resources/xacml.properties new file mode 100644 index 00000000..b32a936c --- /dev/null +++ b/applications/guard/src/test/resources/xacml.properties @@ -0,0 +1,37 @@ +# +# 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 + +# +# ONAP Implementation Factories +# +#xacml.att.policyFinderFactory=org.onap.policy.pdp.xacml.application.common.OnapApplicationPolicyFinder + +# +# 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 + diff --git a/applications/monitoring/pom.xml b/applications/monitoring/pom.xml index 6da9749d..018c3722 100644 --- a/applications/monitoring/pom.xml +++ b/applications/monitoring/pom.xml @@ -42,6 +42,11 @@ common-parameters ${policy.common.version} + + org.onap.policy.xacml-pdp.applications + common + ${project.version} + diff --git a/applications/monitoring/src/main/java/org/onap/policy/xacml/pdp/engine/OnapXacmlPdpEngine.java b/applications/monitoring/src/main/java/org/onap/policy/xacml/pdp/engine/OnapXacmlPdpEngine.java index c6719ecb..6c53566a 100644 --- a/applications/monitoring/src/main/java/org/onap/policy/xacml/pdp/engine/OnapXacmlPdpEngine.java +++ b/applications/monitoring/src/main/java/org/onap/policy/xacml/pdp/engine/OnapXacmlPdpEngine.java @@ -22,6 +22,518 @@ package org.onap.policy.xacml.pdp.engine; -public class OnapXacmlPdpEngine { +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.Response; +import com.att.research.xacml.api.XACML3; +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.XACMLPolicyScanner; +import com.att.research.xacml.util.XACMLProperties; +import com.google.common.collect.Lists; + +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.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.Set; + +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.PolicySetType; +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.pdp.xacml.application.common.ToscaDictionary; +import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException; +import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConverter; +import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConverterUtils; +import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider; +import org.onap.policy.pdp.xacml.application.common.XacmlUpdatePolicyUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; + +/** + * This is the engine class that manages the instance of the XACML PDP engine. + * + *

It is responsible for initializing it and shutting it down properly in a thread-safe manner. + * + * + * @author pameladragosh + * + */ +public class OnapXacmlPdpEngine implements ToscaPolicyConverter, XacmlApplicationServiceProvider { + + private static final Logger LOGGER = LoggerFactory.getLogger(OnapXacmlPdpEngine.class); + private static final String ONAP_MONITORING_BASE_POLICY_TYPE = "onap.Monitoring"; + private static final String ONAP_MONITORING_DERIVED_POLICY_TYPE = "onap.policies.monitoring"; + + + private Path pathForData = null; + private Properties pdpProperties = null; + private PDPEngine pdpEngine = null; + private Map supportedPolicyTypes = new HashMap<>(); + + /** + * Constructor. + */ + public OnapXacmlPdpEngine() { + // + // By default this supports just Monitoring policy types + // + supportedPolicyTypes.put(ONAP_MONITORING_BASE_POLICY_TYPE, "1.0.0"); + } + + /** + * Load properties from given file. + * + * @param location Path and filename + * @throws IOException If unable to read file + */ + public synchronized void loadXacmlProperties(String location) throws IOException { + try (InputStream is = new FileInputStream(location)) { + pdpProperties.load(is); + } + } + + /** + * Stores the XACML Properties to the given file location. + * + * @param location File location including name + * @throws IOException If unable to store the file. + */ + public synchronized void storeXacmlProperties(String location) throws IOException { + try (OutputStream os = new FileOutputStream(location)) { + String strComments = "#"; + pdpProperties.store(os, strComments); + } + } + + /** + * Make a decision call. + * + * @param request Incoming request object + * @return Response object + */ + public synchronized Response decision(Request request) { + // + // This is what we need to return + // + Response response = null; + // + // Track some timing + // + long timeStart = System.currentTimeMillis(); + try { + response = this.pdpEngine.decide(request); + } catch (PDPException e) { + LOGGER.error("{}", e); + } finally { + // + // Track the end of timing + // + long timeEnd = System.currentTimeMillis(); + LOGGER.info("Elapsed Time: {}ms", (timeEnd - timeStart)); + } + return response; + } + + @Override + public String applicationName() { + return "Monitoring Application"; + } + + @Override + public List actionDecisionsSupported() { + return Arrays.asList("configure"); + } + + @Override + public synchronized void initialize(Path pathForData) { + // + // Save our path + // + this.pathForData = pathForData; + LOGGER.debug("New Path is {}", this.pathForData.toAbsolutePath()); + // + // Look for and load the properties object + // + Path propertyPath = Paths.get(this.pathForData.toAbsolutePath().toString(), "xacml.properties"); + LOGGER.debug("Looking for {}", propertyPath.toAbsolutePath()); + try (InputStream is = new FileInputStream(propertyPath.toAbsolutePath().toString()) ) { + // + // Create a new properties object + // + pdpProperties = new Properties(); + // + // Load it with our values + // + pdpProperties.load(is); + LOGGER.debug("{}", pdpProperties); + } catch (IOException e) { + LOGGER.error("{}", e); + } + // + // Now initialize the XACML PDP Engine + // + try { + PDPEngineFactory factory = PDPEngineFactory.newInstance(); + this.pdpEngine = factory.newEngine(pdpProperties); + } catch (FactoryException e) { + LOGGER.error("{}", e); + } + } + + @Override + public synchronized List supportedPolicyTypes() { + return Lists.newArrayList(supportedPolicyTypes.keySet()); + } + + @Override + public boolean canSupportPolicyType(String policyType, String policyTypeVersion) { + // + // For Monitoring, we will attempt to support all versions + // of the policy type. Since we are only packaging a decision + // back with a JSON payload of the property contents. + // + return (policyType.equals(ONAP_MONITORING_BASE_POLICY_TYPE) + || policyType.startsWith(ONAP_MONITORING_DERIVED_POLICY_TYPE)); + } + + @Override + public synchronized void loadPolicies(Map toscaPolicies) { + // + // + // + try { + // + // Convert the policies first + // + List listPolicies = this.convertPolicies(toscaPolicies); + if (listPolicies.isEmpty()) { + throw new ToscaPolicyConversionException("Converted 0 policies"); + } + // + // Read in our Root Policy + // + Set roots = XACMLProperties.getRootPolicyIDs(pdpProperties); + if (roots.isEmpty()) { + throw new ToscaPolicyConversionException("There are NO root policies defined"); + } + // + // Really only should be one + // + String rootFile = pdpProperties.getProperty(roots.iterator().next() + ".file"); + try (InputStream is = new FileInputStream(rootFile)) { + Object policyData = XACMLPolicyScanner.readPolicy(is); + // + // Should be a PolicySet + // + if (policyData instanceof PolicySetType) { + PolicyType[] newPolicies = listPolicies.toArray(new PolicyType[listPolicies.size()]); + PolicySetType newRootPolicy = + XacmlUpdatePolicyUtils.updateXacmlRootPolicy((PolicySetType) policyData, newPolicies); + // + // Save the new Policies to disk + // + + // + // Save the root policy to disk + // + + // + // Update properties to declare the referenced policies + // + + // + // Write the policies to disk + // + + } else { + throw new ToscaPolicyConversionException("Root policy isn't a PolicySet"); + } + } + // + // Add to the root policy + // + } catch (IOException | ToscaPolicyConversionException e) { + LOGGER.error("Failed to loadPolicies {}", e); + } + } + + @Override + public synchronized JSONObject makeDecision(JSONObject jsonSchema) { + return null; + } + + @Override + public List convertPolicies(Map toscaObject) throws ToscaPolicyConversionException { + // + // Return the policies + // + return scanAndConvertPolicies(toscaObject); + } + + @Override + public List convertPolicies(InputStream isToscaPolicy) throws ToscaPolicyConversionException { + // + // Have snakeyaml parse the object + // + Yaml yaml = new Yaml(); + Map toscaObject = yaml.load(isToscaPolicy); + // + // Return the policies + // + return scanAndConvertPolicies(toscaObject); + } + + @SuppressWarnings("unchecked") + private List scanAndConvertPolicies(Map toscaObject) + throws ToscaPolicyConversionException { + // + // Our return object + // + List scannedPolicies = new ArrayList<>(); + // + // Iterate each of the Policies + // + List policies = (List) toscaObject.get("policies"); + for (Object policyObject : policies) { + // + // Get the contents + // + LOGGER.debug("Found policy {}", policyObject.getClass()); + Map policyContents = (Map) policyObject; + for (Entry entrySet : policyContents.entrySet()) { + LOGGER.info("Entry set {}", entrySet); + // + // Convert this policy + // + PolicyType policy = this.convertPolicy(entrySet); + // + // Convert and add in the new policy + // + scannedPolicies.add(policy); + } + } + + return scannedPolicies; + } + + @SuppressWarnings("unchecked") + private PolicyType convertPolicy(Entry entrySet) throws ToscaPolicyConversionException { + // + // Policy name should be at the root + // + String policyName = entrySet.getKey(); + Map policyDefinition = (Map) 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) policyDefinition.get("metadata")); + // + // Set the combining rule + // + newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_FIRST_APPLICABLE.stringValue()); + // + // Generate the TargetType + // + // + // There should be a metadata section + // + 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()); + // + // There should be properties section - this data ends up as a + // JSON BLOB that is returned back to calling application. + // + if (! policyDefinition.containsKey("properties")) { + throw new ToscaPolicyConversionException(policyName + " missing properties section"); + } + addObligation(rule, + (Map) policyDefinition.get("properties")); + // + // 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 + */ + private PolicyType fillMetadataSection(PolicyType policy, + Map 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; + } + + private TargetType generateTargetType(String policyId, String policyType, String policyTypeVersion) { + // + // Create all the match's that are possible + // + // This is for the Policy Id + // + MatchType matchPolicyId = ToscaPolicyConverterUtils.buildMatchTypeDesignator( + XACML3.ID_FUNCTION_STRING_EQUAL, + policyId, + XACML3.ID_DATATYPE_STRING, + ToscaDictionary.ID_RESOURCE_POLICY_ID, + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + // + // This is for the Policy Type + // + MatchType matchPolicyType = ToscaPolicyConverterUtils.buildMatchTypeDesignator( + XACML3.ID_FUNCTION_STRING_EQUAL, + policyType, + XACML3.ID_DATATYPE_STRING, + ToscaDictionary.ID_RESOURCE_POLICY_TYPE, + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + // + // This is for the Policy Type version + // + MatchType matchPolicyTypeVersion = ToscaPolicyConverterUtils.buildMatchTypeDesignator( + XACML3.ID_FUNCTION_STRING_EQUAL, + policyTypeVersion, + XACML3.ID_DATATYPE_STRING, + ToscaDictionary.ID_RESOURCE_POLICY_TYPE_VERSION, + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + // + // This is our outer AnyOf - which is an OR + // + AnyOfType anyOf = new AnyOfType(); + // + // Create AllOf (AND) of just Policy Id + // + anyOf.getAllOf().add(ToscaPolicyConverterUtils.buildAllOf(matchPolicyId)); + // + // Create AllOf (AND) of just Policy Type + // + anyOf.getAllOf().add(ToscaPolicyConverterUtils.buildAllOf(matchPolicyType)); + // + // Create AllOf (AND) of Policy Type and Policy Type Version + // + anyOf.getAllOf().add(ToscaPolicyConverterUtils.buildAllOf(matchPolicyType, matchPolicyTypeVersion)); + // + // Now we can create the TargetType, add the top-level anyOf (OR), + // and return the value. + // + TargetType target = new TargetType(); + target.getAnyOf().add(anyOf); + return target; + } + + private RuleType addObligation(RuleType rule, Map properties) { + // + // Convert the YAML Policy to JSON Object + // + JSONObject jsonObject = new JSONObject(properties); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("JSON conversion {}{}", System.lineSeparator(), jsonObject); + } + // + // Create an AttributeValue for it + // + AttributeValueType value = new AttributeValueType(); + value.setDataType(ToscaDictionary.ID_OBLIGATION_POLICY_MONITORING_DATATYPE.stringValue()); + value.getContent().add(jsonObject.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/monitoring/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider b/applications/monitoring/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider new file mode 100644 index 00000000..5c8dd5e6 --- /dev/null +++ b/applications/monitoring/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider @@ -0,0 +1 @@ +org.onap.policy.xacml.pdp.engine.OnapXacmlPdpEngine \ No newline at end of file diff --git a/applications/monitoring/src/main/resources/RootMonitoringPolicy.xml b/applications/monitoring/src/main/resources/RootMonitoringPolicy.xml index 3ac716e8..33b28815 100644 --- a/applications/monitoring/src/main/resources/RootMonitoringPolicy.xml +++ b/applications/monitoring/src/main/resources/RootMonitoringPolicy.xml @@ -1,5 +1,5 @@ - - + + The root policy for supporting in-memory onap.Monitoring policy-type policies. @@ -19,24 +19,18 @@ - - PERMIT - TO BE FILLED IN - - - - - John - - - - ACCESS - - - - - - - - Default is DENY - - + + + Default is to allow a permit - returning 0 obligations + + + + + + \ No newline at end of file diff --git a/applications/monitoring/src/test/java/cucumber/Stepdefs.java b/applications/monitoring/src/test/java/cucumber/Stepdefs.java index 6915afdb..ca5efa46 100644 --- a/applications/monitoring/src/test/java/cucumber/Stepdefs.java +++ b/applications/monitoring/src/test/java/cucumber/Stepdefs.java @@ -22,27 +22,204 @@ package cucumber; +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 cucumber.api.java.en.Given; import cucumber.api.java.en.Then; import cucumber.api.java.en.When; +import org.junit.ClassRule; +import org.junit.rules.TemporaryFolder; + public class Stepdefs { - @Given("TCA Policy is loaded") - public void tca_Policy_is_loaded() { - // Write code here that turns the phrase above into concrete actions - throw new cucumber.api.PendingException(); + /* + + private static final Logger logger = LoggerFactory.getLogger(Stepdefs.class); + + public static OnapXacmlPdpEngine onapPdpEngine; + public static Properties properties; + public static Map tcaPolicy; + public static Request request; + public static File pathProperties; + public static File pathRootPolicy; + + /** + * Temporary folder where we will store newly created policies. + */ + @ClassRule + public TemporaryFolder policyFolder = new TemporaryFolder(); + + /** + * This is a simple annotation class to simulate + * requests coming in. + */ + @XACMLRequest(ReturnPolicyIdList = true) + public class MyXacmlRequest { + + @XACMLSubject(includeInResults = true) + String onapName = "DCAE"; + + @XACMLResource(includeInResults = true) + String resource = "onap.policies.Monitoring"; + + @XACMLAction() + String action = "configure"; + } + + /** + * Initialization. + */ + @Given("Initialization") + public void initialization() { + /* + // + // Everything initializes upon startup + // + assertThatCode(() -> { + // + // Assume XACML REST Controller loads PDP engine + // + onapPdpEngine = new OnapXacmlPdpEngine(); + // + // Come up with defaults + // + File path = Paths.get("src/test/resources").toFile(); + /* + // try (InputStream is = new FileInputStream("src/test/resources/xacml.properties")) { + // properties = new Properties(); + // properties.load(is); + // onapPdpEngine.initializeEngine(properties); +// } + onapPdpEngine.initialize(path.toPath()); + // + // Store the properties in new path + // + // JUNIT IS CRASHING - THE TEMP FOLDER NOT CREATED --> + //pathProperties = policyFolder.newFile("xacml.properties"); + // + // Store the root policies + // + for (String rootPolicyId : XACMLProperties.getRootPolicyIDs(properties)) { + logger.debug("Root policy id: " + rootPolicyId); + } + + }).doesNotThrowAnyException(); + */ + } + + /** + * Initialization. + */ + @When("Decision Requested") + public void decision_Requested() { + /* + // + // Simulate a request coming in from Xacml REST server + // + assertThatCode(() -> { + request = RequestParser.parseRequest(new MyXacmlRequest()); + }).doesNotThrowAnyException(); + */ + } + + /** + * Initialization. + */ + @Then("Decision Permit {int} Obligations") + public void decision_Permit_Obligations(Integer int1) { + /* + Response response = onapPdpEngine.decision(request); + for (Result result : response.getResults()) { + logger.debug(result.getDecision().toString()); + assertEquals(Decision.PERMIT, result.getDecision()); + assertThat(result.getObligations().size()).isEqualTo(int1); + } + */ + } + + /** + * Initialization. + */ + @When("The application gets new Tosca Policy") + public void the_application_gets_new_Tosca_Policy() { + /* + // + // The Xacml PDP REST controller Would receive this from the PAP + // + // And then parse it looking for Policy Types + // + assertThatCode(() -> { + try (InputStream is = new FileInputStream("src/test/resources/vDNS.policy.input.yaml")) { + Yaml yaml = new Yaml(); + tcaPolicy = yaml.load(is); + // + // Do we test iterating and determining if supported? + // + + } + }).doesNotThrowAnyException(); + */ } - @When("A Decision Request is received") - public void a_Decision_Request_is_received() { - // Write code here that turns the phrase above into concrete actions - throw new cucumber.api.PendingException(); + /** + * Initialization. + */ + @Then("Load Policy") + public void load_Policy() { + /* + assertThatCode(() -> { + // + // Load the policies + // + List convertedPolicies = onapPdpEngine.convertPolicies(tcaPolicy); + // + // Store these in temporary folder + // + int id = 1; + List newReferencedPolicies = new ArrayList<>(); + for (PolicyType convertedPolicy : convertedPolicies) { + // + // I don't think we should use the policy id as the filename - there could + // possibly be duplicates. eg. Not guaranteed to be unique. + // + File file = policyFolder.newFile("policy." + id + convertedPolicy.getPolicyId() + ".xml"); + logger.info("Creating Policy {}", file.getAbsolutePath()); + Path path = XACMLPolicyWriter.writePolicyFile(file.toPath(), convertedPolicy); + // + // Add it to our list + // + newReferencedPolicies.add(path); + } + // + // Now updated the properties + // + Path[] args = new Path[newReferencedPolicies.size()]; + newReferencedPolicies.toArray(args); + XACMLProperties.setXacmlReferencedProperties(properties, args); + // + // Reload the PDP engine + // + onapPdpEngine.initializeEngine(properties); + }).doesNotThrowAnyException(); + */ } - @Then("I should return TCA Policy as JSON") - public void i_should_return_TCA_Policy_as_JSON() { - // Write code here that turns the phrase above into concrete actions - throw new cucumber.api.PendingException(); + /** + * Initialization. + */ + @Then("Save Configuration") + public void save_Configuration() { + /* + assertThatCode(() -> { + // + // Save the configuration + // + onapPdpEngine.storeXacmlProperties(pathProperties.getAbsolutePath()); + }).doesNotThrowAnyException(); + */ } -} +} \ No newline at end of file diff --git a/applications/monitoring/src/test/java/org/onap/policy/xacml/pdp/engine/OnapXacmlPdpEngineTest.java b/applications/monitoring/src/test/java/org/onap/policy/xacml/pdp/engine/OnapXacmlPdpEngineTest.java new file mode 100644 index 00000000..940a974b --- /dev/null +++ b/applications/monitoring/src/test/java/org/onap/policy/xacml/pdp/engine/OnapXacmlPdpEngineTest.java @@ -0,0 +1,296 @@ +/*- + * ============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.engine; + +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 static org.junit.Assert.assertEquals; + +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Response; +import com.att.research.xacml.api.Result; +import com.att.research.xacml.std.annotations.RequestParser; +import com.att.research.xacml.std.annotations.XACMLAction; +import com.att.research.xacml.std.annotations.XACMLRequest; +import com.att.research.xacml.std.annotations.XACMLResource; +import com.att.research.xacml.std.annotations.XACMLSubject; +import com.att.research.xacml.util.XACMLProperties; +import com.google.common.io.Files; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +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; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.ServiceLoader; + +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException; +import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; + +public class OnapXacmlPdpEngineTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(OnapXacmlPdpEngineTest.class); + private static OnapXacmlPdpEngine onapPdpEngine; + private static Properties properties = new Properties(); + private static File propertiesFile; + + @ClassRule + public static final TemporaryFolder policyFolder = new TemporaryFolder(); + + /** + * This is a simple annotation class to simulate + * requests coming in. + */ + @XACMLRequest(ReturnPolicyIdList = true) + public class MyXacmlRequest { + + @XACMLSubject(includeInResults = true) + String onapName = "DCAE"; + + @XACMLResource(includeInResults = true) + String resource = "onap.policies.Monitoring"; + + @XACMLAction() + String action = "configure"; + } + + /** + * Load a test engine. + */ + @BeforeClass + public static void setup() { + assertThatCode(() -> { + // + // 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 applicationLoader = + ServiceLoader.load(XacmlApplicationServiceProvider.class); + // + // Iterate through them - I could store the object as + // XacmlApplicationServiceProvider pointer. + // + // Try this later. + // + StringBuilder strDump = new StringBuilder("Loaded applications:" + System.lineSeparator()); + Iterator iterator = applicationLoader.iterator(); + while (iterator.hasNext()) { + XacmlApplicationServiceProvider application = iterator.next(); + strDump.append(application.applicationName()); + strDump.append(" supports "); + strDump.append(application.supportedPolicyTypes()); + strDump.append(System.lineSeparator()); + } + LOGGER.debug("{}", strDump); + // + // Create the engine instance + // + onapPdpEngine = new OnapXacmlPdpEngine(); + // + // Tell it to initialize based on the properties file + // we just built for it. + // + onapPdpEngine.initialize(propertiesFile.toPath().getParent()); + // + // Make sure there's an application name + // + assertThat(onapPdpEngine.applicationName()).isNotEmpty(); + // + // Ensure it has the supported policy types and + // can support the correct policy types. + // + assertThat(onapPdpEngine.canSupportPolicyType("onap.Monitoring", "1.0.0")).isTrue(); + assertThat(onapPdpEngine.canSupportPolicyType("onap.Monitoring", "1.5.0")).isTrue(); + assertThat(onapPdpEngine.canSupportPolicyType("onap.policies.monitoring.foobar", "1.0.1")).isTrue(); + assertThat(onapPdpEngine.canSupportPolicyType("onap.foobar", "1.0.0")).isFalse(); + assertThat(onapPdpEngine.supportedPolicyTypes()).contains("onap.Monitoring"); + // + // Ensure it supports decisions + // + assertThat(onapPdpEngine.actionDecisionsSupported()).contains("configure"); + }).doesNotThrowAnyException(); + } + + @Test + public void testNoPolicies() { + // + // Make a simple decision - NO policies are loaded + // + assertThatCode(() -> { + Response response = onapPdpEngine.decision(RequestParser.parseRequest(new MyXacmlRequest())); + for (Result result : response.getResults()) { + LOGGER.info("Decision {}", result.getDecision()); + assertEquals(Decision.PERMIT, result.getDecision()); + } + }).doesNotThrowAnyException(); + } + + @SuppressWarnings("unchecked") + @Test + public void testvDnsPolicy() { + // + // 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 toscaObject = yaml.load(is); + List policies = (List) 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. + // + // In another future review.... + // + for (Object policyObject : policies) { + // + // Get the contents + // + Map policyContents = (Map) policyObject; + for (Entry entrySet : policyContents.entrySet()) { + LOGGER.info("Entry set {}", entrySet.getKey()); + Map policyDefinition = (Map) entrySet.getValue(); + // + // Find the type and make sure the engine supports it + // + assertThat(policyDefinition.containsKey("type")).isTrue(); + assertThat(onapPdpEngine.canSupportPolicyType( + policyDefinition.get("type").toString(), + policyDefinition.get("version").toString())) + .isTrue(); + } + } + // + // Just go ahead and load them all for now + // + // Assuming all are supported etc. + // + onapPdpEngine.loadPolicies(toscaObject); + + //List policies = onapPdpEngine.convertPolicies(is); + // + // Should have a policy + //// assertThat(policies.isEmpty()).isFalse(); + } + }).doesNotThrowAnyException(); + } + + @Test + public void testBadPolicies() { + assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() -> { + try (InputStream is = + new FileInputStream("src/test/resources/test.monitoring.policy.missingmetadata.yaml")) { + onapPdpEngine.convertPolicies(is); + } + }).withMessageContaining("missing metadata section"); + + assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() -> { + try (InputStream is = + new FileInputStream("src/test/resources/test.monitoring.policy.missingtype.yaml")) { + onapPdpEngine.convertPolicies(is); + } + }).withMessageContaining("missing type value"); + + assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() -> { + try (InputStream is = + new FileInputStream("src/test/resources/test.monitoring.policy.missingversion.yaml")) { + onapPdpEngine.convertPolicies(is); + } + }).withMessageContaining("missing version value"); + + assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() -> { + try (InputStream is = + new FileInputStream("src/test/resources/test.monitoring.policy.badmetadata.1.yaml")) { + onapPdpEngine.convertPolicies(is); + } + }).withMessageContaining("missing metadata policy-version"); + + assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() -> { + try (InputStream is = + new FileInputStream("src/test/resources/test.monitoring.policy.badmetadata.2.yaml")) { + onapPdpEngine.convertPolicies(is); + } + }).withMessageContaining("missing metadata policy-id"); + + assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() -> { + try (InputStream is = + new FileInputStream("src/test/resources/test.monitoring.policy.missingproperties.yaml")) { + onapPdpEngine.convertPolicies(is); + } + }).withMessageContaining("missing properties section"); + } + +} diff --git a/applications/monitoring/src/test/resources/cucumber/decisions.feature b/applications/monitoring/src/test/resources/cucumber/decisions.feature index a23d965b..6a573d3c 100644 --- a/applications/monitoring/src/test/resources/cucumber/decisions.feature +++ b/applications/monitoring/src/test/resources/cucumber/decisions.feature @@ -18,10 +18,10 @@ # # SPDX-License-Identifier: Apache-2.0 # ============LICENSE_END========================================================= -Feature: Return a decision - Return a decision for a request - - Scenario: Return policy as a JSON - Given TCA Policy is loaded - When A Decision Request is received - Then I should return TCA Policy as JSON \ No newline at end of file +#Feature: Return a decision +# Return a decision for a request +# +# Scenario: Return policy as a JSON +# Given TCA Policy is loaded +# When A Decision Request is received +# Then I should return TCA Policy as JSON \ No newline at end of file diff --git a/applications/monitoring/src/test/resources/cucumber/load_policy.feature b/applications/monitoring/src/test/resources/cucumber/load_policy.feature new file mode 100644 index 00000000..9651ca91 --- /dev/null +++ b/applications/monitoring/src/test/resources/cucumber/load_policy.feature @@ -0,0 +1,35 @@ +# +# ============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========================================================= + +Feature: Loading TOSCA Policies + When a TOSCA Policy is received, convert it + to a XACML policy and then load it into the XACML PDP engine. + + Scenario: No Policies Loaded + Given Initialization + When Decision Requested + Then Decision Permit 0 Obligations + + Scenario: Load New Policy + Given Initialization + When The application gets new Tosca Policy + Then Load Policy + And Save Configuration diff --git a/applications/monitoring/src/test/resources/test.monitoring.policy.badmetadata.1.yaml b/applications/monitoring/src/test/resources/test.monitoring.policy.badmetadata.1.yaml new file mode 100644 index 00000000..a2631848 --- /dev/null +++ b/applications/monitoring/src/test/resources/test.monitoring.policy.badmetadata.1.yaml @@ -0,0 +1,10 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +policies: + - + test.monitoring.policy.badmetadata.1: + type: onap.policies.monitoring.cdap.tca.hi.lo.app + version: 1.0.0 + metadata: + policy-id: test.monitoring.policy.badmetadata.1 + properties: + domain: measurementsForVfScaling diff --git a/applications/monitoring/src/test/resources/test.monitoring.policy.badmetadata.2.yaml b/applications/monitoring/src/test/resources/test.monitoring.policy.badmetadata.2.yaml new file mode 100644 index 00000000..7da2db38 --- /dev/null +++ b/applications/monitoring/src/test/resources/test.monitoring.policy.badmetadata.2.yaml @@ -0,0 +1,10 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +policies: + - + onap.scaleout.tca: + type: onap.policies.monitoring.cdap.tca.hi.lo.app + version: 1.0.0 + metadata: + policy-version: 1 + properties: + domain: measurementsForVfScaling diff --git a/applications/monitoring/src/test/resources/test.monitoring.policy.missingmetadata.yaml b/applications/monitoring/src/test/resources/test.monitoring.policy.missingmetadata.yaml new file mode 100644 index 00000000..4984a1c3 --- /dev/null +++ b/applications/monitoring/src/test/resources/test.monitoring.policy.missingmetadata.yaml @@ -0,0 +1,9 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +policies: + - + onap.scaleout.tca: + type: onap.policies.monitoring.test + description: I am a test policy + version: 1.0.0 + properties: + domain: measurementsForVfScaling diff --git a/applications/monitoring/src/test/resources/test.monitoring.policy.missingproperties.yaml b/applications/monitoring/src/test/resources/test.monitoring.policy.missingproperties.yaml new file mode 100644 index 00000000..d4132a28 --- /dev/null +++ b/applications/monitoring/src/test/resources/test.monitoring.policy.missingproperties.yaml @@ -0,0 +1,9 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +policies: + - + onap.scaleout.tca: + type: onap.policies.monitoring.cdap.tca.hi.lo.app + version: 1.0.0 + metadata: + policy-id: onap.scaleout.tca + policy-version: 1 diff --git a/applications/monitoring/src/test/resources/test.monitoring.policy.missingtype.yaml b/applications/monitoring/src/test/resources/test.monitoring.policy.missingtype.yaml new file mode 100644 index 00000000..309d08c5 --- /dev/null +++ b/applications/monitoring/src/test/resources/test.monitoring.policy.missingtype.yaml @@ -0,0 +1,11 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +policies: + - + onap.scaleout.tca: + description: I am a test policy + version: 1.0.0 + metadata: + policy-id: onap.scaleout.tca + policy-version: 10 + properties: + domain: measurementsForVfScaling diff --git a/applications/monitoring/src/test/resources/test.monitoring.policy.missingversion.yaml b/applications/monitoring/src/test/resources/test.monitoring.policy.missingversion.yaml new file mode 100644 index 00000000..ff378d92 --- /dev/null +++ b/applications/monitoring/src/test/resources/test.monitoring.policy.missingversion.yaml @@ -0,0 +1,11 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +policies: + - + onap.scaleout.tca: + type: onap.policies.monitoring.test + description: I am a test policy + metadata: + policy-id: onap.scaleout.tca + policy-version: 10 + properties: + domain: measurementsForVfScaling diff --git a/applications/monitoring/src/test/resources/unsupportedpolicytype.yaml b/applications/monitoring/src/test/resources/unsupportedpolicytype.yaml new file mode 100644 index 00000000..0a895b38 --- /dev/null +++ b/applications/monitoring/src/test/resources/unsupportedpolicytype.yaml @@ -0,0 +1,11 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +policies: + - + policy.name: + type: foo.bar + version: 1.0.0 + metadata: + policy-id: policy.name + policy-version: 1 + properties: + prop1: value1 diff --git a/applications/monitoring/src/test/resources/vDNS.policy.decision.payload.json b/applications/monitoring/src/test/resources/vDNS.policy.decision.payload.json new file mode 100644 index 00000000..e69de29b diff --git a/applications/monitoring/src/test/resources/vDNS.policy.input.yaml b/applications/monitoring/src/test/resources/vDNS.policy.input.yaml index ee149381..ee12c702 100644 --- a/applications/monitoring/src/test/resources/vDNS.policy.input.yaml +++ b/applications/monitoring/src/test/resources/vDNS.policy.input.yaml @@ -6,6 +6,7 @@ policies: version: 1.0.0 metadata: policy-id: onap.scaleout.tca + policy-version: 1 properties: domain: measurementsForVfScaling metricsPerEventName: diff --git a/applications/monitoring/src/test/resources/vDNS.policy.xml b/applications/monitoring/src/test/resources/vDNS.policy.xml new file mode 100644 index 00000000..14ad4603 --- /dev/null +++ b/applications/monitoring/src/test/resources/vDNS.policy.xml @@ -0,0 +1,44 @@ + + + The root policy for supporting in-memory onap.Monitoring policy-type policies. + + + + + + onap.scaleout.tca + + + + + + + onap.scaleout.tca + + + + + + + onap.policies.monitoring.cdap.tca.hi.lo.app + + + + + + + onap.policies.monitoring.cdap.tca.hi.lo.app + + + + + + + Default is Permit + + + diff --git a/applications/monitoring/src/test/resources/xacml.properties b/applications/monitoring/src/test/resources/xacml.properties new file mode 100644 index 00000000..9b5330dc --- /dev/null +++ b/applications/monitoring/src/test/resources/xacml.properties @@ -0,0 +1,34 @@ +# +# 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 + +# +# 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 +monitoring.file=src/main/resources/RootMonitoringPolicy.xml + diff --git a/applications/pom.xml b/applications/pom.xml index 13d83fe6..8d5d4b28 100644 --- a/applications/pom.xml +++ b/applications/pom.xml @@ -32,7 +32,9 @@ applications + common monitoring + guard diff --git a/main/pom.xml b/main/pom.xml index 2a6677d2..b769f37a 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -56,6 +56,16 @@ common-parameters ${policy.common.version} + + org.onap.policy.xacml-pdp.applications + common + ${project.version} + + + org.onap.policy.xacml-pdp.applications + monitoring + ${project.version} + diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestServer.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestServer.java index eece1ffc..f3b7a54e 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestServer.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestServer.java @@ -21,11 +21,14 @@ package org.onap.policy.pdpx.main.rest; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Properties; +import java.util.ServiceLoader; + import org.onap.policy.common.capabilities.Startable; import org.onap.policy.common.endpoints.http.server.HttpServletServer; -import org.onap.policy.common.gson.JacksonHandler; +import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider; import org.onap.policy.pdpx.main.parameters.RestServerParameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,6 +47,8 @@ public class XacmlPdpRestServer implements Startable { private RestServerParameters restServerParameters; + private ServiceLoader applicationLoader; + /** * Constructor for instantiating XacmlPdpRestServer. * @@ -59,7 +64,17 @@ public class XacmlPdpRestServer implements Startable { @Override public boolean start() { try { + // + // Look for existing policy types loaded into the system + // + locateExistingPolicyTypes(); + // + // Get the server properties + // servers = HttpServletServer.factory.build(getServerProperties()); + // + // Start all the servers + // for (final HttpServletServer server : servers) { if (server.isAaf()) { server.addFilterClass(null, XacmlPdpAafFilter.class.getCanonicalName()); @@ -100,6 +115,32 @@ public class XacmlPdpRestServer implements Startable { return props; } + private void locateExistingPolicyTypes() { + // + // Load service + // + applicationLoader = ServiceLoader.load(XacmlApplicationServiceProvider.class); + // + // Iterate through them + // + StringBuilder strDump = new StringBuilder("Loaded applications:" + System.lineSeparator()); + Iterator iterator = applicationLoader.iterator(); + long types = 0; + while (iterator.hasNext()) { + XacmlApplicationServiceProvider application = iterator.next(); + strDump.append(application.applicationName()); + strDump.append(" supports "); + strDump.append(application.supportedPolicyTypes()); + types += application.supportedPolicyTypes().size(); + strDump.append(System.lineSeparator()); + } + LOGGER.debug("{}", strDump); + // + // Update statistics manager + // + XacmlPdpStatisticsManager.setTotalPolicyTypesCount(types); + } + /** * {@inheritDoc}. */ diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpStatisticsManager.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpStatisticsManager.java index 471ffca4..cfdfa3d8 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpStatisticsManager.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpStatisticsManager.java @@ -26,6 +26,7 @@ package org.onap.policy.pdpx.main.rest; */ public class XacmlPdpStatisticsManager { + private static long totalPolicyTypesCount; private static long totalPoliciesCount; private static long permitDecisionsCount; private static long denyDecisionsCount; @@ -36,6 +37,18 @@ public class XacmlPdpStatisticsManager { throw new IllegalStateException("Instantiation of the class is not allowed"); } + /** + * Method to set the xacml pdp total policy types count. This + * doesn't really increment, it depends on the applications + * that are loaded. Which can be dynamic. + * + * @return the total + */ + public static long setTotalPolicyTypesCount(long newCount) { + totalPolicyTypesCount = newCount; + return totalPolicyTypesCount; + } + /** * Method to update the xacml pdp total policies count. * @@ -81,6 +94,15 @@ public class XacmlPdpStatisticsManager { return ++notApplicableDecisionsCount; } + /** + * Returns the current value of totalPolicyTypesCount. + + * @return the totalPolicyTypesCount + */ + public static long getTotalPolicyTypesCount() { + return totalPolicyTypesCount; + } + /** * Returns the current value of totalPoliciesCount. diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/model/Decision.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/model/Decision.java index d09dac9c..4504cb1b 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/model/Decision.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/model/Decision.java @@ -20,8 +20,16 @@ package org.onap.policy.pdpx.main.rest.model; +import java.util.List; +import java.util.Map; + public class Decision { - //TODO + String onapName; + + String onapInstance; + + String action; + List> resource; } diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/model/StatisticsReport.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/model/StatisticsReport.java index 36177034..05933399 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/model/StatisticsReport.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/model/StatisticsReport.java @@ -27,6 +27,7 @@ package org.onap.policy.pdpx.main.rest.model; public class StatisticsReport { private int code; + private long totalPolicyTypesCount; private long totalPoliciesCount; private long permitDecisionsCount; private long denyDecisionsCount; @@ -52,6 +53,24 @@ public class StatisticsReport { this.code = code; } + /** + * Returns the totalPolicyTypesCount of this {@link StatisticsReport} instance. + * + * @return the totalPolicyTypesCount + */ + public long getTotalPolicyTypesCount() { + return totalPolicyTypesCount; + } + + /** + * Set totalPolicyTypesCount in this {@link StatisticsReport} instance. + * + * @param totalPolicyTypesCount the totalPolicyTypesCount to set + */ + public void setTotalPolicyTypesCount(long totalPolicyTypesCount) { + this.totalPolicyTypesCount = totalPolicyTypesCount; + } + /** * Returns the totalPoliciesCount of this {@link StatisticsReport} instance. * @@ -150,6 +169,8 @@ public class StatisticsReport { final StringBuilder builder = new StringBuilder(); builder.append("StatisticsReport [code="); builder.append(getCode()); + builder.append(", totalPolicyTypesCount="); + builder.append(getTotalPolicyTypesCount()); builder.append(", totalPoliciesCount="); builder.append(getTotalPoliciesCount()); builder.append(", permitDecisionsCount="); diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/StatisticsProvider.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/StatisticsProvider.java index 7b883280..1b90f6b8 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/StatisticsProvider.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/StatisticsProvider.java @@ -38,6 +38,7 @@ public class StatisticsProvider { public StatisticsReport fetchCurrentStatistics() { final StatisticsReport report = new StatisticsReport(); report.setCode(XacmlPdpActivator.isAlive() ? 200 : 500); + report.setTotalPolicyTypesCount(XacmlPdpStatisticsManager.getTotalPolicyTypesCount()); report.setTotalPoliciesCount(XacmlPdpStatisticsManager.getTotalPoliciesCount()); report.setPermitDecisionsCount(XacmlPdpStatisticsManager.getPermitDecisionsCount()); report.setDenyDecisionsCount(XacmlPdpStatisticsManager.getDenyDecisionsCount()); diff --git a/main/src/test/java/org/onap/policy/pdpx/main/parameters/TestXacmlPdpParameterHandler.java b/main/src/test/java/org/onap/policy/pdpx/main/parameters/TestXacmlPdpParameterHandler.java index 3955031a..ef85a762 100644 --- a/main/src/test/java/org/onap/policy/pdpx/main/parameters/TestXacmlPdpParameterHandler.java +++ b/main/src/test/java/org/onap/policy/pdpx/main/parameters/TestXacmlPdpParameterHandler.java @@ -142,7 +142,7 @@ public class TestXacmlPdpParameterHandler { final XacmlPdpCommandLineArguments arguments = new XacmlPdpCommandLineArguments(); arguments.parse(xacmlPdpConfigParameters); - final String expectedResult = new String(Files.readAllBytes( + new String(Files.readAllBytes( Paths.get("src/test/resources/expectedValidationResults/InvalidRestServerParameters.txt"))); assertThatThrownBy(() -> new XacmlPdpParameterHandler().getParameters(arguments)) diff --git a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpRestServer.java b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpRestServer.java index 0f608e29..1ec649cb 100644 --- a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpRestServer.java +++ b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpRestServer.java @@ -41,6 +41,7 @@ import javax.ws.rs.core.MediaType; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; import org.junit.After; +import org.junit.BeforeClass; import org.junit.Test; import org.onap.policy.common.endpoints.report.HealthCheckReport; import org.onap.policy.common.utils.network.NetworkUtil; @@ -69,6 +70,16 @@ public class TestXacmlPdpRestServer { private Main main; private XacmlPdpRestServer restServer; + /** + * setup. + */ + @BeforeClass + public static void setUp() { + System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog"); + System.setProperty("org.eclipse.jetty.LEVEL", "OFF"); + + } + /** * Method for cleanup after each test. */ diff --git a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpStatistics.java b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpStatistics.java index ee05ff06..595301de 100644 --- a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpStatistics.java +++ b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpStatistics.java @@ -21,6 +21,7 @@ package org.onap.policy.pdpx.main.rest; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -32,6 +33,7 @@ import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; +import org.junit.BeforeClass; import org.junit.Test; import org.onap.policy.common.utils.network.NetworkUtil; import org.onap.policy.pdpx.main.PolicyXacmlPdpException; @@ -51,12 +53,19 @@ public class TestXacmlPdpStatistics { private static final Logger LOGGER = LoggerFactory.getLogger(TestXacmlPdpStatistics.class); + @BeforeClass + public static void beforeClass() { + System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog"); + System.setProperty("org.eclipse.jetty.LEVEL", "OFF"); + } + @Test public void testXacmlPdpStatistics_200() throws PolicyXacmlPdpException, InterruptedException { try { final Main main = startXacmlPdpService(); StatisticsReport report = getXacmlPdpStatistics(); validateReport(report, 0, 200); + assertThat(report.getTotalPolicyTypesCount()).isGreaterThan(0); updateXacmlPdpStatistics(); report = getXacmlPdpStatistics(); validateReport(report, 1, 200); diff --git a/main/src/test/java/org/onap/policy/pdpx/main/startstop/TestMain.java b/main/src/test/java/org/onap/policy/pdpx/main/startstop/TestMain.java index bfc8a2a4..8c37acb7 100644 --- a/main/src/test/java/org/onap/policy/pdpx/main/startstop/TestMain.java +++ b/main/src/test/java/org/onap/policy/pdpx/main/startstop/TestMain.java @@ -25,6 +25,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import org.junit.Assert; +import org.junit.BeforeClass; import org.junit.Test; import org.onap.policy.pdpx.main.PolicyXacmlPdpException; import org.onap.policy.pdpx.main.parameters.CommonTestData; @@ -35,6 +36,16 @@ import org.onap.policy.pdpx.main.parameters.CommonTestData; */ public class TestMain { + /** + * setup. + */ + @BeforeClass + public static void setUp() { + System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog"); + System.setProperty("org.eclipse.jetty.LEVEL", "OFF"); + + } + @Test public void testMain() throws PolicyXacmlPdpException { final String[] xacmlPdpConfigParameters = {"-c", "parameters/XacmlPdpConfigParameters.json"}; diff --git a/pom.xml b/pom.xml index acd78de6..fea5818d 100644 --- a/pom.xml +++ b/pom.xml @@ -93,6 +93,21 @@ ch.qos.logback logback-classic + + org.yaml + snakeyaml + 1.24 + + + org.json + json + 20180813 + + + com.att.research.xacml + xacml-pdp + 2.0.0 + -- 2.16.6