X-Git-Url: https://gerrit.onap.org/r/gitweb?p=policy%2Fengine.git;a=blobdiff_plain;f=ONAP-XACML%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Fpolicy%2Fxacml%2Fstd%2Fpap%2FStdPDPGroup.java;h=daa3764d8dfcd178e235d3ab4ad5aff358051991;hp=745a43dca2c545204f1ba8ab71fcc943737e32c8;hb=9bad71c7150ea6f94b2a08b68f356b4ee96c3d66;hpb=4d503f398d2f309cc077b55b5f1cce4c4bd773e6 diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPGroup.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPGroup.java index 745a43dca..daa3764d8 100644 --- a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPGroup.java +++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPGroup.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP-XACML * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,8 +17,21 @@ * limitations under the License. * ============LICENSE_END========================================================= */ + package org.onap.policy.xacml.std.pap; +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDP; +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; + import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; @@ -35,7 +48,8 @@ import java.util.List; import java.util.Properties; import java.util.Set; import java.util.TreeSet; - +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.onap.policy.common.logging.eelf.MessageCodes; @@ -45,1004 +59,995 @@ import org.onap.policy.xacml.api.pap.OnapPDP; import org.onap.policy.xacml.api.pap.OnapPDPGroup; import org.onap.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.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; +@EqualsAndHashCode(callSuper = false) +@ToString +public class StdPDPGroup extends StdPDPItemSetChangeNotifier + implements OnapPDPGroup, StdItemSetChangeListener, Comparable, Serializable { + + private static final long serialVersionUID = 1L; + private static final String MSG_GROUPNOTEXIST = "Group directory does NOT exist"; + private static final String MSG_LOADFAILURE = "Failed to load group policy properties file: "; + private static final String STR_APPEND_NAME = ".name"; + private static final String STR_APPEND_DESCRIPTION = ".description"; + private static final String STR_APPEND_PDPS = ".pdps"; + private static final String STR_CLASS = "StdPDPGroup"; + private static final String PROPS_POLICY = "xacml.policy.properties"; + private static final String PROPS_PIP = "xacml.pip.properties"; + + private static Log logger = LogFactory.getLog(StdPDPGroup.class); + + private String id; + + private boolean isDefault = false; + + private String name; + + private String description; + + private transient StdPDPGroupStatus status = new StdPDPGroupStatus(Status.UNKNOWN); + + private transient Set pdps = new HashSet<>(); + + private transient Set policies = new HashSet<>(); + + private transient Set selectedPolicies = new HashSet<>(); + + private transient Set pipConfigs = new HashSet<>(); + + private String operation; + + @JsonIgnore + private transient Path directory; + + @JsonIgnore + private Integer jmxport; + + public StdPDPGroup() { + // + // Methods needed for JSON deserialization + // + } + + /** + * StdPDPGroup constructor. + * + * @param group OnapPDPGroup + */ + public StdPDPGroup(OnapPDPGroup group) { + this.id = group.getId(); + this.name = group.getName(); + this.description = group.getDescription(); + this.isDefault = group.isDefaultGroup(); + this.pdps = group.getOnapPdps(); + this.policies = group.getPolicies(); + this.pipConfigs = group.getPipConfigs(); + } + + 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; + } + + /** + * StdPDPGroup. + * + * @param id String + * @param isDefault boolean + * @param name String + * @param description String + * @param directory Path + */ + 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(); + } + + /** + * StdPDPGroup. + * + * @param id String + * @param isDefault boolean + * @param properties Properties + * @param directory Path + * @throws PAPException PAPException + */ + 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(STR_APPEND_NAME)) { + this.name = properties.getProperty(key.toString()); + } else if (key.toString().endsWith(STR_APPEND_DESCRIPTION)) { + this.description = properties.getProperty(key.toString()); + } else if (key.toString().endsWith(STR_APPEND_PDPS)) { + String pdpList = properties.getProperty(key.toString()); + if (pdpList != null && pdpList.length() > 0) { + for (String pdpId : Splitter.on(',').omitEmptyStrings().trimResults().split(pdpList)) { + StdPDP pdp = new StdPDP(pdpId, 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 (! directory.toFile().exists()) { + logger.warn("Group directory does NOT exist: " + directory.toString()); + try { + Files.createDirectory(directory); + this.status.addLoadWarning(MSG_GROUPNOTEXIST); + } catch (IOException e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, MSG_GROUPNOTEXIST); + this.status.addLoadError(MSG_GROUPNOTEXIST); + this.status.setStatus(PDPGroupStatus.Status.LOAD_ERRORS); + } + } + // + // Parse policies + // + this.loadPolicies(Paths.get(directory.toString(), PROPS_POLICY)); + // + // Parse pip config + // + this.loadPIPConfig(Paths.get(directory.toString(), PROPS_PIP)); + } + + /** + * loadPolicies. + * + * @param file Path + * @throws PAPException PAPException + */ + 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 + "'", e); + } + } 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(MSG_LOADFAILURE + file, e); + this.status.addLoadError("Not policy properties defined"); + this.status.setStatus(Status.LOAD_ERRORS); + throw new PAPException(MSG_LOADFAILURE + file); + } + } + } + + /** + * loadPIPConfig. + * + * @param file Path + * @throws PAPException PAPException + */ + 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 + 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 + "'", e); + } + // Even if we create a new pip file, we still need to parse and load the properties + try { + this.readPipProperties(pipProperties); + } catch (Exception e) { + throw new PAPException("Failed to load the new pip properties file", e); + } + } 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 ("".equals(pipProperties.get(XACMLProperties.PROP_PIP_ENGINES).toString().trim())) { + pipProperties = setPipProperties(pipProperties); + try (OutputStream os = Files.newOutputStream(file)) { + pipProperties.store(os, ""); + } + } + // + // Parse the pips + // + this.readPipProperties(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(MSG_LOADFAILURE + file); + + } + } + } + + /** + * resetStatus. + */ + public void resetStatus() { + // + // 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().isEmpty()) { + this.status.setStatus(Status.UNKNOWN); + } else if (!this.status.getFailedPDPs().isEmpty() || !this.status.getLastUpdateFailedPDPs().isEmpty()) { + this.status.setStatus(Status.LOAD_ERRORS); + } else if (!this.status.getOutOfSynchPDPs().isEmpty()) { + this.status.setStatus(Status.OUT_OF_SYNCH); + } else if (!this.status.getUpdatingPDPs().isEmpty()) { + 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; + } + + /** + * setDefaultGroup. + * + * @param isDefault boolean + */ + 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. + } + + @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 getSelectedPolicies() { + return this.selectedPolicies; + } + + @Override + public String getOperation() { + return this.operation; + } + + @Override + public Set getPdps() { + return Collections.unmodifiableSet(pdps); + } + + public void setOnapPdps(Set pdps) { + this.pdps = pdps; + } + + @Override + public Set getOnapPdps() { + return Collections.unmodifiableSet(pdps); + } + + public boolean addPDP(OnapPDP 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; + } + + @Override + 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() + STR_APPEND_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; + } + + /** + * publishPolicy. + * + * @param id String + * @param name String + * @param isRoot boolean + * @param policy InputStream + * @return PDPPolicy + * @throws PAPException PAPException + */ + 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()) { + try { + Files.delete(tempFile); + } catch (Exception ee) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, ee, STR_CLASS, + "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) { + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, STR_CLASS, "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 String + * @param policy InputStream + * @throws PAPException PAPException + */ + public void copyPolicyToFile(String id, InputStream policy) throws PAPException { + copyPolicyToFile(id, this.name, policy); + } + + /** + * Policy Engine API Copy one policy file into the Group's directory but do not change the configuration. + * + * @param id String + * @param fileName String + * @param policy InputStream + * @throws PAPException PAPException + */ + public void copyPolicyToFile(String id, String fileName, InputStream policy) throws PAPException { + try { + // + // Copy the policy over + // + long num; + Path policyFilePath = Paths.get(this.directory.toAbsolutePath().toString(), id); + + Path policyFile; + if (policyFilePath.toFile().exists()) { + 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 " + fileName); + 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, fileName, policyFile.toUri()); + if (!tempRootPolicy.isValid()) { + try { + Files.delete(policyFile); + } catch (Exception ee) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, ee, STR_CLASS, + "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) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, "Failed to copyPolicyToFile"); + throw new PAPException("Failed to copy policy to file: " + e); + } + } + + /** + * removePolicyFromGroup. + * + * @param policy PDPPolicy + * @return boolean + */ + public boolean removePolicyFromGroup(PDPPolicy policy) { + PolicyLogger.info("policy: " + policy.getId()); + PolicyLogger.info("Policy ID:" + policy.getPolicyId()); + PolicyLogger.info("Policy Version: " + policy.getVersion()); + PolicyLogger.info("StdPDPPolicy Class cast: " + this.getPolicy(policy.getId()).toString()); + StdPDPPolicy currentPolicy = (StdPDPPolicy) this.getPolicy(policy.getId()); + if (currentPolicy == null) { + 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) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, "Failed to delete policy"); + } + return false; + } + + /** + * removePolicy. + * + * @param policy PDPPolicy + * @return boolean + */ + public boolean removePolicy(PDPPolicy policy) { + PDPPolicy currentPolicy = this.getPolicy(policy.getId()); + if (currentPolicy == null) { + 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) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, "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); + } + + @Override + 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 (! directory.toFile().exists()) { + 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) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, + "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(), PROPS_PIP); + if (! pipPropertiesFile.toFile().exists()) { + try { + Files.createFile(pipPropertiesFile); + fire = true; + this.status.addLoadWarning("Created missing PIP properties file"); + } catch (IOException e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, + "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(), PROPS_POLICY); + if (! policyPropertiesFile.toFile().exists()) { + try { + Files.createFile(policyPropertiesFile); + fire = true; + this.status.addLoadWarning("Created missing Policy properties file"); + } catch (IOException e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, + "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 policyId : policyList) { + // + // Construct the policy filename + // + Path policyPath = Paths.get(directory.toString(), policyId); + // + // Create the Policy Object + // + StdPDPPolicy policy; + try { + policy = new StdPDPPolicy(id, isRoot, policyPath.toUri(), properties); + } catch (IOException e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, + "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 != null && policy.getName() == null) { + policy.setName(policy.getId()); + } + } + isRoot = false; + } + } + + private void readPipProperties(Properties properties) { + String list = properties.getProperty(XACMLProperties.PROP_PIP_ENGINES); + if (list == null || list.length() == 0) { + return; + } + for (String pipId : list.split("[,]")) { + StdPDPPIPConfig config = new StdPDPPIPConfig(pipId, 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 void changed() { + + // save the (changed) properties + try { + saveGroupConfiguration(); + } catch (PAPException | IOException e) { + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, STR_CLASS, + "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(OnapPDPGroup group) { + this.changed(); + } + + @Override + public void pdpChanged(OnapPDP pdp) { + // + // If one of the group's PDP's changed, then the group changed + // + this.changed(); + } + + public boolean isDefault() { + return isDefault; + } -public class StdPDPGroup extends StdPDPItemSetChangeNotifier implements OnapPDPGroup, StdItemSetChangeListener, Comparable, Serializable { - - private static final long serialVersionUID = 1L; - private static final String groupNotExist= "Group directory does NOT exist"; - private static Log logger = LogFactory.getLog(StdPDPGroup.class); - - private String id; - - private boolean isDefault = false; - - private String name; - - private String description; - - private transient StdPDPGroupStatus status = new StdPDPGroupStatus(Status.UNKNOWN); - - private transient Set pdps = new HashSet<>(); - - private transient Set policies = new HashSet<>(); - - private transient Set selectedPolicies = new HashSet<>(); - - private transient Set pipConfigs = new HashSet<>(); - - private String operation; - - @JsonIgnore - private transient 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 pdpId : Splitter.on(',').omitEmptyStrings().trimResults().split(pdpList)) { - StdPDP pdp = new StdPDP(pdpId, 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(groupNotExist); - } catch (IOException e) { - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", groupNotExist); - this.status.addLoadError(groupNotExist); - 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 +"'", e); - } - } 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 - 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 +"'", e); - } - //Even if we create a new pip file, we still need to parse and load the properties - try{ - this.readPIPProperties(pipProperties); - }catch(Exception e){ - throw new PAPException("Failed to load the new pip properties file", e); - } - } 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("".equals(pipProperties.get(XACMLProperties.PROP_PIP_ENGINES).toString().trim())){ - pipProperties = setPIPProperties(pipProperties); - try (OutputStream os = Files.newOutputStream(file)) { - pipProperties.store(os, ""); - } - } - // - // Parse the pips - // - this.readPIPProperties(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() { - // - // 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().isEmpty()) { - this.status.setStatus(Status.UNKNOWN); - } else if (!this.status.getFailedPDPs().isEmpty() || !this.status.getLastUpdateFailedPDPs().isEmpty()) { - this.status.setStatus(Status.LOAD_ERRORS); - } else if (!this.status.getOutOfSynchPDPs().isEmpty()) { - this.status.setStatus(Status.OUT_OF_SYNCH); - } else if (!this.status.getUpdatingPDPs().isEmpty()) { - 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 getSelectedPolicies() { - return this.selectedPolicies; - } - - @Override - public String getOperation() { - return this.operation; - } - - @Override - public Set getPdps() { - return Collections.unmodifiableSet(pdps); - } - - public void setOnapPdps(Set pdps) { - this.pdps = pdps; - } - - @Override - public Set getOnapPdps(){ - return Collections.unmodifiableSet(pdps); - } - - public boolean addPDP(OnapPDP 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; - } - - @Override - 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) { - 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) { - 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); - - 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) { - 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) { - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to copyPolicyToFile"); - throw new PAPException("Failed to copy policy to file: " + e); - } - return; - } - - /** - * Policy Engine API Copy one policy file into the Group's directory but do not change the configuration. - * - * @param id - * @param name - * @param policy - * @return - * @throws PAPException - */ - public void copyPolicyToFile(String id, String name, InputStream policy) throws PAPException { - try { - // - // Copy the policy over - // - long num; - Path policyFilePath = Paths.get(this.directory.toAbsolutePath().toString(), id); - - 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) { - 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) { - 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) { - PolicyLogger.info("policy: " + policy.getId()); - PolicyLogger.info("Policy ID:" + policy.getPolicyId()); - PolicyLogger.info("Policy Version: " + policy.getVersion()); - PolicyLogger.info("StdPDPPolicy Class cast: " + this.getPolicy(policy.getId()).toString()); - StdPDPPolicy currentPolicy = (StdPDPPolicy) this.getPolicy(policy.getId()); - if (currentPolicy == null) { - 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) { - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to delete policy"); - } - return false; - } - - public boolean removePolicy(PDPPolicy policy) { - PDPPolicy currentPolicy = this.getPolicy(policy.getId()); - if (currentPolicy == null) { - 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) { - 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); - } - - @Override - 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) { - 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) { - 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) { - 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 policyId : policyList) { - // - // Construct the policy filename - // - Path policyPath = Paths.get(directory.toString(), policyId ); - // - // Create the Policy Object - // - StdPDPPolicy policy; - try { - policy = new StdPDPPolicy(id, isRoot, policyPath.toUri(), properties); - } catch (IOException 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!=null && policy.getName() == null) { - policy.setName(policy.getId()); - } - } - isRoot = false; - } - } - - private void readPIPProperties(Properties properties) { - String list = properties.getProperty(XACMLProperties.PROP_PIP_ENGINES); - if (list == null || list.length() == 0) { - return; - } - for (String pipId : list.split("[,]")) { - StdPDPPIPConfig config = new StdPDPPIPConfig(pipId, 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 + ",selectedPolicies=" - + selectedPolicies + ",operation=" + operation + "]"; - } - - @Override - public void changed() { - - // save the (changed) properties - try { - saveGroupConfiguration(); - } catch (PAPException | IOException e) { - 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(OnapPDPGroup group) { - this.changed(); - } - - @Override - public void pdpChanged(OnapPDP pdp) { - // - // If one of the group's PDP's changed, then the group changed - // - this.changed(); - } - - - public StdPDPGroup() { - // - // Methods needed for JSON deserialization - // - } - - public StdPDPGroup(OnapPDPGroup group) { - this.id = group.getId(); - this.name = group.getName(); - this.description = group.getDescription(); - this.isDefault = group.isDefaultGroup(); - this.pdps = group.getOnapPdps(); - 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 setSelectedPolicies(Set selectedPolicies) { - this.selectedPolicies = selectedPolicies; - } - public void setOperation(String operation) { - this.operation = operation; - } - - 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) { - 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) { - 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); - } - - //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.onap.policy.xacml.std.pip.engines.aaf.AAFEngine"); - props.setProperty(XACMLProperties.PROP_PIP_ENGINES, "AAF"); - // read from PIP properties file. - Path file = Paths.get(StdEngine.pipPropertyFile); - if (!Files.notExists(file)) { - InputStream in; - Properties prop = new Properties(); - try { - in = new FileInputStream(file.toFile()); - prop.load(in); - } catch (IOException e) { - PolicyLogger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "can not load the pip properties from file" +e); - } - props = prop; - } - return props; - } + public void setStatus(PDPGroupStatus status) { + this.status = new StdPDPGroupStatus(status); + } + + public void setPolicies(Set policies) { + this.policies = policies; + } + + public void setSelectedPolicies(Set selectedPolicies) { + this.selectedPolicies = selectedPolicies; + } + + public void setOperation(String operation) { + this.operation = operation; + } + + /** + * saveGroupConfiguration. + * + * @throws PAPException PAPException + * @throws IOException IOException + */ + 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() + STR_APPEND_NAME, policy.getName()); + } + + // + // Now we can save the file + // + Path file = Paths.get(this.directory.toString(), PROPS_POLICY); + try (OutputStream os = Files.newOutputStream(file)) { + policyProperties.store(os, ""); + } catch (Exception 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(), PROPS_PIP); + try (OutputStream os = Files.newOutputStream(file)) { + pipProperties.store(os, ""); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, "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); + } + + // 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.onap.policy.xacml.std.pip.engines.aaf.AAFEngine"); + props.setProperty(XACMLProperties.PROP_PIP_ENGINES, "AAF"); + // read from PIP properties file. + Path file = Paths.get(StdEngine.PIP_PROPERTY_FILE); + if (file.toFile().exists()) { + InputStream in; + Properties prop = new Properties(); + try { + in = new FileInputStream(file.toFile()); + prop.load(in); + } catch (IOException e) { + PolicyLogger.error( + XACMLErrorConstants.ERROR_SYSTEM_ERROR + "can not load the pip properties from file" + e); + } + props = prop; + } + return props; + } }