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%2FStdEngine.java;h=1fb25183b5778c8b609ec82b5d4d8e96bb87b125;hp=273383ae69dfd6a0f6a11e71160669ba32eac711;hb=9bad71c7150ea6f94b2a08b68f356b4ee96c3d66;hpb=ad57603e2d13c432d680ac924f4ae33a256fedd3 diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdEngine.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdEngine.java index 273383ae6..1fb25183b 100644 --- a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdEngine.java +++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdEngine.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP-XACML * ================================================================================ - * Copyright (C) 2017-2018 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,20 @@ * 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.PDPGroup; +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.att.research.xacml.util.XACMLProperties; +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; +import com.google.common.collect.Sets; + import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; @@ -47,338 +59,343 @@ import org.onap.policy.xacml.api.pap.OnapPDP; import org.onap.policy.xacml.api.pap.OnapPDPGroup; import org.onap.policy.xacml.api.pap.PAPPolicyEngine; -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.PDPPIPConfig; -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. - * + * 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 { - public static final String pipPropertyFile = "pip.properties"; - - private static final String addGroup = "addGroup "; + public static final String PIP_PROPERTY_FILE = "pip.properties"; + + private static final String STR_ADDGROUP = "addGroup "; + private static final String STR_CLASS = "StdEngine"; + 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 Log logger = LogFactory.getLog(StdEngine.class); + private static Log logger = LogFactory.getLog(StdEngine.class); - public static final String PROP_PAP_REPO = "xacml.pap.pdps"; - public static final String PROP_PAP_GROUPS = "xacml.pap.groups"; - public static final String PROP_PAP_GROUPS_DEFAULT = "xacml.pap.groups.default"; - public static final 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; + public static final String PROP_PAP_REPO = "xacml.pap.pdps"; + public static final String PROP_PAP_GROUPS = "xacml.pap.groups"; + public static final String PROP_PAP_GROUPS_DEFAULT = "xacml.pap.groups.default"; + public static final 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)) { - throw new PAPException ("Repository is NOT a directory: " + this.repository.toAbsolutePath()); - } - if (!Files.isWritable(this.repository)) { - 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) { - 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) { - wasDefaultGroupJustAdded = true; - 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("".equals(defaultId)){ - 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("".equals(defaultId)){ - 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) { - 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) { - 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) { - 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) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "StdEngine", "Failed to create default group"); - throw new PAPException("Failed to create default group"); - } - } - - @Override - public OnapPDPGroup getDefaultGroup() throws PAPException{ - for (OnapPDPGroup group : this.groups) { - if (group.isDefaultGroup()) { - return group; - } - } - // - // Default group doesn't exist - // - return null; - } - - @Override - public OnapPDPGroup getGroup(String id) throws PAPException { - for (OnapPDPGroup 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"); - } else { - try { - // - // Create the directory - // - Files.createDirectory(groupPath); - } catch (IOException e) { - 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"); - } 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) { - 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"); - Properties props = new Properties(); - if (Files.exists(pipProperties)) { - logger.warn(addGroup + id + " file exists."); - } else { - try { - props = setPIPProperties(props); - Files.createFile(pipProperties); - try (OutputStream os = Files.newOutputStream(pipProperties)) { - props.store(os, ""); - } - } catch (IOException e) { - 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); - // Add the default PIP configuration. - String list = props.getProperty(XACMLProperties.PROP_PIP_ENGINES); + protected Set groups; + + /** + * StdEngine constructor. + * + * @throws PAPException PAPException + * @throws IOException IOException + */ + 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(); + } + + /** + * StdEngine constructor. + * + * @param properties Properties + * @throws PAPException PAPException + * @throws IOException IOException + */ + 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(); + } + + /** + * StdEngine constructor. + * + * @param repository Path + * @throws PAPException PAPException + * @throws IOException IOException + */ + 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 (! this.repository.toFile().exists()) { + Files.createDirectory(repository); + } + if (! this.repository.toFile().isDirectory()) { + throw new PAPException("Repository is NOT a directory: " + this.repository.toAbsolutePath()); + } + if (! this.repository.toFile().canWrite()) { + 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) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, "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) { + wasDefaultGroupJustAdded = true; + 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 ("".equals(defaultId)) { + defaultId = PROP_PAP_GROUPS_DEFAULT_NAME; + } + logger.warn("Default group does NOT exist, creating " + defaultId); + Path defaultPath = Paths.get(this.repository.toString(), defaultId); + try { + // + // Does it exist? + // + if (! defaultPath.toFile().exists()) { + // + // 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) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, + "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) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, + "Failed to write default pip properties"); + } + } + } + // + // Create the default group + // + StdPDPGroup newDefault = new StdPDPGroup(defaultId, true, PROP_PAP_GROUPS_DEFAULT_NAME, + "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) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, STR_CLASS, + "Failed to save properties with new default group information."); + } + // + // Return it + // + wasDefaultGroupJustAdded = true; + return newDefault; + } catch (IOException e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, STR_CLASS, "Failed to create default group"); + throw new PAPException("Failed to create default group"); + } + } + + @Override + public OnapPDPGroup getDefaultGroup() throws PAPException { + for (OnapPDPGroup group : this.groups) { + if (group.isDefaultGroup()) { + return group; + } + } + // + // Default group doesn't exist + // + return null; + } + + @Override + public OnapPDPGroup getGroup(String id) throws PAPException { + for (OnapPDPGroup g : this.groups) { + if (g.getId().equals(id)) { + return g; + } + } + return null; + } + + @Override + public void newGroup(String name, String description) throws PAPException { + // + // 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(STR_ADDGROUP + id + " directory exists"); + } else { + try { + // + // Create the directory + // + Files.createDirectory(groupPath); + } catch (IOException e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, "Failed to create " + groupPath); + throw new PAPException("Failed to create " + id); + } + } + // + // Create the Policies + // + + Path policyProperties = Paths.get(groupPath.toString(), "xacml.policy.properties"); + if (policyProperties.toFile().exists()) { + logger.warn(STR_ADDGROUP + id + " file exists"); + } 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) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, STR_CLASS, "Failed to create policyProperties"); + throw new PAPException("Failed to create " + id); + } + } + // + // Create the PIP config + // + Path pipProperties = Paths.get(groupPath.toString(), "xacml.pip.properties"); + Properties props = new Properties(); + if (pipProperties.toFile().exists()) { + logger.warn(STR_ADDGROUP + id + " file exists."); + } else { + try { + props = setPipProperties(props); + Files.createFile(pipProperties); + try (OutputStream os = Files.newOutputStream(pipProperties)) { + props.store(os, ""); + } + } catch (IOException e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, "Failed to create pipProperties"); + throw new PAPException("Failed to create " + id); + } + + } + // + // Ok now add it + // + StdPDPGroup newGroup = new StdPDPGroup(id, name, description, groupPath); + // Add the default PIP configuration. + String list = props.getProperty(XACMLProperties.PROP_PIP_ENGINES); if (list != null && list.length() > 0) { Set pipConfigs = new HashSet<>(); for (String pipID : list.split("[,]")) { @@ -389,652 +406,657 @@ public class StdEngine extends StdPDPItemSetChangeNotifier implements PAPPolicyE } newGroup.setPipConfigs(pipConfigs); } - 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 OnapPDP getPDP(String pdpId) throws PAPException { - for (OnapPDPGroup group : this.groups) { - for (OnapPDP pdp : group.getOnapPdps()) { - if (pdp.getId().equals(pdpId)) { - return pdp; - } - } - } - return null; - } - - - @Override - public void movePDP(OnapPDP pdp, OnapPDPGroup 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 { - PolicyLogger.error("Failed to add to new group, putting back into original group."); - if (!((StdPDPGroup) currentGroup).removePDP(pdp)) { - 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(OnapPDP 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 OnapPDP) { - ((OnapPDP)currentPDP).setJmxPort(pdp.getJmxPort()); - } - this.doSave(); - } - - @Override - public void removePDP(OnapPDP 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(OnapPDP pdp) throws PAPException { - return getPDP(pdp.getId()).getStatus(); - } - - @Override - public void publishPolicy(String id, String name, boolean isRoot, InputStream policy, OnapPDPGroup 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()); - } - - - @Override - public void copyPolicy(PDPPolicy policy, OnapPDPGroup group) - throws PAPException { - // - // Currently not used on the PAP side. This is done by ((StdPDPGroup) group).copyPolicyToFile - // - } - - - @Override - public void removePolicy(PDPPolicy policy, OnapPDPGroup 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 pdpGroups = 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 - // - pdpGroups.add(g); - } - // - // Dump what we got - // - if (logger.isDebugEnabled()) { - logger.debug("PDP Group List: " + pdpGroups.toString()); - } - return pdpGroups; - } - - 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 OnapPDP) { - properties.setProperty(pdp.getId() + ".jmxport", (((OnapPDP)pdp).getJmxPort()==0 ? "" : ((OnapPDP)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) { - 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); - } else { + 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 String + * @return String + */ + 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 OnapPDP getPDP(String pdpId) throws PAPException { + for (OnapPDPGroup group : this.groups) { + for (OnapPDP pdp : group.getOnapPdps()) { + if (pdp.getId().equals(pdpId)) { + return pdp; + } + } + } + return null; + } + + @Override + public void movePDP(OnapPDP pdp, OnapPDPGroup 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 { + PolicyLogger.error("Failed to add to new group, putting back into original group."); + if (!((StdPDPGroup) currentGroup).removePDP(pdp)) { + 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(OnapPDP 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 OnapPDP) { + ((OnapPDP) currentPdp).setJmxPort(pdp.getJmxPort()); + } + this.doSave(); + } + + @Override + public void removePDP(OnapPDP 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(OnapPDP pdp) throws PAPException { + return getPDP(pdp.getId()).getStatus(); + } + + @Override + public void publishPolicy(String id, String name, boolean isRoot, InputStream policy, OnapPDPGroup 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()); + } + + @Override + public void copyPolicy(PDPPolicy policy, OnapPDPGroup group) throws PAPException { + // + // Currently not used on the PAP side. This is done by ((StdPDPGroup) group).copyPolicyToFile + // + } + + @Override + public void removePolicy(PDPPolicy policy, OnapPDPGroup 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 pdpGroups = 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 newGroup = 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 + // + pdpGroups.add(newGroup); + } + // + // Dump what we got + // + if (logger.isDebugEnabled()) { + logger.debug("PDP Group List: " + pdpGroups.toString()); + } + return pdpGroups; + } + + 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() + STR_APPEND_NAME, group.getName() == null ? "" : group.getName()); + properties.setProperty(group.getId() + STR_APPEND_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() + STR_APPEND_NAME, pdp.getName() == null ? "" : pdp.getName()); + properties.setProperty(pdp.getId() + STR_APPEND_DESCRIPTION, + pdp.getDescription() == null ? "" : pdp.getDescription()); + if (pdp instanceof OnapPDP) { + properties.setProperty(pdp.getId() + ".jmxport", + (((OnapPDP) pdp).getJmxPort() == 0 ? "" : ((OnapPDP) 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() + STR_APPEND_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, ""); + } + } + + /** + * setGroupProperties. + * + * @param group PDPGroup + * @param properties Properties + */ + 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) { + 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); + } else { newGroupList = ""; } - 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().isEmpty()) { - 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(OnapPDPGroup group) { - if (logger.isDebugEnabled()) { - logger.debug("groupChanged: " + group); - } - this.doSave(); - this.firePDPGroupChanged(group); - } - - - public void pdpChanged(OnapPDP pdp) { - if (logger.isDebugEnabled()) { - logger.debug("pdpChanged: " + pdp); - } - this.doSave(); - this.firePDPChanged(pdp); - } - - private void doSave() { - try { - // - // Save the configuration - // - this.saveConfiguration(); - } catch (IOException|PAPException e) { - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "StdEngine", "Failed to save configuration"); - } - } - - 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.onap.policy.xacml.std.pip.engines.aaf.AAFEngine"); - // read from PIP properties file. - Path file = Paths.get(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); - } + logger.info("New Group List: " + newGroupList); + properties.setProperty(PROP_PAP_GROUPS, newGroupList); + } + // + // Set its properties + // + properties.setProperty(group.getId() + STR_APPEND_NAME, group.getName()); + properties.setProperty(group.getId() + STR_APPEND_DESCRIPTION, group.getDescription()); + // + // Set its PDP list + // + if (!group.getPdps().isEmpty()) { + 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() + STR_APPEND_PDPS, pdpList); + } else { + properties.setProperty(group.getId() + STR_APPEND_PDPS, ""); + } + } + + /** + * changed. + */ + public void changed() { + if (logger.isDebugEnabled()) { + logger.debug("changed"); + } + this.doSave(); + this.fireChanged(); + } + + /** + * groupChanged. + * + * @param group OnapPDPGroup + */ + public void groupChanged(OnapPDPGroup group) { + if (logger.isDebugEnabled()) { + logger.debug("groupChanged: " + group); + } + this.doSave(); + this.firePDPGroupChanged(group); + } + + /** + * pdpChanged. + * + * @param pdp OnapPDP + */ + public void pdpChanged(OnapPDP pdp) { + if (logger.isDebugEnabled()) { + logger.debug("pdpChanged: " + pdp); + } + this.doSave(); + this.firePDPChanged(pdp); + } + + private void doSave() { + try { + // + // Save the configuration + // + this.saveConfiguration(); + } catch (IOException | PAPException e) { + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, STR_CLASS, "Failed to save configuration"); + } + } + + 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.onap.policy.xacml.std.pip.engines.aaf.AAFEngine"); + // read from PIP properties file. + Path file = Paths.get(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; - } - - - @Override - public Set getOnapPDPGroups() throws PAPException { - final Set grps = new HashSet<>(); - for (OnapPDPGroup g : this.groups) { - grps.add(g); - } - return Collections.unmodifiableSet(grps); - } - - @Override - public OnapPDPGroup getPDPGroup(OnapPDP pdp) throws PAPException { - for (OnapPDPGroup group : this.groups) { - if (group.getPdps().contains(pdp)) { - return group; - } - } - return null; - } - - @Override - public void setDefaultGroup(OnapPDPGroup group) throws PAPException { - boolean changesMade = false; - for (OnapPDPGroup aGroup : groups) { - if (aGroup.getId().equals(group.getId())) { - if ( ! aGroup.isDefaultGroup()) { - 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()) { - 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, OnapPDPGroup 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)) { - throw new PAPException("Unknown group, not in our list."); - } - for (OnapPDP p : group.getOnapPdps()) { - 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(OnapPDPGroup 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(), e); - } - // 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 (OnapPDPGroup 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) { - 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(),e); - } - // update the disk - try { - ((StdPDPGroup)group).saveGroupConfiguration(); - } catch (IOException e) { - throw new PAPException("Unable to save new configuration for '" + group.getName() + "': " + e.getMessage(), e); - } - - // 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(OnapPDPGroup group, OnapPDPGroup newGroup) throws PAPException, NullPointerException { - if (group == null) { - throw new NullPointerException(); - } - // - // Does this group exist? - // - if (!this.groups.contains(group)) { - 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.getOnapPdps(); - // - // Are there PDPs? If so, then we need a target group - // - if (!pdps.isEmpty() && 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()) { - 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 (OnapPDP pdp : pdps) { - pdpList.add(pdp); - } - // now we can use the PDPs from the list without having ConcurrentAccessExceptions - for (OnapPDP 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) { - 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; - - } + } + return props; + } + + @Override + public Set getOnapPDPGroups() throws PAPException { + final Set grps = new HashSet<>(); + for (OnapPDPGroup g : this.groups) { + grps.add(g); + } + return Collections.unmodifiableSet(grps); + } + + @Override + public OnapPDPGroup getPDPGroup(OnapPDP pdp) throws PAPException { + for (OnapPDPGroup group : this.groups) { + if (group.getPdps().contains(pdp)) { + return group; + } + } + return null; + } + + @Override + public void setDefaultGroup(OnapPDPGroup group) throws PAPException { + boolean changesMade = false; + for (OnapPDPGroup theGroup : groups) { + if (theGroup.getId().equals(group.getId())) { + if (!theGroup.isDefaultGroup()) { + if (theGroup instanceof StdPDPGroup) { + ((StdPDPGroup) theGroup).setDefault(true); + changesMade = true; + } else { + throw new IllegalArgumentException( + "Group in groups of unknown type '" + theGroup.getClass().getName() + "'"); + } + } + } else { + // not the new default group + if (theGroup.isDefaultGroup()) { + if (theGroup instanceof StdPDPGroup) { + ((StdPDPGroup) theGroup).setDefault(false); + changesMade = true; + } else { + throw new IllegalArgumentException( + "Group in groups of unknown type '" + theGroup.getClass().getName() + "'"); + } + } + } + } + if (changesMade) { + this.doSave(); + } + } + + @Override + public void newPDP(String id, OnapPDPGroup group, String name, String description, int jmxport) + throws PAPException { + if (group == null) { + throw new PAPException("You must specify which group the PDP will belong to."); + } + if (!this.groups.contains(group)) { + throw new PAPException("Unknown group, not in our list."); + } + for (OnapPDP p : group.getOnapPdps()) { + 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); + } + } + } + + @Override + public void updateGroup(OnapPDPGroup group, String userName) throws PAPException { + // To pass the userId for PDP Audit log maintenance. + + } + + @Override + public void updateGroup(OnapPDPGroup 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(), e); + } + // 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 (OnapPDPGroup 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) { + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, STR_CLASS, "Unable to rename directory"); + throw new PAPException( + "Unable to move directory from '" + oldPath + "' to '" + newPath + "': " + e.getMessage(), e); + } + // update the disk + try { + ((StdPDPGroup) group).saveGroupConfiguration(); + } catch (IOException e) { + throw new PAPException( + "Unable to save new configuration for '" + group.getName() + "': " + e.getMessage(), e); + } + + // 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(OnapPDPGroup group, OnapPDPGroup newGroup) throws PAPException { + if (group == null) { + throw new NullPointerException(); + } + // + // Does this group exist? + // + if (!this.groups.contains(group)) { + 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.getOnapPdps(); + // + // Are there PDPs? If so, then we need a target group + // + if (!pdps.isEmpty() && 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()) { + 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 (OnapPDP pdp : pdps) { + pdpList.add(pdp); + } + // now we can use the PDPs from the list without having ConcurrentAccessExceptions + for (OnapPDP 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 (! groupPath.toFile().exists()) { + 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) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, STR_CLASS, "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(); + } }