From 80f072f60509ef3a35369a60857fe05f6c2a993a Mon Sep 17 00:00:00 2001 From: "Tej, Tarun" Date: Mon, 21 Aug 2017 20:00:50 -0400 Subject: Fixes for sonar critical issues Fixes for critical and blocker issues reported in sonar. Issue-Id: POLICY-113 Change-Id: I50969fe93a94b0497f3fb30864a6c45e63208fe6 Signed-off-by: Tej, Tarun --- .../org/onap/policy/pdp/rest/PapUrlResolver.java | 707 +++++++++++---------- .../org/onap/policy/pdp/rest/XACMLPdpServlet.java | 141 ++-- .../policy/pdp/rest/api/services/PAPServices.java | 184 +++--- .../policy/pdp/rest/api/services/PDPServices.java | 19 +- .../api/services/PolicyEngineImportService.java | 2 +- .../ManualNotificationUpdateThread.java | 383 +++++------ .../rest/notifications/NotificationController.java | 673 ++++++++++---------- .../pdp/rest/notifications/NotificationServer.java | 31 +- .../rest/api/test/PolicyEngineServicesTest.java | 3 + .../resources/notification.xacml.pdp.properties | 171 +++++ 10 files changed, 1287 insertions(+), 1027 deletions(-) create mode 100644 ONAP-PDP-REST/src/test/resources/notification.xacml.pdp.properties (limited to 'ONAP-PDP-REST') diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/PapUrlResolver.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/PapUrlResolver.java index cee07fd9f..7ac322ec9 100644 --- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/PapUrlResolver.java +++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/PapUrlResolver.java @@ -26,6 +26,7 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.NoSuchElementException; +import java.util.Objects; import java.util.Properties; import org.onap.policy.common.logging.flexlogger.FlexLogger; @@ -35,343 +36,371 @@ import org.onap.policy.rest.XACMLRestProperties; import com.att.research.xacml.util.XACMLProperties; public class PapUrlResolver { - private static final Logger LOGGER = FlexLogger.getLogger(PapUrlResolver.class); - //how long to keep a pap failed before making it un-failed, in milli-seconds - private static final long FAIL_TIMEOUT = 18000000; - - //thread locks - public static final Object propertyLock = new Object(); - - //keeping this here for backward compatibility - public static String extractIdFromUrl(String url){ - return extractQuery(url); - } - public static String extractQuery(String url){ - try{ - return URI.create(url).getQuery(); - } catch(Exception e){ - LOGGER.error("Exception occured while extracting query. So, empty string is returned"+e); - return ""; - } - } - public static String modifyUrl(String idUrl, String serverUrl){ - URI one = URI.create(idUrl); - String host = one.getPath()+one.getQuery(); - URI two = URI.create(serverUrl); - two.resolve(host); - return two.toString(); - } - - //get an instance of a new PapUrlResolver, using XACMLProperties to get the url lists - public static PapUrlResolver getInstance(){ - return new PapUrlResolver(null,null,null,true); - } - - //get an instance of a new PapUrlResolver, using the provides strings for the url lists - public static PapUrlResolver getInstance(String urlList, String failedList, String succeededList){ - return new PapUrlResolver(urlList, failedList, succeededList,false); - } - - //keeps track of our current location in the list of urls, allows for iterating - private int pointer; - - //should the XACML property lists be updated after anything changes or should we wait for the update - //method to be called. - private boolean autoUpdateProperties; - - //this list keeps the sorted, priority of PAP URLs - private PapUrlNode[] sortedUrlNodes; - //this list keeps the original list of nodes so that they can be entered into the property list correctly - private PapUrlNode[] originalUrlNodes; - - //private constructor to make an instance of a PapUrlResolver, called by static method getInstance. - //If the list property strings are not defined, we get the values from XACMLProperties. - //The instance acts as an iterator, with hasNext and next methods, but does not implement Iterable, - //because it is used for a difference purpose. - private PapUrlResolver(String urlList, String failedList, String succeededList, boolean autoUpdateProperties){ - this.autoUpdateProperties = autoUpdateProperties; - String papUrlLists = urlList; - String papUrlFailedList = failedList; - String papUrlSuccessList = succeededList; - if(papUrlLists == null){ - papUrlLists = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URLS); - if(papUrlLists == null){ - papUrlLists = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL); - } - papUrlFailedList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS); - papUrlSuccessList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS); - } - - String[] urls = papUrlLists.split(","); - if(urls.length == 0){ - //log error - } - String[] failed = emptyOrSplit(papUrlFailedList,urls.length); - String[] succeeded = emptyOrSplit(papUrlSuccessList,urls.length); - - sortedUrlNodes = new PapUrlNode[urls.length]; - for(int i=0;i { - private String papUrl; - private Date failedTime; - private Date succeededTime; - private String userId; - private String pass; - - public PapUrlNode(String url,String userId,String pass){ - this.papUrl = url; - failedTime = null; - this.succeededTime = null; - this.userId = userId; - this.pass = pass; - - } - public String getUserId(){ - return this.userId; - } - public String getPass(){ - return this.pass; - } - - public void setFailedTime(Object time){ - Date failedTimeAsDate = setHandler(time); - if(failedTimeAsDate == null){ - this.failedTime = null; - } else { - long timeDifference = new Date().getTime() - failedTimeAsDate.getTime(); - if(timeDifference < FAIL_TIMEOUT){ - this.failedTime = failedTimeAsDate; - } else { - this.failedTime = null; - } - } - } - - //set the time that this url succeeded at - public void setSucceededTime(Object time){ - this.succeededTime = setHandler(time); - } - - //parses string into a date or a null date, if the url never failed/succeeded (since -1 will be in the property) - private Date setHandler(Object time){ - if(time instanceof String){ - if("-1".equals((String)time)){ - return null; - } - try { - DateFormat df = new SimpleDateFormat(); - return df.parse((String)time); - } catch (ParseException e) { - return null; - } - } - if(time instanceof Date){ - return (Date)time; - } - return null; - } - - - public String getFailedTime(){ - return formatTime(this.failedTime); - } - - public String getSucceededTime(){ - return formatTime(this.succeededTime); - } - - //formats a Date into a string or a -1 if there is not date (-1 is used in properties for no date) - private String formatTime(Date d){ - if(d == null){ - return "-1"; - } - DateFormat df = new SimpleDateFormat(); - return df.format(d); - } - - public String getUrl(){ - return papUrl; - } - - @Override - public int compareTo(PapUrlNode other){ - if(this.failedTime == null && other.failedTime != null){ - return -1; - } - if(this.failedTime != null && other.failedTime == null){ - return 1; - } - if(this.failedTime != null){ - return this.failedTime.compareTo(other.failedTime); - } - return 0; - } - } + private static final Logger LOGGER = FlexLogger.getLogger(PapUrlResolver.class); + // how long to keep a pap failed before making it un-failed, in milli-seconds + private static final long FAIL_TIMEOUT = 18000000; + + // thread locks + public static final Object propertyLock = new Object(); + + // keeping this here for backward compatibility + public static String extractIdFromUrl(String url) { + return extractQuery(url); + } + + public static String extractQuery(String url) { + try { + return URI.create(url).getQuery(); + } catch (Exception e) { + LOGGER.error("Exception occured while extracting query. So, empty string is returned" + e); + return ""; + } + } + + public static String modifyUrl(String idUrl, String serverUrl) { + URI one = URI.create(idUrl); + String host = one.getPath() + one.getQuery(); + URI two = URI.create(serverUrl); + two.resolve(host); + return two.toString(); + } + + // get an instance of a new PapUrlResolver, using XACMLProperties to get the url lists + public static PapUrlResolver getInstance() { + return new PapUrlResolver(null, null, null, true); + } + + // get an instance of a new PapUrlResolver, using the provides strings for the url lists + public static PapUrlResolver getInstance(String urlList, String failedList, String succeededList) { + return new PapUrlResolver(urlList, failedList, succeededList, false); + } + + // keeps track of our current location in the list of urls, allows for iterating + private int pointer; + + // should the XACML property lists be updated after anything changes or should we wait for the update + // method to be called. + private boolean autoUpdateProperties; + + // this list keeps the sorted, priority of PAP URLs + private PapUrlNode[] sortedUrlNodes; + // this list keeps the original list of nodes so that they can be entered into the property list correctly + private PapUrlNode[] originalUrlNodes; + + // private constructor to make an instance of a PapUrlResolver, called by static method getInstance. + // If the list property strings are not defined, we get the values from XACMLProperties. + // The instance acts as an iterator, with hasNext and next methods, but does not implement Iterable, + // because it is used for a difference purpose. + private PapUrlResolver(String urlList, String failedList, String succeededList, boolean autoUpdateProperties) { + this.autoUpdateProperties = autoUpdateProperties; + String papUrlLists = urlList; + String papUrlFailedList = failedList; + String papUrlSuccessList = succeededList; + if (papUrlLists == null) { + papUrlLists = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URLS); + if (papUrlLists == null) { + papUrlLists = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL); + } + papUrlFailedList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS); + papUrlSuccessList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS); + } + + String[] urls = papUrlLists.split(","); + if (urls.length == 0) { + // log error + } + String[] failed = emptyOrSplit(papUrlFailedList, urls.length); + String[] succeeded = emptyOrSplit(papUrlSuccessList, urls.length); + + sortedUrlNodes = new PapUrlNode[urls.length]; + for (int i = 0; i < urls.length; i++) { + + String userId = null; + String pass = null; + userId = XACMLProperties.getProperty(urls[i] + "." + XACMLRestProperties.PROP_PAP_USERID); + pass = XACMLProperties.getProperty(urls[i] + "." + XACMLRestProperties.PROP_PAP_PASS); + if (userId == null || pass == null) { + userId = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID); + pass = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS); + } + if (userId == null || pass == null) { + userId = ""; + pass = ""; + } + PapUrlNode newNode = new PapUrlNode(urls[i], userId, pass); + newNode.setFailedTime(failed[i]); + newNode.setSucceededTime(succeeded[i]); + if (sortedUrlNodes[i] == null) { + sortedUrlNodes[i] = newNode; + } + } + originalUrlNodes = sortedUrlNodes.clone(); + sort(sortedUrlNodes); + pointer = 0; + } + + // either split a list by commas, or fill an array to the expected length, if the property list is not long enough + private String[] emptyOrSplit(String list, int expectedLength) { + String[] ret; + if (list == null) { + ret = new String[expectedLength]; + for (int i = 0; i < expectedLength; i++) { + ret[i] = "-1"; + } + } else { + ret = list.split(","); + if (ret.length != expectedLength) { + ret = emptyOrSplit(null, expectedLength); + } + } + return ret; + } + + private void sort(PapUrlNode[] array) { + + // O(n^2) double-loop most likely the best in this case, since number of records will be VERY small + for (int i = 0; i < array.length; i++) { + for (int j = i; j < array.length; j++) { + if (array[j].compareTo(array[i]) < 0) { + PapUrlNode temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + } + } + } + + // returns whether this PapUrlResolver object has more PAP urls that can be tried + public boolean hasMoreUrls() { + return pointer < sortedUrlNodes.length; + } + + // sets the current PAP url as being failed + // this will set the failed time to now and remove any succeeded time + public void failed() { + LOGGER.error("PAP Server FAILED: " + sortedUrlNodes[pointer].getUrl()); + + sortedUrlNodes[pointer].setFailedTime(new Date()); + sortedUrlNodes[pointer].setSucceededTime(null); + propertiesUpdated(); + } + + // sets the current PAP url as being working + // this will set the succeeded time to now and remove any failed time + // Also, this will cause hasMoreUrls to return false, since a working one has been found + + public void succeeded() { + registered(); + pointer = sortedUrlNodes.length; + } + + public void registered() { + sortedUrlNodes[pointer].setFailedTime(null); + sortedUrlNodes[pointer].setSucceededTime(new Date()); + LOGGER.info("PAP server SUCCEEDED " + sortedUrlNodes[pointer].getUrl()); + propertiesUpdated(); + } + + // returns a properties object with the properties that pertain to PAP urls + public Properties getProperties() { + String failedPropertyString = ""; + String succeededPropertyString = ""; + String urlPropertyString = ""; + for (int i = 0; i < originalUrlNodes.length; i++) { + failedPropertyString = failedPropertyString.concat(",").concat(originalUrlNodes[i].getFailedTime()); + succeededPropertyString = succeededPropertyString.concat(",") + .concat(originalUrlNodes[i].getSucceededTime()); + urlPropertyString = urlPropertyString.concat(",").concat(originalUrlNodes[i].getUrl()); + } + Properties prop = new Properties(); + failedPropertyString = failedPropertyString.substring(1); + succeededPropertyString = succeededPropertyString.substring(1); + urlPropertyString = urlPropertyString.substring(1); + prop.setProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS, failedPropertyString); + prop.setProperty(XACMLRestProperties.PROP_PAP_URLS, urlPropertyString); + prop.setProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS, succeededPropertyString); + return prop; + } + + // saves the updates urls to the correct properties + private void propertiesUpdated() { + if (!autoUpdateProperties) { + return; + } + Properties prop = getProperties(); + + LOGGER.debug("Failed PAP Url List: " + prop.getProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS)); + LOGGER.debug("Succeeded PAP Url List: " + prop.getProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS)); + XACMLProperties.setProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS, + prop.getProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS)); + XACMLProperties.setProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS, + prop.getProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS)); + } + + // iterates to the next available PAP url, according to the priority order + public void getNext() { + pointer++; + } + + // returns the url of the current PAP server that we are iterating over + // will append the provided policy id to the url + public String getUrl(String query) { + if (sortedUrlNodes[pointer] == null) { + throw new NoSuchElementException(); + } else { + return sortedUrlNodes[pointer].getUrl().concat("?").concat(query); + } + } + + // returns the url of the current PAP server that we are iterating over + // Just returns the url, with no id appended to it + public String getUrl() { + if (sortedUrlNodes[pointer] == null) { + throw new NoSuchElementException(); + } else { + + return sortedUrlNodes[pointer].getUrl(); + } + } + + public String getUserId() { + if (sortedUrlNodes[pointer] == null) { + throw new NoSuchElementException(); + } else { + + return sortedUrlNodes[pointer].getUserId(); + } + } + + public String getPass() { + if (sortedUrlNodes[pointer] == null) { + throw new NoSuchElementException(); + } else { + + return sortedUrlNodes[pointer].getPass(); + } + } + + // This is the class to hold the details of a single PAP URL + // including: the url itself, the last time it failed, and the last time it succeeded + // It also includes the custom comparer which can compare based on failed and succeeded times, and takes into + // account + // the timeout on failures. + private class PapUrlNode implements Comparable { + private String papUrl; + private Date failedTime; + private Date succeededTime; + private String userId; + private String pass; + + public PapUrlNode(String url, String userId, String pass) { + this.papUrl = url; + failedTime = null; + this.succeededTime = null; + this.userId = userId; + this.pass = pass; + + } + + public String getUserId() { + return this.userId; + } + + public String getPass() { + return this.pass; + } + + public void setFailedTime(Object time) { + Date failedTimeAsDate = setHandler(time); + if (failedTimeAsDate == null) { + this.failedTime = null; + } else { + long timeDifference = new Date().getTime() - failedTimeAsDate.getTime(); + if (timeDifference < FAIL_TIMEOUT) { + this.failedTime = failedTimeAsDate; + } else { + this.failedTime = null; + } + } + } + + // set the time that this url succeeded at + public void setSucceededTime(Object time) { + this.succeededTime = setHandler(time); + } + + // parses string into a date or a null date, if the url never failed/succeeded (since -1 will be in the + // property) + private Date setHandler(Object time) { + if (time instanceof String) { + if ("-1".equals((String) time)) { + return null; + } + try { + DateFormat df = new SimpleDateFormat(); + return df.parse((String) time); + } catch (ParseException e) { + return null; + } + } + if (time instanceof Date) { + return (Date) time; + } + return null; + } + + public String getFailedTime() { + return formatTime(this.failedTime); + } + + public String getSucceededTime() { + return formatTime(this.succeededTime); + } + + // formats a Date into a string or a -1 if there is not date (-1 is used in properties for no date) + private String formatTime(Date d) { + if (d == null) { + return "-1"; + } + DateFormat df = new SimpleDateFormat(); + return df.format(d); + } + + public String getUrl() { + return papUrl; + } + + @Override + public int compareTo(PapUrlNode other) { + if (this.failedTime == null && other.failedTime != null) { + return -1; + } + if (this.failedTime != null && other.failedTime == null) { + return 1; + } + if (this.failedTime != null) { + return this.failedTime.compareTo(other.failedTime); + } + return 0; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof PapUrlNode)) { + return false; + } + PapUrlNode papUrlNode = (PapUrlNode) obj; + return Objects.equals(papUrlNode.papUrl, papUrl) && Objects.equals(papUrlNode.failedTime, failedTime) + && Objects.equals(papUrlNode.succeededTime, succeededTime) + && Objects.equals(papUrlNode.userId, userId) && Objects.equals(papUrlNode.pass, pass); + } + + @Override + public int hashCode() { + return Objects.hash(papUrl, failedTime, succeededTime, userId, pass); + } + } } diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/XACMLPdpServlet.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/XACMLPdpServlet.java index d57e88498..18c201737 100644 --- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/XACMLPdpServlet.java +++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/XACMLPdpServlet.java @@ -130,8 +130,8 @@ public class XACMLPdpServlet extends HttpServlet implements Runnable { // This thread may getting invoked on startup, to let the PAP know // that we are up and running. // - private Thread registerThread = null; - private XACMLPdpRegisterThread registerRunnable = null; + private static transient Thread registerThread = null; + private static transient XACMLPdpRegisterThread registerRunnable = null; // // This is our PDP engine pointer. There is a synchronized lock used // for access to the pointer. In case we are servicing PEP requests while @@ -176,10 +176,10 @@ public class XACMLPdpServlet extends HttpServlet implements Runnable { // This is our configuration thread that attempts to load // a new configuration request. // - private Thread configThread = null; - private volatile boolean configThreadTerminate = false; - private ONAPLoggingContext baseLoggingContext = null; - private IntegrityMonitor im; + private static transient Thread configThread = null; + private static volatile boolean configThreadTerminate = false; + private transient ONAPLoggingContext baseLoggingContext = null; + private transient IntegrityMonitor im; /** * Default constructor. */ @@ -198,16 +198,12 @@ public class XACMLPdpServlet extends HttpServlet implements Runnable { // Initialize // XACMLRest.xacmlInit(config); - // Load the Notification Delay. - try{ - XACMLPdpServlet.notificationDelay = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_DELAY)); - }catch(Exception e){ - logger.info("Notification Delay Not set. Keeping it 0 as default."+e); - } + // Load the Notification Delay. + setNotificationDelay(); // Load Queue size. int queueSize = 5; // Set default Queue Size here. queueSize = Integer.parseInt(XACMLProperties.getProperty("REQUEST_BUFFER_SIZE",String.valueOf(queueSize))); - queue = new LinkedBlockingQueue(queueSize); + initQueue(queueSize); // Load our engine - this will use the latest configuration // that was saved to disk and set our initial status object. // @@ -250,25 +246,14 @@ public class XACMLPdpServlet extends HttpServlet implements Runnable { } PolicyLogger.info("\n Properties Given : \n" + properties.toString()); } - pdpResourceName = properties.getProperty(XACMLRestProperties.PDP_RESOURCE_NAME); - if(pdpResourceName == null){ - PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, XACMLRestProperties.PDP_RESOURCE_NAME, "xacml.pdp"); - throw new ServletException("pdpResourceName is null"); - } - + setPDPResourceName(properties); dependencyGroups = properties.getProperty(IntegrityMonitorProperties.DEPENDENCY_GROUPS); if(dependencyGroups == null){ PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, IntegrityMonitorProperties.DEPENDENCY_GROUPS, "xacml.pdp"); throw new ServletException("dependency_groups is null"); } - // dependency_groups is a semicolon-delimited list of groups, and - // each group is a comma-separated list of nodes. For our purposes - // we just need a list of dependencies without regard to grouping, - // so split the list into nodes separated by either comma or semicolon. - dependencyNodes = dependencyGroups.split("[;,]"); - for (int i = 0 ; i < dependencyNodes.length ; i++){ - dependencyNodes[i] = dependencyNodes[i].trim(); - } + setDependencyNodes(dependencyGroups); + // CreateUpdatePolicy ResourceName createUpdateResourceName = properties.getProperty("createUpdatePolicy.impl.className", CREATE_UPDATE_POLICY_SERVICE); @@ -282,25 +267,59 @@ public class XACMLPdpServlet extends HttpServlet implements Runnable { PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to create IntegrityMonitor" +e); throw new ServletException(e); } - - environment = XACMLProperties.getProperty("ENVIRONMENT", "DEVL"); - // - // Kick off our thread to register with the PAP servlet. - // - if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER))) { - this.registerRunnable = new XACMLPdpRegisterThread(baseLoggingContext); - this.registerThread = new Thread(this.registerRunnable); - this.registerThread.start(); - } - // - // This is our thread that manages incoming configuration - // changes. - // - this.configThread = new Thread(this); - this.configThread.start(); + startThreads(baseLoggingContext, new Thread(this)); } - /** + private static void startThreads(ONAPLoggingContext baseLoggingContext, Thread thread) { + environment = XACMLProperties.getProperty("ENVIRONMENT", "DEVL"); + // + // Kick off our thread to register with the PAP servlet. + // + if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER))) { + XACMLPdpServlet.registerRunnable = new XACMLPdpRegisterThread(baseLoggingContext); + XACMLPdpServlet.registerThread = new Thread(XACMLPdpServlet.registerRunnable); + XACMLPdpServlet.registerThread.start(); + } + // + // This is our thread that manages incoming configuration + // changes. + // + XACMLPdpServlet.configThread = thread; + XACMLPdpServlet.configThread.start(); + } + + private static void setDependencyNodes(String dependencyGroups) { + // dependency_groups is a semicolon-delimited list of groups, and + // each group is a comma-separated list of nodes. For our purposes + // we just need a list of dependencies without regard to grouping, + // so split the list into nodes separated by either comma or semicolon. + dependencyNodes = dependencyGroups.split("[;,]"); + for (int i = 0 ; i < dependencyNodes.length ; i++){ + dependencyNodes[i] = dependencyNodes[i].trim(); + } + } + + private static void setPDPResourceName(Properties properties) throws ServletException { + pdpResourceName = properties.getProperty(XACMLRestProperties.PDP_RESOURCE_NAME); + if(pdpResourceName == null){ + PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, XACMLRestProperties.PDP_RESOURCE_NAME, "xacml.pdp"); + throw new ServletException("pdpResourceName is null"); + } + } + + private static void initQueue(int queueSize) { + queue = new LinkedBlockingQueue<>(queueSize); + } + + private static void setNotificationDelay() { + try{ + XACMLPdpServlet.notificationDelay = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_DELAY)); + }catch(NumberFormatException e){ + logger.error("Error in notification delay format, Taking the default value.", e); + } + } + + /** * @see Servlet#destroy() */ @Override @@ -310,33 +329,39 @@ public class XACMLPdpServlet extends HttpServlet implements Runnable { // // Make sure the register thread is not running // - if (this.registerRunnable != null) { + if (XACMLPdpServlet.registerRunnable != null) { try { - this.registerRunnable.terminate(); - if (this.registerThread != null) { - this.registerThread.interrupt(); - this.registerThread.join(); + XACMLPdpServlet.registerRunnable.terminate(); + if (XACMLPdpServlet.registerThread != null) { + XACMLPdpServlet.registerThread.interrupt(); + XACMLPdpServlet.registerThread.join(); } } catch (InterruptedException e) { logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e); PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, ""); + XACMLPdpServlet.registerThread.interrupt(); } } // // Make sure the configure thread is not running // - this.configThreadTerminate = true; + setConfigThreadTerminate(true); try { - this.configThread.interrupt(); - this.configThread.join(); + XACMLPdpServlet.configThread.interrupt(); + XACMLPdpServlet.configThread.join(); } catch (InterruptedException e) { logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e); PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, ""); + XACMLPdpServlet.configThread.interrupt(); } logger.info("Destroyed."); } - /** + private static void setConfigThreadTerminate(boolean value) { + XACMLPdpServlet.configThreadTerminate = value; + } + + /** * PUT - The PAP engine sends configuration information using HTTP PUT request. * * One parameter is expected: @@ -937,7 +962,13 @@ public class XACMLPdpServlet extends HttpServlet implements Runnable { // Read in the string // StringBuilder buffer = new StringBuilder(); - BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream())); + BufferedReader reader = null; + try{ + reader = new BufferedReader(new InputStreamReader(request.getInputStream())); + }catch(IOException e){ + logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error during reading input stream",e); + return; + } String line; try{ while((line = reader.readLine()) != null){ @@ -1198,7 +1229,7 @@ public class XACMLPdpServlet extends HttpServlet implements Runnable { // try { // variable not used, but constructor has needed side-effects so don't remove: - while (! this.configThreadTerminate) { + while (! XACMLPdpServlet.configThreadTerminate) { PutRequest request = XACMLPdpServlet.queue.take(); StdPDPStatus newStatus = new StdPDPStatus(); diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PAPServices.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PAPServices.java index e7216e152..f7c175c0c 100644 --- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PAPServices.java +++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PAPServices.java @@ -227,112 +227,96 @@ public class PAPServices { String [] parameters = {"apiflag=version","policyScope="+policyScope, "filePrefix="+filePrefix, "policyName="+policyName}; if (paps == null || paps.isEmpty()) { LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "PAPs List is Empty."); - try { - throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE +"PAPs List is empty."); - } catch (Exception e) { - LOGGER.error(e.getMessage() + e); - } - }else { - int papsCount = 0; - boolean connected = false; - while (papsCount < paps.size()) { - try { - String fullURL = getPAP(); - if (parameters != null && parameters.length > 0) { - String queryString = ""; - for (String p : parameters) { - queryString += "&" + p; - } - fullURL += "?" + queryString.substring(1); + }else { + int papsCount = 0; + boolean connected = false; + while (papsCount < paps.size()) { + try { + String fullURL = getPAP(); + if (parameters != null && parameters.length > 0) { + String queryString = ""; + for (String p : parameters) { + queryString += "&" + p; } - - URL url = new URL (fullURL); - - //Open the connection - connection = (HttpURLConnection)url.openConnection(); - - // Setting Content-Type - connection.setRequestProperty("Content-Type", - "application/json"); - - // Adding Authorization - connection.setRequestProperty("Authorization", "Basic " - + getPAPEncoding()); - - connection.setRequestProperty("Environment", environment); - connection.setRequestProperty("ClientScope", clientScope); + fullURL += "?" + queryString.substring(1); + } - - //set the method and headers - connection.setRequestMethod("GET"); - connection.setUseCaches(false); - connection.setInstanceFollowRedirects(false); - connection.setDoOutput(true); - connection.setDoInput(true); - connection.setRequestProperty("X-ECOMP-RequestID", requestID.toString()); - - //DO the connect - connection.connect(); - - // If Connected to PAP then break from the loop and continue with the Request - if (connection.getResponseCode() > 0) { - connected = true; - break; + URL url = new URL (fullURL); - } else { - LOGGER.debug(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP connection Error"); - } - } catch (Exception e) { - // This means that the PAP is not working - LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP connection Error : " + e); - rotatePAPList(); + //Open the connection + connection = (HttpURLConnection)url.openConnection(); + + // Setting Content-Type + connection.setRequestProperty("Content-Type", + "application/json"); + + // Adding Authorization + connection.setRequestProperty("Authorization", "Basic " + + getPAPEncoding()); + + connection.setRequestProperty("Environment", environment); + connection.setRequestProperty("ClientScope", clientScope); + + + //set the method and headers + connection.setRequestMethod("GET"); + connection.setUseCaches(false); + connection.setInstanceFollowRedirects(false); + connection.setDoOutput(true); + connection.setDoInput(true); + connection.setRequestProperty("X-ECOMP-RequestID", requestID.toString()); + + //DO the connect + connection.connect(); + + // If Connected to PAP then break from the loop and continue with the Request + if (connection.getResponseCode() > 0) { + connected = true; + break; + + } else { + LOGGER.debug(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP connection Error"); } - papsCount++; + } catch (Exception e) { + // This means that the PAP is not working + LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP connection Error : " + e); + rotatePAPList(); } - - if (connected) { - //Read the Response - LOGGER.debug("connected to the PAP : " + getPAP()); - LOGGER.debug("--- Response: ---"); - Map> headers = connection.getHeaderFields(); - for (String key : headers.keySet()) { - LOGGER.debug("Header :" + key + " Value: " + headers.get(key)); - } - try { - if (connection.getResponseCode() == 200) { - // Check for successful creation of policy - version = connection.getHeaderField("version"); - LOGGER.debug("ActiveVersion from the Header: " + version); - } else if (connection.getResponseCode() == 403) { - LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS + "response code of the URL is " - + connection.getResponseCode() + ". PEP is not Authorized for making this Request!! \n Contact Administrator for this Scope. "); - version = "pe100"; - } else if (connection.getResponseCode() == 404) { - LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "response code of the URL is " - + connection.getResponseCode() + ". This indicates a problem with getting the version from the PAP"); - version = "pe300"; - } else { - LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "BAD REQUEST: Error occured while getting the version from the PAP. The request may be incorrect."); - } - } catch (IOException e) { - LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e); - try { - throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE +"ERROR in connecting to the PAP ", e); - } catch (Exception e1) { - LOGGER.error(e1.getMessage() + e1); - } - } - - } else { - LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get valid response from PAP(s) " + paps); - try { - throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE +"ERROR in connecting to the PAP "); - } catch (Exception e) { - LOGGER.error(e.getMessage() + e); - } - } + papsCount++; } - return version; + + if (connected) { + //Read the Response + LOGGER.debug("connected to the PAP : " + getPAP()); + LOGGER.debug("--- Response: ---"); + Map> headers = connection.getHeaderFields(); + for (String key : headers.keySet()) { + LOGGER.debug("Header :" + key + " Value: " + headers.get(key)); + } + try { + if (connection.getResponseCode() == 200) { + // Check for successful creation of policy + version = connection.getHeaderField("version"); + LOGGER.debug("ActiveVersion from the Header: " + version); + } else if (connection.getResponseCode() == 403) { + LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS + "response code of the URL is " + + connection.getResponseCode() + ". PEP is not Authorized for making this Request!! \n Contact Administrator for this Scope. "); + version = "pe100"; + } else if (connection.getResponseCode() == 404) { + LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "response code of the URL is " + + connection.getResponseCode() + ". This indicates a problem with getting the version from the PAP"); + version = "pe300"; + } else { + LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "BAD REQUEST: Error occured while getting the version from the PAP. The request may be incorrect."); + } + } catch (IOException e) { + LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e); + } + } else { + LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get valid response from PAP(s) " + paps); + } + } + return version; } private String checkResponse(HttpURLConnection connection, UUID requestID) throws IOException { diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PDPServices.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PDPServices.java index e495c9950..efaa5c167 100644 --- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PDPServices.java +++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PDPServices.java @@ -21,10 +21,10 @@ package org.onap.policy.pdp.rest.api.services; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; -import java.net.MalformedURLException; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -37,6 +37,7 @@ import javax.json.JsonReader; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; @@ -65,6 +66,7 @@ import com.att.research.xacml.api.Request; import com.att.research.xacml.api.Response; import com.att.research.xacml.api.Result; import com.att.research.xacml.api.pdp.PDPEngine; +import com.att.research.xacml.api.pdp.PDPException; import com.att.research.xacml.std.json.JSONRequest; import com.att.research.xacml.std.json.JSONResponse; import com.att.research.xacml.util.XACMLProperties; @@ -333,7 +335,7 @@ public class PDPServices { return treatment; } - private PDPResponse configCall(String pdpConfigLocation) throws Exception{ + private PDPResponse configCall(String pdpConfigLocation) throws PDPException, IOException{ PDPResponse pdpResponse = new PDPResponse(); if(pdpConfigLocation.contains("/")){ pdpConfigLocation = pdpConfigLocation.replace("/", File.separator); @@ -366,7 +368,7 @@ public class PDPServices { pdpResponse.setConfig(writer.toString()); } catch (Exception e) { LOGGER.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID+ e); - throw new Exception(XACMLErrorConstants.ERROR_SCHEMA_INVALID+ "Unable to parse the XML config", e); + throw new PDPException(XACMLErrorConstants.ERROR_SCHEMA_INVALID+ "Unable to parse the XML config", e); } } else if (pdpConfigLocation.endsWith("properties")) { pdpResponse.setType(PolicyType.PROPERTIES); @@ -394,14 +396,14 @@ public class PDPServices { PolicyResponseStatus.NO_ACTION_REQUIRED, PolicyConfigStatus.CONFIG_RETRIEVED); return pdpResponse; - } catch (IOException e) { + } catch (IOException | ParserConfigurationException e) { LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e); - throw new Exception(XACMLErrorConstants.ERROR_PROCESS_FLOW + + throw new PDPException(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Cannot open a connection to the configURL", e); } - } catch (MalformedURLException e) { + } catch (FileNotFoundException e) { LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e); - throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in ConfigURL", e); + throw new PDPException(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in ConfigURL", e); }finally{ if(inputStream != null){ inputStream.close(); @@ -409,8 +411,7 @@ public class PDPServices { } } - private Response callPDP(Request request, - UUID requestID) throws Exception{ + private Response callPDP(Request request, UUID requestID){ Response response = null; // Get the PDPEngine if (requestID == null) { diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PolicyEngineImportService.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PolicyEngineImportService.java index 2d8af54c5..d0649d78a 100644 --- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PolicyEngineImportService.java +++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PolicyEngineImportService.java @@ -62,7 +62,7 @@ public class PolicyEngineImportService { requestUUID = UUID.fromString(requestID); } catch (IllegalArgumentException e) { requestUUID = UUID.randomUUID(); - LOGGER.info("Generated Random UUID: " + requestUUID.toString()); + LOGGER.info("Generated Random UUID: " + requestUUID.toString(), e); } }else{ requestUUID = UUID.randomUUID(); diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/ManualNotificationUpdateThread.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/ManualNotificationUpdateThread.java index c1306572f..9027e27a5 100644 --- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/ManualNotificationUpdateThread.java +++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/ManualNotificationUpdateThread.java @@ -44,186 +44,205 @@ import com.att.research.xacml.util.XACMLProperties; @SuppressWarnings("deprecation") public class ManualNotificationUpdateThread implements Runnable { - private static final Logger LOGGER = FlexLogger.getLogger(ManualNotificationUpdateThread.class); - - private static String topic = null; - private static CambriaConsumer CConsumer = null; - private static String clusterList = null; - private static String update = null; - private static BusConsumer dmaapConsumer = null; - private static List dmaapList = null; - private static String propNotificationType = null; - private static String aafLogin = null; - private static String aafPassword = null; - - public volatile boolean isRunning = false; - - public synchronized boolean isRunning() { - return this.isRunning; - } - - public synchronized void terminate() { - this.isRunning = false; - } - - /** - * - * This is our thread that runs on startup if the system is configured to UEB to accept manual update requests - * - */ - @Override - public void run() { - synchronized(this) { - this.isRunning = true; - } - - URL aURL = null; - String group = UUID.randomUUID ().toString (); - String id = "0"; - String returnTopic = null; - propNotificationType = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TYPE); - if ("ueb".equals(propNotificationType)){ - try { - clusterList = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_SERVERS).trim(); - String url = XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID); - aURL = new URL(url); - topic = aURL.getHost() + aURL.getPort(); - } catch (NumberFormatException e) { - LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Unable to get UEB cluster list or pdp url: ", e); - this.isRunning = false; - } catch (MalformedURLException e) { - LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in processing URL to create topic for Notification ", e); - } - if(aURL != null){ - String consumerTopic = aURL.getHost() + aURL.getPort() + "UpdateRequest"; - SendMessage(consumerTopic, "Starting-Topic"); - final LinkedList urlList = new LinkedList<> (); - for ( String u : clusterList.split ( "," ) ){ - urlList.add ( u ); - } - - try { - CConsumer = CambriaClientFactory.createConsumer ( null, urlList, consumerTopic , group, id, 20*1000, 1000 ); - } catch (MalformedURLException | GeneralSecurityException e1) { - LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unable to create UEB Consumer: ", e1); - } - - while (this.isRunning()) { - LOGGER.debug("While loop test _ take out "); - try { - for ( String msg : CConsumer.fetch () ){ - LOGGER.debug("Manual Notification Recieved Message " + msg + " from UEB cluster : "); - returnTopic = processMessage(msg); - if(returnTopic != null){ - SendMessage(returnTopic, update); - } - } - } catch (IOException e) { - LOGGER.debug(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in processing UEB message" + e); - } - } - LOGGER.debug("Stopping UEB Consumer loop will no longer fetch messages from the cluster"); - } - } else if ("dmaap".equals(propNotificationType)) { - String dmaapServers = null; - try { - dmaapServers = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_SERVERS); - topic = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TOPIC); - aafLogin = XACMLProperties.getProperty("DMAAP_AAF_LOGIN"); - aafPassword = XACMLProperties.getProperty("DMAAP_AAF_PASSWORD"); - } catch (Exception e) { - LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Unable to get DMaaP servers list:", e); - this.isRunning = false; - } - - if(dmaapServers==null || topic==null){ - LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "DMaaP properties are missing from the property file "); - try { - throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE + "DMaaP properties are missing from the property file "); - } catch (Exception e) { - LOGGER.error(e); - } - } - - dmaapServers.trim(); - topic.trim(); - aafLogin.trim(); - aafPassword.trim(); - - String consumerTopic = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TOPIC).trim(); - SendMessage(consumerTopic, "Starting-Topic"); - dmaapList = new ArrayList<>(); - for ( String u : dmaapServers.split ( "," ) ){ - dmaapList.add ( u ); - } - - try { - - dmaapConsumer = new BusConsumer.DmaapConsumerWrapper(dmaapList, consumerTopic, aafLogin, aafPassword, group, id, 20*1000, 1000); - } catch (Exception e1) { - LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unable to create DMaaP Consumer: ", e1); - } - - while (this.isRunning()) { - LOGGER.debug("While loop test _ take out "); - try { - for ( String msg : dmaapConsumer.fetch () ){ - LOGGER.debug("Manual Notification Recieved Message " + msg + " from DMaaP server : "); - returnTopic = processMessage(msg); - if(returnTopic != null){ - SendMessage(returnTopic, update); - } - } - }catch (Exception e) { - LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in processing DMaaP message: ", e); } - } - LOGGER.debug("Stopping DMaaP Consumer loop will no longer fetch messages from the servers"); - } - } - - private void SendMessage( String topic, String message) { - CambriaPublisher pub = null; - BusPublisher publisher = null; - try { - if ("ueb".equals(propNotificationType)) { - pub = CambriaClientFactory.createSimplePublisher (null, clusterList, topic ); - pub.send( "pdpReturnMessage", message ); - LOGGER.debug("Sending Message to UEB topic: " + topic); - pub.close(); - - } else if ("dmaap".equals(propNotificationType)){ - publisher = new BusPublisher.DmaapPublisherWrapper(dmaapList,topic,aafLogin,aafPassword); - publisher.send( "pdpReturnMessage", message ); - LOGGER.debug("Sending to Message to DMaaP topic: " + topic); - publisher.close(); - } - - } catch (Exception e) { - LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+ "Error sending notification update: ", e); - } - if(pub != null){ - try { - pub.send( "pdpReturnMessage", message ); - LOGGER.debug("Sending to Message to tpoic" + topic); - pub.close(); - } catch (IOException e) { - LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+ "Error sending notification update" +e); - } - } - } - - private String processMessage(String msg) { - LOGGER.debug("notification message: " + msg); - String[] UID = msg.split("=")[1].split("\""); - - String returnTopic = topic + UID[0]; - if(msg.contains("Starting-Topic")){ - return null; - } - return returnTopic; - } - public static void setUpdate(String update) { - ManualNotificationUpdateThread.update = update; - } - + private static final Logger LOGGER = FlexLogger.getLogger(ManualNotificationUpdateThread.class); + + private String topic = null; + private CambriaConsumer cConsumer = null; + private static String clusterList = null; + private static String update = null; + private BusConsumer dmaapConsumer = null; + private List dmaapList = null; + private static String propNotificationType = null; + private static String aafLogin = null; + private static String aafPassword = null; + + public volatile boolean isRunning = false; + + public synchronized boolean isRunning() { + return this.isRunning; + } + + public synchronized void terminate() { + this.isRunning = false; + } + + /** + * + * This is our thread that runs on startup if the system is configured to UEB to accept manual update requests + * + */ + @Override + public void run() { + synchronized (this) { + this.isRunning = true; + } + + URL aURL = null; + String group = UUID.randomUUID().toString(); + String id = "0"; + String returnTopic = null; + setPropNotification(); + if ("ueb".equals(propNotificationType)) { + try { + setCluster(); + String url = XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID); + aURL = new URL(url); + topic = aURL.getHost() + aURL.getPort(); + } catch (NumberFormatException e) { + LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Unable to get UEB cluster list or pdp url: ", e); + this.isRunning = false; + } catch (MalformedURLException e) { + LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + + "Error in processing URL to create topic for Notification ", e); + } + if (aURL != null) { + String consumerTopic = aURL.getHost() + aURL.getPort() + "UpdateRequest"; + sendMessage(consumerTopic, "Starting-Topic"); + final LinkedList urlList = new LinkedList<>(); + for (String u : clusterList.split(",")) { + urlList.add(u); + } + + try { + cConsumer = CambriaClientFactory.createConsumer(null, urlList, consumerTopic, group, id, 20 * 1000, + 1000); + } catch (MalformedURLException | GeneralSecurityException e1) { + LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unable to create UEB Consumer: ", e1); + } + + while (this.isRunning()) { + LOGGER.debug("While loop test _ take out "); + try { + for (String msg : cConsumer.fetch()) { + LOGGER.debug("Manual Notification Recieved Message " + msg + " from UEB cluster : "); + returnTopic = processMessage(msg); + if (returnTopic != null) { + sendMessage(returnTopic, update); + } + } + } catch (IOException e) { + LOGGER.debug(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in processing UEB message" + e); + } + } + LOGGER.debug("Stopping UEB Consumer loop will no longer fetch messages from the cluster"); + } + } else if ("dmaap".equals(propNotificationType)) { + String dmaapServers = null; + try { + dmaapServers = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_SERVERS); + topic = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TOPIC); + setAAFCreds(); + } catch (Exception e) { + LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Unable to get DMaaP servers list:", e); + this.isRunning = false; + } + + if (dmaapServers == null || topic == null) { + LOGGER.error( + XACMLErrorConstants.ERROR_DATA_ISSUE + "DMaaP properties are missing from the property file "); + } + + dmaapServers = dmaapServers.trim(); + topic = topic.trim(); + + String consumerTopic = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TOPIC).trim(); + sendMessage(consumerTopic, "Starting-Topic"); + dmaapList = new ArrayList<>(); + for (String u : dmaapServers.split(",")) { + dmaapList.add(u); + } + + try { + dmaapConsumer = new BusConsumer.DmaapConsumerWrapper(dmaapList, consumerTopic, aafLogin, aafPassword, + group, id, 20 * 1000, 1000); + } catch (Exception e1) { + LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unable to create DMaaP Consumer: ", e1); + } + + while (this.isRunning()) { + LOGGER.debug("While loop test _ take out "); + try { + for (String msg : dmaapConsumer.fetch()) { + LOGGER.debug("Manual Notification Recieved Message " + msg + " from DMaaP server : "); + returnTopic = processMessage(msg); + if (returnTopic != null) { + sendMessage(returnTopic, update); + } + } + } catch (Exception e) { + LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in processing DMaaP message: ", e); + } + } + LOGGER.debug("Stopping DMaaP Consumer loop will no longer fetch messages from the servers"); + } + } + + private static void setAAFCreds() { + aafLogin = XACMLProperties.getProperty("DMAAP_AAF_LOGIN"); + aafPassword = XACMLProperties.getProperty("DMAAP_AAF_PASSWORD"); + if (aafLogin != null) { + aafLogin = aafLogin.trim(); + } + if (aafPassword != null) { + aafPassword = aafPassword.trim(); + } + } + + private static void setCluster() { + clusterList = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_SERVERS); + if (clusterList != null) { + clusterList = clusterList.trim(); + } + } + + private static void setPropNotification() { + propNotificationType = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TYPE); + } + + private void sendMessage(String topic, String message) { + CambriaPublisher pub = null; + BusPublisher publisher = null; + try { + if ("ueb".equals(propNotificationType)) { + pub = CambriaClientFactory.createSimplePublisher(null, clusterList, topic); + pub.send("pdpReturnMessage", message); + LOGGER.debug("Sending Message to UEB topic: " + topic); + pub.close(); + + } else if ("dmaap".equals(propNotificationType)) { + publisher = new BusPublisher.DmaapPublisherWrapper(dmaapList, topic, aafLogin, aafPassword); + publisher.send("pdpReturnMessage", message); + LOGGER.debug("Sending to Message to DMaaP topic: " + topic); + publisher.close(); + } + + } catch (Exception e) { + LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error sending notification update: ", e); + } + if (pub != null) { + try { + pub.send("pdpReturnMessage", message); + LOGGER.debug("Sending to Message to tpoic" + topic); + pub.close(); + } catch (IOException e) { + LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error sending notification update" + e); + } + } + } + + private String processMessage(String msg) { + LOGGER.debug("notification message: " + msg); + String[] uID = msg.split("=")[1].split("\""); + + String returnTopic = topic + uID[0]; + if (msg.contains("Starting-Topic")) { + return null; + } + return returnTopic; + } + + public static void setUpdate(String update) { + ManualNotificationUpdateThread.update = update; + } + } diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationController.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationController.java index 109d421f8..577d5b347 100644 --- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationController.java +++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationController.java @@ -59,284 +59,301 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; /** - * NotificationController Checks for the Updated and Removed policies. It - * notifies the Server to send Notifications to the Client. + * NotificationController Checks for the Updated and Removed policies. It notifies the Server to send Notifications to + * the Client. * * @version 0.2 * */ public class NotificationController { - private static final Logger LOGGER = FlexLogger.getLogger(NotificationController.class); - private static Notification record = new Notification(); - private PDPStatus oldStatus = null; - private Removed removed = null; - private Updated updated = null; - private ManualNotificationUpdateThread registerMaunualNotificationRunnable = null; - private Thread manualNotificationThread = null; - private boolean manualThreadStarted = false; - - private static String notificationJSON = null; - private static String propNotificationType = null; - private static String pdpURL = null; - private static Boolean notificationFlag = false; - - public void check(PDPStatus newStatus,Map policyContainer) { - boolean updated = false; - boolean removed = false; - Notification notification = new Notification(); - HashSet removedPolicies = new HashSet<>(); - HashSet updatedPolicies = new HashSet<>(); + private static final Logger LOGGER = FlexLogger.getLogger(NotificationController.class); + private static Notification record = new Notification(); + private PDPStatus oldStatus = null; + private Removed removed = null; + private Updated updated = null; + private ManualNotificationUpdateThread registerMaunualNotificationRunnable = null; + private Thread manualNotificationThread = null; + private boolean manualThreadStarted = false; - if (oldStatus == null) { - oldStatus = newStatus; - } - // Debugging purpose only. - LOGGER.debug("old config Status :" + oldStatus.getStatus()); - LOGGER.debug("new config Status :" + newStatus.getStatus()); + private static String notificationJSON = null; + private static String propNotificationType = null; + private static String pdpURL = null; + private static Boolean notificationFlag = false; - // Depending on the above condition taking the Change as an Update. - if (oldStatus.getStatus().toString() != newStatus.getStatus().toString()) { - LOGGER.info("There is an Update to the PDP"); - LOGGER.debug(oldStatus.getLoadedPolicies()); - LOGGER.debug(newStatus.getLoadedPolicies()); - // Check if there is an Update/additions in the policy. - for (PDPPolicy newPolicy : newStatus.getLoadedPolicies()) { - boolean change = true; - for (PDPPolicy oldPolicy : oldStatus.getLoadedPolicies()) { - // Check if there are same policies. - if (oldPolicy.getId().equals(newPolicy.getId())) { - // Check if they have same version. - if (oldPolicy.getVersion().equals(newPolicy.getVersion())) { - change = false; - } - } - } - // if there is a change Send the notifications to the Client. - if (change) { - sendUpdate(newPolicy, policyContainer); - updated = true; - updatedPolicies.add(this.updated); - } - } - // Check if there is any removal of policy. - for (PDPPolicy oldPolicy : oldStatus.getLoadedPolicies()) { - boolean change = true; - for (PDPPolicy newPolicy : newStatus.getLoadedPolicies()) { - // Check if there are same policies. - if (oldPolicy.getId().equals(newPolicy.getId())) { - // Check if they have same version. - if (oldPolicy.getVersion().equals(newPolicy.getVersion())) { - change = false; - } - } - } - // if there is a change Send the notifications to the Client. - if (change) { - sendremove(oldPolicy); - removed = true; - removedPolicies.add(this.removed); - } - } - } - // At the end the oldStatus must be updated with the newStatus. - oldStatus = newStatus; - // Sending Notification to the Server to pass over to the clients - if (updated || removed) { - // Call the Notification Server.. - notification.setRemovedPolicies(removedPolicies); - notification.setLoadedPolicies(updatedPolicies); - notification = setUpdateTypes(updated, removed, notification); - ObjectWriter om = new ObjectMapper().writer(); - try { - notificationJSON = om.writeValueAsString(notification); - LOGGER.info(notificationJSON); - // NotificationServer Method here. - propNotificationType = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TYPE); - pdpURL = XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID); - if (("ueb".equals(propNotificationType)||"dmaap".equals(propNotificationType)) && !manualThreadStarted) { - LOGGER.debug("Starting Thread to accept UEB or DMAAP notfications."); - this.registerMaunualNotificationRunnable = new ManualNotificationUpdateThread(); - this.manualNotificationThread = new Thread(this.registerMaunualNotificationRunnable); - this.manualNotificationThread.start(); - manualThreadStarted = true; - } - String notificationJSON= null; - notificationFlag = true; - try{ - notificationJSON= record(notification); - }catch(Exception e){ - LOGGER.error(e); - } - NotificationServer.setUpdate(notificationJSON); - ManualNotificationUpdateThread.setUpdate(notificationJSON); - } catch (JsonProcessingException e) { - LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getMessage() +e); - } - } - } - - public static void sendNotification(){ - if(notificationFlag){ - try { - NotificationServer.sendNotification(notificationJSON, propNotificationType, pdpURL); - } catch (Exception e) { - LOGGER.info(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error in sending the Event Notification: "+ e.getMessage() + e); - } - notificationFlag = false; - } - } - - private void sendremove(PDPPolicy oldPolicy) { - removed = new Removed(); - // Want to know what is removed ? - LOGGER.info("Policy removed: " + oldPolicy.getId()+ " with version number: " + oldPolicy.getVersion()); - removed.setPolicyName(oldPolicy.getId()); - removed.setVersionNo(oldPolicy.getVersion()); - removeFile(oldPolicy); - } + public void check(PDPStatus newStatus, Map policyContainer) { + boolean updated = false; + boolean removed = false; + Notification notification = new Notification(); + HashSet removedPolicies = new HashSet<>(); + HashSet updatedPolicies = new HashSet<>(); - private void sendUpdate(PDPPolicy newPolicy,Map policyContainer) { - updated = new Updated(); - // Want to know what is new ? - LOGGER.info("The new Policy is: " + newPolicy.getId()); - LOGGER.info("The version no. is: " + newPolicy.getVersion()); - updated.setPolicyName(newPolicy.getId()); - updated.setVersionNo(newPolicy.getVersion()); - updated.setUpdateType(UpdateType.NEW); - // If the policy is of Config type then retrieve its matches. - if (newPolicy.getName().contains(".Config_")) { - // Take a Configuration copy to PDP webapps. - final String urlStart = "attributeId=URLID,expression"; - final String urlEnd = "}}},{"; - String policy = policyContainer.get(newPolicy.getId()).toString(); - if(policy.contains(urlStart)){ - String urlFinePartOne = policy.substring(policy.indexOf(urlStart)+urlStart.length()); - String urlFinePart = urlFinePartOne.substring(0,urlFinePartOne.indexOf(urlEnd)); - String urlString = urlFinePart.substring(urlFinePart.indexOf("value=$URL")+6); - callPap(urlString, "Config"); - } - Iterator anyOfs = policyContainer.get(newPolicy.getId()).getTarget().getAnyOfs(); - while (anyOfs.hasNext()) { - AnyOf anyOf = anyOfs.next(); - Iterator allOfs = anyOf.getAllOfs(); - while (allOfs.hasNext()) { - AllOf allOf = allOfs.next(); - Iterator matches = allOf.getMatches(); - HashMap matchValues = new HashMap<>(); - while (matches.hasNext()) { - Match match = matches.next(); - LOGGER.info("Attribute Value is: "+ match.getAttributeValue().getValue().toString()); - String[] result = match.getAttributeRetrievalBase().toString().split("attributeId="); - result[1] = result[1].replaceAll("}", ""); - if (!result[1].equals("urn:oasis:names:tc:xacml:1.0:subject:subject-id")) { - LOGGER.info("Attribute id is: " + result[1]); - } - matchValues.put(result[1], match.getAttributeValue().getValue().toString()); - LOGGER.info("Match is : "+ result[1]+ " , " + match.getAttributeValue().getValue().toString()); - } - updated.setMatches(matchValues); - } - } - }else if(newPolicy.getName().contains(".Action_")){ - // Take Configuration copy to PDP Webapps. - // Action policies have .json as extension. - String urlString = "$URL/Action/" + newPolicy.getId().substring(0, newPolicy.getId().lastIndexOf(".")) + ".json"; - callPap(urlString, "Action"); - } - } + if (oldStatus == null) { + oldStatus = newStatus; + } + // Debugging purpose only. + LOGGER.debug("old config Status :" + oldStatus.getStatus()); + LOGGER.debug("new config Status :" + newStatus.getStatus()); + + // Depending on the above condition taking the Change as an Update. + if (oldStatus.getStatus().toString() != newStatus.getStatus().toString()) { + LOGGER.info("There is an Update to the PDP"); + LOGGER.debug(oldStatus.getLoadedPolicies()); + LOGGER.debug(newStatus.getLoadedPolicies()); + // Check if there is an Update/additions in the policy. + for (PDPPolicy newPolicy : newStatus.getLoadedPolicies()) { + boolean change = true; + for (PDPPolicy oldPolicy : oldStatus.getLoadedPolicies()) { + // Check if there are same policies. + if (oldPolicy.getId().equals(newPolicy.getId())) { + // Check if they have same version. + if (oldPolicy.getVersion().equals(newPolicy.getVersion())) { + change = false; + } + } + } + // if there is a change Send the notifications to the Client. + if (change) { + sendUpdate(newPolicy, policyContainer); + updated = true; + updatedPolicies.add(this.updated); + } + } + // Check if there is any removal of policy. + for (PDPPolicy oldPolicy : oldStatus.getLoadedPolicies()) { + boolean change = true; + for (PDPPolicy newPolicy : newStatus.getLoadedPolicies()) { + // Check if there are same policies. + if (oldPolicy.getId().equals(newPolicy.getId())) { + // Check if they have same version. + if (oldPolicy.getVersion().equals(newPolicy.getVersion())) { + change = false; + } + } + } + // if there is a change Send the notifications to the Client. + if (change) { + sendremove(oldPolicy); + removed = true; + removedPolicies.add(this.removed); + } + } + } + // At the end the oldStatus must be updated with the newStatus. + oldStatus = newStatus; + // Sending Notification to the Server to pass over to the clients + if (updated || removed) { + // Call the Notification Server.. + notification.setRemovedPolicies(removedPolicies); + notification.setLoadedPolicies(updatedPolicies); + notification = setUpdateTypes(updated, removed, notification); + ObjectWriter om = new ObjectMapper().writer(); + try { + setNotificationJSON(om.writeValueAsString(notification)); + LOGGER.info(notificationJSON); + // NotificationServer Method here. + setPropNotification(); + if (("ueb".equals(propNotificationType) || "dmaap".equals(propNotificationType)) + && !manualThreadStarted) { + LOGGER.debug("Starting Thread to accept UEB or DMAAP notfications."); + this.registerMaunualNotificationRunnable = new ManualNotificationUpdateThread(); + this.manualNotificationThread = new Thread(this.registerMaunualNotificationRunnable); + this.manualNotificationThread.start(); + manualThreadStarted = true; + } + String notificationJSONString = null; + setNotificationFlag(true); + try { + notificationJSONString = record(notification); + } catch (Exception e) { + LOGGER.error(e); + } + NotificationServer.setUpdate(notificationJSONString); + ManualNotificationUpdateThread.setUpdate(notificationJSONString); + } catch (JsonProcessingException e) { + LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getMessage() + e); + } + } + } + + private void setNotificationFlag(boolean value) { + notificationFlag = value; + } + + private static void setNotificationJSON(String message) { + notificationJSON = message; + } + + private static void setPropNotification() { + propNotificationType = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TYPE); + pdpURL = XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID); + } + + public static void sendNotification() { + if (notificationFlag) { + try { + NotificationServer.sendNotification(notificationJSON, propNotificationType, pdpURL); + } catch (Exception e) { + LOGGER.info(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error in sending the Event Notification: " + + e.getMessage() + e); + } + notificationFlag = false; + } + } + + private void sendremove(PDPPolicy oldPolicy) { + removed = new Removed(); + // Want to know what is removed ? + LOGGER.info("Policy removed: " + oldPolicy.getId() + " with version number: " + oldPolicy.getVersion()); + removed.setPolicyName(oldPolicy.getId()); + removed.setVersionNo(oldPolicy.getVersion()); + removeFile(oldPolicy); + } + + private void sendUpdate(PDPPolicy newPolicy, Map policyContainer) { + updated = new Updated(); + // Want to know what is new ? + LOGGER.info("The new Policy is: " + newPolicy.getId()); + LOGGER.info("The version no. is: " + newPolicy.getVersion()); + updated.setPolicyName(newPolicy.getId()); + updated.setVersionNo(newPolicy.getVersion()); + updated.setUpdateType(UpdateType.NEW); + // If the policy is of Config type then retrieve its matches. + if (newPolicy.getName().contains(".Config_")) { + // Take a Configuration copy to PDP webapps. + final String urlStart = "attributeId=URLID,expression"; + final String urlEnd = "}}},{"; + String policy = policyContainer.get(newPolicy.getId()).toString(); + if (policy.contains(urlStart)) { + String urlFinePartOne = policy.substring(policy.indexOf(urlStart) + urlStart.length()); + String urlFinePart = urlFinePartOne.substring(0, urlFinePartOne.indexOf(urlEnd)); + String urlString = urlFinePart.substring(urlFinePart.indexOf("value=$URL") + 6); + callPap(urlString, "Config"); + } + Iterator anyOfs = policyContainer.get(newPolicy.getId()).getTarget().getAnyOfs(); + while (anyOfs.hasNext()) { + AnyOf anyOf = anyOfs.next(); + Iterator allOfs = anyOf.getAllOfs(); + while (allOfs.hasNext()) { + AllOf allOf = allOfs.next(); + Iterator matches = allOf.getMatches(); + HashMap matchValues = new HashMap<>(); + while (matches.hasNext()) { + Match match = matches.next(); + LOGGER.info("Attribute Value is: " + match.getAttributeValue().getValue().toString()); + String[] result = match.getAttributeRetrievalBase().toString().split("attributeId="); + result[1] = result[1].replaceAll("}", ""); + if (!result[1].equals("urn:oasis:names:tc:xacml:1.0:subject:subject-id")) { + LOGGER.info("Attribute id is: " + result[1]); + } + matchValues.put(result[1], match.getAttributeValue().getValue().toString()); + LOGGER.info( + "Match is : " + result[1] + " , " + match.getAttributeValue().getValue().toString()); + } + updated.setMatches(matchValues); + } + } + } else if (newPolicy.getName().contains(".Action_")) { + // Take Configuration copy to PDP Webapps. + // Action policies have .json as extension. + String urlString = "$URL/Action/" + newPolicy.getId().substring(0, newPolicy.getId().lastIndexOf(".")) + + ".json"; + callPap(urlString, "Action"); + } + } + + // Adding this for Recording the changes to serve Polling requests.. + private static String record(Notification notification) { + // Initialization with updates. + if (record.getRemovedPolicies() == null || record.getLoadedPolicies() == null) { + record.setRemovedPolicies(notification.getRemovedPolicies()); + record.setLoadedPolicies(notification.getLoadedPolicies()); + } else { + // Check if there is anything new and update the record.. + if (record.getLoadedPolicies() != null || record.getRemovedPolicies() != null) { + HashSet removedPolicies = (HashSet) record.getRemovedPolicies(); + HashSet updatedPolicies = (HashSet) record.getLoadedPolicies(); - // Adding this for Recording the changes to serve Polling requests.. - private static String record(Notification notification) throws Exception { - // Initialization with updates. - if (record.getRemovedPolicies() == null || record.getLoadedPolicies() == null) { - record.setRemovedPolicies(notification.getRemovedPolicies()); - record.setLoadedPolicies(notification.getLoadedPolicies()); - } else { - // Check if there is anything new and update the record.. - if (record.getLoadedPolicies() != null || record.getRemovedPolicies() != null) { - HashSet removedPolicies = (HashSet) record.getRemovedPolicies(); - HashSet updatedPolicies = (HashSet) record.getLoadedPolicies(); + // Checking with New updated policies. + if (notification.getLoadedPolicies() != null && !notification.getLoadedPolicies().isEmpty()) { + for (Updated newUpdatedPolicy : notification.getLoadedPolicies()) { + // If it was removed earlier then we need to remove from our record + Iterator oldRemovedPolicy = removedPolicies.iterator(); + while (oldRemovedPolicy.hasNext()) { + Removed policy = oldRemovedPolicy.next(); + if (newUpdatedPolicy.getPolicyName().equals(policy.getPolicyName())) { + if (newUpdatedPolicy.getVersionNo().equals(policy.getVersionNo())) { + oldRemovedPolicy.remove(); + } + } + } + // If it was previously updated need to Overwrite it to the record. + Iterator oldUpdatedPolicy = updatedPolicies.iterator(); + while (oldUpdatedPolicy.hasNext()) { + Updated policy = oldUpdatedPolicy.next(); + if (newUpdatedPolicy.getPolicyName().equals(policy.getPolicyName())) { + if (newUpdatedPolicy.getVersionNo().equals(policy.getVersionNo())) { + oldUpdatedPolicy.remove(); + } + } + } + updatedPolicies.add(newUpdatedPolicy); + } + } + // Checking with New Removed policies. + if (notification.getRemovedPolicies() != null && !notification.getRemovedPolicies().isEmpty()) { + for (Removed newRemovedPolicy : notification.getRemovedPolicies()) { + // If it was previously removed Overwrite it to the record. + Iterator oldRemovedPolicy = removedPolicies.iterator(); + while (oldRemovedPolicy.hasNext()) { + Removed policy = oldRemovedPolicy.next(); + if (newRemovedPolicy.getPolicyName().equals(policy.getPolicyName())) { + if (newRemovedPolicy.getVersionNo().equals(policy.getVersionNo())) { + oldRemovedPolicy.remove(); + } + } + } + // If it was added earlier then we need to remove from our record. + Iterator oldUpdatedPolicy = updatedPolicies.iterator(); + while (oldUpdatedPolicy.hasNext()) { + Updated policy = oldUpdatedPolicy.next(); + if (newRemovedPolicy.getPolicyName().equals(policy.getPolicyName())) { + if (newRemovedPolicy.getVersionNo().equals(policy.getVersionNo())) { + oldUpdatedPolicy.remove(); + } + } + } + removedPolicies.add(newRemovedPolicy); + } + } + record.setRemovedPolicies(removedPolicies); + record.setLoadedPolicies(updatedPolicies); + } + } + // Send the Result to the caller. + ObjectWriter om = new ObjectMapper().writer(); + String json = null; + try { + json = om.writeValueAsString(record); + } catch (JsonProcessingException e) { + LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getMessage() + e); + } + LOGGER.info(json); + return json; + } - // Checking with New updated policies. - if (notification.getLoadedPolicies() != null && !notification.getLoadedPolicies().isEmpty()) { - for (Updated newUpdatedPolicy : notification.getLoadedPolicies()) { - // If it was removed earlier then we need to remove from our record - Iterator oldRemovedPolicy = removedPolicies.iterator(); - while (oldRemovedPolicy.hasNext()) { - Removed policy = oldRemovedPolicy.next(); - if (newUpdatedPolicy.getPolicyName().equals(policy.getPolicyName())) { - if (newUpdatedPolicy.getVersionNo().equals(policy.getVersionNo())) { - oldRemovedPolicy.remove(); - } - } - } - // If it was previously updated need to Overwrite it to the record. - Iterator oldUpdatedPolicy = updatedPolicies.iterator(); - while (oldUpdatedPolicy.hasNext()) { - Updated policy = oldUpdatedPolicy.next(); - if (newUpdatedPolicy.getPolicyName().equals(policy.getPolicyName())) { - if (newUpdatedPolicy.getVersionNo().equals(policy.getVersionNo())) { - oldUpdatedPolicy.remove(); - } - } - } - updatedPolicies.add(newUpdatedPolicy); - } - } - // Checking with New Removed policies. - if (notification.getRemovedPolicies() != null && !notification.getRemovedPolicies().isEmpty()) { - for (Removed newRemovedPolicy : notification.getRemovedPolicies()) { - // If it was previously removed Overwrite it to the record. - Iterator oldRemovedPolicy = removedPolicies.iterator(); - while (oldRemovedPolicy.hasNext()) { - Removed policy = oldRemovedPolicy.next(); - if (newRemovedPolicy.getPolicyName().equals(policy.getPolicyName())) { - if (newRemovedPolicy.getVersionNo().equals(policy.getVersionNo())) { - oldRemovedPolicy.remove(); - } - } - } - // If it was added earlier then we need to remove from our record. - Iterator oldUpdatedPolicy = updatedPolicies.iterator(); - while (oldUpdatedPolicy.hasNext()) { - Updated policy = oldUpdatedPolicy.next(); - if (newRemovedPolicy.getPolicyName().equals(policy.getPolicyName())) { - if (newRemovedPolicy.getVersionNo().equals(policy.getVersionNo())) { - oldUpdatedPolicy.remove(); - } - } - } - removedPolicies.add(newRemovedPolicy); - } - } - record.setRemovedPolicies(removedPolicies); - record.setLoadedPolicies(updatedPolicies); - } - } - // Send the Result to the caller. - ObjectWriter om = new ObjectMapper().writer(); - String json = null; - try { - json = om.writeValueAsString(record); - } catch (JsonProcessingException e) { - LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getMessage() + e); - } - LOGGER.info(json); - return json; - } - - private static Notification setUpdateTypes(boolean updated, boolean removed, Notification notification) { - if(notification!=null){ - if(updated && removed){ + private static Notification setUpdateTypes(boolean updated, boolean removed, Notification notification) { + if (notification != null) { + if (updated && removed) { notification.setNotificationType(NotificationType.BOTH); - if(notification.getLoadedPolicies()!=null){ - HashSet updatedPolicies = new HashSet<>(); - for(Updated oldUpdatedPolicy: notification.getLoadedPolicies()){ + if (notification.getLoadedPolicies() != null) { + HashSet updatedPolicies = new HashSet<>(); + for (Updated oldUpdatedPolicy : notification.getLoadedPolicies()) { Updated updatePolicy = oldUpdatedPolicy; - if(notification.getRemovedPolicies()!=null){ - for(RemovedPolicy removedPolicy: notification.getRemovedPolicies()){ + if (notification.getRemovedPolicies() != null) { + for (RemovedPolicy removedPolicy : notification.getRemovedPolicies()) { String regex = ".(\\d)*.xml"; - if(removedPolicy.getPolicyName().replaceAll(regex, "").equals(oldUpdatedPolicy.getPolicyName().replaceAll(regex, ""))){ + if (removedPolicy.getPolicyName().replaceAll(regex, "") + .equals(oldUpdatedPolicy.getPolicyName().replaceAll(regex, ""))) { updatePolicy.setUpdateType(UpdateType.UPDATE); break; } @@ -346,70 +363,76 @@ public class NotificationController { } notification.setLoadedPolicies(updatedPolicies); } - }else if(updated){ + } else if (updated) { notification.setNotificationType(NotificationType.UPDATE); - }else if(removed){ + } else if (removed) { notification.setNotificationType(NotificationType.REMOVE); } } return notification; } - - private void removeFile(PDPPolicy oldPolicy) { - try{ - Path removedPolicyFile = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_CONFIG)+File.separator+oldPolicy.getId()); - Files.deleteIfExists(removedPolicyFile); - boolean delete=false; - File dir= null; - if(oldPolicy.getName().contains(".Config_")){ - delete = true; - dir = new File(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_WEBAPPS)+File.separator+"Config"); - }else if(oldPolicy.getName().contains(".Action_")){ - delete = true; - dir = new File(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_WEBAPPS)+File.separator+"Action"); - } - if(delete){ - FileFilter fileFilter = new WildcardFileFilter(oldPolicy.getId().substring(0, oldPolicy.getId().lastIndexOf("."))+".*"); - File[] configFile = dir.listFiles(fileFilter); - if(configFile.length==1){ - Files.deleteIfExists(configFile[0].toPath()); - } - } - }catch(Exception e){ - LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Couldn't remove the policy/config file " + oldPolicy.getName() + e); - } - } - - private void callPap(String urlString, String type) { - Path configLocation = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_WEBAPPS)+File.separator+type); - if(Files.notExists(configLocation)){ - try { - Files.createDirectories(configLocation); - } catch (IOException e) { - LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW +"Failed to create config directory: " + configLocation.toAbsolutePath().toString(), e); - } - } - PapUrlResolver papUrls = PapUrlResolver.getInstance(); - while(papUrls.hasMoreUrls()){ - String papPath = papUrls.getUrl(); - papPath = papPath.substring(0, papPath.lastIndexOf("/pap")); - String papAddress= urlString.replace("$URL", papPath); - String fileName = papAddress.substring(papAddress.lastIndexOf("/")+1); - String fileLocation = configLocation.toString() + File.separator + fileName; - try { - URL papURL = new URL(papAddress); - LOGGER.info("Calling " +papAddress + " for Configuration Copy."); - URLConnection urlConnection = papURL.openConnection(); - File file= new File(fileLocation); - try (InputStream is = urlConnection.getInputStream(); - OutputStream os = new FileOutputStream(file)) { - IOUtils.copy(is, os); - break; - } - } catch (Exception e) { - LOGGER.error(e + e.getMessage()); - } - papUrls.getNext(); - } - } + + private void removeFile(PDPPolicy oldPolicy) { + try { + Path removedPolicyFile = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_CONFIG) + + File.separator + oldPolicy.getId()); + Files.deleteIfExists(removedPolicyFile); + boolean delete = false; + File dir = null; + if (oldPolicy.getName().contains(".Config_")) { + delete = true; + dir = new File( + XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_WEBAPPS) + File.separator + "Config"); + } else if (oldPolicy.getName().contains(".Action_")) { + delete = true; + dir = new File( + XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_WEBAPPS) + File.separator + "Action"); + } + if (delete) { + FileFilter fileFilter = new WildcardFileFilter( + oldPolicy.getId().substring(0, oldPolicy.getId().lastIndexOf(".")) + ".*"); + File[] configFile = dir.listFiles(fileFilter); + if (configFile.length == 1) { + Files.deleteIfExists(configFile[0].toPath()); + } + } + } catch (Exception e) { + LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Couldn't remove the policy/config file " + + oldPolicy.getName() + e); + } + } + + private void callPap(String urlString, String type) { + Path configLocation = Paths + .get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_WEBAPPS) + File.separator + type); + if (Files.notExists(configLocation)) { + try { + Files.createDirectories(configLocation); + } catch (IOException e) { + LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to create config directory: " + + configLocation.toAbsolutePath().toString(), e); + } + } + PapUrlResolver papUrls = PapUrlResolver.getInstance(); + while (papUrls.hasMoreUrls()) { + String papPath = papUrls.getUrl(); + papPath = papPath.substring(0, papPath.lastIndexOf("/pap")); + String papAddress = urlString.replace("$URL", papPath); + String fileName = papAddress.substring(papAddress.lastIndexOf("/") + 1); + String fileLocation = configLocation.toString() + File.separator + fileName; + try { + URL papURL = new URL(papAddress); + LOGGER.info("Calling " + papAddress + " for Configuration Copy."); + URLConnection urlConnection = papURL.openConnection(); + File file = new File(fileLocation); + try (InputStream is = urlConnection.getInputStream(); OutputStream os = new FileOutputStream(file)) { + IOUtils.copy(is, os); + break; + } + } catch (Exception e) { + LOGGER.error(e + e.getMessage()); + } + papUrls.getNext(); + } + } } diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationServer.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationServer.java index 690d8c517..2f3d58203 100644 --- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationServer.java +++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationServer.java @@ -38,6 +38,7 @@ import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; +import org.onap.policy.api.PolicyEngineException; import org.onap.policy.common.logging.eelf.MessageCodes; import org.onap.policy.common.logging.eelf.PolicyLogger; import org.onap.policy.common.logging.flexlogger.FlexLogger; @@ -66,8 +67,6 @@ public class NotificationServer { private static final Logger LOGGER = FlexLogger.getLogger(NotificationServer.class); private static Queue queue = new ConcurrentLinkedQueue<>(); private static String update = null; - private static String hosts = null; - private static URL aURL = null; @OnOpen public void openConnection(Session session) { @@ -88,7 +87,7 @@ public class NotificationServer { } @OnMessage - public void Message(String message, Session session) { + public void message(String message, Session session) { if(message.equalsIgnoreCase("Manual")) { try { @@ -101,14 +100,14 @@ public class NotificationServer { } } - public static void sendNotification(String notification, String propNotificationType, String pdpURL) throws Exception { + public static void sendNotification(String notification, String propNotificationType, String pdpURL) throws PolicyEngineException, IOException, InterruptedException { LOGGER.debug("Notification set to " + propNotificationType); if (propNotificationType.equals("ueb")){ String topic = null; try { - aURL = new URL(pdpURL); + URL aURL = new URL(pdpURL); topic = aURL.getHost() + aURL.getPort(); } catch (MalformedURLException e1) { pdpURL = pdpURL.replace("/", ""); @@ -116,7 +115,7 @@ public class NotificationServer { LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error in parsing out pdpURL for UEB notfication "); PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e1, "Error in parsing out pdpURL for UEB notfication "); } - hosts = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_SERVERS); + String hosts = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_SERVERS); String apiKey = XACMLProperties.getProperty(XACMLRestProperties.PROP_UEB_API_KEY); String apiSecret = XACMLProperties.getProperty(XACMLRestProperties.PROP_UEB_API_SECRET); @@ -125,13 +124,13 @@ public class NotificationServer { try { if(hosts==null || topic==null || apiKey==null || apiSecret==null){ LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "UEB properties are missing from the property file "); - throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE + "UEB properties are missing from the property file "); + throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "UEB properties are missing from the property file "); } - hosts.trim(); - topic.trim(); - apiKey.trim(); - apiSecret.trim(); + hosts = hosts.trim(); + topic = topic.trim(); + apiKey = apiKey.trim(); + apiSecret = apiSecret.trim(); pub = new CambriaClientBuilders.PublisherBuilder () .usingHosts ( hosts ) .onTopic ( topic ) @@ -175,13 +174,13 @@ public class NotificationServer { try { if(dmaapServers==null || topic==null){ LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "DMaaP properties are missing from the property file "); - throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE + "DMaaP properties are missing from the property file "); + throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "DMaaP properties are missing from the property file "); } - dmaapServers.trim(); - topic.trim(); - aafLogin.trim(); - aafPassword.trim(); + dmaapServers= dmaapServers.trim(); + topic= topic.trim(); + aafLogin= aafLogin.trim(); + aafPassword= aafPassword.trim(); List dmaapList = null; if(dmaapServers.contains(",")) { diff --git a/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/test/PolicyEngineServicesTest.java b/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/test/PolicyEngineServicesTest.java index aa55a2a14..fe4ce0599 100644 --- a/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/test/PolicyEngineServicesTest.java +++ b/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/test/PolicyEngineServicesTest.java @@ -195,6 +195,9 @@ public class PolicyEngineServicesTest { @Test public void getNotificationTopicValidPassTest() throws Exception{ + XACMLProperties.reloadProperties(); + System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, "src/test/resources/notification.xacml.pdp.properties"); + XACMLProperties.getProperties(); // Add a Topic. mockMvc.perform(post("/getNotification").headers(headers).header(UUIDHEADER, "123").content("test")).andExpect(status().isOk()); // Try to add same topic should fail. diff --git a/ONAP-PDP-REST/src/test/resources/notification.xacml.pdp.properties b/ONAP-PDP-REST/src/test/resources/notification.xacml.pdp.properties new file mode 100644 index 000000000..9ca1bba9c --- /dev/null +++ b/ONAP-PDP-REST/src/test/resources/notification.xacml.pdp.properties @@ -0,0 +1,171 @@ +### +# ============LICENSE_START======================================================= +# ONAP-PDP-REST +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +### + +# Default XACML Properties File for PDP RESTful servlet +# +# Standard API Factories +# +xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory +xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory +xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory +# NOT USED SEE BELOW xacml.pipFinderFactory=org.onap.policy.xacml.std.pip.StdPIPFinderFactory +xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory +# +# AT&T PDP Implementation Factories +# +xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory +xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory +xacml.att.functionDefinitionFactory=org.onap.policy.xacml.custom.OnapFunctionDefinitionFactory +# NOT USED SEE BELOW xacml.att.policyFinderFactory=org.onap.policy.pdp.std.StdPolicyFinderFactory +# creteUpdate Policy Implementation Class details. +createUpdatePolicy.impl.className=org.onap.policy.pdp.rest.api.services.CreateUpdatePolicyServiceImpl +# AAF Implementation class details +aafClient.impl.className=org.onap.policy.utils.AAFPolicyClientImpl +# +# AT&T RESTful PDP Implementation Factories +# +xacml.pipFinderFactory=org.onap.policy.pdp.rest.impl.XACMLPdpPIPFinderFactory +xacml.att.policyFinderFactory=org.onap.policy.pdp.rest.XACMLPdpPolicyFinderFactory +# +# When set to true, this flag tells the StdPolicyFinderFactory to combined all the root policy files into +# into one PolicySet and use the given Policy Algorithm. +# +xacml.att.policyFinderFactory.combineRootPolicies=urn:com:att:xacml:3.0:policy-combining-algorithm:combined-permit-overrides +# +# PDP RESTful API properties +# +# Set this to the address where the XACML-PAP-REST servlet is running +xacml.rest.pap.url=http://localhost:8070/pap/ + +#if multiple paps exist, the xacml.rest.pap.url can be removed and they can be defined like this: +#xacml.rest.pap.urls=http://localhost:9090/pap/,http://localhost:9091/pap/ + +# +# Give the running PDP an ID for the PAP. The url that its running as is a good choice. +# The PAP identifies PDP's using the URL of the PDP. +# +xacml.rest.pdp.id=http://localhost:8082/pdp/ + +# Give the port number used for the PDP + +xacml.jmx.port=0 + + +# Notification Properties +# Notifcation type: websocket, ueb or dmaap... if left blank websocket is the default +NOTIFICATION_TYPE=websocket +NOTIFICATION_SERVERS=test +NOTIFICATION_TOPIC=test +NOTIFICATION_DELAY=5000 +UEB_API_KEY= +UEB_API_SECRET= +DMAAP_AAF_LOGIN=test +DMAAP_AAF_PASSWORD=test + +# +# Set the directory where the PDP holds its Policy Cache and PIP Configuration +# +xacml.rest.pdp.config=config + +xacml.rest.pdp.webapps=/home/users/PolicyEngine/webapps/ConfigPAP/ +# +# Initialize register with PAP servlet +# +xacml.rest.pdp.register=true +# +# Sleep period in seconds between register attempts +# +xacml.rest.pdp.register.sleep=15 +# +# number of attempts to register. -1 means keep trying forever. +# +xacml.rest.pdp.register.retries=-1 +# +# max number of bytes in a POST of a XML/JSON request +# old value #32767 +xacml.rest.pdp.maxcontent=99999999 +# +# Set UserID here +xacml.rest.pdp.userid=testpdp +# Set Password here +xacml.rest.pdp.password=alpha456 + +# id PAP +xacml.rest.pap.userid=testpap +#if multiple paps have different logins, they can be defined like this: +#http\://localhost\:9090/pap/.xacml.rest.pap.userid=testpap + +# pass PAP +xacml.rest.pap.password=alpha123 +#http\://localhost\:9090/pap/.xacml.rest.pap.password=alpha123 + +# Delay for Notifications Don't change this. Value in milliSec. +xacml.rest.notification.delay=30 +# Buffer Size. +REQUEST_BUFFER_SIZE=15 + +#properties for MySql xacml database: PLEASE DO NOT REMOVE... NEEDED FOR APIs +javax.persistence.jdbc.driver=com.mysql.jdbc.Driver +javax.persistence.jdbc.url=jdbc:mysql://localhost:3306/xacml +javax.persistence.jdbc.user=policy_user +javax.persistence.jdbc.password=policy_user + + +#***Properties for IntegrityMonitor integration defined in XACMLRestProperties.java*** + +#The name of the PDP. Must be unique across the system +xacml.rest.pdp.resource.name=site_1.pdp_1 + +#***Properties for IntegrityMonitor integration defined in IntegrityMonitorProperties.java*** + +#Interval between forward progress counter updates in seconds +fp_monitor_interval=30 + +#Number of forward progress counter failures before failover +failed_counter_threshold=3 + +#Interval in seconds between test transactions if there is no other traffic +test_trans_interval=10 + +#Interval in seconds between updates of the forward progress counter in the DB +write_fpc_interval=5 + +#Name of the site +site_name=site_1 + +#Node type +node_type=pdp_xacml + +#Dependency groups are groups of resources upon which a node operational state is dependent upon). +#Each group is a comma-separated list of resource names and groups are separated by a semicolon. +#A group may contain one or more members. Resource names must match the resource names defined +#in the respective servers' properties files +dependency_groups=site_1.pdplp_1;site_1.astragw_1;site_1.brmsgw_1 + +# this can be DEVL, TEST, PROD +ENVIRONMENT=DEVL +xacml.rest.pep.idfile = src/test/resources/client.properties + +#AAF Policy Name space +#Not Mandatory for Open Onap +policy.aaf.namespace = +policy.aaf.resource = +# +DMAAP_AAF_LOGIN = -- cgit 1.2.3-korg