From 91d04c64771832a0b8815ffbe1f0f9920320d94d Mon Sep 17 00:00:00 2001 From: Pamela Dragosh Date: Tue, 14 Feb 2017 19:41:00 -0500 Subject: Initial OpenECOMP policy/engine commit Change-Id: I7dbff37733b661643dd4d1caefa3d7dccc361b6e Signed-off-by: Pamela Dragosh --- .../policy/xacml/api/XACMLErrorConstants.java | 56 + .../xacml/api/pap/ECOMPPapEngineFactory.java | 38 + .../policy/xacml/api/pap/EcompPAPPolicy.java | 89 ++ .../openecomp/policy/xacml/api/pap/EcompPDP.java | 46 + .../policy/xacml/api/pap/EcompPDPGroup.java | 11 + .../policy/xacml/api/pap/PAPPolicyEngine.java | 66 ++ .../openecomp/policy/xacml/std/pap/StdEngine.java | 1087 ++++++++++++++++++++ .../policy/xacml/std/pap/StdEngineFactory.java | 57 + .../policy/xacml/std/pap/StdPAPPolicy.java | 889 ++++++++++++++++ .../org/openecomp/policy/xacml/std/pap/StdPDP.java | 222 ++++ .../policy/xacml/std/pap/StdPDPGroup.java | 1031 +++++++++++++++++++ .../policy/xacml/std/pap/StdPDPGroupStatus.java | 405 ++++++++ .../xacml/std/pap/StdPDPItemSetChangeNotifier.java | 84 ++ .../policy/xacml/std/pap/StdPDPPIPConfig.java | 217 ++++ .../policy/xacml/std/pap/StdPDPPolicy.java | 368 +++++++ .../policy/xacml/std/pap/StdPDPStatus.java | 265 +++++ .../xacml/std/pip/engines/aaf/AAFEngine.java | 276 +++++ .../openecomp/policy/xacml/util/MetricsUtil.java | 80 ++ .../policy/xacml/util/XACMLPolicyScanner.java | 727 +++++++++++++ .../policy/xacml/util/XACMLPolicyWriter.java | 344 +++++++ 20 files changed, 6358 insertions(+) create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/XACMLErrorConstants.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/ECOMPPapEngineFactory.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/EcompPAPPolicy.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/EcompPDP.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/EcompPDPGroup.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/PAPPolicyEngine.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdEngine.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdEngineFactory.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPAPPolicy.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDP.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPGroup.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPGroupStatus.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPItemSetChangeNotifier.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPPIPConfig.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPPolicy.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPStatus.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pip/engines/aaf/AAFEngine.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/util/MetricsUtil.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/util/XACMLPolicyScanner.java create mode 100644 ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/util/XACMLPolicyWriter.java (limited to 'ECOMP-XACML/src/main/java/org/openecomp/policy') diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/XACMLErrorConstants.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/XACMLErrorConstants.java new file mode 100644 index 000000000..5a2eac109 --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/XACMLErrorConstants.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.api; + +/** + * List of Error Classifications + * PE100 - Permissions + * PE200 - System Error (such as availability, timeout, configuration, etc...) + * PE300 - Data Issue( such as request for REST/JSON ) + * PE400 - Schema validation + * PE500 - Process Flow issues + * PE900 - Default/Unknown Errors + * + * + */ +public class XACMLErrorConstants { + //Captures all the errors related to Authentication, Authorizations and Permissions in the PolicyEngine Process + public static final String ERROR_PERMISSIONS = "PE100 - Permissions Error: "; + + //Captures all the errors related to availability, timeout configuration variables, etc... in the PolicyEngine + public static final String ERROR_SYSTEM_ERROR = "PE200 - System Error: "; + + /* + * Captures all the errors related to configuration values from properties files and data from the interfacing System + * like REST/JSON values + */ + public static final String ERROR_DATA_ISSUE = "PE300 - Data Issue: "; + + //Captures all the errors related to the XML schemas and/or REST/JSON structures + public static final String ERROR_SCHEMA_INVALID = "PE400 - Schema validation Error: "; + + //Captures all the errors related to the Process, when data from one Process to another Process does not flow + public static final String ERROR_PROCESS_FLOW = "PE500 - Process Flow Issue: "; + + //Captures all the errors that not related to the list of above error codes + public static final String ERROR_UNKNOWN = "PE900 - Unknown Error: "; + + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/ECOMPPapEngineFactory.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/ECOMPPapEngineFactory.java new file mode 100644 index 000000000..d34d03348 --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/ECOMPPapEngineFactory.java @@ -0,0 +1,38 @@ +package org.openecomp.policy.xacml.api.pap; + +import java.util.Properties; + +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.FactoryFinder; + +public abstract class ECOMPPapEngineFactory{ + + /** + * Creates a new PAPEngineFactory instance using the given class name and the default thread class loader. + * + * @param factoryClassName the String name of the factory class to instantiate + * @return an instance of an object that extends ECOMPPapEngineFactory to use in creating PAPPolicyEngine objects. + */ + public static ECOMPPapEngineFactory newInstance(String factoryClassName) throws FactoryException { + return FactoryFinder.newInstance(factoryClassName, ECOMPPapEngineFactory.class, null, true); + } + + /** + * Creates a new PAPPolicyEngine based on the configured ECOMPPapEngineFactory. + * + * @return a new PAPPolicyEngine + * @throws PAPException + */ + public abstract PAPPolicyEngine newEngine() throws FactoryException, PAPException; + + /** + * Creates a new PAPPolicyEngine based on the configured ECOMPPapEngineFactory. + * + * @return a new PAPPolicyEngine + * @throws PAPException + */ + public abstract PAPPolicyEngine newEngine(Properties properties) throws FactoryException, PAPException; + + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/EcompPAPPolicy.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/EcompPAPPolicy.java new file mode 100644 index 000000000..c18ad230f --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/EcompPAPPolicy.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.api.pap; + +import java.net.URI; +import java.util.List; +import java.util.Map; + +import org.openecomp.policy.xacml.std.pap.StdPAPPolicy; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonSubTypes.Type; + +/* + * The following allows us to use Jackson to convert sub-types of this type into JSON and back to objects. + */ +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "PAPPolicyType") +@JsonSubTypes({ + @Type(value = StdPAPPolicy.class, name = "StdPAPPolicy") }) +public interface EcompPAPPolicy { + + public String getPolicyName(); + public String getOldPolicyFileName(); + public String getPolicyDescription(); + public String getEcompName(); + public String getConfigName(); + public Map getDynamicFieldConfigAttributes(); + public Map getDynamicSettingsMap(); + public List getDynamicRuleAlgorithmLabels(); + public List getDynamicRuleAlgorithmCombo(); + public List getDynamicRuleAlgorithmField1(); + public List getDynamicRuleAlgorithmField2(); + public List getDynamicVariableList(); + public List getDataTypeList(); + public String getConfigBodyData(); + public String getPolicyID(); + public String getRuleID(); + public String getConfigType(); + public Boolean isEditPolicy(); + public Boolean isDraft(); + public String getVersion(); + public String getDomainDir(); + public String getConfigPolicyType(); + public String getJsonBody(); + public Integer getHighestVersion(); + public URI getLocation(); + public String getActionPerformer(); + public String getActionAttribute(); + public String getActionBody(); + public Map getDropDownMap(); + public String getActionDictHeader(); + public String getActionDictType(); + public String getActionDictUrl(); + public String getActionDictMethod(); + public String getServiceType(); + public String getUuid(); + public String getMsLocation(); + public String getPriority(); + public String getDeleteCondition(); + public String getDictionaryType(); + public String getDictionary(); + public Map getDictionaryFields(); + + public String getRiskLevel(); + public String getGuard(); + public String getRiskType(); + public String getTTLDate(); +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/EcompPDP.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/EcompPDP.java new file mode 100644 index 000000000..f00dd7ac5 --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/EcompPDP.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.api.pap; + +import java.util.Set; + +import org.openecomp.policy.xacml.std.pap.StdPDP; + +import com.att.research.xacml.api.pap.PDP; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonSubTypes.Type; + +/* + * The following allows us to use Jackson to convert sub-types of this type into JSON and back to objects. + */ +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "PDPType") +@JsonSubTypes({ + @Type(value = StdPDP.class, name = "StdPDP") }) +public interface EcompPDP extends PDP { + + public Integer getJmxPort(); + + public void setJmxPort(Integer jmxport); + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/EcompPDPGroup.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/EcompPDPGroup.java new file mode 100644 index 000000000..a64b4b6dc --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/EcompPDPGroup.java @@ -0,0 +1,11 @@ +package org.openecomp.policy.xacml.api.pap; + +import java.util.Set; + +import com.att.research.xacml.api.pap.PDPGroup; + +public interface EcompPDPGroup extends PDPGroup { + + public Set getEcompPdps(); + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/PAPPolicyEngine.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/PAPPolicyEngine.java new file mode 100644 index 000000000..0c5c334da --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/api/pap/PAPPolicyEngine.java @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.api.pap; + +import java.io.InputStream; +import java.util.Set; + +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDPPolicy; +import com.att.research.xacml.api.pap.PDPStatus; + +public interface PAPPolicyEngine{ + + public EcompPDPGroup getDefaultGroup() throws PAPException; + + public void SetDefaultGroup(EcompPDPGroup group) throws PAPException; + + public void newPDP(String id, EcompPDPGroup group, String name, String description, int jmxport) throws PAPException, NullPointerException; + + public void newGroup(String name, String description) throws PAPException, NullPointerException; + + public EcompPDPGroup getGroup(String id) throws PAPException; + + public Set getEcompPDPGroups() throws PAPException; + + public EcompPDPGroup getPDPGroup(EcompPDP pdp) throws PAPException; + + public PDPStatus getStatus(EcompPDP pdp) throws PAPException; + + public void movePDP(EcompPDP pdp, EcompPDPGroup newGroup) throws PAPException; + + public void updatePDP(EcompPDP pdp) throws PAPException; + + public void removePDP(EcompPDP pdp) throws PAPException; + + public EcompPDP getPDP(String pdpId) throws PAPException; + + public void updateGroup(EcompPDPGroup group) throws PAPException; + + public void removeGroup(EcompPDPGroup group, EcompPDPGroup newGroup) throws PAPException, NullPointerException; + +public void publishPolicy(String id, String name, boolean isRoot, InputStream policy, EcompPDPGroup group) throws PAPException; + + // copy the given policy file into the group's directory, but do not include the policy in the group's policy set + public void copyPolicy(PDPPolicy policy, EcompPDPGroup group) throws PAPException; + + public void removePolicy(PDPPolicy policy, EcompPDPGroup group) throws PAPException; + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdEngine.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdEngine.java new file mode 100644 index 000000000..397f763f2 --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdEngine.java @@ -0,0 +1,1087 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.std.pap; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.policy.xacml.api.pap.EcompPDP; +import org.openecomp.policy.xacml.api.pap.EcompPDPGroup; +import org.openecomp.policy.xacml.api.pap.PAPPolicyEngine; +import org.openecomp.policy.common.logging.eelf.MessageCodes; +import org.openecomp.policy.common.logging.eelf.PolicyLogger; +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDP; +import com.att.research.xacml.api.pap.PDPGroup; +import com.att.research.xacml.api.pap.PDPPolicy; +import com.att.research.xacml.api.pap.PDPStatus; +import com.att.research.xacml.util.XACMLProperties; +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; +import com.google.common.collect.Sets; + +/** + * This is a simple PAP engine that uses some property files and a simple directory + * structure in the file system to manage a policy repository and set of PDP nodes. + * + * + */ +public class StdEngine extends StdPDPItemSetChangeNotifier implements PAPPolicyEngine { + private static Log logger = LogFactory.getLog(StdEngine.class); + + public static String PROP_PAP_REPO = "xacml.pap.pdps"; + public static String PROP_PAP_GROUPS = "xacml.pap.groups"; + public static String PROP_PAP_GROUPS_DEFAULT = "xacml.pap.groups.default"; + public static String PROP_PAP_GROUPS_DEFAULT_NAME = "default"; + //this value will be accessed from XacmlPapServlet so that we know if a default group did not exist + //and was just added. This way, we can add the new group to the database. + public boolean wasDefaultGroupJustAdded = false; + + protected final Path repository; + protected Set groups; + + public StdEngine() throws PAPException, IOException { + // + // Get the location in the file system of our repository + // + this.repository = Paths.get(XACMLProperties.getProperty(PROP_PAP_REPO)); + // + // Initialize + // + this.intialize(); + } + + public StdEngine(Properties properties) throws PAPException, IOException { + // + // Get the location in the file system of our repository + // + this.repository = Paths.get(properties.getProperty(PROP_PAP_REPO)); + // + // Initialize + // + this.intialize(); + } + + public StdEngine(Path repository) throws PAPException, IOException { + // + // Save our location + // + this.repository = repository; + // + // Initialize + // + this.intialize(); + } + + private void intialize() throws PAPException, IOException { + // + // Sanity check the repository path + // + if (this.repository == null) { + throw new PAPException ("No repository specified."); + } + if (Files.notExists(this.repository)) { + Files.createDirectory(repository); + } + if (Files.isDirectory(this.repository) == false) { + throw new PAPException ("Repository is NOT a directory: " + this.repository.toAbsolutePath()); + } + if (Files.isWritable(this.repository) == false) { + throw new PAPException ("Repository is NOT writable: " + this.repository.toAbsolutePath()); + } + // + // Load our groups + // + this.loadGroups(); + } + + private void loadGroups() throws PAPException { + // + // Create a properties object + // + Properties properties = new Properties(); + Path file = Paths.get(this.repository.toString(), XACMLProperties.XACML_PROPERTIES_NAME); + try { + // + // Load the properties + // + try (InputStream is = new FileInputStream(file.toFile())) { + properties.load(is); + } + + // + // Parse it + // + this.groups = this.readProperties(this.repository, properties); + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to load " + file.toAbsolutePath().toString()); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdEngine", "Failed to load properties file"); + this.groups = new HashSet(); + } + // + // Initialize the default group + // + PDPGroup defaultGroup = this.initializeDefaultGroup(file, properties); + logger.info("Default group is: " + defaultGroup.getId() + "=" + defaultGroup.getName()); + } + + private PDPGroup initializeDefaultGroup(Path file, Properties properties) throws PAPException { + wasDefaultGroupJustAdded = false; + // + // Make sure we have the default group + // + PDPGroup group = this.getDefaultGroup(); + if (group != null) { + return group; + } + // + // We don't have the default group, create it + // + String defaultId = properties.getProperty(PROP_PAP_GROUPS_DEFAULT, PROP_PAP_GROUPS_DEFAULT_NAME); + if(defaultId == null){ + defaultId = PROP_PAP_GROUPS_DEFAULT_NAME; + } + if(defaultId.equals("")){ + defaultId = PROP_PAP_GROUPS_DEFAULT_NAME; + } + //we're going to check one more time in case the PROP_PAP_GROUPS_DEFAULT_NAME doesn't exist + if(defaultId == null){ + defaultId = "default"; + } + if(defaultId.equals("")){ + defaultId = "default"; + } + logger.warn("Default group does NOT exist, creating " + defaultId); + Path defaultPath = Paths.get(this.repository.toString(), defaultId); + try { + // + // Does it exist? + // + if (Files.notExists(defaultPath)) { + // + // Create its directory + // + Files.createDirectory(defaultPath); + // + // Create property files + // + { + Properties props = new Properties(); + props.setProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, ""); + props.setProperty(XACMLProperties.PROP_ROOTPOLICIES, ""); + Path policyPath = Paths.get(defaultPath.toAbsolutePath().toString(), "xacml.policy.properties"); + Files.createFile(policyPath); + try (OutputStream os = Files.newOutputStream(policyPath)) { + props.store(os, ""); + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to write default policy properties", e); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdEngine", "Failed to write default policy properties"); + } + } + { + Properties props = new Properties(); + props = setPIPProperties(props); + Path pipPath = Paths.get(defaultPath.toAbsolutePath().toString(), "xacml.pip.properties"); + Files.createFile(pipPath); + try (OutputStream os = Files.newOutputStream(pipPath)) { + props.store(os, ""); + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to write default pip properties", e); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdEngine", "Failed to write default pip properties"); + } + } + } + // + // Create the default group + // + StdPDPGroup newDefault = new StdPDPGroup(defaultId, true, "default", "The default group where new PDP's are put.", defaultPath); + // + // Add it to our list + // + this.groups.add(newDefault); + // + // Save our properties out since we have + // a new default group. + // + StdEngine.setGroupProperties(newDefault, properties); + // + // Save it to disk + // + try { + try (OutputStream os = Files.newOutputStream(file)) { + properties.store(os, ""); + } + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Failed to save properties with new default group information.", e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "StdEngine", "Failed to save properties with new default group information."); + } + // + // Return it + // + wasDefaultGroupJustAdded = true; + return newDefault; + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Failed to create default group: " + defaultId, e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "StdEngine", "Failed to create default group"); + throw new PAPException("Failed to create default group"); + } + } + + + + + @Override + public EcompPDPGroup getDefaultGroup() throws PAPException + { + for (EcompPDPGroup group : this.groups) { + if (group.isDefaultGroup()) { + return group; + } + } + // + // Default group doesn't exist + // + return null; + } + + /*@Override + public void SetDefaultGroup(PDPGroup group) throws PAPException { + + boolean changesMade = false; + for (PDPGroup aGroup : groups) { + if (aGroup.getId().equals(group.getId())) { + if ( ! aGroup.isDefaultGroup()) { +//TODO - since the original code checked for type we do also. + if (aGroup instanceof StdPDPGroup) { + ((StdPDPGroup) aGroup).setDefault(true); + changesMade = true; + } else { + throw new IllegalArgumentException("Group in groups of unknown type '" + aGroup.getClass().getName() + "'"); + } + } + } else { + // not the new default group + if (aGroup.isDefaultGroup()) { +//TODO - since the original code checked for type we do also. + if (aGroup instanceof StdPDPGroup) { + ((StdPDPGroup) aGroup).setDefault(false); + changesMade = true; + } else { + throw new IllegalArgumentException("Group in groups of unknown type '" + aGroup.getClass().getName() + "'"); + } + } + } + } + if (changesMade) { + this.doSave(); + } + + return; + }*/ + + /*@Override + public Set getPDPGroups() throws PAPException { + final Set grps = new HashSet(); + for (PDPGroup g : this.groups) { + grps.add(g); + } + return Collections.unmodifiableSet(grps); + }*/ + + @Override + public EcompPDPGroup getGroup(String id) throws PAPException { + for (EcompPDPGroup g: this.groups) { + if (g.getId().equals(id)) { + return g; + } + } + return null; + } + + @Override + public void newGroup(String name, String description) throws PAPException, NullPointerException + { + // + // Null check + // + if (name == null) { + throw new NullPointerException(); + } + // + // Do we already have this group? + // + for (PDPGroup group : this.groups) { + if (group.getName().equals(name)) { + throw new PAPException("Group with this name=" + name + " already exists."); + } + } + + + // create an Id that can be used as a file name and a properties file key. + // Ids must not contain \/:*?"<>|=,; + // The ID must also be unique within the current set of PDPGroups. + String id = createNewPDPGroupId(name); + + + // + // Construct the directory path + // + Path groupPath = Paths.get(this.repository.toString(), id); + // + // If it exists already + // + if (Files.exists(groupPath)) { + logger.warn("addGroup " + id + " directory exists" + groupPath.toString()); + } else { + try { + // + // Create the directory + // + Files.createDirectory(groupPath); + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to create " + groupPath); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdEngine", "Failed to create " + groupPath); + throw new PAPException("Failed to create " + id); + } + } + // + // Create the Policies + // + + Path policyProperties = Paths.get(groupPath.toString(), "xacml.policy.properties"); + if (Files.exists(policyProperties)) { + logger.warn("addGroup " + id + " file exists: " + policyProperties.toString()); + } else { + Properties props = new Properties(); + props.setProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, ""); + props.setProperty(XACMLProperties.PROP_ROOTPOLICIES, ""); + try { + Files.createFile(policyProperties); + try (OutputStream os = Files.newOutputStream(policyProperties)) { + props.store(os, ""); + } + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Failed to create " + policyProperties); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "StdEngine", "Failed to create " + policyProperties); + throw new PAPException("Failed to create " + id); + } + } + // + // Create the PIP config + // + Path pipProperties = Paths.get(groupPath.toString(), "xacml.pip.properties"); + if (Files.exists(pipProperties)) { + logger.warn("addGroup " + id + " file exists: " + pipProperties.toString()); + } else { + try { + Properties props = new Properties(); + props = setPIPProperties(props); + Files.createFile(pipProperties); + try (OutputStream os = Files.newOutputStream(pipProperties)) { + props.store(os, ""); + } + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to create " + pipProperties); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdEngine", "Failed to create " + pipProperties); + throw new PAPException("Failed to create " + id); + } + + } + // + // Ok now add it + // + StdPDPGroup newGroup = new StdPDPGroup(id, name, description, groupPath); + if (this.groups.add(newGroup)) { + // save the new group in our properties and notify any listeners of the change + groupChanged(newGroup); + } + + } + + + + + /** + * Helper to create a new Group ID. + * Use the Name field to create the Id. + * The Name is expected to not be null; if it is then this method throws an exception. + * The name is supposed to be unique within the current set of groups, + * so creating the ID based on the name will create a unique string. + * + * @param name + * @return + */ + private String createNewPDPGroupId(String name) { + String id = name; + // replace "bad" characters with sequences that will be ok for file names and properties keys. + id = id.replace(" ", "_sp_"); + id = id.replace("\t", "_tab_"); + id = id.replace("\\", "_bksl_"); + id = id.replace("/", "_sl_"); + id = id.replace(":", "_col_"); + id = id.replace("*", "_ast_"); + id = id.replace("?", "_q_"); + id = id.replace("\"", "_quo_"); + id = id.replace("<", "_lt_"); + id = id.replace(">", "_gt_"); + id = id.replace("|", "_bar_"); + id = id.replace("=", "_eq_"); + id = id.replace(",", "_com_"); + id = id.replace(";", "_scom_"); + + return id; + } + + + @Override + public EcompPDP getPDP(String pdpId) throws PAPException { + for (EcompPDPGroup group : this.groups) { + for (EcompPDP pdp : group.getEcompPdps()) { + if (pdp.getId().equals(pdpId)) { + return pdp; + } + } + } + return null; + } + + + @Override + public void movePDP(EcompPDP pdp, EcompPDPGroup newGroup) throws PAPException { + if (newGroup == null) { + throw new NullPointerException("You must specify which group the PDP will belong to."); + } + PDPGroup currentGroup = this.getPDPGroup(pdp); + if (currentGroup == null) { + throw new PAPException("PDP must already belong to a group."); + } + if (currentGroup.equals(newGroup)) { + logger.warn("Already in that group."); + return; + } + if (currentGroup instanceof StdPDPGroup && newGroup instanceof StdPDPGroup) { + if (((StdPDPGroup) currentGroup).removePDP(pdp)) { + boolean result = ((StdPDPGroup) newGroup).addPDP(pdp); + if (result) { + // + // Save the configuration + // + this.doSave(); + } else { + //TODO:EELF Cleanup - Remove logger + //logger.error("Failed to add to new group, putting back into original group."); + PolicyLogger.error("Failed to add to new group, putting back into original group."); + if (((StdPDPGroup) currentGroup).removePDP(pdp) == false) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to put PDP back into original group."); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Failed to put PDP back into original group."); + } + } + } + } else { + String message = "Unknown PDP group class: " + newGroup.getClass().getCanonicalName() + " and " + currentGroup.getClass().getCanonicalName(); + logger.warn(message); + throw new PAPException(message); + } + } + + + @Override + public void updatePDP(EcompPDP pdp) throws PAPException { + PDP currentPDP = this.getPDP(pdp.getId()); + if (currentPDP == null) { + String message = "Unknown PDP id '" + pdp.getId() + "'"; + logger.warn(message); + throw new PAPException(message); + } + + // the only things that the user can change are name and description + currentPDP.setDescription(pdp.getDescription()); + currentPDP.setName(pdp.getName()); + if (currentPDP instanceof EcompPDP && pdp instanceof EcompPDP) { + ((EcompPDP)currentPDP).setJmxPort(((EcompPDP)pdp).getJmxPort()); + } + this.doSave(); + } + + @Override + public void removePDP(EcompPDP pdp) throws PAPException { + PDPGroup group = this.getPDPGroup(pdp); + if (group == null) { + throw new NullPointerException(); + } + if (group instanceof StdPDPGroup) { + boolean result = ((StdPDPGroup) group).removePDP(pdp); + if (result) { + this.doSave(); + } + return; + } + String message = "Unknown PDP group class: " + group.getClass().getCanonicalName(); + logger.warn(message); + throw new PAPException(message); + } + + + @Override + /** + * Should never be called - Detailed status is held on the PDP, not the PAP + */ + public PDPStatus getStatus(EcompPDP pdp) throws PAPException { + return getPDP(pdp.getId()).getStatus(); + } + + @Override + public void publishPolicy(String id, String name, boolean isRoot, InputStream policy, EcompPDPGroup group) throws PAPException { + if (group == null) { + throw new NullPointerException(); + } + if (group instanceof StdPDPGroup && this.groups.contains(group)) { + ((StdPDPGroup) group).publishPolicy(id, name, isRoot, policy); + return; + } + logger.warn("unknown PDP Group: " + group); + throw new PAPException("Unknown PDP Group: " + group.getId()); + } + + // Currently not used on the PAP side. This is done by ((StdPDPGroup) group).copyPolicyToFile + @Override + public void copyPolicy(PDPPolicy policy, EcompPDPGroup group) + throws PAPException { + } + + + @Override + public void removePolicy(PDPPolicy policy, EcompPDPGroup group) throws PAPException { + if (group == null) { + throw new NullPointerException(); + } + if (group instanceof StdPDPGroup && this.groups.contains(group)) { + ((StdPDPGroup) group).removePolicy(policy); + return; + } + logger.warn("unknown PDP Group: " + group); + throw new PAPException("Unknown PDP Group: " + group.getId()); + } + + + // + // HELPER methods + // + + private Set readProperties(Path repository, Properties properties) throws PAPException { + Set groups = new HashSet(); + // + // See if there is a groups property + // + String groupList = properties.getProperty(PROP_PAP_GROUPS, ""); + if (groupList == null) { + logger.warn("null group list " + PROP_PAP_GROUPS); + groupList = ""; + } + if (logger.isDebugEnabled()) { + logger.debug("group list: " + groupList); + } + // + // Iterate the groups, converting to a set ensures we have unique groups. + // + for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(groupList)) { + // + // Add our Group Object + // + StdPDPGroup g = new StdPDPGroup(id.trim(), + id.equals(properties.getProperty(PROP_PAP_GROUPS_DEFAULT, PROP_PAP_GROUPS_DEFAULT_NAME)), + properties, + Paths.get(repository.toString(), id)); + + // + // Add it in + // + groups.add(g); + } + // + // Dump what we got + // + if (logger.isDebugEnabled()) { + logger.debug("PDP Group List: " + groups.toString()); + } + return groups; + } + + private void saveConfiguration() throws PAPException, IOException { + // + // Create our properties object + // + Properties properties = new Properties() { + private static final long serialVersionUID = 1L; + // For Debugging it is helpful for the file to be in a sorted order, + // any by returning the keys in the natural Alpha order for strings we get close enough. + // TreeSet is sorted, and this just overrides the normal Properties method to get the keys. + @Override + public synchronized Enumeration keys() { + return Collections.enumeration(new TreeSet(super.keySet())); + } + }; + // + // Iterate our groups + // + List ids = new ArrayList(); + for (PDPGroup group : this.groups) { + ids.add(group.getId()); + properties.setProperty(group.getId() + ".name", (group.getName() == null ? "" : group.getName())); + properties.setProperty(group.getId() + ".description", (group.getDescription() == null ? "" : group.getDescription())); + // + // Iterate its PDPs + // + List pdps = new ArrayList(); + for (PDP pdp : group.getPdps()) { + pdps.add(pdp.getId()); + properties.setProperty(pdp.getId() + ".name", (pdp.getName() == null ? "" : pdp.getName())); + properties.setProperty(pdp.getId() + ".description", (pdp.getDescription() == null ? "" : pdp.getDescription())); + if (pdp instanceof EcompPDP) { + properties.setProperty(pdp.getId() + ".jmxport", (((EcompPDP)pdp).getJmxPort()==0 ? "" : ((EcompPDP)pdp).getJmxPort()).toString()); + } + } + String pdpList = ""; + if (pdps.size() == 1) { + pdpList = pdps.get(0); + } else if (pdps.size() > 1) { + pdpList = Joiner.on(',').skipNulls().join(pdps); + } + if (logger.isDebugEnabled()) { + logger.debug("Group " + group.getId() + " PDPS: " + pdpList); + } + properties.setProperty(group.getId() + ".pdps", pdpList); + } + if (ids.isEmpty()) { + throw new PAPException("Inconsistency - we have NO groups. We should have at least one."); + } + String groupList = ""; + if (ids.size() == 1) { + groupList = ids.get(0); + } else if (ids.size() > 1){ + groupList = Joiner.on(',').skipNulls().join(ids); + } + logger.info("New Group List: " + groupList); + + properties.setProperty(PROP_PAP_GROUPS, groupList); + // + // Get the default group + // + PDPGroup defaultGroup = this.getDefaultGroup(); + if (defaultGroup == null) { + throw new PAPException("Invalid state - no default group."); + } + properties.setProperty(PROP_PAP_GROUPS_DEFAULT, defaultGroup.getId()); + // + // Now we can save the file + // + Path file = Paths.get(this.repository.toString(), "xacml.properties"); + try (OutputStream os = Files.newOutputStream(file)) { + properties.store(os, ""); + } + } + + public static void removeGroupProperties(String id, Properties properties) { + for (Object key : properties.keySet()) { + if (key.toString().startsWith(id + ".")) { + properties.remove(key); + } + } + } + + public static void setGroupProperties(PDPGroup group, Properties properties) { + // + // make sure its in the list of groups + // + Iterable groups = Splitter.on(',').trimResults().omitEmptyStrings().split( properties.getProperty(PROP_PAP_GROUPS, "")); + boolean inList = false; + for (String g : groups) { + if (g.equals(group.getId())) { + inList = true; + } + } + if (inList == false) { + Set grps = Sets.newHashSet(groups); + grps.add(group.getId()); + String newGroupList = "";; + if (grps.size() == 1) { + newGroupList = grps.iterator().next(); + } else if (grps.size() > 1) { + newGroupList = Joiner.on(',').skipNulls().join(grps); + } + logger.info("New Group List: " + newGroupList); + properties.setProperty(PROP_PAP_GROUPS, newGroupList); + } + // + // Set its properties + // + properties.setProperty(group.getId() + ".name", group.getName()); + properties.setProperty(group.getId() + ".description", group.getDescription()); + // + // Set its PDP list + // + if (group.getPdps().size() > 0) { + String pdpList = ""; + if (group.getPdps().size() == 1) { + pdpList = group.getPdps().iterator().next().getId(); + } else if (group.getPdps().size() > 1) { + Set ids = new HashSet(); + for (PDP pdp : group.getPdps()) { + ids.add(pdp.getId()); + } + pdpList = Joiner.on(',').skipNulls().join(ids); + } + properties.setProperty(group.getId() + ".pdps", pdpList); + } else { + properties.setProperty(group.getId() + ".pdps", ""); + } + } + + + public void changed() { + if (logger.isDebugEnabled()) { + logger.debug("changed"); + } + this.doSave(); + this.fireChanged(); + } + + public void groupChanged(EcompPDPGroup group) { + if (logger.isDebugEnabled()) { + logger.debug("groupChanged: " + group); + } + this.doSave(); + this.firePDPGroupChanged(group); + } + + + public void pdpChanged(EcompPDP pdp) { + if (logger.isDebugEnabled()) { + logger.debug("pdpChanged: " + pdp); + } + this.doSave(); + this.firePDPChanged(pdp); + } + + private void doSave() { + try { + // + // Save the configuration + // + this.saveConfiguration(); + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to save configuration", e); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "StdEngine", "Failed to save configuration"); + } catch (PAPException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to save configuration", e); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "StdEngine", "Failed to save configuration"); + } + } + + // TODO: Adding Default PIP engine(s) while Loading initially. We don't want + // Programmer intervention with the PIP engines. + private Properties setPIPProperties(Properties props){ + props.setProperty(XACMLProperties.PROP_PIP_ENGINES, "AAF"); + props.setProperty("AAF.name", "AAFEngine"); + props.setProperty("AAF.description", "AAFEngine to communicate with AAF to take decisions"); + props.setProperty("AAF.classname","org.openecomp.policy.xacml.std.pip.engines.aaf.AAFEngine"); + return props; + } + + + @Override + public Set getEcompPDPGroups() throws PAPException { + final Set grps = new HashSet(); + for (EcompPDPGroup g : this.groups) { + grps.add(g); + } + return Collections.unmodifiableSet(grps); + } + + @Override + public EcompPDPGroup getPDPGroup(EcompPDP pdp) throws PAPException { + for (EcompPDPGroup group : this.groups) { + if (group.getPdps().contains(pdp)) { + return group; + } + } + return null; + } + + @Override + public void SetDefaultGroup(EcompPDPGroup group) throws PAPException { + boolean changesMade = false; + for (EcompPDPGroup aGroup : groups) { + if (aGroup.getId().equals(group.getId())) { + if ( ! aGroup.isDefaultGroup()) { +//TODO - since the original code checked for type we do also. + if (aGroup instanceof StdPDPGroup) { + ((StdPDPGroup) aGroup).setDefault(true); + changesMade = true; + } else { + throw new IllegalArgumentException("Group in groups of unknown type '" + aGroup.getClass().getName() + "'"); + } + } + } else { + // not the new default group + if (aGroup.isDefaultGroup()) { +//TODO - since the original code checked for type we do also. + if (aGroup instanceof StdPDPGroup) { + ((StdPDPGroup) aGroup).setDefault(false); + changesMade = true; + } else { + throw new IllegalArgumentException("Group in groups of unknown type '" + aGroup.getClass().getName() + "'"); + } + } + } + } + if (changesMade) { + this.doSave(); + } + + return; + + } + + @Override + public void newPDP(String id, EcompPDPGroup group, String name, String description, int jmxport) + throws PAPException, NullPointerException { + if (group == null) { + throw new PAPException("You must specify which group the PDP will belong to."); + } + if (this.groups.contains(group) == false) { + throw new PAPException("Unknown group, not in our list."); + } + for (EcompPDP p : group.getEcompPdps()) { + if (p.getId().equals(id)) { + throw new PAPException("A PDP with this ID exists."); + } + } + if (group instanceof StdPDPGroup) { + StdPDP pdp = new StdPDP(id, name, description, jmxport); + if (((StdPDPGroup) group).addPDP(pdp)) { + // + // Save the properties and notify any listeners + // + pdpChanged(pdp); + return; + } + } + return; + + } + + @Override + public void updateGroup(EcompPDPGroup group) throws PAPException { + if (group == null || group.getId() == null) { + throw new PAPException("Group or id is null"); + } + if (group.getName() == null || group.getName().trim().length() == 0) { + throw new PAPException("New name for group cannot be null or blank"); + } + StdPDPGroup existingGroup = (StdPDPGroup)getGroup(group.getId()); + if (existingGroup == null) { + throw new PAPException("Update found no existing group with id '" + group.getId() + "'"); + } + + + // We do dramatically different things when the Name changes + // because the Name is essentially the identity of the group (as the User knows it) so when the Identity changes we have to change the group ID. + if (group.getName().equals(existingGroup.getName())) { + + // update the disk + try { + ((StdPDPGroup)group).saveGroupConfiguration(); + } catch (IOException e) { + throw new PAPException("Unable to save new configuration for '" + group.getName() + "': " + e.getMessage()); + } + // update the group in the set by simply replacing the old instance with the new one + this.groups.remove(existingGroup); + this.groups.add((StdPDPGroup)group); + + } else { + // the name/identity of the group has changed + // generate the new id + String newId = createNewPDPGroupId(group.getName()); + + // make sure no other group uses the new id + for (EcompPDPGroup g : groups) { + if (g.getId().equals(newId)) { + throw new PAPException("Replacement name maps to ID '" + newId + "' which is already in use"); + } + } + ((StdPDPGroup)group).setId(newId); + + // rename the existing directory to the new id + Path oldPath = existingGroup.getDirectory(); + Path newPath = Paths.get(oldPath.getParent().toString(), newId); + ((StdPDPGroup)group).setDirectory(newPath); + + try { + boolean success = oldPath.toFile().renameTo(newPath.toFile()); + if ( ! success) { + throw new PAPException("Unable to rename directory; reason unknown"); + } + } catch (Exception e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Move '" + oldPath + "' to '" + newPath + "': " + e.getMessage(), e); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "StdEngine", "Unable to rename directory"); + throw new PAPException("Unable to move directory from '" + oldPath + "' to '" + newPath + "': " + e.getMessage()); + } + // update the disk + try { + ((StdPDPGroup)group).saveGroupConfiguration(); + } catch (IOException e) { + throw new PAPException("Unable to save new configuration for '" + group.getName() + "': " + e.getMessage()); + } + + // save the new group into the Set + groups.remove(existingGroup); + groups.add((StdPDPGroup)group); + + } + + // perhaps only the group changed, but if the name/id changed it may look to a listener like more than one group + changed(); + + + } + + @Override + public void removeGroup(EcompPDPGroup group, EcompPDPGroup newGroup) throws PAPException, NullPointerException { + if (group == null) { + throw new NullPointerException(); + } + // + // Does this group exist? + // + if (this.groups.contains(group) == false) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "This group doesn't exist."); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "This group doesn't exist."); + throw new PAPException("The group '" + group.getId() + "' does not exist"); + } + // + // Is it the default group? + // + if (group.isDefaultGroup()) { + throw new PAPException("You cannot delete the default group."); + } + Set pdps = group.getEcompPdps(); + // + // Are there PDPs? If so, then we need a target group + // + if (pdps.isEmpty() == false && newGroup == null) { + throw new NullPointerException("Group targeted for deletion has PDPs, you must provide a new group for them."); + } + // + // Move the PDPs + // + if (pdps.isEmpty() == false) { + if (! (newGroup instanceof StdPDPGroup)) { + throw new PAPException("Unexpected class for newGroup: " + newGroup.getClass().getCanonicalName()); + } + // The movePDP function will modify the set of PDPs in the group. + // To avoid concurrent modification exceptions we need to duplicate the list before calling that function. + List pdpList = new ArrayList(); + for (EcompPDP pdp : pdps) { + pdpList.add(pdp); + } + // now we can use the PDPs from the list without having ConcurrentAccessExceptions + for (EcompPDP pdp : pdpList) { + this.movePDP(pdp, newGroup); + } + } + // + // remove the directory for the group + // + String id = group.getId(); + Path groupPath = Paths.get(this.repository.toString(), id); + // + // If it exists already + // + if ( ! Files.exists(groupPath)) { + logger.warn("removeGroup " + id + " directory does not exist" + groupPath.toString()); + } else { + try { + Files.walkFileTree(groupPath, new SimpleFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return super.visitFile(file, attrs); + } + + }); + // + // delete the directory + // + Files.delete(groupPath); + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to delete " + groupPath + ": " +e); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdEngine", "Failed to delete " + groupPath); + throw new PAPException("Failed to delete " + id); + } + } + + // remove the group from the set of all groups + groups.remove(group); + + // + // Save changes + // + changed(); + this.doSave(); + return; + + } + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdEngineFactory.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdEngineFactory.java new file mode 100644 index 000000000..b8ca1f2e9 --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdEngineFactory.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.std.pap; + +import org.openecomp.policy.common.logging.eelf.MessageCodes; +import org.openecomp.policy.common.logging.eelf.PolicyLogger; + +import java.io.IOException; +import java.util.Properties; + +import org.openecomp.policy.xacml.api.pap.ECOMPPapEngineFactory; +import org.openecomp.policy.xacml.api.pap.PAPPolicyEngine; + +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.util.FactoryException; + +public class StdEngineFactory extends ECOMPPapEngineFactory { + + @Override + public PAPPolicyEngine newEngine() throws FactoryException, PAPException { + try { + return (PAPPolicyEngine) new StdEngine(); + } catch (IOException e) { + PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "StdEngineFactory", "Failed to create engine"); + return null; + } + } + + @Override + public PAPPolicyEngine newEngine(Properties properties) throws FactoryException, + PAPException { + try { + return (PAPPolicyEngine) new StdEngine(properties); + } catch (IOException e) { + PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "StdEngineFactory", "Failed to create engine"); + return null; + } + } + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPAPPolicy.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPAPPolicy.java new file mode 100644 index 000000000..f4817ac8a --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPAPPolicy.java @@ -0,0 +1,889 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.std.pap; + +import java.io.Serializable; +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.openecomp.policy.xacml.api.pap.EcompPAPPolicy; + +public class StdPAPPolicy implements EcompPAPPolicy, Serializable{ + private static final long serialVersionUID = 5260230629397322000L; + + private String policyName = null; + private String oldPolicyFileName = null; + private String policyDescription = null; + private String ecompName = null; + private String configName = null; + private Map dyanamicFieldConfigAttributes = new HashMap(); + private Map dropDownMap = new HashMap(); + private Map dynamicSettingsMap = new HashMap(); + private List dynamicRuleAlgorithmLabels; + private List dynamicRuleAlgorithmCombo; + private List dynamicRuleAlgorithmField1; + private List dynamicRuleAlgorithmField2; + private List dynamicVariableList; + private List dataTypeList; + private String configBodyData = null; + private String policyID = null; + private String ruleID = null; + private String configType = null; + private Boolean editPolicy = false; + private Boolean draft = false; + private String version = null; + private String domain = null; + private String configPolicyType = null; + private String jsonBody = null; + private String serviceType = null; + private Integer highestVersion = null; + private URI location = null; + private String actionPerformer = null; + private String actionAttribute = null; + private String actionBody = null; + private String actionDictHeader = null; + private String actionDictType = null; + private String actionDictUrl = null; + private String actionDictMethod = null; + private String uuid = null; + private String msLocation = null; + private String priority = null; + private Map drlRuleAndUIParams=null; + private String deleteCondition = null; + private String dictionaryType = null; + private String dictionary = null; + private Map dictionaryFields = new HashMap(); + private String providerComboBox = null; + private String riskType = null; + private String guard = null; + private String riskLevel; + private String ttlDate = null; + + + public StdPAPPolicy() { + + } + + //Constructor for sending location when pushing policies + public StdPAPPolicy(URI location) { + this.location = location; + } + + //Constructor for Validating Config Policies + public StdPAPPolicy(String policyName, String body, String configType, String configPolicyType) { + this.policyName = policyName; + this.configBodyData = body; + this.configType = configType; + this.configPolicyType = configPolicyType; + } + + //convenience constructor + public StdPAPPolicy(String configPolicyType, String policyName, String description, String ecompName, String configName, Map attributes, String configType, + String body, Boolean editPolicy, String domain, String riskLevel, String riskType, String guard, String ttlDate){ + this(configPolicyType, policyName, description, ecompName, configName, attributes, configType, + body, editPolicy, domain, 1, riskLevel, riskType, guard, ttlDate); + } + + //Constructor for Create/Update Action Policies from API + public StdPAPPolicy(String policyName, String description, Map attributes, List dynamicRuleAlgorithmLabels, List dynamicRuleAlgorithmCombo, + List dynamicRuleAlgorithmField1, List dynamicRuleAlgorithmField2, String actionPerformer,String actionAttribute, Boolean editPolicy, + String domain, int highestVersion) { + + this.policyName = policyName; + this.policyDescription = description; + this.dyanamicFieldConfigAttributes = attributes; + this.dynamicRuleAlgorithmLabels = dynamicRuleAlgorithmLabels; + this.dynamicRuleAlgorithmCombo = dynamicRuleAlgorithmCombo; + this.dynamicRuleAlgorithmField1 = dynamicRuleAlgorithmField1; + this.dynamicRuleAlgorithmField2 = dynamicRuleAlgorithmField2; + this.actionPerformer = actionPerformer; + this.actionAttribute = actionAttribute; + this.editPolicy = editPolicy; + this.domain = domain; + this.highestVersion = highestVersion; + + } + + //Constructor for Create/Update Decision Policies from Admin Console + public StdPAPPolicy(String policyName, String description, String ecompName, String providerComboBox, Map attributes, Map settings, + List dynamicRuleAlgorithmLabels, List dynamicRuleAlgorithmCombo, List dynamicRuleAlgorithmField1, + List dynamicRuleAlgorithmField2, Map dropDownMap, List dynamicVariableList, + List dataTypeList, Boolean editPolicy, String domain, int highestVersion) { + + this.policyName = policyName; + this.policyDescription = description; + this.ecompName = ecompName; + this.setProviderComboBox(providerComboBox); + this.dyanamicFieldConfigAttributes = attributes; + this.dynamicSettingsMap = settings; + this.dynamicRuleAlgorithmLabels = dynamicRuleAlgorithmLabels; + this.dynamicRuleAlgorithmCombo = dynamicRuleAlgorithmCombo; + this.dynamicRuleAlgorithmField1 = dynamicRuleAlgorithmField1; + this.dynamicRuleAlgorithmField2 = dynamicRuleAlgorithmField2; + this.dynamicVariableList = dynamicVariableList; + this.dataTypeList = dataTypeList; + this.dropDownMap = dropDownMap; + this.editPolicy = editPolicy; + this.domain = domain; + this.highestVersion = highestVersion; + + } + + + //Constructor for Create Config Policies from API and Admin Console + //Constructor for Updating Config Policies from the API + public StdPAPPolicy(String configPolicyType, String policyName, String description, String ecompName, String configName, Map attributes, String configType, + String body, Boolean editPolicy, String domain, int highestVersion, String riskLevel, String riskType, String guard, String ttlDate) { + + this.configPolicyType = configPolicyType; + this.policyName = policyName; + this.policyDescription = description; + this.ecompName = ecompName; + this.configName = configName; + this.dyanamicFieldConfigAttributes = attributes; + this.configType = configType; + this.configBodyData = body; + this.editPolicy = editPolicy; + this.domain = domain; + this.highestVersion = highestVersion; + this.riskLevel = riskLevel; + this.riskType = riskType; + this.guard = guard; + this.ttlDate = ttlDate; + } + + //convenience constructor + public StdPAPPolicy (String configPolicyType, String policyName, String description, String ecompName, String configName, Map attributes, String body, String policyID, + String ruleID, String configType, Boolean editPolicy, String version, String domain, String riskLevel, String riskType, String guard, String ttlDate) { + this (configPolicyType, policyName, description, ecompName, configName, attributes, body, policyID, + ruleID, configType, editPolicy, version, domain, 1, riskLevel, riskType, guard, ttlDate); + } + + //Constructor for Updating Config Policies from Admin Console + public StdPAPPolicy (String configPolicyType, String policyName, String description, String ecompName, String configName, Map attributes, String body, String policyID, + String ruleID, String configType, Boolean editPolicy, String version, String domain, int highestVersion, String riskLevel, String riskType, String guard, String ttlDate) { + + this.configPolicyType = configPolicyType; + this.policyName = policyName; + this.policyDescription = description; + this.ecompName = ecompName; + this.configName = configName; + this.dyanamicFieldConfigAttributes = attributes; + this.configBodyData = body; + this.policyID = policyID; + this.ruleID = ruleID; + this.configType = configType; + this.editPolicy = editPolicy; + this.version = version; + this.domain = domain; + this.highestVersion = highestVersion; + this.riskLevel = riskLevel; + this.riskType = riskType; + this.guard = guard; + this.ttlDate = ttlDate; + } + + + //Constructor for Creating Config Firewall Policies + public StdPAPPolicy (String configPolicyType, String policyName, String description, String configName, + Boolean editPolicy, String domain, String jsonBody, Integer highestVersion, String riskLevel, String riskType, String guard, String ttlDate) { + + this.configPolicyType = configPolicyType; + this.policyName = policyName; + this.policyDescription = description; + this.configName = configName; + this.editPolicy = editPolicy; + this.domain = domain; + this.jsonBody = jsonBody; + this.highestVersion = highestVersion; + this.riskLevel = riskLevel; + this.riskType = riskType; + this.guard = guard; + this.ttlDate = ttlDate; + + } + + //Constructor for Creating Goc Policies + public StdPAPPolicy (String configPolicyType, String policyName, String description, String configName, + Boolean editPolicy, String domain, String jsonBody, Integer highestVersion, String eCompName, String riskLevel, String riskType, String guard, String ttlDate) { + + this.configPolicyType = configPolicyType; + this.policyName = policyName; + this.policyDescription = description; + this.configName = configName; + this.editPolicy = editPolicy; + this.domain = domain; + this.jsonBody = jsonBody; + this.highestVersion = highestVersion; + this.ecompName=eCompName; + this.riskLevel = riskLevel; + this.riskType = riskType; + this.guard = guard; + this.ttlDate = ttlDate; + } + + //Constructor for Creating BRMS Policies from the Admin Console + public StdPAPPolicy (String configPolicyType, String policyName, String description, + String configName, Boolean editPolicy, String domain, + Map dyanamicFieldConfigAttributes, Integer highestVersion, String eCompName, + String configBodyData, String riskLevel, String riskType, String guard, String ttlDate) { + + this.configPolicyType = configPolicyType; + this.policyName = policyName; + this.policyDescription = description; + this.configName = configName; + this.editPolicy = editPolicy; + this.domain = domain; + this.dyanamicFieldConfigAttributes = dyanamicFieldConfigAttributes; + this.highestVersion = highestVersion; + this.ecompName=eCompName; + this.configBodyData=configBodyData; + this.riskLevel = riskLevel; + this.riskType = riskType; + this.guard = guard; + this.ttlDate = ttlDate; + } + + //Constructor for Creating BRMS Param Policies from the Admin Console + public StdPAPPolicy (String configPolicyType, String policyName, String description, + String configName, Boolean editPolicy, String domain, + Map dyanamicFieldConfigAttributes, Integer highestVersion, String eCompName, + String configBodyData,Map drlRuleAndUIParams, String riskLevel, String riskType, String guard, String ttlDate) { + + this.configPolicyType = configPolicyType; + this.policyName = policyName; + this.policyDescription = description; + this.configName = configName; + this.editPolicy = editPolicy; + this.domain = domain; + this.dyanamicFieldConfigAttributes = dyanamicFieldConfigAttributes; + this.highestVersion = highestVersion; + this.ecompName=eCompName; + this.configBodyData=configBodyData; + this.drlRuleAndUIParams=drlRuleAndUIParams; + this.riskLevel = riskLevel; + this.riskType = riskType; + this.guard = guard; + this.ttlDate = ttlDate; + } + + //Constructor for Creating CloseLoop_Fault and Performance Metric Policies + public StdPAPPolicy (String configPolicyType, String policyName, String description, String ecompName, + String jsonBody, Boolean draft, String oldPolicyFileName, String serviceType, Boolean editPolicy, + String domain, Integer highestVersion, String riskLevel, String riskType, String guard, String ttlDate) { + + this.configPolicyType = configPolicyType; + this.policyName = policyName; + this.policyDescription = description; + this.ecompName = ecompName; + this.jsonBody = jsonBody; + this.draft = draft; + this.oldPolicyFileName = oldPolicyFileName; + this.serviceType = serviceType; + this.editPolicy = editPolicy; + this.domain = domain; + this.highestVersion = highestVersion; + this.riskLevel = riskLevel; + this.riskType = riskType; + this.guard = guard; + this.ttlDate = ttlDate; + } + + //Constructor for Updating Config Firewall Policies from the Admin Console + public StdPAPPolicy (String configPolicyType, String policyName, String description, String configName, Boolean editPolicy, String domain, String policyID, + String ruleID, String version, String jsonBody, Integer highestVersion, String riskLevel, String riskType, String guard, String ttlDate) { + + this.configPolicyType = configPolicyType; + this.policyName = policyName; + this.policyDescription = description; + this.configName = configName; + this.editPolicy = editPolicy; + this.domain = domain; + this.policyID = policyID; + this.ruleID = ruleID; + this.version = version; + this.jsonBody = jsonBody; + this.highestVersion = highestVersion; + this.riskLevel = riskLevel; + this.riskType = riskType; + this.guard = guard; + this.ttlDate = ttlDate; + } + + //Constructor for Micro Service Creating/Updating Policies from the Admin Console + public StdPAPPolicy(String configPolicyType, String policyName, String description, String ecompName, String configName, String serviceType, String uuid, + String msLocation, String jsonBody, String priority, String version, Boolean editPolicy, String domain, int highestVersion, String riskLevel, + String riskType, String guard, String ttlDate) { + + this.configPolicyType = configPolicyType; + this.policyName = policyName; + this.policyDescription = description; + this.ecompName = ecompName; + this.configName = configName; + this.serviceType = serviceType; + this.uuid = uuid; + this.msLocation = msLocation; + this.priority = priority; + this.version = version; + this.jsonBody = jsonBody; + this.editPolicy = editPolicy; + this.domain = domain; + this.highestVersion = highestVersion; + this.riskLevel = riskLevel; + this.riskType = riskType; + this.guard = guard; + this.ttlDate = ttlDate; + } + + //Constructor for Updating Goc Policies from the Admin Console + public StdPAPPolicy (String configPolicyType, String policyName, String description, + String configName, Boolean editPolicy, String domain, + String policyID, String ruleID, String version, + String jsonBody, Integer highestVersion, String eCompName,String riskLevel, String riskType, String guard, String ttlDate) { + + this.configPolicyType = configPolicyType; + this.policyName = policyName; + this.policyDescription = description; + this.configName = configName; + this.editPolicy = editPolicy; + this.domain = domain; + this.policyID = policyID; + this.ruleID = ruleID; + this.version = version; + this.jsonBody = jsonBody; + this.highestVersion = highestVersion; + this.ecompName=eCompName; + this.riskLevel = riskLevel; + this.riskType = riskType; + this.guard = guard; + this.ttlDate = ttlDate; + } + + //Constructor for Updating Brms Policies from the Admin Console + public StdPAPPolicy (String configPolicyType, String policyName, String description, + String configName, Boolean editPolicy, String domain, + String policyID, String ruleID, String version, + Map dyanamicFieldConfigAttributes, Integer highestVersion, String eCompName, + String configBodyData , String riskLevel, String riskType, String guard, String ttlDate + ) { + this.configPolicyType = configPolicyType; + this.policyName = policyName; + this.policyDescription = description; + this.configName = configName; + this.editPolicy = editPolicy; + this.domain = domain; + this.policyID = policyID; + this.ruleID = ruleID; + this.version = version; + this.dyanamicFieldConfigAttributes = dyanamicFieldConfigAttributes; + this.highestVersion = highestVersion; + this.ecompName=eCompName; + this.configBodyData=configBodyData; + this.riskLevel = riskLevel; + this.riskType = riskType; + this.guard = guard; + this.ttlDate = ttlDate; + } + + //Constructor for Updating Brms Param Policies from the Admin Console + public StdPAPPolicy (String configPolicyType, String policyName, String description, + String configName, Boolean editPolicy, String domain, + String policyID, String ruleID, String version, + Map dyanamicFieldConfigAttributes, Integer highestVersion, String eCompName, + Map drlRuleAndUIParams, String riskLevel, String riskType, String guard, String ttlDate + ) { + this.configPolicyType = configPolicyType; + this.policyName = policyName; + this.policyDescription = description; + this.configName = configName; + this.editPolicy = editPolicy; + this.domain = domain; + this.policyID = policyID; + this.ruleID = ruleID; + this.version = version; + this.dyanamicFieldConfigAttributes = dyanamicFieldConfigAttributes; + this.highestVersion = highestVersion; + this.ecompName=eCompName; + this.drlRuleAndUIParams=drlRuleAndUIParams; + this.riskLevel = riskLevel; + this.riskType = riskType; + this.guard = guard; + this.ttlDate = ttlDate; + } + + // Constructor for deleting policies from the API + public StdPAPPolicy(String policyName, String deleteCondition) { + this.policyName = policyName; + this.deleteCondition = deleteCondition; + } + + // Constructor for creating dictionary items from the API + public StdPAPPolicy(String dictionaryType, String dictionary, Map dictionaryFields) { + this.dictionaryType = dictionaryType; + this.dictionary = dictionary; + this.dictionaryFields = dictionaryFields; + } + + @Override + public String getPolicyName() { + return policyName; + } + + @Override + public String getPolicyDescription() { + return policyDescription; + } + + @Override + public String getEcompName() { + return ecompName; + } + + @Override + public String getConfigName() { + return configName; + } + + @Override + public Map getDynamicFieldConfigAttributes() { + return dyanamicFieldConfigAttributes; + } + + @Override + public String getConfigBodyData() { + return configBodyData; + } + + @Override + public String getPolicyID() { + return policyID; + } + + @Override + public String getRuleID() { + return ruleID; + } + + @Override + public String getConfigType() { + return configType; + } + + @Override + public Boolean isEditPolicy() { + return editPolicy; + } + + @Override + public Boolean isDraft() { + return draft; + } + + @Override + public String getVersion() { + return version; + } + + @Override + public String getDomainDir() { + return domain; + } + + @Override + public String getConfigPolicyType() { + return configPolicyType; + } + + @Override + public String getJsonBody() { + return jsonBody; + } + + @Override + public Integer getHighestVersion() { + return highestVersion; + } + + @Override + public URI getLocation() { + return location; + } + + @Override + public List getDynamicRuleAlgorithmLabels() { + return dynamicRuleAlgorithmLabels; + } + + @Override + public List getDynamicRuleAlgorithmCombo() { + return dynamicRuleAlgorithmCombo; + } + + @Override + public List getDynamicRuleAlgorithmField1() { + return dynamicRuleAlgorithmField1; + } + + @Override + public List getDynamicRuleAlgorithmField2() { + return dynamicRuleAlgorithmField2; + } + + @Override + public String getActionPerformer() { + return actionPerformer; + } + + @Override + public String getActionAttribute() { + return actionAttribute; + } + + @Override + public String getActionBody() { + return actionBody; + } + + @Override + public Map getDropDownMap() { + return dropDownMap; + } + + @Override + public String getActionDictHeader() { + return actionDictHeader; + } + + @Override + public String getActionDictType() { + return actionDictType; + } + + @Override + public String getActionDictUrl() { + return actionDictUrl; + } + + @Override + public String getActionDictMethod() { + return actionDictMethod; + } + + @Override + public Map getDynamicSettingsMap() { + return dynamicSettingsMap; + } + + @Override + public List getDynamicVariableList() { + return dynamicVariableList; + } + + @Override + public List getDataTypeList() { + return dataTypeList; + } + + @Override + public String getOldPolicyFileName() { + return oldPolicyFileName; + } + + @Override + public String getServiceType() { + return serviceType; + } + + @Override + public String getUuid() { + return uuid; + } + + @Override + public String getMsLocation() { + return msLocation; + } + + @Override + public String getPriority() { + return priority; + } + + @Override + public String getDeleteCondition() { + return deleteCondition; + } + + @Override + public String getDictionaryType() { + return dictionaryType; + } + + @Override + public String getDictionary() { + return dictionary; + } + + @Override + public String getTTLDate(){ + return ttlDate; + } + + @Override + public Map getDictionaryFields() { + return dictionaryFields; + } + + @Override + public String getRiskType() { + return riskType; + } + + @Override + public String getRiskLevel() { + return riskLevel; + } + + @Override + public String getGuard() { + return guard; + } + + @Override + public String toString() { + return "StdPAPPolicy [policyName=" + policyName + ", policyDescription=" + policyDescription + ", ecompName=" + + ecompName + ", configName=" + configName + ", dyanamicFieldConfigAttributes=" + dyanamicFieldConfigAttributes + ", configBodyData=" + configBodyData + + ", policyID=" + policyID + ", ruleID=" + ruleID + ", configType=" + configType + ", editPolicy=" + ", version=" + ", domain=" + domain + + ", configPolicyType=" + configPolicyType + ", jsonBody=" + jsonBody + ", highestVersion=" + highestVersion + ", location=" + location + + ",dynamicRuleAlgorithmLabels=" + dynamicRuleAlgorithmLabels + ",dynamicRuleAlgorithmCombo=" + dynamicRuleAlgorithmCombo + + ",dynamicRuleAlgorithmField1=" + dynamicRuleAlgorithmField1 + ",dynamicRuleAlgorithmField2=" + dynamicRuleAlgorithmField2 + + ",actionPerformer=" + actionPerformer + ",actionAttribute=" + actionAttribute + ",actionBody=" + actionBody + ",dropDownMap=" + dropDownMap + + ",actionDictHeader=" + actionDictHeader + ",actionDictType=" + actionDictType + ",actionDictUrl=" + actionDictUrl + + ",actionDictMethod=" + actionDictMethod + ",dynamicSettingsMap=" + dynamicSettingsMap + ",dynamicVariableList=" + dynamicVariableList + ",providerComboBox=" + providerComboBox + + ",dataTypeList=" + dataTypeList + ",draft=" + ",oldPolicyFileName=" + oldPolicyFileName + ",serviceType=" + serviceType + + ",uuid=" + uuid + ",msLocation=" + msLocation + ",priority=" + priority + ",deleteCondition=" + deleteCondition + ",dictionaryType=" + dictionaryType + + ",dictionary=" + dictionary + ",dictionaryFields=" + dictionaryFields + ",uuid=" + uuid + ",msLocation=" + msLocation + ",priority=" + + priority + ",deleteCondition=" + deleteCondition + ",riskType="+riskType + ",riskLevel="+riskLevel + ",guard="+ guard + ",ttlDate="+ ttlDate + "]"; + } + + // Methods needed for JSON Deserialization + public void setPolicyName(String policyName) { + this.policyName = policyName; + } + + public void setPolicyDescription(String policyDescription) { + this.policyDescription = policyDescription; + } + + public void setEcompName(String ecompName) { + this.ecompName = ecompName; + } + + public void setConfigName(String configName) { + this.configName = configName; + } + + public void setDyanamicFieldConfigAttributes( + Map dyanamicFieldConfigAttributes) { + this.dyanamicFieldConfigAttributes = dyanamicFieldConfigAttributes; + } + + public void setConfigBodyData(String configBodyData) { + this.configBodyData = configBodyData; + } + + public void setPolicyID(String policyID) { + this.policyID = policyID; + } + + public void setRuleID(String ruleID) { + this.ruleID = ruleID; + } + + public void setConfigType(String configType) { + this.configType = configType; + } + + public void setEditPolicy(Boolean editPolicy) { + this.editPolicy = editPolicy; + } + + public void setVersion(String version) { + this.version = version; + } + + public void setDomainDir(String domain) { + this.domain = domain; + } + + public void setConfigPolicyType(String configPolicyType) { + this.configPolicyType = configPolicyType; + } + + public void setJsonBody(String jsonBody) { + this.jsonBody = jsonBody; + } + + public void setHighestVersion(Integer highestVersion) { + this.highestVersion = highestVersion; + } + + public void setLocation (URI location) { + this.location = location; + } + + public void setDynamicRuleAlgorithmLabels( + List dynamicRuleAlgorithmLabels) { + this.dynamicRuleAlgorithmLabels = dynamicRuleAlgorithmLabels; + } + + public void setDynamicRuleAlgorithmCombo(List dynamicRuleAlgorithmCombo) { + this.dynamicRuleAlgorithmCombo = dynamicRuleAlgorithmCombo; + } + + public void setDynamicRuleAlgorithmField1( + List dynamicRuleAlgorithmField1) { + this.dynamicRuleAlgorithmField1 = dynamicRuleAlgorithmField1; + } + + public void setDynamicRuleAlgorithmField2( + List dynamicRuleAlgorithmField2) { + this.dynamicRuleAlgorithmField2 = dynamicRuleAlgorithmField2; + } + + public void setActionPerformer(String actionPerformer) { + this.actionPerformer = actionPerformer; + } + + public void setActionAttribute(String actionAttribute) { + this.actionAttribute = actionAttribute; + } + + public void setActionBody(String actionBody) { + this.actionBody = actionBody; + } + + public void setDropDownMap(Map dropDownMap) { + this.dropDownMap = dropDownMap; + } + + public void setActionDictHeader(String actionDictHeader) { + this.actionDictHeader = actionDictHeader; + } + + public void setActionDictType(String actionDictType) { + this.actionDictType = actionDictType; + } + + public void setActionDictUrl(String actionDictUrl) { + this.actionDictUrl = actionDictUrl; + } + + public void setActionDictMethod(String actionDictMethod) { + this.actionDictMethod = actionDictMethod; + } + + public void setDynamicSettingsMap(Map dynamicSettingsMap) { + this.dynamicSettingsMap = dynamicSettingsMap; + } + + public void setDynamicVariableList(List dynamicVariableList) { + this.dynamicVariableList = dynamicVariableList; + } + + public void setDataTypeList(List dataTypeList) { + this.dataTypeList = dataTypeList; + } + + public void setDraft(Boolean draft) { + this.draft = draft; + } + + public void setOldPolicyFileName(String oldPolicyFileName) { + this.oldPolicyFileName = oldPolicyFileName; + } + + public void setServiceType(String serviceType) { + this.serviceType = serviceType; + } + + + public Map getDrlRuleAndUIParams() { + return drlRuleAndUIParams; + } + + public void setDrlRuleAndUIParams(Map drlRuleAndUIParams) { + this.drlRuleAndUIParams = drlRuleAndUIParams; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public void setMsLocation(String msLocation) { + this.msLocation = msLocation; + } + + public void setPriority(String priority) { + this.priority = priority; + } + + public void setDeleteCondition(String deleteCondition) { + this.deleteCondition = deleteCondition; + } + + public void setDictionaryType(String dictionaryType) { + this.dictionaryType = dictionaryType; + } + + public void setDictionary(String dictionary) { + this.dictionary = dictionary; + } + + public void setDictionaryFields(Map dictionaryFields) { + this.dictionaryFields = dictionaryFields; + } + + public String getProviderComboBox() { + return providerComboBox; + } + + public void setProviderComboBox(String providerComboBox) { + this.providerComboBox = providerComboBox; + } + + public void setRiskType(String riskType){ + this.riskType = riskType; + } + + public void setRiskLevel(String riskLevel){ + this.riskLevel = riskLevel; + } + + public void setGuard(String guard){ + this.guard = guard; + } + + public void setTTLDate(String ttlDate){ + this.ttlDate = ttlDate; + } +} + diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDP.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDP.java new file mode 100644 index 000000000..b8fb59b60 --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDP.java @@ -0,0 +1,222 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.std.pap; + +import java.io.Serializable; +import java.util.Collections; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; + +import org.openecomp.policy.xacml.api.pap.EcompPDP; + +import org.openecomp.policy.common.logging.flexlogger.FlexLogger; +import org.openecomp.policy.common.logging.flexlogger.Logger; +import com.att.research.xacml.api.pap.PDPPIPConfig; +import com.att.research.xacml.api.pap.PDPPolicy; +import com.att.research.xacml.api.pap.PDPStatus; + +public class StdPDP extends StdPDPItemSetChangeNotifier implements EcompPDP, Comparable, Serializable { + private static final long serialVersionUID = 1L; + private static Logger logger = FlexLogger.getLogger(StdPDP.class); + + private String id; + + private String name; + + private String description; + + private Integer jmxport = 0; + + private PDPStatus status = new StdPDPStatus(); + + private Set policies = new HashSet(); + + private Set pipConfigs = new HashSet(); + + public StdPDP() { + + } + + public StdPDP(String id, Integer jmxport) { + this(id, null, null, jmxport); + } + + public StdPDP(String id, String name, Integer jmxport) { + this(id, name, null, jmxport); + } + + public StdPDP(String id, String name, String description, Integer jmxport) { + this.id = id; + this.name = name; + this.description = description; + if(jmxport != null){ + this.jmxport = jmxport; + } + } + + public StdPDP(String id, Properties properties) { + this(id, 0); + + this.initialize(properties); + } + + public void initialize(Properties properties) { + for (Object key : properties.keySet()) { + if (key.toString().startsWith(this.id + ".")) { + if (logger.isDebugEnabled()) { + logger.debug("Found: " + key); + } + if (key.toString().endsWith(".name")) { + this.name = properties.getProperty(key.toString()); + } else if (key.toString().endsWith(".description")) { + this.description = properties.getProperty(key.toString()); + }else if (key.toString().endsWith(".jmxport")) { + //todo fix this hackjob + if (properties.getProperty(key.toString()) != null && properties.getProperty(key.toString()).trim().length() > 0){ + logger.debug("initialize before: " + this.jmxport); + this.jmxport = Integer.valueOf( properties.getProperty(key.toString())); + logger.debug("initialize after: " + this.jmxport); + }else{ + this.jmxport = 0; + } + } + } + } + } + + @Override + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id=id; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public void setName(String name) { + this.name = name; + this.firePDPChanged(this); + } + + @Override + public String getDescription() { + return this.description; + } + + @Override + public void setDescription(String description) { + this.description = description; + this.firePDPChanged(this); + } + + @Override + public PDPStatus getStatus() { + return this.status; + } + + public void setStatus(PDPStatus status) { + this.status = status; + } + + @Override + public Set getPolicies() { + return Collections.unmodifiableSet(this.policies); + } + + public void setPolicies(Set policies) { + this.policies = policies; + } + + @Override + public Set getPipConfigs() { + return Collections.unmodifiableSet(this.pipConfigs); + } + + public void setPipConfigs(Set pipConfigs) { + this.pipConfigs = pipConfigs; + } + public void setJmxPort(Integer jmxport) { + this.jmxport = jmxport; + } + @Override + public Integer getJmxPort() { + return this.jmxport; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StdPDP other = (StdPDP) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + + @Override + public String toString() { + return "StdPDP [id=" + id + ", name=" + name + ", description=" + + description + ", jmxport=" + jmxport + ", status=" + status + ", policies=" + policies + + ", pipConfigs=" + pipConfigs + "]"; + } + + // + // Comparable interface + // + @Override + public int compareTo(StdPDP o) { + if (o == null) { + return -1; + } + if ( ! (o instanceof StdPDP)) { + return -1; + } + if (((StdPDP)o).name == null) { + return -1; + } + if (name == null) { + return 1; + } + return name.compareTo(((StdPDP)o).name); + } + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPGroup.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPGroup.java new file mode 100644 index 000000000..ae4a43db6 --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPGroup.java @@ -0,0 +1,1031 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.std.pap; + +import org.openecomp.policy.common.logging.eelf.MessageCodes; +import org.openecomp.policy.common.logging.eelf.PolicyLogger; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Serializable; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.policy.xacml.api.pap.EcompPDP; +import org.openecomp.policy.xacml.api.pap.EcompPDPGroup; +import org.openecomp.policy.xacml.std.pap.StdPDPItemSetChangeNotifier.StdItemSetChangeListener; + +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDP; +import com.att.research.xacml.api.pap.PDPGroup; +//import com.att.research.xacml.api.pap.PDPGroup; +import com.att.research.xacml.api.pap.PDPGroupStatus; +import com.att.research.xacml.api.pap.PDPGroupStatus.Status; +import com.att.research.xacml.api.pap.PDPPIPConfig; +import com.att.research.xacml.api.pap.PDPPolicy; +import com.att.research.xacml.util.XACMLProperties; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; +import com.google.common.io.ByteStreams; + +public class StdPDPGroup extends StdPDPItemSetChangeNotifier implements EcompPDPGroup, StdItemSetChangeListener, Comparable, Serializable { + private static final long serialVersionUID = 1L; + private static Log logger = LogFactory.getLog(StdPDPGroup.class); + + private String id; + + private boolean isDefault = false; + + private String name; + + private String description; + + private StdPDPGroupStatus status = new StdPDPGroupStatus(Status.UNKNOWN); + + private Set pdps = new HashSet(); + + private Set policies = new HashSet(); + + private Set pipConfigs = new HashSet(); + + @JsonIgnore + private Path directory; + + @JsonIgnore + private Integer jmxport; + + + public StdPDPGroup(String id, Path directory) { + this.id = id; + this.directory = directory; + } + + public StdPDPGroup(String id, boolean isDefault, Path directory) { + this(id, directory); + this.isDefault = isDefault; + } + + public StdPDPGroup(String id, boolean isDefault, String name, String description, Path directory) { + this(id, isDefault, directory); + this.name = name; + // force all policies to have a name + if (name == null) { + this.name = id; + } + this.description = description; + } + + public StdPDPGroup(String id, String name, String description, Path directory) { + this(id, false, name, description, directory); + this.resetStatus(); + } + + public StdPDPGroup(String id, boolean isDefault, Properties properties, Path directory) throws PAPException { + this(id, isDefault, directory); + this.initialize(properties, directory); + this.resetStatus(); + } + + private void initialize(Properties properties, Path directory) throws PAPException { + if (this.id == null || this.id.length() == 0) { + logger.warn("Cannot initialize with a null or zero length id"); + return; + } + // + // Pull the group's properties + // + for (Object key : properties.keySet()) { + if (key.toString().startsWith(this.id + ".")) { + if (key.toString().endsWith(".name")) { + this.name = properties.getProperty(key.toString()); + } else if (key.toString().endsWith(".description")) { + this.description = properties.getProperty(key.toString()); + } else if (key.toString().endsWith(".pdps")) { + String pdpList = properties.getProperty(key.toString()); + if (pdpList != null && pdpList.length() > 0) { + for (String id : Splitter.on(',').omitEmptyStrings().trimResults().split(pdpList)) { + StdPDP pdp = new StdPDP(id, properties); + pdp.addItemSetChangeListener(this); + this.pdps.add(pdp); + } + } + } + } + // force all policies to have a name + if (this.name == null) { + this.name = this.id; + } + } + // + // Validate our directory + // + if (Files.notExists(directory)) { + logger.warn("Group directory does NOT exist: " + directory.toString()); + try { + Files.createDirectory(directory); + this.status.addLoadWarning("Group directory does NOT exist"); + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Group directory does NOT exist"); + this.status.addLoadError("Group directory does NOT exist"); + this.status.setStatus(PDPGroupStatus.Status.LOAD_ERRORS); + } + } + // + // Parse policies + // + this.loadPolicies(Paths.get(directory.toString(), "xacml.policy.properties")); + // + // Parse pip config + // + this.loadPIPConfig(Paths.get(directory.toString(), "xacml.pip.properties")); + } + + public void loadPolicies(Path file) throws PAPException { + // + // Read the Groups Policies + // + Properties policyProperties = new Properties(); + if ( ! file.toFile().exists()) { + // need to create the properties file with default values + policyProperties.setProperty(XACMLProperties.PROP_ROOTPOLICIES, ""); + policyProperties.setProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, ""); + // save properties to file + try (OutputStream os = Files.newOutputStream(file)) { + policyProperties.store(os, ""); + } catch (Exception e) { + throw new PAPException("Failed to create new default policy properties file '" + file +"'"); + } + } else { + // load previously existing file + try { + // + // Load the properties + // + try (InputStream is = Files.newInputStream(file)) { + policyProperties.load(is); + } + // + // Parse the policies + // + this.readPolicyProperties(directory, policyProperties); + } catch (IOException e) { + logger.warn("Failed to load group policy properties file: " + file, e); + this.status.addLoadError("Not policy properties defined"); + this.status.setStatus(Status.LOAD_ERRORS); + throw new PAPException("Failed to load group policy properties file: " + file); + } + } + } + + public void loadPIPConfig(Path file) throws PAPException { + // + // Read the Groups' PIP configuration + // + Properties pipProperties = new Properties(); + if ( ! file.toFile().exists()) { + // need to create the properties file with no values + // TODO: Adding Default PIP engine(s) while Loading initially. We don't want + // Programmer intervention with the PIP engines. + pipProperties = setPIPProperties(pipProperties); + // save properties to file + try { + try (OutputStream os = Files.newOutputStream(file)) { + pipProperties.store(os, ""); + } + } catch (Exception e) { + throw new PAPException("Failed to create new default pip properties file '" + file +"'"); + } + } else { + try { + // + // Load the properties + // + try (InputStream is = Files.newInputStream(file)) { + pipProperties.load(is); + } + // For all old PIP config's modify to the new PIP Configuration. + // If PIP is empty add the new values and save it. + if(pipProperties.get(XACMLProperties.PROP_PIP_ENGINES).toString().trim().equals("")){ + pipProperties = setPIPProperties(pipProperties); + try (OutputStream os = Files.newOutputStream(file)) { + pipProperties.store(os, ""); + } + } + // + // Parse the pips + // + this.readPIPProperties(directory, pipProperties); + } catch (IOException e) { + logger.warn("Failed to open group PIP Config properties file: " + file, e); + this.status.addLoadError("Not PIP config properties defined"); + this.status.setStatus(Status.LOAD_ERRORS); + throw new PAPException("Failed to load group policy properties file: " + file); + + } + } + } + + public void resetStatus() { +// // +// // If we are updating, don't allow reset +// // +// if (this.status.getStatus() == Status.UPDATING_CONFIGURATION) { +// logger.warn("We are updating, chill."); +// return; +// } +// // +// // Load errors take precedence +// // +// if (this.status.getStatus() == Status.LOAD_ERRORS) { +// logger.warn("We had load errors."); +// return; +// } + // + // Reset our status object + // + this.status.reset(); + // + // Determine our status + // + for (PDP pdp : this.pdps) { + switch (pdp.getStatus().getStatus()) { + case OUT_OF_SYNCH: + this.status.addOutOfSynchPDP(pdp); + break; + case LAST_UPDATE_FAILED: + this.status.addLastUpdateFailedPDP(pdp); + break; + case LOAD_ERRORS: + this.status.addFailedPDP(pdp); + break; + case UPDATING_CONFIGURATION: + this.status.addUpdatingPDP(pdp); + break; + case UP_TO_DATE: + this.status.addInSynchPDP(pdp); + break; + case UNKNOWN: + case CANNOT_CONNECT: + case NO_SUCH_HOST: + default: + this.status.addUnknownPDP(pdp); + break; + } + } + + // priority is worst-cast to best case + if (this.status.getUnknownPDPs().size() > 0) { + this.status.setStatus(Status.UNKNOWN); + } else if (this.status.getFailedPDPs().size() > 0 || this.status.getLastUpdateFailedPDPs().size() > 0) { + this.status.setStatus(Status.LOAD_ERRORS); + } else if (this.status.getOutOfSynchPDPs().size() > 0) { + this.status.setStatus(Status.OUT_OF_SYNCH); + } else if (this.status.getUpdatingPDPs().size() > 0) { + this.status.setStatus(Status.UPDATING_CONFIGURATION); + } else { + this.status.setStatus(Status.OK); + } + } + + @Override + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public boolean isDefaultGroup() { + return this.isDefault; + } + + public void setDefaultGroup(boolean isDefault) { + this.isDefault = isDefault; + // + // Cannot fire this because 2 operations have + // to occur: 1) old default=false (don't want to fire) and + // then 2) new default=true (yes fire - but we'll have to do that + // elsewhere. + //this.firePDPGroupChanged(this); + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String groupName) { + this.name = groupName; + this.firePDPGroupChanged(this); + } + + @Override + public String getDescription() { + return this.description; + } + + @Override + public void setDescription(String groupDescription) { + this.description = groupDescription; + this.firePDPGroupChanged(this); + } + + public Path getDirectory() { + return this.directory; + } + + public void setDirectory(Path groupDirectory) { + this.directory = groupDirectory; + // this is used only for transmission on the RESTful interface, so no need to fire group changed? + } + + @Override + public PDPGroupStatus getStatus() + { + return this.status; + } + + @Override + public Set getPdps() { + return Collections.unmodifiableSet(pdps); + } + + public void setEcompPdps(Set pdps) { + this.pdps = pdps; + } + + public Set getEcompPdps(){ + return Collections.unmodifiableSet(pdps); + } + + public boolean addPDP(EcompPDP pdp) { + return this.pdps.add(pdp); + } + + public boolean removePDP(PDP pdp) { + return this.pdps.remove(pdp); + } + + @Override + public Set getPolicies() { + return Collections.unmodifiableSet(this.policies); + } + + @Override + public PDPPolicy getPolicy(String id) { + for (PDPPolicy policy : this.policies) { + if (policy.getId().equals(id)) { + return policy; + } + } + return null; + } + + public Properties getPolicyProperties() + { + Properties properties = new Properties(){ + private static final long serialVersionUID = 1L; + // For Debugging it is helpful for the file to be in a sorted order, + // any by returning the keys in the natural Alpha order for strings we get close enough. + // TreeSet is sorted, and this just overrides the normal Properties method to get the keys. + @Override + public synchronized Enumeration keys() { + return Collections.enumeration(new TreeSet(super.keySet())); + } + };; + List roots = new ArrayList(); + List refs = new ArrayList(); + + for (PDPPolicy policy : this.policies) { + // for all policies need to tell PDP the "name", which is the base name for the file id + if (policy.getName() != null) { + properties.setProperty(policy.getId() + ".name", policy.getName()); + } + // put the policy on the correct list + if (policy.isRoot()) { + roots.add(policy.getId()); + } else { + refs.add(policy.getId()); + } + } + + properties.setProperty(XACMLProperties.PROP_ROOTPOLICIES, Joiner.on(',').join(roots)); + properties.setProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, Joiner.on(',').join(refs)); + + return properties; + } + + public PDPPolicy publishPolicy(String id, String name, boolean isRoot, InputStream policy) throws PAPException { + // + // Does it exist already? + // + if (this.getPolicy(id) != null) { + throw new PAPException("Policy with id " + id + " already exists - unpublish it first."); + } + Path tempFile = null; + try { + // + // Copy the policy over + // + tempFile = Files.createFile(Paths.get(this.directory.toAbsolutePath().toString(), id)); + long num; + try (OutputStream os = Files.newOutputStream(tempFile)) { + num = ByteStreams.copy(policy, os); + } + logger.info("Copied " + num + " bytes for policy " + name); + + StdPDPPolicy tempRootPolicy = new StdPDPPolicy(id, isRoot, name, tempFile.toUri()); + if (tempRootPolicy.isValid() == false) { + try { + Files.delete(tempFile); + } catch(Exception ee) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy was invalid, could NOT delete it.", ee); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, ee, "StdPDPGroup", "Policy was invalid, could NOT delete it."); + } + throw new PAPException("Policy is invalid"); + } + // + // Add it in + // + this.policies.add(tempRootPolicy); + // + // We are changed + // + this.firePDPGroupChanged(this); + // + // Return our new object. + // + return tempRootPolicy; + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to publishPolicy: ", e); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "StdPDPGroup", "Failed to publishPolicy"); + } + return null; + } + + /** + * Copy one policy file into the Group's directory but do not change the configuration. + * This is one part of a multi-step process of publishing policies. + * There may be multiple changes in the group (adding multiple policies, deleting policies, changine root<->referenced) + * that must be done all at once, so we just copy the file in preparation for a later "update whole group" operation. + * + * @param id + * @param name + * @param isRoot + * @param policy + * @return + * @throws PAPException + */ + public void copyPolicyToFile(String id, InputStream policy) throws PAPException { + try { + // + // Copy the policy over + // + long num; + Path policyFilePath = Paths.get(this.directory.toAbsolutePath().toString(), id); + + // + // THERE IS A WEIRD PROBLEM ON WINDOWS... + // The file is already "in use" when we try to access it. + // Looking at the file externally while this is halted here does not show the file in use, + // so there is no indication what is causing the problem. + // + // As a way to by-pass the issue, I simply check if the input and the existing file are identical + // and generate an exception if they are not. + // + + + +// if (Files.exists(policyFilePath)) { +// // compare the +// String incomingPolicyString = null; +// try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { +// num = ByteStreams.copy(policy, os); +// incomingPolicyString = new String(os.toByteArray(), "UTF-8"); +// } +// String existingPolicyString = null; +// try { +// byte[] bytes = Files.readAllBytes(policyFilePath); +// existingPolicyString = new String(bytes, "UTF-8"); +// } catch (Exception e) { +// //TODO:EELF Cleanup - Remove logger +// logger.error("Unable to read existing file '" + policyFilePath + "': " + e, e); +// PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "StdPDPGroup", "Unable to read existing policy file"); +// throw new PAPException("Unable to read policy file for comparison: " + e); +// } +// if (incomingPolicyString.equals(existingPolicyString)) { +// throw new PAPException("Policy '" + policyFilePath + "' does not match existing policy on server"); +// } +// // input is same as existing file +// return; +// } + + + Path policyFile; + if (Files.exists(policyFilePath)) { + policyFile = policyFilePath; + } else { + policyFile = Files.createFile(policyFilePath); + } + + try (OutputStream os = Files.newOutputStream(policyFile)) { + num = ByteStreams.copy(policy, os); + } + + logger.info("Copied " + num + " bytes for policy " + name); + + for (PDPPolicy p : policies) { + if (p.getId().equals(id)) { + // we just re-copied/refreshed/updated the policy file for a policy that already exists in this group + logger.info("Policy '" + id + "' already exists in group '" + getId() + "'"); + return; + } + } + + // policy is new to this group + StdPDPPolicy tempRootPolicy = new StdPDPPolicy(id, true, name, policyFile.toUri()); + if (tempRootPolicy.isValid() == false) { + try { + Files.delete(policyFile); + } catch(Exception ee) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy was invalid, could NOT delete it.", ee); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, ee, "StdPDPGroup", "Policy was invalid, could NOT delete it."); + } + throw new PAPException("Policy is invalid"); + } + // + // Add it in + // + this.policies.add(tempRootPolicy); + // + // We are changed + // + this.firePDPGroupChanged(this); + + + + + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to copyPolicyToFile: ", e); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to copyPolicyToFile"); + throw new PAPException("Failed to copy policy to file: " + e); + } + return; + } + + public boolean removePolicyFromGroup(PDPPolicy policy) { + StdPDPPolicy currentPolicy = (StdPDPPolicy) this.getPolicy(policy.getId()); + if (currentPolicy == null) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy " + policy.getId() + " does not exist."); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Policy " + policy.getId() + " does not exist."); + return false; + } + try { + // + // Remove it from our list + // + this.policies.remove(currentPolicy); + // + // We are changed + // + this.firePDPGroupChanged(this); + return true; + } catch (Exception e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to delete policy " + policy); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to delete policy"); + } + return false; + } + + public boolean removePolicy(PDPPolicy policy) { + StdPDPPolicy currentPolicy = (StdPDPPolicy) this.getPolicy(policy.getId()); + if (currentPolicy == null) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy " + policy.getId() + " does not exist."); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Policy " + policy.getId() + " does not exist."); + return false; + } + try { + // + // Delete it on disk + // + Files.delete(Paths.get(currentPolicy.getLocation())); + // + // Remove it from our list + // + this.policies.remove(currentPolicy); + // + // We are changed + // + this.firePDPGroupChanged(this); + return true; + } catch (Exception e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to delete policy " + policy); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to delete policy " + policy); + } + return false; + } + + @Override + public Set getPipConfigs() { + return Collections.unmodifiableSet(this.pipConfigs); + } + + @Override + public PDPPIPConfig getPipConfig(String id) { + for (PDPPIPConfig config : this.pipConfigs) { + if (config.getId().equals(id)) { + return config; + } + } + return null; + } + + public void setPipConfigs(Set pipConfigs) { + this.pipConfigs = pipConfigs; + this.firePDPGroupChanged(this); + } + + public void removeAllPIPConfigs() { + this.pipConfigs.clear(); + this.firePDPGroupChanged(this); + } + + public Properties getPipConfigProperties() { + Properties properties = new Properties(); + List configs = new ArrayList(); + + for (PDPPIPConfig config : this.pipConfigs) { + configs.add(config.getId()); + properties.putAll(config.getConfiguration()); + } + + properties.setProperty(XACMLProperties.PROP_PIP_ENGINES, Joiner.on(',').join(configs)); + + return properties; + } + + @Override + public void repair() { + // + // Reset the status object + // + this.status.reset(); + // + // Validate our directory + // + boolean fire = false; + if (Files.notExists(directory)) { + logger.warn("Group directory does NOT exist: " + directory.toString()); + try { + Files.createDirectory(directory); + fire = true; + this.status.addLoadWarning("Created missing group directory"); + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to create missing Group directory."); + this.status.addLoadError("Failed to create missing Group directory."); + this.status.setStatus(PDPGroupStatus.Status.LOAD_ERRORS); + } + } + // + // Validate our PIP config file + // + Path pipPropertiesFile = Paths.get(directory.toString(), "xacml.pip.properties"); + if (Files.notExists(pipPropertiesFile)) { + try { + Files.createFile(pipPropertiesFile); + fire = true; + this.status.addLoadWarning("Created missing PIP properties file"); + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to create missing PIP properties file"); + this.status.addLoadError("Failed to create missing PIP properties file"); + this.status.setStatus(PDPGroupStatus.Status.LOAD_ERRORS); + } + } + // + // Valid our policy properties file + // + Path policyPropertiesFile = Paths.get(directory.toString(), "xacml.policy.properties"); + if (Files.notExists(policyPropertiesFile)) { + try { + Files.createFile(policyPropertiesFile); + fire = true; + this.status.addLoadWarning("Created missing Policy properties file"); + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to create missing Policy properties file"); + this.status.addLoadError("Failed to create missing Policy properties file"); + this.status.setStatus(PDPGroupStatus.Status.LOAD_ERRORS); + } + } + this.resetStatus(); + if (fire) { + this.fireChanged(); + } + } + + private void readPolicyProperties(Path directory, Properties properties) { + // + // There are 2 property values that hold policies, root and referenced + // + String[] lists = new String[2]; + lists[0] = properties.getProperty(XACMLProperties.PROP_ROOTPOLICIES); + lists[1] = properties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES); + // + // Iterate each policy list + // + boolean isRoot = true; + for (String list : lists) { + // + // Was there actually a property? + // + if (list == null || list.length() == 0) { + isRoot = false; + continue; + } + // + // Parse it out + // + Iterable policyList = Splitter.on(',').trimResults().omitEmptyStrings().split(list); + // + // Was there actually a list + // + if (policyList == null) { + isRoot = false; + continue; + } + for (String id : policyList) { + // + // Construct the policy filename + // + Path policyPath = Paths.get(directory.toString(), id ); + // + // Create the Policy Object + // + StdPDPPolicy policy; + try { + policy = new StdPDPPolicy(id, isRoot, policyPath.toUri(), properties); + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to create policy object", e); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to create policy object"); + policy = null; + } + // + // Is it valid? + // + if (policy != null && policy.isValid()) { + this.policies.add(policy); + this.status.addLoadedPolicy(policy); + } else { + this.status.addFailedPolicy(policy); + this.status.setStatus(Status.LOAD_ERRORS); + } + // force all policies to have a name + if (policy.getName() == null) { + policy.setName(policy.getId()); + } + } + isRoot = false; + } + } + + private void readPIPProperties(Path directory, Properties properties) { + String list = properties.getProperty(XACMLProperties.PROP_PIP_ENGINES); + if (list == null || list.length() == 0) { + return; + } + for (String id : list.split("[,]")) { + StdPDPPIPConfig config = new StdPDPPIPConfig(id, properties); + if (config.isConfigured()) { + this.pipConfigs.add(config); + this.status.addLoadedPipConfig(config); + } else { + this.status.addFailedPipConfig(config); + this.status.setStatus(Status.LOAD_ERRORS); + } + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StdPDPGroup other = (StdPDPGroup) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + + @Override + public String toString() { + return "StdPDPGroup [id=" + id + ", isDefault=" + isDefault + ", name=" + + name + ", description=" + description + ", status=" + status + + ", pdps=" + pdps + ", policies=" + policies + ", pipConfigs=" + + pipConfigs + ", directory=" + directory + "]"; + } + + @Override + public void changed() { + + // save the (changed) properties + try { + saveGroupConfiguration(); + } catch (PAPException | IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unable to save group configuration change"); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "StdPDPGroup", "Unable to save group configuration change"); + // don't notify other things of change if we cannot save it??? + return; + } + + this.firePDPGroupChanged(this); + + } + + @Override + public void groupChanged(EcompPDPGroup group) { + this.changed(); + } + + @Override + public void pdpChanged(EcompPDP pdp) { + // + // If one of the group's PDP's changed, then the group changed + // + // TODO Really? + // + this.changed(); + } + + + // + // Methods needed for JSON deserialization + // + public StdPDPGroup() { + + } + + public StdPDPGroup(EcompPDPGroup group) { + this.id = group.getId(); + this.name = group.getName(); + this.description = group.getDescription(); + this.isDefault = group.isDefaultGroup(); + this.pdps = group.getEcompPdps(); + this.policies = group.getPolicies(); + this.pipConfigs = group.getPipConfigs(); + } + + public boolean isDefault() { + return isDefault; + } + public void setDefault(boolean isDefault) { + this.isDefault = isDefault; + } + public void setStatus(PDPGroupStatus status) { + this.status = new StdPDPGroupStatus(status); + } + public void setPolicies(Set policies) { + this.policies = policies; + } + + + + public void saveGroupConfiguration() throws PAPException, IOException { + + // First save the Policy properties + + // save the lists of policies + Properties policyProperties = this.getPolicyProperties(); + + // save info about each policy + for (PDPPolicy policy : this.policies){ + policyProperties.put(policy.getId() + ".name", policy.getName()); + } + + // + // Now we can save the file + // + Path file = Paths.get(this.directory.toString(), "xacml.policy.properties"); + try (OutputStream os = Files.newOutputStream(file)) { + policyProperties.store(os, ""); + } catch (Exception e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Group Policies Config save failed: " + e, e); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "STdPDPGroup", "Group Policies Config save failed"); + throw new PAPException("Failed to save policy properties file '" + file +"'"); + } + + + // Now save the PIP Config properties + Properties pipProperties = this.getPipConfigProperties(); + + // + // Now we can save the file + // + file = Paths.get(this.directory.toString(), "xacml.pip.properties"); + try (OutputStream os = Files.newOutputStream(file)) { + pipProperties.store(os, ""); + } catch (Exception e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Group PIP Config save failed: " + e, e); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Group PIP Config save failed"); + throw new PAPException("Failed to save pip properties file '" + file +"'"); + } + } + + // + // Comparable Interface + // + @Override + public int compareTo(Object arg0) { + if (arg0 == null) { + return -1; + } + if ( ! (arg0 instanceof StdPDPGroup)) { + return -1; + } + if (((StdPDPGroup)arg0).name == null) { + return -1; + } + if (name == null) { + return 1; + } + + return name.compareTo(((StdPDPGroup)arg0).name); + } + + // TODO: Adding Default PIP engine(s) while Loading initially. We don't want + // Programmer intervention with the PIP engines. + private Properties setPIPProperties(Properties props){ + props.setProperty("AAF.name", "AAFEngine"); + props.setProperty("AAF.description", "AAFEngine to communicate with AAF to take decisions"); + props.setProperty("AAF.classname","org.openecomp.policy.xacml.std.pip.engines.aaf.AAFEngine"); + props.setProperty(XACMLProperties.PROP_PIP_ENGINES, "AAF"); + return props; + } + + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPGroupStatus.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPGroupStatus.java new file mode 100644 index 000000000..dcb1f8fe0 --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPGroupStatus.java @@ -0,0 +1,405 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.std.pap; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import com.att.research.xacml.api.pap.PDP; +import com.att.research.xacml.api.pap.PDPGroupStatus; +import com.att.research.xacml.api.pap.PDPPIPConfig; +import com.att.research.xacml.api.pap.PDPPolicy; +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class StdPDPGroupStatus implements PDPGroupStatus { + + private Status status = Status.UNKNOWN; + + private Set loadErrors = new HashSet(); + + private Set loadWarnings = new HashSet(); + + private Set loadedPolicies = new HashSet(); + + private Set failedPolicies = new HashSet(); + + private Set loadedPIPConfigs = new HashSet(); + + private Set failedPIPConfigs = new HashSet(); + + private Set inSynchPDPs = new HashSet(); + + private Set outOfSynchPDPs = new HashSet(); + + private Set failedPDPs = new HashSet(); + + private Set updatingPDPs = new HashSet(); + + private Set lastUpdateFailedPDPs = new HashSet(); + + private Set unknownPDPs = new HashSet(); + + + // Constructor needed for JSON deserialization + public StdPDPGroupStatus() { + + } + + public StdPDPGroupStatus(Status status) { + this.status = status; + } + + public StdPDPGroupStatus(PDPGroupStatus stat) { + this.status = stat.getStatus(); + this.failedPDPs.clear(); this.failedPDPs.addAll(stat.getFailedPDPs()); + this.failedPIPConfigs.clear(); this.failedPIPConfigs.addAll(stat.getFailedPipConfigs()); + this.failedPolicies.clear(); this.failedPolicies.addAll(stat.getFailedPolicies()); + this.inSynchPDPs.clear(); this.inSynchPDPs.addAll(stat.getInSynchPDPs()); + this.lastUpdateFailedPDPs.clear(); this.lastUpdateFailedPDPs.addAll(stat.getLastUpdateFailedPDPs()); + this.loadedPIPConfigs.clear(); this.loadedPIPConfigs.addAll(stat.getLoadedPipConfigs()); + this.loadedPolicies.clear(); this.loadedPolicies.addAll(stat.getLoadedPolicies()); + this.loadErrors.clear(); this.loadErrors.addAll(stat.getLoadErrors()); + this.loadWarnings.clear(); this.loadWarnings.addAll(stat.getLoadWarnings()); + this.outOfSynchPDPs.clear(); this.outOfSynchPDPs.addAll(stat.getOutOfSynchPDPs()); + this.unknownPDPs.clear(); this.unknownPDPs.addAll(stat.getUpdatingPDPs()); + this.updatingPDPs.clear(); this.updatingPDPs.addAll(stat.getUpdatingPDPs()); + } + + public Set getLoadedPIPConfigs() { + return loadedPIPConfigs; + } + public void setLoadedPIPConfigs(Set loadedPIPConfigs) { + this.loadedPIPConfigs = loadedPIPConfigs; + } + public Set getFailedPIPConfigs() { + return failedPIPConfigs; + } + public void setFailedPIPConfigs(Set failedPIPConfigs) { + this.failedPIPConfigs = failedPIPConfigs; + } + public Set getUnknownPDPs() { + return unknownPDPs; + } + public void setUnknownPDPs(Set unknownPDPs) { + this.unknownPDPs = unknownPDPs; + } + public void setLoadErrors(Set loadErrors) { + this.loadErrors = loadErrors; + } + public void setLoadWarnings(Set loadWarnings) { + this.loadWarnings = loadWarnings; + } + public void setLoadedPolicies(Set loadedPolicies) { + this.loadedPolicies = loadedPolicies; + } + public void setFailedPolicies(Set failedPolicies) { + this.failedPolicies = failedPolicies; + } + public void setInSynchPDPs(Set inSynchPDPs) { + this.inSynchPDPs = inSynchPDPs; + } + public void setOutOfSynchPDPs(Set outOfSynchPDPs) { + this.outOfSynchPDPs = outOfSynchPDPs; + } + public void setFailedPDPs(Set failedPDPs) { + this.failedPDPs = failedPDPs; + } + public void setUpdatingPDPs(Set updatingPDPs) { + this.updatingPDPs = updatingPDPs; + } + public void setLastUpdateFailedPDPs(Set lastUpdateFailedPDPs) { + this.lastUpdateFailedPDPs = lastUpdateFailedPDPs; + } + + + @Override + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + @Override + public Set getLoadErrors() { + return Collections.unmodifiableSet(this.loadErrors); + } + + public void addLoadError(String error) { + this.loadErrors.add(error); + } + + @Override + public Set getLoadWarnings() { + return Collections.unmodifiableSet(this.loadWarnings); + } + + public void addLoadWarning(String warning) { + this.loadWarnings.add(warning); + } + + @Override + public Set getLoadedPolicies() { + return Collections.unmodifiableSet(this.loadedPolicies); + } + + public void addLoadedPolicy(PDPPolicy policy) { + this.loadedPolicies.add(policy); + } + + @Override + public Set getFailedPolicies() { + return Collections.unmodifiableSet(this.failedPolicies); + } + + public void addFailedPolicy(PDPPolicy policy) { + this.failedPolicies.add(policy); + } + + @Override + public boolean policiesOK() { + if (this.failedPolicies.size() > 0) { + return false; + } + return true; + } + + @Override + public Set getLoadedPipConfigs() { + return Collections.unmodifiableSet(this.loadedPIPConfigs); + } + + public void addLoadedPipConfig(PDPPIPConfig config) { + this.loadedPIPConfigs.add(config); + } + + @Override + public Set getFailedPipConfigs() { + return Collections.unmodifiableSet(this.failedPIPConfigs); + } + + public void addFailedPipConfig(PDPPIPConfig config) { + this.failedPIPConfigs.add(config); + } + + @Override + public boolean pipConfigOK() { + if (this.failedPIPConfigs.size() > 0) { + return false; + } + return true; + } + + @Override + public Set getInSynchPDPs() { + return Collections.unmodifiableSet(this.inSynchPDPs); + } + + public void addInSynchPDP(PDP pdp) { + this.inSynchPDPs.add(pdp); + } + + @Override + public Set getOutOfSynchPDPs() { + return Collections.unmodifiableSet(this.outOfSynchPDPs); + } + + public void addOutOfSynchPDP(PDP pdp) { + this.outOfSynchPDPs.add(pdp); + } + + @Override + public Set getFailedPDPs() { + return Collections.unmodifiableSet(this.failedPDPs); + } + + public void addFailedPDP(PDP pdp) { + this.failedPDPs.add(pdp); + } + + @Override + public Set getUpdatingPDPs() { + return Collections.unmodifiableSet(this.updatingPDPs); + } + + public void addUpdatingPDP(PDP pdp) { + this.updatingPDPs.add(pdp); + } + + @Override + public Set getLastUpdateFailedPDPs() { + return Collections.unmodifiableSet(this.lastUpdateFailedPDPs); + } + + public void addLastUpdateFailedPDP(PDP pdp) { + this.lastUpdateFailedPDPs.add(pdp); + } + + @Override + @JsonIgnore + public Set getUnknownStatusPDPs() { + return Collections.unmodifiableSet(this.unknownPDPs); + } + + public void addUnknownPDP(PDP pdp) { + this.unknownPDPs.add(pdp); + } + + @Override + public boolean pdpsOK() { + if (this.outOfSynchPDPs.size() > 0) { + return false; + } + if (this.failedPDPs.size() > 0) { + return false; + } + if (this.lastUpdateFailedPDPs.size() > 0) { + return false; + } + if (this.unknownPDPs.size() > 0) { + return false; + } + return true; + } + + @Override + @JsonIgnore + public boolean isGroupOk() { + if (this.policiesOK() == false) { + return false; + } + if (this.pipConfigOK() == false) { + return false; + } + if (this.pdpsOK() == false) { + return false; + } + if (this.loadErrors.isEmpty() == false) { + return false; + } + return (this.status == Status.OK); + } + + public void reset() { + this.status = Status.OK; + + this.loadErrors.clear(); + this.loadWarnings.clear(); + this.loadedPolicies.clear(); + this.failedPolicies.clear(); + this.loadedPIPConfigs.clear(); + this.failedPIPConfigs.clear(); + this.inSynchPDPs.clear(); + this.outOfSynchPDPs.clear(); + this.failedPDPs.clear(); + this.updatingPDPs.clear(); + this.lastUpdateFailedPDPs.clear(); + this.unknownPDPs.clear(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + (failedPDPs.hashCode()); + result = prime + * result + + (failedPIPConfigs.hashCode()); + result = prime * result + + (failedPolicies.hashCode()); + result = prime * result + + (inSynchPDPs.hashCode()); + result = prime + * result + + (lastUpdateFailedPDPs.hashCode()); + result = prime * result + + (loadErrors.hashCode()); + result = prime * result + + (loadWarnings.hashCode()); + result = prime + * result + + (loadedPIPConfigs.hashCode()); + result = prime * result + + (loadedPolicies.hashCode()); + result = prime * result + + (outOfSynchPDPs.hashCode()); + result = prime * result + (status.hashCode()); + result = prime * result + + (unknownPDPs.hashCode()); + result = prime * result + + (updatingPDPs.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StdPDPGroupStatus other = (StdPDPGroupStatus) obj; + if (!failedPDPs.equals(other.failedPDPs)) + return false; + if (!failedPIPConfigs.equals(other.failedPIPConfigs)) + return false; + if (!failedPolicies.equals(other.failedPolicies)) + return false; + if (!inSynchPDPs.equals(other.inSynchPDPs)) + return false; + if (!lastUpdateFailedPDPs.equals(other.lastUpdateFailedPDPs)) + return false; + if (!loadErrors.equals(other.loadErrors)) + return false; + if (!loadWarnings.equals(other.loadWarnings)) + return false; + if (!loadedPIPConfigs.equals(other.loadedPIPConfigs)) + return false; + if (!loadedPolicies.equals(other.loadedPolicies)) + return false; + if (!outOfSynchPDPs.equals(other.outOfSynchPDPs)) + return false; + if (status != other.status) + return false; + if (!unknownPDPs.equals(other.unknownPDPs)) + return false; + if (!updatingPDPs.equals(other.updatingPDPs)) + return false; + return true; + } + + @Override + public String toString() { + return "StdPDPGroupStatus [status=" + status + ", loadErrors=" + + loadErrors + ", loadWarnings=" + loadWarnings + + ", loadedPolicies=" + loadedPolicies + ", failedPolicies=" + + failedPolicies + ", loadedPIPConfigs=" + loadedPIPConfigs + + ", failedPIPConfigs=" + failedPIPConfigs + ", inSynchPDPs=" + + inSynchPDPs + ", outOfSynchPDPs=" + outOfSynchPDPs + + ", failedPDPs=" + failedPDPs + ", updatingPDPs=" + + updatingPDPs + ", lastUpdateFailedPDPs=" + + lastUpdateFailedPDPs + ", unknownPDPs=" + unknownPDPs + "]"; + } + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPItemSetChangeNotifier.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPItemSetChangeNotifier.java new file mode 100644 index 000000000..38f8a5800 --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPItemSetChangeNotifier.java @@ -0,0 +1,84 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.std.pap; + +import java.util.Collection; +import java.util.LinkedList; + +import org.openecomp.policy.xacml.api.pap.EcompPDP; +import org.openecomp.policy.xacml.api.pap.EcompPDPGroup; + +import com.att.research.xacml.api.pap.PDP; +import com.att.research.xacml.api.pap.PDPGroup; + +public class StdPDPItemSetChangeNotifier { + + private Collection listeners = null; + + public interface StdItemSetChangeListener { + + public void changed(); + + public void groupChanged(EcompPDPGroup group); + + public void pdpChanged(EcompPDP pdp); + + } + + public void addItemSetChangeListener(StdItemSetChangeListener listener) { + if (this.listeners == null) { + this.listeners = new LinkedList(); + } + this.listeners.add(listener); + } + + public void removeItemSetChangeListener(StdItemSetChangeListener listener) { + if (this.listeners != null) { + this.listeners.remove(listener); + } + } + + public void fireChanged() { + if (this.listeners == null) { + return; + } + for (StdItemSetChangeListener l : this.listeners) { + l.changed(); + } + } + + public void firePDPGroupChanged(EcompPDPGroup group) { + if (this.listeners == null) { + return; + } + for (StdItemSetChangeListener l : this.listeners) { + l.groupChanged(group); + } + } + + public void firePDPChanged(EcompPDP pdp) { + if (this.listeners == null) { + return; + } + for (StdItemSetChangeListener l : this.listeners) { + l.pdpChanged(pdp); + } + } +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPPIPConfig.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPPIPConfig.java new file mode 100644 index 000000000..814dbe3af --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPPIPConfig.java @@ -0,0 +1,217 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.std.pap; + +import java.io.Serializable; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import com.att.research.xacml.api.pap.PDPPIPConfig; +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.openecomp.policy.common.logging.flexlogger.FlexLogger; +import org.openecomp.policy.common.logging.flexlogger.Logger; + +public class StdPDPPIPConfig implements PDPPIPConfig, Serializable { + private static final long serialVersionUID = 1L; + private static Logger logger = FlexLogger.getLogger(StdPDPPIPConfig.class); + + private String id; + + private String name; + + private String description; + + private String classname; + + private Map config = new HashMap(); + + public StdPDPPIPConfig() { + + } + + public StdPDPPIPConfig(String id) { + this.id = id; + } + + public StdPDPPIPConfig(String id, String name, String description) { + this(id); + this.name = name; + this.description = description; + } + + public StdPDPPIPConfig(String id, Properties properties) { + this(id); + if ( ! this.initialize(properties) ) { + throw new IllegalArgumentException("PIP Engine '" + id + "' has no classname property in config"); + } + } + + public boolean initialize(Properties properties) { + boolean classnameSeen = false; + for (Object key : properties.keySet()) { + if (key.toString().startsWith(this.id + ".")) { + if (logger.isDebugEnabled()) { + logger.debug("Found: " + key); + } + if (key.toString().equals(this.id + ".name")) { + this.name = properties.getProperty(key.toString()); + } else if (key.toString().equals(this.id + ".description")) { + this.description = properties.getProperty(key.toString()); + } else if (key.toString().equals(this.id + ".classname")) { + this.classname = properties.getProperty(key.toString()); + classnameSeen = true; + } + // all properties, including the special ones located above, are included in the properties list + this.config.put(key.toString(), properties.getProperty(key.toString())); + } + } + return classnameSeen; + } + + @Override + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String getDescription() { + return this.description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public String getClassname() { + return classname; + } + + public void setClassname(String classname) { + this.classname = classname; + } + + @Override + @JsonIgnore + public Map getConfiguration() { + return Collections.unmodifiableMap(this.config); + } + + public void setValues(Map config) { + this.config = config; + } + + @Override + @JsonIgnore + public boolean isConfigured() { + // + // TODO + // Also include this in the JSON I/O if it is a data field rather than calculated + // + return true; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((classname == null) ? 0 : classname.hashCode()); + result = prime * result + ((config == null) ? 0 : config.hashCode()); + result = prime * result + + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StdPDPPIPConfig other = (StdPDPPIPConfig) obj; + if (classname == null) { + if (other.classname != null) + return false; + } else if (!classname.equals(other.classname)) + return false; + if (config == null) { + if (other.config != null) + return false; + } else if (!config.equals(other.config)) + return false; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + return "StdPDPPIPConfig [id=" + id + ", name=" + name + + ", description=" + description + ", classname=" + classname + + ", config=" + config + "]"; + } + + + + // + // Methods needed for JSON serialization/deserialization + // + + public Map getConfig() { + return config; + } + public void setConfig(Map config) { + this.config = config; + } + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPPolicy.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPPolicy.java new file mode 100644 index 000000000..06c2498f6 --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPPolicy.java @@ -0,0 +1,368 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.std.pap; + +import org.openecomp.policy.common.logging.eelf.PolicyLogger; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Properties; + +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.policy.xacml.util.XACMLPolicyScanner; + +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDPPolicy; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.google.common.base.Splitter; +import com.google.common.collect.Lists; + + +public class StdPDPPolicy implements PDPPolicy, Serializable { + private static final long serialVersionUID = 1L; + private static Log logger = LogFactory.getLog(StdPDPPolicy.class); + + private String id = null; + + private String name = null; + + private String policyId = null; + + private String description = null; + + private int[] version = null; + + private boolean isRoot = false; + + private boolean isValid = false; + + private URI location = null; + + + public StdPDPPolicy(String id, boolean isRoot) { + this.id = id; + this.isRoot = isRoot; + } + + public StdPDPPolicy(String id, boolean isRoot, String name) { + this(id, isRoot); + this.name = name; + } + + + public StdPDPPolicy(String id, boolean isRoot, String name, URI location) throws IOException { + this(id, isRoot); + this.name = name; + this.location = location; + + // + // Read the policy data + // + String theID = this.readPolicyData(); + + if (this.id == null) { + logger.debug("id is null so we are calling readPolicyData() to get the policyID"); + this.id = theID; + } + + logger.debug("The final outcome of the constructor returned the following: id = " + id + + ", location = " + location + ", name = " + name); + + } + + public StdPDPPolicy(String id, boolean isRoot, String name, URI location, boolean isValid, String policyId, + String description, String version) throws IOException { + this(id, isRoot); + this.name = name; + this.location = location; + this.policyId = policyId; + this.description = description; + this.version = versionStringToArray(version); + this.isValid = isValid; + + logger.debug("The final outcome of the constructor returned the following: id = " + id + + ", location = " + location + ", name = " + name + ", policyId = " + policyId + + ", description = " + description + ", Version = " + version); + + } + + public StdPDPPolicy(String id, boolean isRoot, String name, URI location, boolean isFromAPI) throws IOException { + this(id, isRoot); + this.name = name; + this.location = location; + this.isValid = isFromAPI; + + logger.debug("The final outcome of the constructor returned the following: id = " + id + + ", location = " + location + ", name = " + name); + + } + + public StdPDPPolicy(String id, boolean isRoot, URI location, Properties properties) throws IOException { + this(id, isRoot); + this.location = location; + // + // Read the policy data + // + this.readPolicyData(); + // + // See if there's a name + // + for (Object key : properties.keySet()) { + if (key.toString().equals(id + ".name")) { + this.name = properties.getProperty(key.toString()); + break; + } + } + } + + + private String readPolicyData() throws IOException { + // + // Extract XACML policy information + // + URL url = this.location.toURL(); + Object rootElement = XACMLPolicyScanner.readPolicy(url.openStream()); + if (rootElement == null || + ( + ! (rootElement instanceof PolicySetType) && + ! (rootElement instanceof PolicyType) + ) ) { + logger.warn("No root policy element in URI: " + this.location.toString() + " : " + rootElement); + this.isValid = false; + } else { + this.version = versionStringToArray(XACMLPolicyScanner.getVersion(rootElement)); + if (rootElement instanceof PolicySetType) { + this.policyId = ((PolicySetType)rootElement).getPolicySetId(); + this.description = ((PolicySetType)rootElement).getDescription(); + this.isValid = true; + this.version = versionStringToArray(((PolicySetType)rootElement).getVersion()); + } else if (rootElement instanceof PolicyType) { + this.policyId = ((PolicyType)rootElement).getPolicyId(); + this.description = ((PolicyType)rootElement).getDescription(); + this.version = versionStringToArray(((PolicyType)rootElement).getVersion()); + this.isValid = true; + } else { + //TODO:EELF Cleanup - Remove logger + //logger.error("Unknown root element: " + rootElement.getClass().getCanonicalName()); + PolicyLogger.error("Unknown root element: " + rootElement.getClass().getCanonicalName()); + } + } + if (this.policyId != null) { + ArrayList foo = Lists.newArrayList(Splitter.on(':').split(this.policyId)); + if (foo.isEmpty() == false) { + return foo.get(foo.size() - 1); + } + } + return null; + } + + @Override + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String getPolicyId() { + return this.policyId; + } + + @Override + public String getDescription() { + return this.description; + } + + @Override + public String getVersion() { + return versionArrayToString(this.version); + } + + @Override + @JsonIgnore + public int[] getVersionInts() { + return version; + } + + @Override + public boolean isRoot() { + return this.isRoot; + } + + @Override + public boolean isValid() + { + return this.isValid; + } + + @Override + @JsonIgnore + public InputStream getStream() throws PAPException, IOException { + try { + if (this.location != null) { + URL url = this.location.toURL(); + return url.openStream(); + } + return null; + } catch (FileNotFoundException e) { + throw new PAPException(e); + } + } + + @Override + public URI getLocation() throws PAPException { + return this.location; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + + ((policyId == null) ? 0 : policyId.hashCode()); + result = prime * result; + if (version != null) { + for (int i = 0; i < version.length; i++) { + result += version[i]; + } + } + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StdPDPPolicy other = (StdPDPPolicy) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (policyId == null) { + if (other.policyId != null) + return false; + } else if (!policyId.equals(other.policyId)) + return false; + if (version != other.version) + return false; + return true; + } + + @Override + public String toString() { + return "StdPDPPolicy [id=" + id + ", name=" + name + ", policyId=" + + policyId + ", description=" + description + ", version=" + + this.getVersion() + ", isRoot=" + isRoot + ", isValid=" + isValid + + ", location=" + location + "]"; + } + + + /** + * Given a version string consisting of integers with dots between them, convert it into an array of ints. + * + * @param version + * @return + * @throws NumberFormatException + */ + public static int[] versionStringToArray(String version) throws NumberFormatException { + if (version == null || version.length() == 0) { + return new int[0]; + } + String[] stringArray = version.split("\\."); + int[] resultArray = new int[stringArray.length]; + for (int i = 0; i < stringArray.length; i++) { + resultArray[i] = Integer.parseInt(stringArray[i]); + } + return resultArray; + } + + /** + * Given an array representing a version, create the corresponding dot-separated string. + * + * @param array + * @return + */ + public static String versionArrayToString(int[] array) { + if (array == null || array.length == 0) { + return ""; + } + String versionString = ""; + if (array.length > 0) { + versionString = "" + array[0]; + for (int i = 1; i < array.length; i++) { + versionString += "." + array[i]; + } + } + return versionString; + } + + + + // + // Methods needed for JSON Deserialization + // + public StdPDPPolicy() {} + + public void setPolicyId(String policyId) { + this.policyId = policyId; + } + public void setDescription(String description) { + this.description = description; + } + public void setVersion(String version) { + this.version = versionStringToArray(version); + } + public void setRoot(boolean isRoot) { + this.isRoot = isRoot; + } + public void setValid(boolean isValid) { + this.isValid = isValid; + } + public void setLocation(URI location) { + this.location = location; + } + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPStatus.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPStatus.java new file mode 100644 index 000000000..dc297657a --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pap/StdPDPStatus.java @@ -0,0 +1,265 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.std.pap; + +import java.io.Serializable; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import com.att.research.xacml.api.pap.PDPPIPConfig; +import com.att.research.xacml.api.pap.PDPPolicy; +import com.att.research.xacml.api.pap.PDPStatus; +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class StdPDPStatus implements Serializable, PDPStatus { + private static final long serialVersionUID = 1L; + + private Status status = Status.UNKNOWN; + + private Set loadErrors = new HashSet(); + + private Set loadWarnings = new HashSet(); + + private Set loadedPolicies = new HashSet(); + + private Set loadedRootPolicies = new HashSet(); + + private Set failedPolicies = new HashSet(); + + private Set loadedPIPConfigs = new HashSet(); + + private Set failedPIPConfigs = new HashSet(); + + public StdPDPStatus() { + } + + public void set(StdPDPStatus newStatus) { + this.status = newStatus.status; + this.loadErrors.clear(); + this.loadErrors.addAll(newStatus.getLoadErrors()); + this.loadWarnings.clear(); + this.loadWarnings.addAll(newStatus.getLoadWarnings()); + this.loadedPolicies.clear(); + this.loadedPolicies.addAll(newStatus.getLoadedPolicies()); + this.loadedRootPolicies.clear(); + this.loadedRootPolicies.addAll(newStatus.getLoadedRootPolicies()); + this.failedPolicies.clear(); + this.failedPolicies.addAll(newStatus.getFailedPolicies()); + this.loadedPIPConfigs.clear(); + this.loadedPIPConfigs.addAll(newStatus.getLoadedPipConfigs()); + this.failedPIPConfigs.clear(); + this.failedPIPConfigs.addAll(newStatus.getFailedPipConfigs()); + } + + + + @Override + public Status getStatus() { + return this.status; + } + + public void setStatus(Status status) { + this.status = status; + } + + @Override + public Set getLoadErrors() { + return Collections.unmodifiableSet(this.loadErrors); + } + + public void setLoadErrors(Set errors) { + this.loadErrors = errors; + } + + public void addLoadError(String error) { + this.loadErrors.add(error); + } + + @Override + public Set getLoadWarnings() { + return Collections.unmodifiableSet(this.loadWarnings); + } + + public void setLoadWarnings(Set warnings) { + this.loadWarnings = warnings; + } + + public void addLoadWarning(String warning) { + this.loadWarnings.add(warning); + } + + @Override + public Set getLoadedPolicies() { + return Collections.unmodifiableSet(this.loadedPolicies); + } + + public void setLoadedPolicies(Set policies) { + this.loadedPolicies = policies; + } + + public void addLoadedPolicy(PDPPolicy policy) { + this.loadedPolicies.add(policy); + } + + @Override + public Set getLoadedRootPolicies() { + return Collections.unmodifiableSet(this.loadedRootPolicies); + } + + public void setLoadedRootPolicies(Set policies) { + this.loadedRootPolicies = policies; + } + + public void addRootPolicy(PDPPolicy policy) { + this.loadedRootPolicies.add(policy); + } + + public void addAllLoadedRootPolicies(Set policies) { + this.loadedRootPolicies.addAll(policies); + } + + @Override + public Set getFailedPolicies() { + return Collections.unmodifiableSet(this.failedPolicies); + } + + public void setFailedPolicies(Set policies) { + this.failedPolicies = policies; + } + + public void addFailedPolicy(PDPPolicy policy) { + this.failedPolicies.add(policy); + } + + @Override + public boolean policiesOK() { + if (this.failedPolicies.size() > 0) { + return false; + } + return true; + } + + @Override + public Set getLoadedPipConfigs() { + return Collections.unmodifiableSet(this.loadedPIPConfigs); + } + + public void setLoadedPipConfigs(Set configs) { + this.loadedPIPConfigs = configs; + } + + public void addLoadedPipConfig(PDPPIPConfig config) { + this.loadedPIPConfigs.add(config); + } + + @Override + public Set getFailedPipConfigs() { + return Collections.unmodifiableSet(this.failedPIPConfigs); + } + + public void setFailedPipConfigs(Set configs) { + this.failedPIPConfigs = configs; + } + + public void addFailedPipConfig(PDPPIPConfig config) { + this.failedPIPConfigs.add(config); + } + + @Override + public boolean pipConfigOK() { + if (this.failedPIPConfigs.size() > 0) { + return false; + } + return true; + } + + @Override + @JsonIgnore + public boolean isOk() { + if (this.policiesOK() == false) { + return false; + } + if (this.pipConfigOK() == false) { + return false; + } + return (this.status == Status.UP_TO_DATE); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime + * result + + (failedPIPConfigs.hashCode()); + result = prime * result + + (failedPolicies.hashCode()); + result = prime * result + + (loadErrors.hashCode()); + result = prime * result + + (loadWarnings.hashCode()); + result = prime + * result + + (loadedPIPConfigs.hashCode()); + result = prime * result + + (loadedPolicies.hashCode()); + result = prime * result + (status.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StdPDPStatus other = (StdPDPStatus) obj; + if (!failedPIPConfigs.equals(other.failedPIPConfigs)) + return false; + if (!failedPolicies.equals(other.failedPolicies)) + return false; + if (!loadErrors.equals(other.loadErrors)) + return false; + if (!loadWarnings.equals(other.loadWarnings)) + return false; + if (!loadedPIPConfigs.equals(other.loadedPIPConfigs)) + return false; + if (!loadedPolicies.equals(other.loadedPolicies)) + return false; + if (status != other.status) + return false; + return true; + } + + @Override + public String toString() { + return "StdPDPStatus [status=" + status + ", loadErrors=" + loadErrors + + ", loadWarnings=" + loadWarnings + ", loadedPolicies=" + + loadedPolicies + ", loadedRootPolicies=" + loadedRootPolicies + + ", failedPolicies=" + failedPolicies + + ", loadedPIPConfigs=" + loadedPIPConfigs + + ", failedPIPConfigs=" + failedPIPConfigs + "]"; + } + + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pip/engines/aaf/AAFEngine.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pip/engines/aaf/AAFEngine.java new file mode 100644 index 000000000..6dea4c21f --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/std/pip/engines/aaf/AAFEngine.java @@ -0,0 +1,276 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.std.pip.engines.aaf; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.policy.utils.AAFPolicyClient; +import org.openecomp.policy.utils.AAFPolicyException; + +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.api.pip.PIPException; +import com.att.research.xacml.api.pip.PIPFinder; +import com.att.research.xacml.api.pip.PIPRequest; +import com.att.research.xacml.api.pip.PIPResponse; +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.std.StdMutableAttribute; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.pip.StdMutablePIPResponse; +import com.att.research.xacml.std.pip.StdPIPRequest; +import com.att.research.xacml.std.pip.StdPIPResponse; +import com.att.research.xacml.std.pip.engines.StdConfigurableEngine; + +/** + * PIP Engine for Implementing {@link com.att.research.xacml.std.pip.engines.ConfigurableEngine} interface to provide + * attribute retrieval from AT&T AAF interface. + * + * @version $Revision$ + */ +public class AAFEngine extends StdConfigurableEngine { + + public static final String DEFAULT_DESCRIPTION = "PIP for authenticating aaf attributes using the AT&T AAF REST interface"; + public static final String DEFAULT_ISSUER = "att-aaf"; + + private static final String SUCCESS = "Success"; + + public static final String AAF_RESULT= "AAF_RESULT"; + public static final String AAF_RESPONSE= "AAF_RESPONSE"; + // + public static final Identifier AAF_RESPONSE_ID = new IdentifierImpl(AAF_RESPONSE); + public static final Identifier AAF_RESULT_ID = new IdentifierImpl(AAF_RESULT); + + // + private static final PIPRequest PIP_REQUEST_UID = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_ID"), XACML3.ID_DATATYPE_STRING); + private static final PIPRequest PIP_REQUEST_PASS = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_PASS"), XACML3.ID_DATATYPE_STRING); + private static final PIPRequest PIP_REQUEST_TYPE = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_TYPE"), XACML3.ID_DATATYPE_STRING); + private static final PIPRequest PIP_REQUEST_INSTANCE = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_INSTANCE"), XACML3.ID_DATATYPE_STRING); + private static final PIPRequest PIP_REQUEST_ACTION = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_ACTION"), XACML3.ID_DATATYPE_STRING); + private static final PIPRequest PIP_REQUEST_ENV = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_ENVIRONMENT"), XACML3.ID_DATATYPE_STRING); + + private static final List mapRequiredAttributes = new ArrayList(); + static{ + mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_UID)); + mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_PASS)); + mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_TYPE)); + mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_INSTANCE)); + mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_ACTION)); + mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_ENV)); + } + + private static final Map mapSupportedAttributes = new HashMap(); + static{ + mapSupportedAttributes.put(new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESPONSE_ID, XACML3.ID_DATATYPE_STRING), "response"); + mapSupportedAttributes.put(new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESULT_ID, XACML3.ID_DATATYPE_BOOLEAN), "result"); + } + + protected Log logger = LogFactory.getLog(this.getClass()); + + public AAFEngine(){ + } + + private PIPResponse getAttribute(PIPRequest pipRequest, PIPFinder pipFinder) { + PIPResponse pipResponse = null; + try { + pipResponse = pipFinder.getMatchingAttributes(pipRequest, this); + if (pipResponse.getStatus() != null && !pipResponse.getStatus().isOk()) { + this.logger.warn("Error retrieving " + pipRequest.getAttributeId().stringValue() + ": " + pipResponse.getStatus().toString()); + pipResponse = null; + } + if (pipResponse.getAttributes().size() == 0) { + this.logger.warn("No value for " + pipRequest.getAttributeId().stringValue()); + pipResponse = null; + } + } catch (PIPException ex) { + this.logger.error("PIPException getting subject-id attribute: " + ex.getMessage(), ex); + } + return pipResponse; + } + + private String getValue(PIPResponse pipResponse){ + String result = null; + Collection listAttributes = pipResponse.getAttributes(); + for(Attribute attribute: listAttributes){ + Iterator> iterAttributeValues = attribute.findValues(DataTypes.DT_STRING); + if(iterAttributeValues!=null) { + while(iterAttributeValues.hasNext()){ + result = iterAttributeValues.next().getValue(); + break; + } + } + } + return result; + } + + private synchronized String getResult(PIPFinder pipFinder) { + PIPResponse pipResponseUID = this.getAttribute(PIP_REQUEST_UID, pipFinder); + PIPResponse pipResponsePass = this.getAttribute(PIP_REQUEST_PASS, pipFinder); + PIPResponse pipResponseType = this.getAttribute(PIP_REQUEST_TYPE, pipFinder); + PIPResponse pipResponseAction = this.getAttribute(PIP_REQUEST_ACTION, pipFinder); + PIPResponse pipResponseInstance = this.getAttribute(PIP_REQUEST_INSTANCE, pipFinder); + PIPResponse pipResponseEnv = this.getAttribute(PIP_REQUEST_ENV, pipFinder); + String response = null; + // Evaluate AAF if we have all the required values. + if(pipResponseUID!=null && pipResponsePass!=null && pipResponseType != null && pipResponseAction!= null && pipResponseInstance!=null && pipResponseEnv!=null){ + // Check the Environment. + String environment = getValue(pipResponseEnv); + if(environment == null){ + response = "Environment Value is not set. "; + } + String userName = getValue(pipResponseUID); + String pass = getValue(pipResponsePass); + AAFPolicyClient aafClient = null; + Properties properties = new Properties(); + if(environment.equalsIgnoreCase("PROD")){ + properties.setProperty("ENVIRONMENT", "PROD"); + }else if(environment.equalsIgnoreCase("TEST")){ + properties.setProperty("ENVIRONMENT", "TEST"); + }else{ + properties.setProperty("ENVIRONMENT", "DEVL"); + } + logger.debug("environment : " + environment); + if(userName!=null && pass!=null){ + try { + aafClient = AAFPolicyClient.getInstance(properties); + } catch (AAFPolicyException e) { + logger.error("AAF configuration failed. " + e.getMessage()); + } + if(aafClient!=null){ + if(aafClient.checkAuth(userName, pass)){ + String type = getValue(pipResponseType); + String instance = getValue(pipResponseInstance); + String action = getValue(pipResponseAction); + if(aafClient.checkPerm(userName, pass, type, instance, action)){ + response = SUCCESS + "Permissions Validated"; + }else{ + response = "No Permissions for "+userName+" to: "+type+", "+instance+", "+action; + } + }else{ + response = "Authentication Failed for the given Values"; + } + } + }else{ + response = "ID and Password are not given"; + } + + }else{ + response = "Insufficient Values to Evaluate AAF"; + } + return response; + } + + private void addStringAttribute(StdMutablePIPResponse stdPIPResponse, Identifier category, Identifier attributeId, String value) { + if (value != null) { + AttributeValue attributeValue = null; + try { + attributeValue = DataTypes.DT_STRING.createAttributeValue(value); + } catch (Exception ex) { + this.logger.error("Failed to convert " + value + " to an AttributeValue", ex); + } + if (attributeValue != null) { + stdPIPResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue, this.getIssuer(), false)); + } + } + } + + private void addBooleanAttribute(StdMutablePIPResponse stdPIPResponse, Identifier category, Identifier attributeId, boolean value) { + AttributeValue attributeValue = null; + try { + attributeValue = DataTypes.DT_BOOLEAN.createAttributeValue(value); + } catch (Exception ex) { + this.logger.error("Failed to convert " + value + " to an AttributeValue", ex); + } + if (attributeValue != null) { + stdPIPResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue, this.getIssuer(), false)); + } + } + + @Override + public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder pipFinder) throws PIPException { + /* + * First check to see if the issuer is set and then match it + */ + String string; + if ((string = pipRequest.getIssuer()) != null) { + if (!string.equals(this.getIssuer())) { + this.logger.debug("Requested issuer '" + string + "' does not match " + (this.getIssuer() == null ? "null" : "'" + this.getIssuer() + "'")); + return StdPIPResponse.PIP_RESPONSE_EMPTY; + } + } + + /* + * Drop the issuer and see if the request matches any of our supported queries + */ + PIPRequest pipRequestSupported = (pipRequest.getIssuer() == null ? pipRequest : new StdPIPRequest(pipRequest.getCategory(), pipRequest.getAttributeId(), pipRequest.getDataTypeId())); + if (!mapSupportedAttributes.containsKey(pipRequestSupported)) { + this.logger.debug("Requested attribute '" + pipRequest.toString() + "' is not supported"); + return StdPIPResponse.PIP_RESPONSE_EMPTY; + } + StdMutablePIPResponse stdPIPResponse = new StdMutablePIPResponse(); + String response = this.getResult(pipFinder); + boolean result = false; + if(response.contains(SUCCESS)){ + result = true; + } + this.addBooleanAttribute(stdPIPResponse, XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESULT_ID, result); + this.addStringAttribute(stdPIPResponse, XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESPONSE_ID, response); + return new StdPIPResponse(stdPIPResponse); + } + + @Override + public void configure(String id, Properties properties) throws PIPException { + super.configure(id, properties); + if (this.getDescription() == null) { + this.setDescription(DEFAULT_DESCRIPTION); + } + if (this.getIssuer() == null) { + this.setIssuer(DEFAULT_ISSUER); + } + } + + @Override + public Collection attributesRequired() { + List attributes = new ArrayList(); + for (PIPRequest attribute: mapRequiredAttributes) { + attributes.add(new StdPIPRequest(attribute)); + } + return attributes; + } + + @Override + public Collection attributesProvided() { + List attributes = new ArrayList(); + for (PIPRequest attribute : mapSupportedAttributes.keySet()) { + attributes.add(new StdPIPRequest(attribute)); + } + return attributes; + } + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/util/MetricsUtil.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/util/MetricsUtil.java new file mode 100644 index 000000000..45a51a191 --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/util/MetricsUtil.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.util; + +public class MetricsUtil { + + public static class AvgLatency { + private long cumLatency = 0; + private long count = 0; + + public void compute(long latency) { + cumLatency += latency; + count++; + } + + public long avg() { + if (count == 0) + return 0; + + return (cumLatency / count); + } + + public void reset() { + cumLatency = 0; + count = 0; + } + } + + public static class MinLatency { + private long min = Long.MAX_VALUE; + + public synchronized void compute(long ts) { + if (ts < min) + min = ts; + } + + public long min() { + return min; + } + + public void reset() { + min = Long.MAX_VALUE; + } + } + + public static class MaxLatency { + private long max = Long.MIN_VALUE; + + public synchronized void compute(long ts) { + if (ts > max) + max = ts; + } + + public long max() { + return max; + } + + public void reset() { + max = Long.MIN_VALUE; + } + } + +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/util/XACMLPolicyScanner.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/util/XACMLPolicyScanner.java new file mode 100644 index 000000000..7fa2aa414 --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/util/XACMLPolicyScanner.java @@ -0,0 +1,727 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.util; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.Unmarshaller; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.openecomp.policy.common.logging.eelf.MessageCodes; +import org.openecomp.policy.common.logging.eelf.PolicyLogger; + +import com.att.research.xacml.api.AttributeAssignment; +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.std.StdAttribute; +import com.att.research.xacml.std.StdAttributeAssignment; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdMutableAdvice; +import com.att.research.xacml.std.StdMutableObligation; +import com.att.research.xacml.util.XACMLPolicyScanner.Callback; +import com.att.research.xacml.util.XACMLPolicyScanner.CallbackResult; + +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeSelectorType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.IdReferenceType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType; +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 oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType; + +/** + * class XACMLPolicyScanner + * + * This class traverses the hierarchy of a XACML 3.0 policy. You can optionally pass a Callback class + * and override any desired methods to retrieve information from a policy. + * + * + */ +public class XACMLPolicyScanner { + + private static final Log logger = LogFactory.getLog(XACMLPolicyScanner.class); + private Object policyObject = null; + private Callback callback = null; + + public XACMLPolicyScanner(Path filename, Callback callback) { + try (InputStream is = Files.newInputStream(filename)) { + this.policyObject = XACMLPolicyScanner.readPolicy(is); + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to read policy", e); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy"); + } + this.callback = callback; + } + + public XACMLPolicyScanner(PolicySetType policySet, Callback callback) { + this.policyObject = policySet; + this.callback = callback; + } + + public XACMLPolicyScanner(PolicySetType policySet) { + this(policySet, null); + } + + public XACMLPolicyScanner(PolicyType policy, Callback callback) { + this.policyObject = policy; + this.callback = callback; + } + + public XACMLPolicyScanner(PolicyType policy) { + this(policy, null); + } + + /** + * Sets the callback interface to be used. + * + * @param cb + */ + public void setCallback(Callback cb) { + this.callback = cb; + } + + /** + * Saves the given callback object then calls the scan() method. + * + * @param cb + * @return + */ + public Object scan(Callback cb) { + this.callback = cb; + return this.scan(); + } + + /** + * + * This begins the scanning of the contained object. + * + * @return - The PolicySet/Policy that was scanned. + */ + public Object scan() { + if (this.policyObject == null) { + return null; + } + if (this.callback != null) { + if (this.callback.onBeginScan(this.policyObject) == CallbackResult.STOP) { + return this.policyObject; + } + } + if (this.policyObject instanceof PolicyType) { + this.scanPolicy(null, (PolicyType) this.policyObject); + } else if (this.policyObject instanceof PolicySetType) { + this.scanPolicySet(null, (PolicySetType) this.policyObject); + } else { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unknown class type: " + this.policyObject.getClass().getCanonicalName()); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + "Unknown class type: " + this.policyObject.getClass().getCanonicalName()); + } + if (this.callback != null) { + this.callback.onFinishScan(this.policyObject); + } + return this.policyObject; + } + + /** + * This performs the scan of a PolicySet + * + * @param parent - Its parent PolicySet. Can be null if this is the root. + * @param policySet - The PolicySet object. + * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning. + */ + /** + * @param parent + * @param policySet + * @return + */ + protected CallbackResult scanPolicySet(PolicySetType parent, PolicySetType policySet) { + if (logger.isTraceEnabled()) { + logger.trace("scanning policy set: " + policySet.getPolicySetId() + " " + policySet.getDescription()); + } + if (this.callback != null) { + if (this.callback.onPreVisitPolicySet(parent, policySet) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + } + // + // Scan its info + // + if (this.scanTarget(policySet, policySet.getTarget()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + if (this.scanObligations(policySet, policySet.getObligationExpressions()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + if (this.scanAdvice(policySet, policySet.getAdviceExpressions()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + // + // Iterate the policy sets and/or policies + // + List> list = policySet.getPolicySetOrPolicyOrPolicySetIdReference(); + for (JAXBElement element: list) { + if (element.getName().getLocalPart().equals("PolicySet")) { + if (this.scanPolicySet(policySet, (PolicySetType)element.getValue()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + } else if (element.getName().getLocalPart().equals("Policy")) { + if (this.scanPolicy(policySet, (PolicyType)element.getValue()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + } else if (element.getValue() instanceof IdReferenceType) { + if (element.getName().getLocalPart().equals("PolicySetIdReference")) { + + } else if (element.getName().getLocalPart().equals("PolicyIdReference")) { + + } + } else { + logger.warn("generating policy sets found unsupported element: " + element.getName().getNamespaceURI()); + } + } + if (this.callback != null) { + if (this.callback.onPostVisitPolicySet(parent, policySet) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + } + return CallbackResult.CONTINUE; + } + + /** + * + * This performs scanning of the Policy object. + * + * @param parent - The parent PolicySet of the policy. This can be null if this is a root Policy. + * @param policy - The policy being scanned. + * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning. + */ + protected CallbackResult scanPolicy(PolicySetType parent, PolicyType policy) { + if (logger.isTraceEnabled()) { + logger.trace("scanning policy: " + policy.getPolicyId() + " " + policy.getDescription()); + } + if (this.callback != null) { + if (this.callback.onPreVisitPolicy(parent, policy) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + } + // + // Scan its info + // + if (this.scanTarget(policy, policy.getTarget()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + if (this.scanVariables(policy, policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + if (this.scanObligations(policy, policy.getObligationExpressions()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + if (this.scanAdvice(policy, policy.getAdviceExpressions()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + // + // Iterate the rules + // + List list = policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition(); + for (Object o: list) { + if (o instanceof RuleType) { + RuleType rule = (RuleType) o; + if (logger.isTraceEnabled()) { + logger.trace("scanning rule: " + rule.getRuleId() + " " + rule.getDescription()); + } + if (this.callback != null) { + if (this.callback.onPreVisitRule(policy, rule) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + } + if (this.scanTarget(rule, rule.getTarget()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + if (this.scanConditions(rule, rule.getCondition()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + if (this.scanObligations(rule, rule.getObligationExpressions()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + if (this.scanAdvice(rule, rule.getAdviceExpressions()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + if (this.callback != null) { + if (this.callback.onPostVisitRule(policy, rule) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + } + } else if (o instanceof VariableDefinitionType) { + if (this.callback != null) { + if (this.callback.onVariable(policy, (VariableDefinitionType) o) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + } + } else { + if (logger.isDebugEnabled()) { + logger.debug("scanning policy rules found unsupported object:" + o.toString()); + } + } + } + if (this.callback != null) { + if (this.callback.onPostVisitPolicy(parent, policy) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + } + return CallbackResult.CONTINUE; + } + + /** + * Scans the given target for attributes. Its sole purpose is to return attributes found. + * + * @param parent - The parent PolicySet/Policy/Rule for the target. + * @param target - The target. + * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning. + */ + protected CallbackResult scanTarget(Object parent, TargetType target) { + if (target == null) { + return CallbackResult.CONTINUE; + } + List anyOfList = target.getAnyOf(); + if (anyOfList != null) { + Iterator iterAnyOf = anyOfList.iterator(); + while (iterAnyOf.hasNext()) { + AnyOfType anyOf = iterAnyOf.next(); + List allOfList = anyOf.getAllOf(); + if (allOfList != null) { + Iterator iterAllOf = allOfList.iterator(); + while (iterAllOf.hasNext()) { + AllOfType allOf = iterAllOf.next(); + List matchList = allOf.getMatch(); + if (matchList != null) { + Iterator iterMatch = matchList.iterator(); + while (iterMatch.hasNext()) { + MatchType match = iterMatch.next(); + // + // Finally down to the actual attribute + // + StdAttribute attribute = null; + AttributeValueType value = match.getAttributeValue(); + if (match.getAttributeDesignator() != null && value != null) { + AttributeDesignatorType designator = match.getAttributeDesignator(); + // + // The content may be tricky + // + attribute = new StdAttribute(new IdentifierImpl(designator.getCategory()), + new IdentifierImpl(designator.getAttributeId()), + new StdAttributeValue>(new IdentifierImpl(value.getDataType()), value.getContent()), + designator.getIssuer(), + false); + } else if (match.getAttributeSelector() != null && value != null) { + AttributeSelectorType selector = match.getAttributeSelector(); + attribute = new StdAttribute(new IdentifierImpl(selector.getCategory()), + new IdentifierImpl(selector.getContextSelectorId()), + new StdAttributeValue>(new IdentifierImpl(value.getDataType()), value.getContent()), + null, + false); + } else { + logger.warn("NULL designator/selector or value for match."); + } + if (attribute != null && this.callback != null) { + if (this.callback.onAttribute(parent, target, attribute) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + } + } + } + } + } + } + } + return CallbackResult.CONTINUE; + } + + /** + * Scan the list of obligations. + * + * @param parent - The parent PolicySet/Policy/Rule for the obligation. + * @param obligationExpressionsType - All the obligation expressions. + * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning. + */ + protected CallbackResult scanObligations(Object parent, ObligationExpressionsType obligationExpressionsType) { + if (obligationExpressionsType == null) { + return CallbackResult.CONTINUE; + } + List expressions = obligationExpressionsType.getObligationExpression(); + if (expressions == null || expressions.size() == 0) { + return CallbackResult.CONTINUE; + } + for (ObligationExpressionType expression : expressions) { + StdMutableObligation ob = new StdMutableObligation(new IdentifierImpl(expression.getObligationId())); + List assignments = expression.getAttributeAssignmentExpression(); + if (assignments != null) { + for (AttributeAssignmentExpressionType assignment : assignments) { + // category is optional and may be null + IdentifierImpl categoryId = null; + if (assignment.getCategory() != null) { + categoryId = new IdentifierImpl(assignment.getCategory()); + } + AttributeAssignment attribute = new StdAttributeAssignment( + categoryId, + new IdentifierImpl(assignment.getAttributeId()), + assignment.getIssuer(), + new StdAttributeValue(null, null) + ); + ob.addAttributeAssignment(attribute); + } + } + if (this.callback != null) { + if (this.callback.onObligation(parent, expression, ob) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + } + } + return CallbackResult.CONTINUE; + } + + /** + * + * Scans the list of advice expressions returning each individually. + * + * @param parent - The parent PolicySet/Policy/Rule for the advice. + * @param adviceExpressionstype - The list of advice expressions. + * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning. + */ + protected CallbackResult scanAdvice(Object parent, AdviceExpressionsType adviceExpressionstype) { + if (adviceExpressionstype == null) { + return CallbackResult.CONTINUE; + } + List expressions = adviceExpressionstype.getAdviceExpression(); + if (expressions == null || expressions.size() == 0) { + return CallbackResult.CONTINUE; + } + for (AdviceExpressionType expression : expressions) { + StdMutableAdvice ob = new StdMutableAdvice(new IdentifierImpl(expression.getAdviceId())); + List assignments = expression.getAttributeAssignmentExpression(); + if (assignments != null) { + for (AttributeAssignmentExpressionType assignment : assignments) { + IdentifierImpl categoryId = null; + if (assignment.getCategory() != null) { + categoryId = new IdentifierImpl(assignment.getCategory()); + } + AttributeAssignment attribute = new StdAttributeAssignment( + categoryId, + new IdentifierImpl(assignment.getAttributeId()), + assignment.getIssuer(), + new StdAttributeValue(null, null) + ); + ob.addAttributeAssignment(attribute); + } + } + if (this.callback != null) { + if (this.callback.onAdvice(parent, expression, ob) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + } + } + return CallbackResult.CONTINUE; + } + + /** + * Scans the list of variable definitions. + * + * @param policy - Policy object containing the variable definition. + * @param list - List of variable definitions. + * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning. + */ + protected CallbackResult scanVariables(PolicyType policy, List list) { + if (list == null) { + return CallbackResult.CONTINUE; + } + for (Object o : list) { + if (o instanceof VariableDefinitionType) { + if (this.callback != null) { + if (this.callback.onVariable(policy, (VariableDefinitionType) o) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + } + } + } + + return CallbackResult.CONTINUE; + } + + /** + * Scans the list of conditions. + * + * @param rule + * @param condition + * @return + */ + protected CallbackResult scanConditions(RuleType rule, ConditionType condition) { + if (condition != null) { + if (this.callback != null) { + if (this.callback.onCondition(rule, condition) == CallbackResult.STOP) { + return CallbackResult.STOP; + } + } + } + return CallbackResult.CONTINUE; + } + + /** + * Reads the XACML XML policy file in and returns the version contained in the root Policy/PolicySet element. + * + * @param policy - The policy file. + * @return - The version string from the file (uninterpreted) + * @throws IOException + */ + public static String getVersion(Path policy) throws IOException { + Object data = null; + try (InputStream is = Files.newInputStream(policy)) { + data = XACMLPolicyScanner.readPolicy(is); + } catch (IOException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to read policy", e); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy"); + throw e; + } + if (data == null) { + logger.warn("Version is null."); + return null; + } + return getVersion(data); + } + + /** + * Reads the Policy/PolicySet element object and returns its current version. + * + * @param data - Either a PolicySet or Policy XACML type object. + * @return - The integer version value. -1 if it doesn't exist or was un-parsable. + */ + public static String getVersion(Object data) { + String version = null; + try { + if (data instanceof PolicySetType) { + version = ((PolicySetType)data).getVersion(); + } else if (data instanceof PolicyType) { + version = ((PolicyType)data).getVersion(); + } else { + if (data != null) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: " + data.getClass().getCanonicalName()); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: " + data.getClass().getCanonicalName()); + } + return null; + } + if (version != null && version.length() > 0) { + return version; + } else { + logger.warn("No version set in policy"); + } + } catch (NumberFormatException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid version contained in policy: " + version); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Invalid version contained in policy: " + version); + return null; + } + return null; + } + + /** + * Returns the Policy or PolicySet ID. + * + * @param data - A XACML 3.0 Policy or PolicySet element object. + * @return The policy/policyset's policy ID + */ + public static String getID(Object data) { + if (data instanceof PolicySetType) { + return ((PolicySetType)data).getPolicySetId(); + } else if (data instanceof PolicyType) { + return ((PolicyType)data).getPolicyId(); + } else { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: " + data.getClass().getCanonicalName()); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: " + data.getClass().getCanonicalName()); + return null; + } + } + + public static List getCreatedByModifiedBy(Path policyPath) throws IOException{ + String createdBy = ""; + String modifiedBy= ""; + String cValue = "@CreatedBy:"; + String mValue = "@ModifiedBy:"; + for(String line: Files.readAllLines(policyPath)){ + line = line.replaceAll("\\s+", ""); + if(line.isEmpty()){ + continue; + } + if(line.contains("") && line.contains(cValue) && line.contains(mValue)){ + createdBy = line.substring(line.indexOf(cValue) + cValue.length(), line.lastIndexOf(cValue)); + modifiedBy = line.substring(line.indexOf(mValue) + mValue.length(), line.lastIndexOf(mValue)); + break; + } + } + return Arrays.asList(createdBy, modifiedBy); + } + + //get the Created Name of the User on reading the Xml file + public static String getCreatedBy(Path policyPath) throws IOException{ + String userId = ""; + String value = "@CreatedBy:"; + for(String line: Files.readAllLines(policyPath)){ + line = line.replaceAll("\\s+", ""); + if(line.isEmpty()){ + continue; + } + if(line.contains("") && line.contains(value)){ + userId = line.substring(line.indexOf(value) + value.length(), line.lastIndexOf(value)); + break; + } + } + return userId; + } + + //get the Modified Name of the User on reading the Xml file + public static String getModifiedBy(Path policyPath) throws IOException{ + String modifiedBy = ""; + String value = "@ModifiedBy:"; + for(String line: Files.readAllLines(policyPath)){ + line = line.replaceAll("\\s+", ""); + if(line.isEmpty()){ + continue; + } + if(line.contains("") && line.contains(value)){ + modifiedBy = line.substring(line.indexOf(value) + value.length(), line.lastIndexOf(value)); + break; + } + } + return modifiedBy; + } + + /** + * readPolicy - does the work to read in policy data from a file. + * + * @param policy - The path to the policy file. + * @return - The policy data object. This *should* be either a PolicySet or a Policy. + */ + public static Object readPolicy(InputStream is) { + try { + // + // Create a DOM parser + // + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + // + // Parse the policy file + // + Document doc = db.parse(is); + // + // Because there is no root defined in xacml, + // find the first element + // + NodeList nodes = doc.getChildNodes(); + Node node = nodes.item(0); + Element e = null; + if (node.getNodeType() == Node.ELEMENT_NODE) { + e = (Element) node; + // + // Is it a 3.0 policy? + // + if (e.getNamespaceURI().equals("urn:oasis:names:tc:xacml:3.0:core:schema:wd-17")) { + // + // A policyset or policy could be the root + // + if (e.getNodeName().endsWith("Policy")) { + // + // Now we can create the context for the policy set + // and unmarshall the policy into a class. + // + JAXBContext context = JAXBContext.newInstance(PolicyType.class); + Unmarshaller um = context.createUnmarshaller(); + JAXBElement root = um.unmarshal(e, PolicyType.class); + // + // Here is our policy set class + // + return root.getValue(); + } else if (e.getNodeName().endsWith("PolicySet")) { + // + // Now we can create the context for the policy set + // and unmarshall the policy into a class. + // + JAXBContext context = JAXBContext.newInstance(PolicySetType.class); + Unmarshaller um = context.createUnmarshaller(); + JAXBElement root = um.unmarshal(e, PolicySetType.class); + // + // Here is our policy set class + // + return root.getValue(); + } else { + if (logger.isDebugEnabled()) { + logger.debug("Not supported yet: " + e.getNodeName()); + } + } + } else { + logger.warn("unsupported namespace: " + e.getNamespaceURI()); + } + } else { + if (logger.isDebugEnabled()) { + logger.debug("No root element contained in policy " + + " Name: " + node.getNodeName() + " type: " + node.getNodeType() + + " Value: " + node.getNodeValue()); + } + } + } catch (Exception e) { + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID + e.getMessage()); + PolicyLogger.error(MessageCodes.ERROR_SCHEMA_INVALID, e, "XACMLPolicyScanner", "Exception in readPolicy"); + } + return null; + } + + /** + * @return the policyObject + */ + public Object getPolicyObject() { + return policyObject; + } +} diff --git a/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/util/XACMLPolicyWriter.java b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/util/XACMLPolicyWriter.java new file mode 100644 index 000000000..3706bda3f --- /dev/null +++ b/ECOMP-XACML/src/main/java/org/openecomp/policy/xacml/util/XACMLPolicyWriter.java @@ -0,0 +1,344 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 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.openecomp.policy.xacml.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Iterator; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; + +import org.openecomp.policy.common.logging.eelf.MessageCodes; +import org.openecomp.policy.common.logging.eelf.PolicyLogger; + + +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType; +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; + +/** + * Helper static class for policy writing. + * + * + */ +public class XACMLPolicyWriter { + + /** + * Helper static class that does the work to write a policy set to a file on disk. + * + * + */ + public static Path writePolicyFile(Path filename, PolicySetType policySet) { + JAXBElement policySetElement = new ObjectFactory().createPolicySet(policySet); + try { + JAXBContext context = JAXBContext.newInstance(PolicySetType.class); + Marshaller m = context.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + m.marshal(policySetElement, filename.toFile()); + + if (Files.exists(filename)) { + return filename; + } else { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "File does not exist after marshalling."); + return null; + } + + } catch (JAXBException e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyWriter", "writePolicyFile failed"); + return null; + } + } + + /** + * Helper static class that does the work to write a policy set to an output stream. + * + * + */ + public static void writePolicyFile(OutputStream os, PolicySetType policySet) { + JAXBElement policySetElement = new ObjectFactory().createPolicySet(policySet); + try { + JAXBContext context = JAXBContext.newInstance(PolicySetType.class); + Marshaller m = context.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + m.marshal(policySetElement, os); + } catch (JAXBException e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyWriter", "writePolicyFile failed"); + } + } + + /** + * Helper static class that does the work to write a policy to a file on disk. + * + * + */ + public static Path writePolicyFile(Path filename, PolicyType policy) { + JAXBElement policyElement = new ObjectFactory().createPolicy(policy); + try { + JAXBContext context = JAXBContext.newInstance(PolicyType.class); + Marshaller m = context.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + m.marshal(policyElement, filename.toFile()); + + if (Files.exists(filename)) { + return filename; + } else { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "File does not exist after marshalling."); + return null; + } + + } catch (JAXBException e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyWriter", "writePolicyFile failed"); + return null; + } + } + + + /** + * Helper static class that does the work to write a policy to a file on disk. + * + * + */ + public static InputStream getXmlAsInputStream(PolicyType policy) { + JAXBElement policyElement = new ObjectFactory().createPolicy(policy); + try { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + JAXBContext context = JAXBContext.newInstance(PolicyType.class); + Marshaller m = context.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + m.marshal(policyElement, byteArrayOutputStream); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); + + return byteArrayInputStream; + + } catch (JAXBException e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyWriter", "writePolicyFile failed"); + return null; + } + } + /** + * Helper static class that does the work to write a policy set to an output stream. + * + * + */ + public static void writePolicyFile(OutputStream os, PolicyType policy) { + JAXBElement policySetElement = new ObjectFactory().createPolicy(policy); + try { + JAXBContext context = JAXBContext.newInstance(PolicyType.class); + Marshaller m = context.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + m.marshal(policySetElement, os); + } catch (JAXBException e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyWriter", "writePolicyFile failed"); + } + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static String changeFileNameInXmlWhenRenamePolicy(Path filename) { + + PolicyType policyType = null; + String extension = ""; + String domain = null; + String repository = "repository"; + if(filename.toString().contains("Config_")){ + domain = filename.toString().substring(filename.toString().indexOf(repository) + (repository.toString().length()+1), filename.toString().indexOf("Config_")); + }else if(filename.toString().contains("Action_")){ + domain = filename.toString().substring(filename.toString().indexOf(repository) + (repository.toString().length()+1), filename.toString().indexOf("Action_")); + }else if(filename.toString().contains("Decision_")){ + domain = filename.toString().substring(filename.toString().indexOf(repository) + (repository.toString().length()+1), filename.toString().indexOf("Decision_")); + } + if(domain.contains(File.separator)){ + domain = domain.replace(File.separator, "."); + } + try { + JAXBContext context = JAXBContext.newInstance(PolicyType.class); + Unmarshaller m = context.createUnmarshaller(); + JAXBElement policyElement = (JAXBElement) m.unmarshal(filename.toFile()); + policyType = policyElement.getValue(); + if (policyType != null) { + TargetType targetType = policyType.getTarget(); + List anyOfTypes = targetType.getAnyOf(); + for( Iterator anyOfIte = anyOfTypes.iterator(); anyOfIte.hasNext(); ){ + AnyOfType anyOfType = (AnyOfType) anyOfIte.next(); + List allOf = anyOfType.getAllOf(); + for( Iterator allOfIte = allOf.iterator(); allOfIte.hasNext(); ){ + AllOfType allOfType = (AllOfType) allOfIte.next(); + List match = allOfType.getMatch(); + for( Iterator matchIte = match.iterator(); matchIte.hasNext();) { + MatchType matchType = (MatchType) matchIte.next(); + if(matchType.getAttributeDesignator().getAttributeId().equals("PolicyName")){ + AttributeValueType attributeValueType = matchType.getAttributeValue(); + List contents = attributeValueType.getContent(); + if (contents != null && contents.size() > 0) { + String value = (String) contents.get(0); + String version = value; + version = version.substring(0, version.lastIndexOf(".")); + version = version.substring(version.lastIndexOf(".")); + if(filename.toString().contains("Config_")){ + value = value.substring(0, value.indexOf("Config_")); + }else{ + value = value.substring(0, value.indexOf("Decision_")); + } + String tmp = filename.getFileName()+""; + String newName = tmp.substring(0, tmp.lastIndexOf(".")); + attributeValueType.getContent().clear(); + attributeValueType.getContent().add(domain + newName + "." + "xml"); + } + } + } + } + } + if(filename.toString().contains("Config_") || filename.toString().contains("Action_")){ + List objects = policyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition(); + if (objects != null && objects.size() > 0) { + for (Iterator ite = objects.iterator(); ite.hasNext();) { + + RuleType ruleType = (RuleType ) ite.next(); + AdviceExpressionsType adviceExpressionsType = ruleType.getAdviceExpressions(); + if (adviceExpressionsType != null) { + List adviceExpressionTypes = adviceExpressionsType.getAdviceExpression(); + if (adviceExpressionTypes != null && adviceExpressionTypes.size() > 0) { + for (Iterator iterator = adviceExpressionTypes + .iterator(); iterator.hasNext();) { + AdviceExpressionType adviceExpressionType = (AdviceExpressionType) iterator + .next(); + if (adviceExpressionType.getAdviceId() != null && !adviceExpressionType.getAdviceId().equals("") && (adviceExpressionType.getAdviceId().equals("configID") + || adviceExpressionType.getAdviceId().equals("faultID") || adviceExpressionType.getAdviceId().equals("PMID")||adviceExpressionType.getAdviceId().equals("firewallConfigID") + || adviceExpressionType.getAdviceId().equals("MSID")) || adviceExpressionType.getAdviceId().equals("GocID")||adviceExpressionType.getAdviceId().equals("GocHPID")||adviceExpressionType.getAdviceId().equals("BRMSRAWID") + ||adviceExpressionType.getAdviceId().equals("BRMSPARAMID")|| adviceExpressionType.getAdviceId().equals("HPSuppID") || adviceExpressionType.getAdviceId().equals("HPFlapID") || adviceExpressionType.getAdviceId().equals("HPOverID")) + { + List attributeAssignmentExpressionTypes = adviceExpressionType.getAttributeAssignmentExpression(); + if (attributeAssignmentExpressionTypes != null && attributeAssignmentExpressionTypes.size() > 0) { + for (Iterator iterator2 = attributeAssignmentExpressionTypes + .iterator(); iterator2.hasNext();) { + AttributeAssignmentExpressionType attributeAssignmentExpressionType = (AttributeAssignmentExpressionType) iterator2 + .next(); + if (attributeAssignmentExpressionType.getAttributeId().equals("URLID")) { + JAXBElement attributeValueType = (JAXBElement) attributeAssignmentExpressionType.getExpression(); + AttributeValueType attributeValueType1 = attributeValueType.getValue(); + String configUrl = "$URL"; + String urlVal = (String) attributeValueType1.getContent().get(0); + String origExtension = urlVal.substring(urlVal.lastIndexOf('.')+1).trim(); + extension = origExtension; + attributeValueType1.getContent().clear(); + String txtFileName = filename.getFileName().toString(); + txtFileName = txtFileName.substring(0, txtFileName.lastIndexOf(".")+1) + origExtension; + txtFileName = configUrl+ File.separator + "Config" + File.separator + domain + txtFileName; + attributeValueType1.getContent().add(txtFileName); + } else if (attributeAssignmentExpressionType.getAttributeId().equals("PolicyName")) { + JAXBElement attributeValueType = (JAXBElement) attributeAssignmentExpressionType.getExpression(); + AttributeValueType attributeValueType1 = attributeValueType.getValue(); + List contents = attributeValueType1.getContent(); + if (contents != null && contents.size() > 0) { + String value = (String) contents.get(0); + String version = value; + version = version.substring(0, version.lastIndexOf(".")); + version = version.substring(version.lastIndexOf(".")); + value = value.substring(0, value.indexOf("Config_")); + String tmp = filename.getFileName()+""; + String newName = tmp.substring(0, tmp.lastIndexOf(".")); + attributeValueType1.getContent().clear(); + attributeValueType1.getContent().add(domain + newName + "." + "xml"); + } + + } + + } + } + } + } + } + } + } + if (objects != null && objects.size() > 0) { + for (Iterator ite1 = objects.iterator(); ite1.hasNext();) { + + RuleType ruleType1 = (RuleType ) ite1.next(); + ObligationExpressionsType obligationExpressionsType = ruleType1.getObligationExpressions(); + if (obligationExpressionsType != null) { + List obligationExpressionType = obligationExpressionsType.getObligationExpression(); + if (obligationExpressionType != null && obligationExpressionType.size() > 0) { + for (Iterator iterator = obligationExpressionType + .iterator(); iterator.hasNext();) { + ObligationExpressionType obligationExpressionTypes = (ObligationExpressionType) iterator + .next(); + if (obligationExpressionTypes.getObligationId() != null && !obligationExpressionTypes.getObligationId().equals("")) { + List attributeAssignmentExpressionTypes = obligationExpressionTypes.getAttributeAssignmentExpression(); + if (attributeAssignmentExpressionTypes != null && attributeAssignmentExpressionTypes.size() > 0) { + for (Iterator iterator2 = attributeAssignmentExpressionTypes + .iterator(); iterator2.hasNext();) { + AttributeAssignmentExpressionType attributeAssignmentExpressionType = (AttributeAssignmentExpressionType) iterator2 + .next(); + if (attributeAssignmentExpressionType.getAttributeId().equals("body")) { + JAXBElement attributeValueType = (JAXBElement) attributeAssignmentExpressionType.getExpression(); + AttributeValueType attributeValueType1 = attributeValueType.getValue(); + String configUrl = "$URL"; + String urlVal = (String) attributeValueType1.getContent().get(0); + String origExtension = urlVal.substring(urlVal.lastIndexOf('.')+1).trim(); + extension = "json"; + attributeValueType1.getContent().clear(); + String txtFileName = filename.getFileName().toString(); + txtFileName = txtFileName.substring(0, txtFileName.lastIndexOf(".")+1) + origExtension; + txtFileName = configUrl+ File.separator + "Action" + File.separator + domain + txtFileName; + attributeValueType1.getContent().add(txtFileName); + } + + } + } + + } + + } + } + } + } + } + } + } + writePolicyFile(filename, policyType); + } + }catch (JAXBException e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyWriter", "writePolicyFile failed"); + } + + return extension; + } + +} -- cgit 1.2.3-korg