Merge "Fix comparison issues in onap pap rest"
[policy/engine.git] / ONAP-PAP-REST / src / main / java / org / onap / policy / pap / xacml / rest / XACMLPapServlet.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-PAP-REST
4  * ================================================================================
5  * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.pap.xacml.rest;
22
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.io.UnsupportedEncodingException;
29 import java.net.ConnectException;
30 import java.net.HttpURLConnection;
31 import java.net.InetAddress;
32 import java.net.MalformedURLException;
33 import java.net.SocketTimeoutException;
34 import java.net.URL;
35 import java.net.URLDecoder;
36 import java.net.UnknownHostException;
37 import java.nio.file.Files;
38 import java.nio.file.Path;
39 import java.nio.file.Paths;
40 import java.util.ArrayList;
41 import java.util.HashMap;
42 import java.util.HashSet;
43 import java.util.List;
44 import java.util.Objects;
45 import java.util.Properties;
46 import java.util.Scanner;
47 import java.util.Set;
48 import java.util.UUID;
49 import java.util.concurrent.CopyOnWriteArrayList;
50
51 import javax.persistence.EntityManagerFactory;
52 import javax.persistence.Persistence;
53 import javax.persistence.PersistenceException;
54 import javax.servlet.Servlet;
55 import javax.servlet.ServletConfig;
56 import javax.servlet.ServletException;
57 import javax.servlet.annotation.WebInitParam;
58 import javax.servlet.annotation.WebServlet;
59 import javax.servlet.http.HttpServlet;
60 import javax.servlet.http.HttpServletRequest;
61 import javax.servlet.http.HttpServletResponse;
62
63 import org.apache.commons.io.IOUtils;
64 import org.onap.policy.common.ia.IntegrityAudit;
65 import org.onap.policy.common.im.AdministrativeStateException;
66 import org.onap.policy.common.im.ForwardProgressException;
67 import org.onap.policy.common.im.IntegrityMonitor;
68 import org.onap.policy.common.im.IntegrityMonitorException;
69 import org.onap.policy.common.im.IntegrityMonitorProperties;
70 import org.onap.policy.common.im.StandbyStatusException;
71 import org.onap.policy.common.logging.ONAPLoggingContext;
72 import org.onap.policy.common.logging.ONAPLoggingUtils;
73 import org.onap.policy.common.logging.eelf.MessageCodes;
74 import org.onap.policy.common.logging.eelf.PolicyLogger;
75 import org.onap.policy.common.logging.flexlogger.FlexLogger;
76 import org.onap.policy.common.logging.flexlogger.Logger;
77 import org.onap.policy.pap.xacml.rest.components.PolicyDBDao;
78 import org.onap.policy.pap.xacml.rest.components.PolicyDBDaoTransaction;
79 import org.onap.policy.pap.xacml.rest.handler.APIRequestHandler;
80 import org.onap.policy.pap.xacml.rest.handler.PushPolicyHandler;
81 import org.onap.policy.pap.xacml.rest.handler.SavePolicyHandler;
82 import org.onap.policy.pap.xacml.restAuth.CheckPDP;
83 import org.onap.policy.rest.XACMLRest;
84 import org.onap.policy.rest.XACMLRestProperties;
85 import org.onap.policy.rest.dao.PolicyDBException;
86 import org.onap.policy.utils.CryptoUtils;
87 import org.onap.policy.utils.PolicyUtils;
88 import org.onap.policy.xacml.api.XACMLErrorConstants;
89 import org.onap.policy.xacml.api.pap.ONAPPapEngineFactory;
90 import org.onap.policy.xacml.api.pap.OnapPDP;
91 import org.onap.policy.xacml.api.pap.OnapPDPGroup;
92 import org.onap.policy.xacml.api.pap.PAPPolicyEngine;
93 import org.onap.policy.xacml.std.pap.StdPDP;
94 import org.onap.policy.xacml.std.pap.StdPDPGroup;
95 import org.onap.policy.xacml.std.pap.StdPDPItemSetChangeNotifier.StdItemSetChangeListener;
96 import org.onap.policy.xacml.std.pap.StdPDPPolicy;
97 import org.onap.policy.xacml.std.pap.StdPDPStatus;
98
99 import com.att.research.xacml.api.pap.PAPException;
100 import com.att.research.xacml.api.pap.PDPPolicy;
101 import com.att.research.xacml.api.pap.PDPStatus;
102 import com.att.research.xacml.util.FactoryException;
103 import com.att.research.xacml.util.XACMLProperties;
104 import com.fasterxml.jackson.databind.ObjectMapper;
105 import com.google.common.base.Splitter;
106
107 /**
108  * Servlet implementation class XacmlPapServlet
109  */
110 @WebServlet(
111         description = "Implements the XACML PAP RESTful API.",
112         urlPatterns = {"/"},
113         loadOnStartup = 1,
114         initParams = {
115                 @WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pap.properties",
116                         description = "The location of the properties file holding configuration information.")
117         })
118 public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeListener, Runnable {
119     private static final long serialVersionUID = 1L;
120     private static final Logger LOGGER = FlexLogger.getLogger(XACMLPapServlet.class);
121     // audit (transaction) LOGGER
122     private static final Logger auditLogger = FlexLogger.getLogger("auditLogger");
123     //Persistence Unit for JPA
124     private static final String PERSISTENCE_UNIT = "XACML-PAP-REST";
125     private static final String AUDIT_PAP_PERSISTENCE_UNIT = "auditPapPU";
126     // Client Headers.
127     private static final String ENVIRONMENT_HEADER = "Environment";
128     private static final String ADD_GROUP_ERROR = "addGroupError";
129     private static final String PERSISTENCE_JDBC_PWD = "javax.persistence.jdbc.password";
130
131     private static final String REGEX = "[0-9a-zA-Z._ ]*";
132
133     /*
134      * List of Admin Console URLs.
135      * Used to send notifications when configuration changes.
136      *
137      * The CopyOnWriteArrayList *should* protect from concurrency errors.
138      * This list is seldom changed but often read, so the costs of this approach make sense.
139      */
140     private static final CopyOnWriteArrayList<String> adminConsoleURLStringList = new CopyOnWriteArrayList<>();
141
142     private static String configHome;
143     private static String actionHome;
144     /*
145      * This PAP instance's own URL.
146      * Need this when creating URLs to send to the PDPs so they can GET the Policy files from this process.
147      */
148     private static String papURL = null;
149     // The heartbeat thread.
150     private static Heartbeat heartbeat = null;
151     private static Thread heartbeatThread = null;
152     //The entity manager factory for JPA access
153     private static EntityManagerFactory emf;
154     private static PolicyDBDao policyDBDao;
155     /*
156      * papEngine - This is our engine workhorse that manages the PDP Groups and Nodes.
157      */
158     private static PAPPolicyEngine papEngine = null;
159     /*
160      * These are the parameters needed for DB access from the PAP
161      */
162     private static int papIntegrityAuditPeriodSeconds = -1;
163     private static String papDbDriver = null;
164     private static String papDbUrl = null;
165     private static String papDbUser = null;
166     private static String papDbPassword = null;
167     private static String papResourceName = null;
168     private static String[] papDependencyGroupsFlatArray = null;
169     private static String environment = null;
170     private static String pdpFile = null;
171
172     private transient IntegrityMonitor im;
173     private transient IntegrityAudit ia;
174
175     //MicroService Model Properties
176     private static String msOnapName;
177     private static String msPolicyName;
178     /*
179      * This thread may be invoked upon startup to initiate sending PDP policy/pip configuration when
180      * this servlet starts. Its configurable by the admin.
181      */
182     private static transient Thread initiateThread = null;
183     private transient ONAPLoggingContext baseLoggingContext = null;
184
185     /**
186      * @see HttpServlet#HttpServlet()
187      */
188     public XACMLPapServlet() {
189         super();
190     }
191
192     /**
193      * @see Servlet#init(ServletConfig)
194      */
195     public void init(ServletConfig config) throws ServletException {
196         try {
197             // Logging
198             baseLoggingContext = new ONAPLoggingContext();
199             // fixed data that will be the same in all logging output goes here
200             try {
201                 String hostname = InetAddress.getLocalHost().getCanonicalHostName();
202                 baseLoggingContext.setServer(hostname);
203             } catch (UnknownHostException e) {
204                 LOGGER.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get hostname for logging", e);
205             }
206             // Initialize
207             XACMLRest.xacmlInit(config);
208             // Load the properties
209             XACMLRest.loadXacmlProperties(null, null);
210             /*
211              * Retrieve the property values
212              */
213             setCommonProperties();
214             String papSiteName = XACMLProperties.getProperty(XACMLRestProperties.PAP_SITE_NAME);
215             if (papSiteName == null) {
216                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet",
217                         " ERROR: Bad papSiteName property entry");
218                 throw new PAPException("papSiteName is null");
219             }
220             String papNodeType = XACMLProperties.getProperty(XACMLRestProperties.PAP_NODE_TYPE);
221             if (papNodeType == null) {
222                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet",
223                         " ERROR: Bad papNodeType property entry");
224                 throw new PAPException("papNodeType is null");
225             }
226             //Integer will throw an exception of anything is missing or unrecognized
227             int papTransWait = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT));
228             int papTransTimeout =
229                     Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_TIMEOUT));
230             int papAuditTimeout =
231                     Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_TIMEOUT));
232             //Boolean will default to false if anything is missing or unrecognized
233             boolean papAuditFlag =
234                     Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_RUN_AUDIT_FLAG));
235             boolean papFileSystemAudit =
236                     Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_FLAG));
237             String papDependencyGroups = XACMLProperties.getProperty(XACMLRestProperties.PAP_DEPENDENCY_GROUPS);
238             if (papDependencyGroups == null) {
239                 throw new PAPException("papDependencyGroups is null");
240             }
241             setPAPDependencyGroups(papDependencyGroups);
242             //Integer will throw an exception of anything is missing or unrecognized
243             int fpMonitorInterval =
244                     Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.FP_MONITOR_INTERVAL));
245             int failedCounterThreshold =
246                     Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.FAILED_COUNTER_THRESHOLD));
247             int testTransInterval =
248                     Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.TEST_TRANS_INTERVAL));
249             int writeFpcInterval =
250                     Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.WRITE_FPC_INTERVAL));
251             LOGGER.debug("\n\n\n**************************************"
252                     + "\n*************************************"
253                     + "\n"
254                     + "\n   papDbDriver = " + papDbDriver
255                     + "\n   papDbUrl = " + papDbUrl
256                     + "\n   papDbUser = " + papDbUser
257                     + "\n   papTransWait = " + papTransWait
258                     + "\n   papTransTimeout = " + papTransTimeout
259                     + "\n   papAuditTimeout = " + papAuditTimeout
260                     + "\n   papAuditFlag = " + papAuditFlag
261                     + "\n   papFileSystemAudit = " + papFileSystemAudit
262                     + "\n       papResourceName = " + papResourceName
263                     + "\n       fpMonitorInterval = " + fpMonitorInterval
264                     + "\n       failedCounterThreshold = " + failedCounterThreshold
265                     + "\n       testTransInterval = " + testTransInterval
266                     + "\n       writeFpcInterval = " + writeFpcInterval
267                     + "\n       papSiteName = " + papSiteName
268                     + "\n       papNodeType = " + papNodeType
269                     + "\n       papDependencyGroupsList = " + papDependencyGroups
270                     + "\n   papIntegrityAuditPeriodSeconds = " + papIntegrityAuditPeriodSeconds
271                     + "\n\n*************************************"
272                     + "\n**************************************");
273             // Pull custom persistence settings
274             Properties properties;
275             try {
276                 properties = XACMLProperties.getProperties();
277                 LOGGER.debug("\n\n\n**************************************"
278                         + "\n**************************************"
279                         + "\n\n"
280                         + "properties = " + properties
281                         + "\n\n**************************************");
282             } catch (IOException e) {
283                 PolicyLogger
284                         .error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPapServlet", " Error loading properties with: "
285                                 + "XACMLProperties.getProperties()");
286                 throw new ServletException(e.getMessage(), e.getCause());
287             }
288             // Create an IntegrityMonitor
289             if (properties.getProperty(PERSISTENCE_JDBC_PWD) != null) {
290                 properties.setProperty(PERSISTENCE_JDBC_PWD,
291                         CryptoUtils.decryptTxtNoExStr(properties.getProperty(PERSISTENCE_JDBC_PWD, "")));
292             }
293             im = IntegrityMonitor.getInstance(papResourceName, properties);
294             // Create an IntegrityAudit
295             ia = new IntegrityAudit(papResourceName, AUDIT_PAP_PERSISTENCE_UNIT, properties);
296             ia.startAuditThread();
297             // Create the entity manager factory
298             setEMF(properties);
299             // we are about to call the PDPs and give them their configuration.
300             // To do that we need to have the URL of this PAP so we can construct the Policy file URLs
301             setPAPURL(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL));
302             //Create the policyDBDao
303             setPolicyDBDao();
304             // Load our PAP engine, first create a factory
305             ONAPPapEngineFactory factory = ONAPPapEngineFactory
306                     .newInstance(XACMLProperties.getProperty(XACMLProperties.PROP_PAP_PAPENGINEFACTORY));
307             // The factory knows how to go about creating a PAP Engine
308             setPAPEngine((PAPPolicyEngine) factory.newEngine());
309             PolicyDBDaoTransaction addNewGroup = null;
310             if (((org.onap.policy.xacml.std.pap.StdEngine) papEngine).wasDefaultGroupJustAdded) {
311                 try {
312                     addNewGroup = policyDBDao.getNewTransaction();
313                     OnapPDPGroup group = papEngine.getDefaultGroup();
314                     addNewGroup.createGroup(group.getId(), group.getName(), group.getDescription(),
315                             "automaticallyAdded");
316                     addNewGroup.commitTransaction();
317                     addNewGroup = policyDBDao.getNewTransaction();
318                     addNewGroup.changeDefaultGroup(group, "automaticallyAdded");
319                     addNewGroup.commitTransaction();
320                 } catch (Exception e) {
321                     PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet",
322                             " Error creating new default group in the database");
323                     if (addNewGroup != null) {
324                         addNewGroup.rollbackTransaction();
325                     }
326                 }
327             }
328             policyDBDao.setPapEngine((PAPPolicyEngine) XACMLPapServlet.papEngine);
329             if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_RUN_AUDIT_FLAG))) {
330                 /*
331                  * Auditing the local File System groups to be in sync with the Database
332                  */
333
334                 //get an AuditTransaction to lock out all other transactions
335                 PolicyDBDaoTransaction auditTrans = policyDBDao.getNewAuditTransaction();
336
337                 LOGGER.info("PapServlet: calling auditLocalFileSystem for PDP group audit");
338                 LOGGER.info("PapServlet: old group is " + papEngine.getDefaultGroup().toString());
339                 //get the current filesystem group and update from the database if needed
340                 StdPDPGroup group = (StdPDPGroup) papEngine.getDefaultGroup();
341                 StdPDPGroup updatedGroup = policyDBDao.auditLocalFileSystem(group);
342                 if (updatedGroup != null) {
343                     papEngine.updateGroup(updatedGroup);
344                 }
345                 LOGGER.info("PapServlet:  updated group is " + papEngine.getDefaultGroup().toString());
346
347                 //release the transaction lock
348                 auditTrans.close();
349             }
350
351             // Sanity check for URL.
352             if (XACMLPapServlet.papURL == null) {
353                 throw new PAPException("The property " + XACMLRestProperties.PROP_PAP_URL + " is not valid: " +
354                         XACMLPapServlet.papURL);
355             }
356             // Configurable - have the PAP servlet initiate sending the latest PDP policy/pip configuration
357             // to all its known PDP nodes.
358             if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_INITIATE_PDP_CONFIG))) {
359                 startInitiateThreadService(new Thread(this));
360             }
361             // After startup, the PAP does Heartbeat's to each of the PDPs periodically
362             startHeartBeatService(new Heartbeat((PAPPolicyEngine) XACMLPapServlet.papEngine));
363
364         } catch (FactoryException | PAPException e) {
365             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Failed to create engine");
366             throw new ServletException(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP not initialized; error: " + e);
367         } catch (Exception e) {
368             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet",
369                     " Failed to create engine - unexpected error");
370             throw new ServletException(
371                     XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP not initialized; unexpected error: " + e);
372         }
373     }
374
375     private static void startInitiateThreadService(Thread thread) {
376         initiateThread = thread;
377         initiateThread.start();
378     }
379
380     private static void mapperWriteValue(ObjectMapper mapper, HttpServletResponse response, Object value) {
381         try {
382             mapper.writeValue(response.getOutputStream(), value);
383         } catch (Exception e) {
384             LOGGER.error(e);
385         }
386     }
387
388     private static void startHeartBeatService(Heartbeat heartbeat) {
389         XACMLPapServlet.heartbeat = heartbeat;
390         XACMLPapServlet.heartbeatThread = new Thread(XACMLPapServlet.heartbeat);
391         XACMLPapServlet.heartbeatThread.start();
392     }
393
394     private static void setPolicyDBDao() throws ServletException {
395         try {
396             policyDBDao = PolicyDBDao.getPolicyDBDaoInstance(getEmf());
397         } catch (Exception e) {
398             throw new ServletException("Unable to Create Policy DBDao Instance", e);
399         }
400     }
401
402     private static void setEMF(Properties properties) throws ServletException {
403         emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT, properties);
404         if (emf == null) {
405             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE +
406                     " Error creating entity manager factory with persistence unit: "
407                     + PERSISTENCE_UNIT);
408             throw new ServletException("Unable to create Entity Manager Factory");
409         }
410     }
411
412     private static void setPAPURL(String papURL) {
413         XACMLPapServlet.papURL = papURL;
414     }
415
416     private static void setPAPEngine(PAPPolicyEngine newEngine) {
417         XACMLPapServlet.papEngine = newEngine;
418     }
419
420     private static void setPAPDependencyGroups(String papDependencyGroups) throws PAPException {
421         try {
422             //Now we have flattened the array into a simple comma-separated list
423             papDependencyGroupsFlatArray = papDependencyGroups.split("[;,]");
424             //clean up the entries
425             for (int i = 0; i < papDependencyGroupsFlatArray.length; i++) {
426                 papDependencyGroupsFlatArray[i] = papDependencyGroupsFlatArray[i].trim();
427             }
428             try {
429                 if (XACMLProperties.getProperty(XACMLRestProperties.PAP_INTEGRITY_AUDIT_PERIOD_SECONDS) != null) {
430                     papIntegrityAuditPeriodSeconds = Integer.parseInt(
431                             XACMLProperties.getProperty(XACMLRestProperties.PAP_INTEGRITY_AUDIT_PERIOD_SECONDS).trim());
432                 }
433             } catch (Exception e) {
434                 String msg = "integrity_audit_period_seconds ";
435                 LOGGER.error("\n\nERROR: " + msg + "Bad property entry: " + e.getMessage() + "\n");
436                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet",
437                         " ERROR: " + msg + "Bad property entry");
438                 throw e;
439             }
440         } catch (Exception e) {
441             PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR: Bad property entry");
442             throw new PAPException(e);
443         }
444     }
445
446     private static void setCommonProperties() throws PAPException {
447         setConfigHome();
448         setActionHome();
449         papDbDriver = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_DRIVER);
450         if (papDbDriver == null) {
451             PolicyLogger
452                     .error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet", " ERROR: Bad papDbDriver property entry");
453             throw new PAPException("papDbDriver is null");
454         }
455         setPapDbDriver(papDbDriver);
456         papDbUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_URL);
457         if (papDbUrl == null) {
458             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet", " ERROR: Bad papDbUrl property entry");
459             throw new PAPException("papDbUrl is null");
460         }
461         setPapDbUrl(papDbUrl);
462         papDbUser = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_USER);
463         if (papDbUser == null) {
464             PolicyLogger
465                     .error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet", " ERROR: Bad papDbUser property entry");
466             throw new PAPException("papDbUser is null");
467         }
468         setPapDbUser(papDbUser);
469         papDbPassword = CryptoUtils
470                 .decryptTxtNoExStr(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_PASSWORD, ""));
471         if (papDbPassword == null) {
472             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet",
473                     " ERROR: Bad papDbPassword property entry");
474             throw new PAPException("papDbPassword is null");
475         }
476         setPapDbPassword(papDbPassword);
477         papResourceName = XACMLProperties.getProperty(XACMLRestProperties.PAP_RESOURCE_NAME);
478         if (papResourceName == null) {
479             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet",
480                     " ERROR: Bad papResourceName property entry");
481             throw new PAPException("papResourceName is null");
482         }
483         environment = XACMLProperties.getProperty("ENVIRONMENT", "DEVL");
484         //Micro Service Properties
485         msOnapName = XACMLProperties.getProperty("xacml.policy.msOnapName");
486         setMsOnapName(msOnapName);
487         msPolicyName = XACMLProperties.getProperty("xacml.policy.msPolicyName");
488         setMsPolicyName(msPolicyName);
489         // PDPId File location 
490         XACMLPapServlet.pdpFile = XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_IDFILE);
491         if (XACMLPapServlet.pdpFile == null) {
492             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " The PDP Id Authentication File Property is not valid: "
493                     + XACMLRestProperties.PROP_PDP_IDFILE);
494             throw new PAPException("The PDP Id Authentication File Property :" + XACMLRestProperties.PROP_PDP_IDFILE +
495                     " is not Valid. ");
496         }
497     }
498
499     /**
500      * Thread used only during PAP startup to initiate change messages to all known PDPs.
501      * This must be on a separate thread so that any GET requests from the PDPs during this update can be serviced.
502      */
503     @Override
504     public void run() {
505         // send the current configuration to all the PDPs that we know about
506         changed();
507     }
508
509     /**
510      * @see Servlet#destroy()
511      * <p>
512      * Depending on how this servlet is run, we may or may not care about cleaning up the resources.
513      * For now we assume that we do care.
514      */
515     @Override
516     public void destroy() {
517         // Make sure our threads are destroyed
518         if (XACMLPapServlet.heartbeatThread != null) {
519             // stop the heartbeat
520             try {
521                 if (XACMLPapServlet.heartbeat != null) {
522                     XACMLPapServlet.heartbeat.terminate();
523                 }
524                 XACMLPapServlet.heartbeatThread.interrupt();
525                 XACMLPapServlet.heartbeatThread.join();
526             } catch (InterruptedException e) {
527                 XACMLPapServlet.heartbeatThread.interrupt();
528                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Error stopping heartbeat");
529             }
530         }
531         if (initiateThread != null) {
532             try {
533                 initiateThread.interrupt();
534                 initiateThread.join();
535             } catch (InterruptedException e) {
536                 initiateThread.interrupt();
537                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Error stopping thread");
538             }
539         }
540     }
541
542     /**
543      * Called by:
544      * - PDP nodes to register themselves with the PAP, and
545      * - Admin Console to make changes in the PDP Groups.
546      *
547      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
548      */
549     protected void doPost(HttpServletRequest request, HttpServletResponse response)
550             throws ServletException, IOException {
551         ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
552         loggingContext.transactionStarted();
553         loggingContext.setServiceName("PAP.post");
554         if ((loggingContext.getRequestID() == null) || (Objects.equals(loggingContext.getRequestID(), ""))) {
555             UUID requestID = UUID.randomUUID();
556             loggingContext.setRequestID(requestID.toString());
557             PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doPost) so we generated one");
558         } else {
559             PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doPost)");
560         }
561         PolicyDBDaoTransaction pdpTransaction = null;
562         loggingContext.metricStarted();
563         try {
564             im.startTransaction();
565             loggingContext.metricEnded();
566             PolicyLogger.metrics("XACMLPapServlet doPost im startTransaction");
567         } catch (AdministrativeStateException ae) {
568             String message = "POST interface called for PAP " + papResourceName + " but it has an Administrative"
569                     + " state of " + im.getStateManager().getAdminState()
570                     + "\n Exception Message: " + PolicyUtils.CATCH_EXCEPTION;
571             LOGGER.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message, ae);
572             loggingContext.metricEnded();
573             PolicyLogger.metrics("XACMLPapServlet doPost im startTransaction");
574             loggingContext.transactionEnded();
575             PolicyLogger.audit("Transaction Failed - See Error.log");
576             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
577             return;
578         } catch (StandbyStatusException se) {
579             String message = "POST interface called for PAP " + papResourceName + " but it has a Standby Status"
580                     + " of " + im.getStateManager().getStandbyStatus()
581                     + "\n Exception Message: " + se.getMessage();
582             LOGGER.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message, se);
583             loggingContext.metricEnded();
584             PolicyLogger.metrics("XACMLPapServlet doPost im startTransaction");
585             loggingContext.transactionEnded();
586             PolicyLogger.audit("Transaction Failed - See Error.log");
587             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
588             return;
589         } catch (IntegrityMonitorException e) {
590             String message = "POST interface called for PAP " + papResourceName + " but an exception occurred"
591                     + "\n Exception Message: " + e.getMessage();
592             LOGGER.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message, e);
593             loggingContext.metricEnded();
594             PolicyLogger.metrics("XACMLPapServlet doPost im startTransaction");
595             loggingContext.transactionEnded();
596             PolicyLogger.audit("Transaction Failed - See Error.log");
597             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
598             return;
599         }
600         try {
601             loggingContext.metricStarted();
602             XACMLRest.dumpRequest(request);
603             loggingContext.metricEnded();
604             PolicyLogger.metrics("XACMLPapServlet doPost dumpRequest");
605             // since getParameter reads the content string, explicitly get the content before doing that.
606             // Simply getting the inputStream seems to protect it against being consumed by getParameter.
607             request.getInputStream();
608             String groupId = request.getParameter("groupId");
609             String apiflag = request.getParameter("apiflag");
610             if (groupId != null) {
611                 // Is this from the Admin Console or API?
612                 if (apiflag != null && apiflag.equalsIgnoreCase("api")) {
613                     // this is from the API so we need to check the client credentials before processing the request
614                     if (!authorizeRequest(request)) {
615                         String message = "PEP not Authorized for making this Request!!";
616                         PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
617                         loggingContext.transactionEnded();
618                         PolicyLogger.audit("Transaction Failed - See Error.log");
619                         setResponseError(response, HttpServletResponse.SC_FORBIDDEN, message);
620                         im.endTransaction();
621                         return;
622                     }
623                 }
624                 loggingContext.metricStarted();
625                 doACPost(request, response, groupId, loggingContext);
626                 loggingContext.metricEnded();
627                 PolicyLogger.metrics("XACMLPapServlet doPost doACPost");
628                 loggingContext.transactionEnded();
629                 PolicyLogger.audit("Transaction Ended Successfully");
630                 im.endTransaction();
631                 return;
632             }
633             // Request is from a PDP asking for its config.
634             loggingContext.setServiceName("PDP:PAP.register");
635             // Get the PDP's ID
636             String id = this.getPDPID(request);
637             String jmxport = this.getPDPJMX(request);
638             LOGGER.info("Request(doPost) from PDP coming up: " + id);
639             // Get the PDP Object
640             OnapPDP pdp = XACMLPapServlet.papEngine.getPDP(id);
641             // Is it known?
642             if (pdp == null) {
643                 LOGGER.info("Unknown PDP: " + id);
644                 // Check PDP ID
645                 if (CheckPDP.validateID(id)) {
646                     pdpTransaction = policyDBDao.getNewTransaction();
647                     try {
648                         pdpTransaction.addPdpToGroup(id, XACMLPapServlet.papEngine.getDefaultGroup().getId(), id,
649                                 "Registered on first startup", Integer.parseInt(jmxport), "PDP autoregister");
650                         XACMLPapServlet.papEngine.newPDP(id, XACMLPapServlet.papEngine.getDefaultGroup(), id,
651                                 "Registered on first startup", Integer.parseInt(jmxport));
652                     } catch (NullPointerException | PAPException | IllegalArgumentException | IllegalStateException | PersistenceException | PolicyDBException e) {
653                         pdpTransaction.rollbackTransaction();
654                         String message = "Failed to create new PDP for id: " + id;
655                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " " + message);
656                         loggingContext.transactionEnded();
657                         PolicyLogger.audit("Transaction Failed - See Error.log");
658                         setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
659                         im.endTransaction();
660                         return;
661                     }
662                     // get the PDP we just created
663                     try {
664                         pdp = XACMLPapServlet.papEngine.getPDP(id);
665                     } catch (PAPException e) {
666                         LOGGER.error(e);
667                     }
668                     if (pdp == null) {
669                         if (pdpTransaction != null) {
670                             pdpTransaction.rollbackTransaction();
671                         }
672                         String message = "Failed to create new PDP for id: " + id;
673                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " " + message);
674                         loggingContext.transactionEnded();
675                         PolicyLogger.audit("Transaction Failed - See Error.log");
676                         setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
677                         im.endTransaction();
678                         return;
679                     }
680                 } else {
681                     String message = "PDP is Unauthorized to Connect to PAP: " + id;
682                     loggingContext.transactionEnded();
683                     PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
684                     setResponseError(response, HttpServletResponse.SC_UNAUTHORIZED,
685                             "PDP not Authorized to connect to this PAP. Please contact the PAP Admin for registration" +
686                                     ".");
687                     PolicyLogger.audit("Transaction Failed - See Error.log");
688                     im.endTransaction();
689                     return;
690                 }
691                 try {
692                     loggingContext.metricStarted();
693                     pdpTransaction.commitTransaction();
694                     loggingContext.metricEnded();
695                     PolicyLogger.metrics("XACMLPapServlet doPost commitTransaction");
696                 } catch (Exception e) {
697                     PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet",
698                             "Could not commit transaction to put pdp in the database");
699                 }
700             }
701             if (jmxport != null && !Objects.equals(jmxport, "")) {
702                 try {
703                     ((StdPDP) pdp).setJmxPort(Integer.valueOf(jmxport));
704                 } catch (NumberFormatException e) {
705                     LOGGER.error(e);
706                 }
707             }
708             // Get the PDP's Group
709             OnapPDPGroup group = null;
710             try {
711                 group = XACMLPapServlet.papEngine.getPDPGroup((OnapPDP) pdp);
712             } catch (PAPException e) {
713                 LOGGER.error(e);
714             }
715             if (group == null) {
716                 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW +
717                         " PDP not associated with any group, even the default");
718                 loggingContext.transactionEnded();
719                 PolicyLogger.audit("Transaction Failed - See Error.log");
720                 setResponseError(response, HttpServletResponse.SC_UNAUTHORIZED,
721                         "PDP not associated with any group, even the default");
722                 im.endTransaction();
723                 return;
724             }
725             // Determine what group the PDP node is in and get
726             // its policy/pip properties.
727             Properties policies = group.getPolicyProperties();
728             Properties pipconfig = group.getPipConfigProperties();
729             // Get the current policy/pip configuration that the PDP has
730             Properties pdpProperties = new Properties();
731             try {
732                 pdpProperties.load(request.getInputStream());
733             } catch (IOException e) {
734                 LOGGER.error(e);
735             }
736             LOGGER.info("PDP Current Properties: " + pdpProperties.toString());
737             LOGGER.info("Policies: " + (policies != null ? policies.toString() : "null"));
738             LOGGER.info("Pip config: " + (pipconfig != null ? pipconfig.toString() : "null"));
739             // Validate the node's properties
740             boolean isCurrent = this.isPDPCurrent(policies, pipconfig, pdpProperties);
741             // Send back current configuration
742             if (isCurrent == false) {
743                 // Tell the PDP we are sending back the current policies/pip config
744                 LOGGER.info("PDP configuration NOT current.");
745                 if (policies != null) {
746                     // Put URL's into the properties in case the PDP needs to
747                     // retrieve them.
748                     this.populatePolicyURL(request.getRequestURL(), policies);
749                     // Copy the properties to the output stream
750                     try {
751                         policies.store(response.getOutputStream(), "");
752                     } catch (IOException e) {
753                         LOGGER.error(e);
754                     }
755                 }
756                 if (pipconfig != null) {
757                     // Copy the properties to the output stream
758                     try {
759                         pipconfig.store(response.getOutputStream(), "");
760                     } catch (IOException e) {
761                         LOGGER.error(e);
762                     }
763                 }
764                 // We are good - and we are sending them information
765                 response.setStatus(HttpServletResponse.SC_OK);
766                 try {
767                     setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH);
768                 } catch (PAPException e) {
769                     LOGGER.error(e);
770                 }
771             } else {
772                 // Tell them they are good
773                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
774                 try {
775                     setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE);
776                 } catch (PAPException e) {
777                     LOGGER.error(e);
778                 }
779             }
780             // tell the AC that something changed
781             loggingContext.metricStarted();
782             notifyAC();
783             loggingContext.metricEnded();
784             PolicyLogger.metrics("XACMLPapServlet doPost notifyAC");
785             loggingContext.transactionEnded();
786             auditLogger.info("Success");
787             PolicyLogger.audit("Transaction Ended Successfully");
788         } catch (PAPException | IOException | NumberFormatException e) {
789             if (pdpTransaction != null) {
790                 pdpTransaction.rollbackTransaction();
791             }
792             LOGGER.debug(XACMLErrorConstants.ERROR_PROCESS_FLOW + "POST exception: " + e, e);
793             loggingContext.transactionEnded();
794             PolicyLogger.audit("Transaction Failed - See Error.log");
795             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
796             im.endTransaction();
797             return;
798         }
799         //Catch anything that fell through
800         loggingContext.transactionEnded();
801         PolicyLogger.audit("Transaction Ended");
802         im.endTransaction();
803     }
804
805     private void setResponseError(HttpServletResponse response, int responseCode, String message) {
806         try {
807             if (message != null && !message.isEmpty()) {
808                 response.sendError(responseCode, message);
809             }
810         } catch (IOException e) {
811             LOGGER.error("Error setting Error response Header ", e);
812         }
813     }
814
815     /**
816      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
817      */
818     protected void doGet(HttpServletRequest request, HttpServletResponse response)
819             throws ServletException, IOException {
820         ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
821         loggingContext.transactionStarted();
822         loggingContext.setServiceName("PAP.get");
823         if ((loggingContext.getRequestID() == null) || (Objects.equals(loggingContext.getRequestID(), ""))) {
824             UUID requestID = UUID.randomUUID();
825             loggingContext.setRequestID(requestID.toString());
826             PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doGet) so we generated one");
827         } else {
828             PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doGet)");
829         }
830         loggingContext.metricStarted();
831         XACMLRest.dumpRequest(request);
832         loggingContext.metricEnded();
833         PolicyLogger.metrics("XACMLPapServlet doGet dumpRequest");
834         String pathInfo = request.getRequestURI();
835         LOGGER.info("path info: " + pathInfo);
836         if (pathInfo != null) {
837             //DO NOT do a im.startTransaction for the test request
838             if (pathInfo.equals("/pap/test")) {
839                 try {
840                     testService(loggingContext, response);
841                 } catch (IOException e) {
842                     LOGGER.debug(e);
843                 }
844                 return;
845             }
846         }
847         //This im.startTransaction() covers all other Get transactions
848         try {
849             loggingContext.metricStarted();
850             im.startTransaction();
851             loggingContext.metricEnded();
852             PolicyLogger.metrics("XACMLPapServlet doGet im startTransaction");
853         } catch (AdministrativeStateException ae) {
854             String message = "GET interface called for PAP " + papResourceName + " but it has an Administrative"
855                     + " state of " + im.getStateManager().getAdminState()
856                     + "\n Exception Message: " + ae.getMessage();
857             LOGGER.info(message, ae);
858             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
859             loggingContext.transactionEnded();
860             PolicyLogger.audit("Transaction Failed - See Error.log");
861             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
862             return;
863         } catch (StandbyStatusException se) {
864             String message = "GET interface called for PAP " + papResourceName + " but it has a Standby Status"
865                     + " of " + im.getStateManager().getStandbyStatus()
866                     + "\n Exception Message: " + se.getMessage();
867             LOGGER.info(message, se);
868             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
869             loggingContext.transactionEnded();
870             PolicyLogger.audit("Transaction Failed - See Error.log");
871             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
872             return;
873         } catch (IntegrityMonitorException e) {
874             String message = "GET interface called for PAP " + papResourceName + " but an exception occurred"
875                     + "\n Exception Message: " + e.getMessage();
876             LOGGER.info(message, e);
877             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
878             loggingContext.transactionEnded();
879             PolicyLogger.audit("Transaction Failed - See Error.log");
880             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
881             return;
882         }
883         // Request from the API to get the gitPath
884         String apiflag = request.getParameter("apiflag");
885         if (apiflag != null) {
886             if (authorizeRequest(request)) {
887                 APIRequestHandler apiRequestHandler = new APIRequestHandler();
888                 try {
889                     loggingContext.metricStarted();
890                     apiRequestHandler.doGet(request, response, apiflag);
891                     loggingContext.metricEnded();
892                     PolicyLogger.metrics("XACMLPapServlet doGet apiRequestHandler doGet");
893                 } catch (IOException e) {
894                     LOGGER.error(e);
895                 }
896                 loggingContext.transactionEnded();
897                 PolicyLogger.audit("Transaction Ended Successfully");
898                 im.endTransaction();
899                 return;
900             } else {
901                 String message =
902                         "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
903                 PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
904                 loggingContext.transactionEnded();
905                 PolicyLogger.audit("Transaction Failed - See Error.log");
906                 setResponseError(response, HttpServletResponse.SC_FORBIDDEN, message);
907                 im.endTransaction();
908                 return;
909             }
910         }
911         // Is this from the Admin Console?
912         String groupId = request.getParameter("groupId");
913         if (groupId != null) {
914             // this is from the Admin Console, so handle separately
915             try {
916                 loggingContext.metricStarted();
917                 doACGet(request, response, groupId, loggingContext);
918                 loggingContext.metricEnded();
919                 PolicyLogger.metrics("XACMLPapServlet doGet doACGet");
920             } catch (IOException e) {
921                 LOGGER.error(e);
922             }
923             loggingContext.transactionEnded();
924             PolicyLogger.audit("Transaction Ended Successfully");
925             im.endTransaction();
926             return;
927         }
928         // Get the PDP's ID
929         String id = this.getPDPID(request);
930         LOGGER.info("doGet from: " + id);
931         // Get the PDP Object
932         OnapPDP pdp = null;
933         try {
934             pdp = XACMLPapServlet.papEngine.getPDP(id);
935         } catch (PAPException e) {
936             LOGGER.error(e);
937         }
938         // Is it known?
939         if (pdp == null) {
940             // Check if request came from localhost
941             if (request.getRemoteHost().equals("localhost") ||
942                     request.getRemoteHost().equals(request.getLocalAddr())) {
943                 // Return status information - basically all the groups
944                 loggingContext.setServiceName("PAP.getGroups");
945                 Set<OnapPDPGroup> groups = null;
946                 try {
947                     groups = papEngine.getOnapPDPGroups();
948                 } catch (PAPException e) {
949                     LOGGER.debug(e);
950                     PolicyLogger.error(MessageCodes.ERROR_UNKNOWN, e, "XACMLPapServlet", " GET exception");
951                     loggingContext.transactionEnded();
952                     PolicyLogger.audit("Transaction Failed - See Error.log");
953                     setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
954                     im.endTransaction();
955                     return;
956                 }
957                 // convert response object to JSON and include in the response
958                 mapperWriteValue(new ObjectMapper(), response, groups);
959                 response.setHeader("content-type", "application/json");
960                 response.setStatus(HttpServletResponse.SC_OK);
961                 loggingContext.transactionEnded();
962                 PolicyLogger.audit("Transaction Ended Successfully");
963                 im.endTransaction();
964                 return;
965             }
966             String message =
967                     "Unknown PDP: " + id + " from " + request.getRemoteHost() + " us: " + request.getLocalAddr();
968             PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
969             loggingContext.transactionEnded();
970             PolicyLogger.audit("Transaction Failed - See Error.log");
971             setResponseError(response, HttpServletResponse.SC_UNAUTHORIZED, message);
972             im.endTransaction();
973             return;
974         }
975         loggingContext.setServiceName("PAP.getPolicy");
976         // Get the PDP's Group
977         OnapPDPGroup group = null;
978         try {
979             group = XACMLPapServlet.papEngine.getPDPGroup((OnapPDP) pdp);
980         } catch (PAPException e) {
981             LOGGER.error(e);
982         }
983         if (group == null) {
984             String message = "No group associated with pdp " + pdp.getId();
985             LOGGER.warn(XACMLErrorConstants.ERROR_PERMISSIONS + message);
986             loggingContext.transactionEnded();
987             PolicyLogger.audit("Transaction Failed - See Error.log");
988             setResponseError(response, HttpServletResponse.SC_UNAUTHORIZED, message);
989             im.endTransaction();
990             return;
991         }
992         // Which policy do they want?
993         String policyId = request.getParameter("id");
994         if (policyId == null) {
995             String message = "Did not specify an id for the policy";
996             LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
997             loggingContext.transactionEnded();
998             PolicyLogger.audit("Transaction Failed - See Error.log");
999             setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
1000             im.endTransaction();
1001             return;
1002         }
1003         PDPPolicy policy = group.getPolicy(policyId);
1004         if (policy == null) {
1005             String message = "Unknown policy: " + policyId;
1006             LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
1007             loggingContext.transactionEnded();
1008             PolicyLogger.audit("Transaction Failed - See Error.log");
1009             setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
1010             im.endTransaction();
1011             return;
1012         }
1013         try {
1014             LOGGER.warn("PolicyDebugging: Policy Validity: " + policy.isValid() + "\n "
1015                     + "Policy Name : " + policy.getName() + "\n Policy URI: " + policy.getLocation().toString());
1016         } catch (PAPException | IOException e) {
1017             LOGGER.error(e);
1018         }
1019         try (InputStream is = new FileInputStream(
1020                 ((StdPDPGroup) group).getDirectory().toString() + File.separator + policyId);
1021              OutputStream os = response.getOutputStream()) {
1022             // Send the policy back
1023             IOUtils.copy(is, os);
1024             response.setStatus(HttpServletResponse.SC_OK);
1025             loggingContext.transactionEnded();
1026             auditLogger.info("Success");
1027             PolicyLogger.audit("Transaction Ended Successfully");
1028         } catch (IOException e) {
1029             String message = "Failed to open policy id " + policyId;
1030             LOGGER.debug(e);
1031             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
1032             loggingContext.transactionEnded();
1033             PolicyLogger.audit("Transaction Failed - See Error.log");
1034             setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
1035         }
1036         loggingContext.transactionEnded();
1037         PolicyLogger.audit("Transaction Ended");
1038         im.endTransaction();
1039     }
1040
1041     /**
1042      * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response)
1043      */
1044     protected void doPut(HttpServletRequest request, HttpServletResponse response)
1045             throws ServletException, IOException {
1046         ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
1047         loggingContext.transactionStarted();
1048         loggingContext.setServiceName("PAP.put");
1049         if ((loggingContext.getRequestID() == null) || (Objects.equals(loggingContext.getRequestID(), ""))) {
1050             UUID requestID = UUID.randomUUID();
1051             loggingContext.setRequestID(requestID.toString());
1052             PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doPut) so we generated one");
1053         } else {
1054             PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doPut)");
1055         }
1056         try {
1057             loggingContext.metricStarted();
1058             im.startTransaction();
1059             loggingContext.metricEnded();
1060             PolicyLogger.metrics("XACMLPapServlet doPut im startTransaction");
1061         } catch (IntegrityMonitorException e) {
1062             String message = "PUT interface called for PAP " + papResourceName;
1063             if (e instanceof AdministrativeStateException) {
1064                 message += " but it has an Administrative state of "
1065                         + im.getStateManager().getAdminState();
1066             } else if (e instanceof StandbyStatusException) {
1067                 message += " but it has a Standby Status of "
1068                         + im.getStateManager().getStandbyStatus();
1069             } else {
1070                 message += " but an exception occurred";
1071
1072             }
1073             message += "\n Exception Message: " + e.getMessage();
1074
1075             LOGGER.info(message, e);
1076             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
1077             loggingContext.transactionEnded();
1078             PolicyLogger.audit("Transaction Failed - See Error.log");
1079             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1080             return;
1081         }
1082
1083         loggingContext.metricStarted();
1084         XACMLRest.dumpRequest(request);
1085         loggingContext.metricEnded();
1086         PolicyLogger.metrics("XACMLPapServlet doPut dumpRequest");
1087         //need to check if request is from the API or Admin console
1088         String apiflag = request.getParameter("apiflag");
1089         //This would occur if a PolicyDBDao notification was received
1090         String policyDBDaoRequestUrl = request.getParameter("policydbdaourl");
1091         if (policyDBDaoRequestUrl != null) {
1092             LOGGER.info("XACMLPapServlet: PolicyDBDao Notification received.");
1093             String policyDBDaoRequestEntityId = request.getParameter("entityid");
1094             String policyDBDaoRequestEntityType = request.getParameter("entitytype");
1095             String policyDBDaoRequestExtraData = request.getParameter("extradata");
1096             if (policyDBDaoRequestEntityId == null || policyDBDaoRequestEntityType == null) {
1097                 setResponseError(response, 400, "entityid or entitytype not supplied");
1098                 loggingContext.transactionEnded();
1099                 PolicyLogger.audit("Transaction Ended Successfully");
1100                 im.endTransaction();
1101                 return;
1102             }
1103             loggingContext.metricStarted();
1104             LOGGER.info("XACMLPapServlet: Calling PolicyDBDao to handlIncomingHttpNotification");
1105             policyDBDao.handleIncomingHttpNotification(policyDBDaoRequestUrl, policyDBDaoRequestEntityId,
1106                     policyDBDaoRequestEntityType, policyDBDaoRequestExtraData, this);
1107             loggingContext.metricEnded();
1108             PolicyLogger.metrics("XACMLPapServlet doPut handle incoming http notification");
1109             response.setStatus(200);
1110             loggingContext.transactionEnded();
1111             PolicyLogger.audit("Transaction Ended Successfully");
1112             im.endTransaction();
1113             return;
1114         }
1115         /*
1116          * Request for ImportService
1117          */
1118         String importService = request.getParameter("importService");
1119         if (importService != null) {
1120             if (authorizeRequest(request)) {
1121                 APIRequestHandler apiRequestHandler = new APIRequestHandler();
1122                 try {
1123                     loggingContext.metricStarted();
1124                     apiRequestHandler.doPut(request, response, importService);
1125                     loggingContext.metricEnded();
1126                     PolicyLogger.metrics("XACMLPapServlet doPut apiRequestHandler doPut");
1127                 } catch (IOException e) {
1128                     LOGGER.error(e);
1129                 }
1130                 im.endTransaction();
1131                 return;
1132             } else {
1133                 String message =
1134                         "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
1135                 LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS + message);
1136                 loggingContext.transactionEnded();
1137                 PolicyLogger.audit("Transaction Failed - See Error.log");
1138                 setResponseError(response, HttpServletResponse.SC_FORBIDDEN, message);
1139                 return;
1140             }
1141         }
1142         //
1143         // See if this is Admin Console registering itself with us
1144         //
1145         String acURLString = request.getParameter("adminConsoleURL");
1146         if (acURLString != null) {
1147             loggingContext.setServiceName("AC:PAP.register");
1148             // remember this Admin Console for future updates
1149             if (!adminConsoleURLStringList.contains(acURLString)) {
1150                 adminConsoleURLStringList.add(acURLString);
1151             }
1152             if (LOGGER.isDebugEnabled()) {
1153                 LOGGER.debug("Admin Console registering with URL: " + acURLString);
1154             }
1155             response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1156             loggingContext.transactionEnded();
1157             auditLogger.info("Success");
1158             PolicyLogger.audit("Transaction Ended Successfully");
1159             im.endTransaction();
1160             return;
1161         }
1162         /*
1163          * This is to update the PDP Group with the policy/policies being pushed
1164          * Part of a 2 step process to push policies to the PDP that can now be done
1165          * From both the Admin Console and the PolicyEngine API
1166          */
1167         String groupId = request.getParameter("groupId");
1168         if (groupId != null) {
1169             if (apiflag != null) {
1170                 if (!authorizeRequest(request)) {
1171                     String message =
1172                             "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
1173                     PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
1174                     loggingContext.transactionEnded();
1175                     PolicyLogger.audit("Transaction Failed - See Error.log");
1176                     setResponseError(response, HttpServletResponse.SC_FORBIDDEN, message);
1177                     return;
1178                 }
1179                 if (apiflag.equalsIgnoreCase("addPolicyToGroup")) {
1180                     try {
1181                         updateGroupsFromAPI(request, response, groupId, loggingContext);
1182                     } catch (IOException e) {
1183                         LOGGER.error(e);
1184                     }
1185                     loggingContext.transactionEnded();
1186                     PolicyLogger.audit("Transaction Ended Successfully");
1187                     im.endTransaction();
1188                     return;
1189                 }
1190             }
1191             // this is from the Admin Console, so handle separately
1192             try {
1193                 loggingContext.metricEnded();
1194                 doACPut(request, response, groupId, loggingContext);
1195                 loggingContext.metricEnded();
1196                 PolicyLogger.metrics("XACMLPapServlet goPut doACPut");
1197             } catch (IOException e) {
1198                 LOGGER.error(e);
1199             }
1200             loggingContext.transactionEnded();
1201             PolicyLogger.audit("Transaction Ended Successfully");
1202             im.endTransaction();
1203             return;
1204         }
1205         //
1206         // Request is for policy validation and creation
1207         //
1208         if (apiflag != null && apiflag.equalsIgnoreCase("admin")) {
1209             // this request is from the Admin Console
1210             SavePolicyHandler savePolicyHandler = SavePolicyHandler.getInstance();
1211             try {
1212                 loggingContext.metricStarted();
1213                 savePolicyHandler.doPolicyAPIPut(request, response);
1214                 loggingContext.metricEnded();
1215                 PolicyLogger.metrics("XACMLPapServlet goPut savePolicyHandler");
1216             } catch (IOException e) {
1217                 LOGGER.error(e);
1218             }
1219             loggingContext.transactionEnded();
1220             PolicyLogger.audit("Transaction Ended Successfully");
1221             im.endTransaction();
1222             return;
1223         } else if (apiflag != null && "api".equalsIgnoreCase(apiflag)) {
1224             // this request is from the Policy Creation API
1225             if (authorizeRequest(request)) {
1226                 APIRequestHandler apiRequestHandler = new APIRequestHandler();
1227                 try {
1228                     loggingContext.metricStarted();
1229                     apiRequestHandler.doPut(request, response, request.getHeader("ClientScope"));
1230                     loggingContext.metricEnded();
1231                     PolicyLogger.metrics("XACMLPapServlet goPut apiRequestHandler doPut");
1232                 } catch (IOException e) {
1233                     LOGGER.error(e);
1234                 }
1235                 loggingContext.transactionEnded();
1236                 PolicyLogger.audit("Transaction Ended Successfully");
1237                 im.endTransaction();
1238                 return;
1239             } else {
1240                 String message = "PEP not Authorized for making this Request!!";
1241                 PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
1242                 loggingContext.transactionEnded();
1243                 PolicyLogger.audit("Transaction Failed - See Error.log");
1244                 setResponseError(response, HttpServletResponse.SC_FORBIDDEN, message);
1245                 im.endTransaction();
1246                 return;
1247             }
1248         }
1249         // We do not expect anything from anywhere else.
1250         // This method is here in case we ever need to support other operations.
1251         LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Request does not have groupId or apiflag");
1252         loggingContext.transactionEnded();
1253         PolicyLogger.audit("Transaction Failed - See Error.log");
1254         setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "Request does not have groupId or apiflag");
1255         loggingContext.transactionEnded();
1256         PolicyLogger.audit("Transaction Failed - See error.log");
1257         im.endTransaction();
1258     }
1259
1260     /**
1261      * @see HttpServlet#doDelete(HttpServletRequest request, HttpServletResponse response)
1262      */
1263     protected void doDelete(HttpServletRequest request, HttpServletResponse response)
1264             throws ServletException, IOException {
1265         ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
1266         loggingContext.transactionStarted();
1267         loggingContext.setServiceName("PAP.delete");
1268         if ((loggingContext.getRequestID() == null) || (Objects.equals(loggingContext.getRequestID(), ""))) {
1269             UUID requestID = UUID.randomUUID();
1270             loggingContext.setRequestID(requestID.toString());
1271             PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doDelete) so we generated one");
1272         } else {
1273             PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doDelete)");
1274         }
1275         try {
1276             loggingContext.metricStarted();
1277             im.startTransaction();
1278             loggingContext.metricEnded();
1279             PolicyLogger.metrics("XACMLPapServlet doDelete im startTransaction");
1280         } catch (AdministrativeStateException ae) {
1281             String message = "DELETE interface called for PAP " + papResourceName + " but it has an Administrative"
1282                     + " state of " + im.getStateManager().getAdminState()
1283                     + "\n Exception Message: " + ae.getMessage();
1284             LOGGER.info(message, ae);
1285             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
1286             loggingContext.transactionEnded();
1287             PolicyLogger.audit("Transaction Failed - See Error.log");
1288             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1289             return;
1290         } catch (StandbyStatusException se) {
1291             String message = "PUT interface called for PAP " + papResourceName + " but it has a Standby Status"
1292                     + " of " + im.getStateManager().getStandbyStatus()
1293                     + "\n Exception Message: " + se.getMessage();
1294             LOGGER.info(message, se);
1295             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
1296             loggingContext.transactionEnded();
1297             PolicyLogger.audit("Transaction Failed - See Error.log");
1298             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1299             return;
1300         } catch (IntegrityMonitorException e) {
1301             String message = "PUT interface called for PAP " + papResourceName + " but an exception occurred"
1302                     + "\n Exception Message: " + e.getMessage();
1303             LOGGER.info(message, e);
1304             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
1305             loggingContext.transactionEnded();
1306             PolicyLogger.audit("Transaction Failed - See Error.log");
1307             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1308             return;
1309         }
1310         loggingContext.metricStarted();
1311         XACMLRest.dumpRequest(request);
1312         loggingContext.metricEnded();
1313         PolicyLogger.metrics("XACMLPapServlet doDelete dumpRequest");
1314         String groupId = request.getParameter("groupId");
1315         String apiflag = request.getParameter("apiflag");
1316         if (groupId != null) {
1317             // Is this from the Admin Console or API?
1318             if (apiflag != null) {
1319                 if (!authorizeRequest(request)) {
1320                     String message =
1321                             "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
1322                     PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
1323                     loggingContext.transactionEnded();
1324                     PolicyLogger.audit("Transaction Failed - See Error.log");
1325                     setResponseError(response, HttpServletResponse.SC_FORBIDDEN, message);
1326                     return;
1327                 }
1328                 APIRequestHandler apiRequestHandler = new APIRequestHandler();
1329                 try {
1330                     loggingContext.metricStarted();
1331                     apiRequestHandler.doDelete(request, response, loggingContext, apiflag);
1332                     loggingContext.metricEnded();
1333                     PolicyLogger.metrics("XACMLPapServlet doDelete apiRequestHandler doDelete");
1334                 } catch (Exception e) {
1335                     LOGGER.error("Exception Occured" + e);
1336                 }
1337                 if (apiRequestHandler.getNewGroup() != null) {
1338                     groupChanged(apiRequestHandler.getNewGroup(), loggingContext);
1339                 }
1340                 return;
1341             }
1342             // this is from the Admin Console, so handle separately
1343             try {
1344                 loggingContext.metricStarted();
1345                 doACDelete(request, response, groupId, loggingContext);
1346                 loggingContext.metricEnded();
1347                 PolicyLogger.metrics("XACMLPapServlet doDelete doACDelete");
1348             } catch (IOException e) {
1349                 LOGGER.error(e);
1350             }
1351             loggingContext.transactionEnded();
1352             PolicyLogger.audit("Transaction Ended Successfully");
1353             im.endTransaction();
1354             return;
1355         }
1356         //Catch anything that fell through
1357         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Request does not have groupId");
1358         loggingContext.transactionEnded();
1359         PolicyLogger.audit("Transaction Failed - See Error.log");
1360         setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "Request does not have groupId");
1361         im.endTransaction();
1362     }
1363
1364     private boolean isPDPCurrent(Properties policies, Properties pipconfig, Properties pdpProperties) {
1365         String localRootPolicies = policies.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
1366         String localReferencedPolicies = policies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
1367         if (localRootPolicies == null || localReferencedPolicies == null) {
1368             LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing property on PAP server: RootPolicies=" +
1369                     localRootPolicies + "  ReferencedPolicies=" + localReferencedPolicies);
1370             return false;
1371         }
1372         // Compare the policies and pipconfig properties to the pdpProperties
1373         try {
1374             // the policy properties includes only xacml.rootPolicies and
1375             // xacml.referencedPolicies without any .url entries
1376             Properties pdpPolicies = XACMLProperties.getPolicyProperties(pdpProperties, false);
1377             Properties pdpPipConfig = XACMLProperties.getPipProperties(pdpProperties);
1378             if (localRootPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_ROOTPOLICIES)) &&
1379                     localReferencedPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES)) &&
1380                     pdpPipConfig.equals(pipconfig)) {
1381                 // The PDP is current
1382                 return true;
1383             }
1384         } catch (Exception e) {
1385             // we get here if the PDP did not include either xacml.rootPolicies or xacml.pip.engines,
1386             // or if there are policies that do not have a corresponding ".url" property.
1387             // Either of these cases means that the PDP is not up-to-date, so just drop-through to return false.
1388             PolicyLogger.error(MessageCodes.ERROR_SCHEMA_INVALID, e, "XACMLPapServlet", " PDP Error");
1389         }
1390         return false;
1391     }
1392
1393     private void populatePolicyURL(StringBuffer urlPath, Properties policies) {
1394         String lists[] = new String[2];
1395         lists[0] = policies.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
1396         lists[1] = policies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
1397         for (String list : lists) {
1398             if (list != null && list.isEmpty() == false) {
1399                 for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(list)) {
1400                     String url = urlPath + "?id=" + id;
1401                     LOGGER.info("Policy URL for " + id + ": " + url);
1402                     policies.setProperty(id + ".url", url);
1403                 }
1404             }
1405         }
1406     }
1407
1408     protected String getPDPID(HttpServletRequest request) {
1409         String pdpURL = request.getHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID);
1410         if (pdpURL == null || pdpURL.isEmpty()) {
1411             // Should send back its port for identification
1412             LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + "PDP did not send custom header");
1413             pdpURL = "";
1414         }
1415         return pdpURL;
1416     }
1417
1418     protected String getPDPJMX(HttpServletRequest request) {
1419         String pdpJMMX = request.getHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_JMX_PORT);
1420         if (pdpJMMX == null || pdpJMMX.isEmpty()) {
1421             // Should send back its port for identification
1422             LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE +
1423                     "PDP did not send custom header for JMX Port so the value of 0 is assigned");
1424             return null;
1425         }
1426         return pdpJMMX;
1427     }
1428
1429     /**
1430      * Requests from the PolicyEngine API to update the PDP Group with pushed policy
1431      *
1432      * @param request
1433      * @param response
1434      * @param groupId
1435      * @param loggingContext
1436      * @throws ServletException
1437      * @throws IOException
1438      */
1439     public void updateGroupsFromAPI(HttpServletRequest request, HttpServletResponse response, String groupId,
1440                                     ONAPLoggingContext loggingContext) throws IOException {
1441         PolicyDBDaoTransaction acPutTransaction = policyDBDao.getNewTransaction();
1442         PolicyLogger.audit("PolicyDBDaoTransaction started for updateGroupsFromAPI");
1443         try {
1444             // for PUT operations the group may or may not need to exist before the operation can be done
1445             StdPDPGroup group = (StdPDPGroup) papEngine.getGroup(groupId);
1446
1447             // get the request input stream content into a String
1448             String json = null;
1449             java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
1450             scanner.useDelimiter("\\A");
1451             json = scanner.hasNext() ? scanner.next() : "";
1452             scanner.close();
1453
1454             PolicyLogger.info("pushPolicy request from API: " + json);
1455
1456             // convert Object sent as JSON into local object
1457             StdPDPPolicy policy = PolicyUtils.jsonStringToObject(json, StdPDPPolicy.class);
1458
1459             //Get the current policies from the Group and Add the new one
1460             Set<PDPPolicy> currentPoliciesInGroup = new HashSet<>();
1461             currentPoliciesInGroup = group.getPolicies();
1462             //If the selected policy is in the group we must remove the old version of it
1463             LOGGER.info("Removing old version of the policy");
1464             for (PDPPolicy existingPolicy : currentPoliciesInGroup) {
1465                 if (existingPolicy.getName().equals(policy.getName()) &&
1466                         !existingPolicy.getId().equals(policy.getId())) {
1467                     group.removePolicy(existingPolicy);
1468                     LOGGER.info("Removing policy: " + existingPolicy);
1469                     break;
1470                 }
1471             }
1472
1473             // Assume that this is an update of an existing PDP Group
1474             loggingContext.setServiceName("PolicyEngineAPI:PAP.updateGroup");
1475             try {
1476                 acPutTransaction.updateGroup(group, "XACMLPapServlet.doACPut");
1477             } catch (Exception e) {
1478                 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet",
1479                         " Error while updating group in the database: "
1480                                 + "group=" + group.getId());
1481                 throw new PAPException(e.getMessage());
1482             }
1483
1484             LOGGER.info("Calling updatGroup() with new group");
1485             papEngine.updateGroup(group);
1486             String policyId = "empty";
1487             if (policy != null && policy.getId() != null) {
1488                 policyId = policy.getId();
1489             }
1490             if (!policyId.matches(REGEX)) {
1491                 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
1492                 response.addHeader("error", ADD_GROUP_ERROR);
1493                 response.addHeader("message", "Policy Id is not valid");
1494                 return;
1495             }
1496             response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1497             response.addHeader("operation", "push");
1498             response.addHeader("policyId", policyId);
1499             response.addHeader("groupId", groupId);
1500
1501             LOGGER.info("Group '" + group.getId() + "' updated");
1502
1503             loggingContext.metricStarted();
1504             acPutTransaction.commitTransaction();
1505             loggingContext.metricEnded();
1506             PolicyLogger.metrics("XACMLPapServlet updateGroupsFromAPI commitTransaction");
1507             loggingContext.metricStarted();
1508             notifyAC();
1509             loggingContext.metricEnded();
1510             PolicyLogger.metrics("XACMLPapServlet updateGroupsFromAPI notifyAC");
1511
1512             // Group changed, which might include changing the policies
1513             groupChanged(group, loggingContext);
1514             loggingContext.transactionEnded();
1515             LOGGER.info("Success");
1516
1517             if (policy != null &&
1518                     ((policy.getId().contains("Config_MS_")) || (policy.getId().contains("BRMS_Param")))) {
1519                 PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance();
1520                 if (pushPolicyHandler.preSafetyCheck(policy, configHome)) {
1521                     LOGGER.debug("Precheck Successful.");
1522                 }
1523             }
1524
1525             PolicyLogger.audit("Transaction Ended Successfully");
1526         } catch (PAPException e) {
1527             acPutTransaction.rollbackTransaction();
1528             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " API PUT exception");
1529             loggingContext.transactionEnded();
1530             PolicyLogger.audit("Transaction Failed - See Error.log");
1531             String message = XACMLErrorConstants.ERROR_PROCESS_FLOW +
1532                     "Exception in request to update group from API - See Error.log on on the PAP.";
1533             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
1534             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
1535             response.addHeader("error", ADD_GROUP_ERROR);
1536             response.addHeader("message", message);
1537         }
1538     }
1539
1540     /**
1541      * Requests from the Admin Console for operations not on single specific objects
1542      *
1543      * @param request
1544      * @param response
1545      * @param groupId
1546      * @param loggingContext
1547      * @throws ServletException
1548      * @throws IOException
1549      */
1550     private void doACPost(HttpServletRequest request, HttpServletResponse response, String groupId,
1551                           ONAPLoggingContext loggingContext) throws ServletException, IOException {
1552         PolicyDBDaoTransaction doACPostTransaction = null;
1553         try {
1554             String groupName = request.getParameter("groupName");
1555             String groupDescription = request.getParameter("groupDescription");
1556             String apiflag = request.getParameter("apiflag");
1557             if (groupName != null && groupDescription != null) {
1558                 // Args:              group=<groupId> groupName=<name> groupDescription=<description>            <= create
1559                 // a new group
1560                 loggingContext.setServiceName("AC:PAP.createGroup");
1561                 String unescapedName = null;
1562                 String unescapedDescription = null;
1563                 try {
1564                     unescapedName = URLDecoder.decode(groupName, "UTF-8");
1565                     unescapedDescription = URLDecoder.decode(groupDescription, "UTF-8");
1566                 } catch (UnsupportedEncodingException e) {
1567                     LOGGER.error(e);
1568                 }
1569                 PolicyDBDaoTransaction newGroupTransaction = policyDBDao.getNewTransaction();
1570                 try {
1571                     newGroupTransaction.createGroup(PolicyDBDao.createNewPDPGroupId(unescapedName), unescapedName,
1572                             unescapedDescription, "XACMLPapServlet.doACPost");
1573                     papEngine.newGroup(unescapedName, unescapedDescription);
1574                     loggingContext.metricStarted();
1575                     newGroupTransaction.commitTransaction();
1576                     loggingContext.metricEnded();
1577                     PolicyLogger.metrics("XACMLPapServlet doACPost commitTransaction");
1578                 } catch (Exception e) {
1579                     newGroupTransaction.rollbackTransaction();
1580                     PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet",
1581                             " Unable to create new group");
1582                     loggingContext.transactionEnded();
1583                     PolicyLogger.audit("Transaction Failed - See Error.log");
1584                     setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
1585                             "Unable to create new group '" + groupId + "'");
1586                     return;
1587                 }
1588                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1589                 if (LOGGER.isDebugEnabled()) {
1590                     LOGGER.debug("New Group '" + groupId + "' created");
1591                 }
1592                 // tell the Admin Consoles there is a change
1593                 loggingContext.metricStarted();
1594                 notifyAC();
1595                 loggingContext.metricEnded();
1596                 PolicyLogger.metrics("XACMLPapServlet doACPost notifyAC");
1597                 // new group by definition has no PDPs, so no need to notify them of changes
1598                 loggingContext.transactionEnded();
1599                 PolicyLogger.audit("Transaction Failed - See Error.log");
1600                 auditLogger.info("Success");
1601                 PolicyLogger.audit("Transaction Ended Successfully");
1602                 return;
1603             }
1604             // for all remaining POST operations the group must exist before the operation can be done
1605             OnapPDPGroup group = null;
1606             try {
1607                 group = papEngine.getGroup(groupId);
1608             } catch (PAPException e) {
1609                 LOGGER.error(e);
1610             }
1611             if (group == null) {
1612                 String message = "Unknown groupId '" + groupId + "'";
1613                 //for fixing Header Manipulation of Fortify issue
1614                 if (!message.matches(REGEX)) {
1615                     response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
1616                     response.addHeader("error", ADD_GROUP_ERROR);
1617                     response.addHeader("message", "GroupId Id is not valid");
1618                     return;
1619                 }
1620                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
1621                 loggingContext.transactionEnded();
1622                 PolicyLogger.audit("Transaction Failed - See Error.log");
1623                 if (apiflag != null) {
1624                     response.addHeader("error", "unknownGroupId");
1625                     response.addHeader("operation", "push");
1626                     response.addHeader("message", message);
1627                     response.setStatus(HttpServletResponse.SC_NOT_FOUND);
1628                 } else {
1629                     setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
1630                 }
1631                 return;
1632             }
1633
1634             // If the request contains a policyId then we know we are pushing the policy to PDP
1635             if (request.getParameter("policyId") != null) {
1636
1637                 if (apiflag != null) {
1638                     loggingContext.setServiceName("PolicyEngineAPI:PAP.postPolicy");
1639                     LOGGER.info("PushPolicy Request From The API");
1640                 } else {
1641                     loggingContext.setServiceName("AC:PAP.postPolicy");
1642                     LOGGER.info("PushPolicy Request From The AC");
1643                 }
1644
1645                 String policyId = request.getParameter("policyId");
1646                 PolicyDBDaoTransaction addPolicyToGroupTransaction = policyDBDao.getNewTransaction();
1647                 StdPDPGroup updatedGroup = null;
1648                 try {
1649                     //Copying the policy to the file system and updating groups in database
1650                     LOGGER.info("PapServlet: calling PolicyDBDao.addPolicyToGroup()");
1651                     updatedGroup = addPolicyToGroupTransaction
1652                             .addPolicyToGroup(group.getId(), policyId, "XACMLPapServlet.doACPost");
1653                     loggingContext.metricStarted();
1654                     addPolicyToGroupTransaction.commitTransaction();
1655                     loggingContext.metricEnded();
1656                     PolicyLogger.metrics("XACMLPapServlet doACPost commitTransaction");
1657                     LOGGER.info("PapServlet: addPolicyToGroup() succeeded, transaction was committed");
1658
1659                 } catch (Exception e) {
1660                     addPolicyToGroupTransaction.rollbackTransaction();
1661                     String message = "Policy '" + policyId + "' not copied to group '" + groupId + "': " + e;
1662                     //for fixing Header Manipulation of Fortify issue
1663                     if (!message.matches(REGEX)) {
1664                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
1665                         response.addHeader("error", ADD_GROUP_ERROR);
1666                         response.addHeader("message", "Policy Id is not valid");
1667                         return;
1668                     }
1669                     PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " " + message);
1670                     loggingContext.transactionEnded();
1671                     PolicyLogger.audit("Transaction Failed - See Error.log");
1672                     if (apiflag != null) {
1673                         response.addHeader("error", "policyCopyError");
1674                         response.addHeader("message", message);
1675                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
1676                     } else {
1677                         setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1678                     }
1679                     return;
1680                 }
1681
1682                 if (apiflag != null) {
1683                     /*
1684                      * If request comes from the API we need to run the PolicyDBDao updateGroup() to notify other
1685                      * paps of the change.
1686                      * The GUI does this from the POLICY-SDK-APP code.
1687                      */
1688
1689                     // Get new transaction to perform updateGroup()
1690                     PolicyDBDaoTransaction acPutTransaction = policyDBDao.getNewTransaction();
1691                     try {
1692                         // get the request content into a String and read the inputStream into a buffer
1693                         java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
1694                         scanner.useDelimiter("\\A");
1695                         String json = scanner.hasNext() ? scanner.next() : "";
1696                         scanner.close();
1697
1698                         // convert Object sent as JSON into local object
1699                         ObjectMapper mapper = new ObjectMapper();
1700                         Object objectFromJSON = mapper.readValue(json, StdPDPPolicy.class);
1701                         StdPDPPolicy policy = (StdPDPPolicy) objectFromJSON;
1702
1703                         LOGGER.info("Request JSON Payload: " + json);
1704
1705                         // Assume that this is an update of an existing PDP Group
1706                         loggingContext.setServiceName("PolicyEngineAPI:PAP.updateGroup");
1707                         try {
1708                             acPutTransaction.updateGroup(updatedGroup, "XACMLPapServlet.doACPut");
1709                         } catch (Exception e) {
1710                             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet",
1711                                     " Error occurred when notifying PAPs of a group change: "
1712                                             + e);
1713                             throw new PAPException(e.getMessage());
1714                         }
1715
1716                         LOGGER.info("Calling updatGroup() with new group");
1717                         papEngine.updateGroup(updatedGroup);
1718
1719                         LOGGER.info("Group '" + updatedGroup.getId() + "' updated");
1720
1721                         // Commit transaction to send notification to other PAPs
1722                         loggingContext.metricStarted();
1723                         acPutTransaction.commitTransaction();
1724                         loggingContext.metricEnded();
1725                         PolicyLogger.metrics("XACMLPapServlet updateGroupsFromAPI commitTransaction");
1726                         loggingContext.metricStarted();
1727
1728                         notifyAC();
1729                         loggingContext.metricEnded();
1730                         PolicyLogger.metrics("XACMLPapServlet updateGroupsFromAPI notifyAC");
1731
1732                         // Group changed to send notification to PDPs, which might include changing the policies
1733                         groupChanged(updatedGroup, loggingContext);
1734                         loggingContext.transactionEnded();
1735                         LOGGER.info("Success");
1736
1737                         if (policy != null && ((policy.getName().contains("Config_MS_")) ||
1738                                 (policy.getId().contains("BRMS_Param")))) {
1739                             PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance();
1740                             if (pushPolicyHandler.preSafetyCheck(policy, configHome)) {
1741                                 LOGGER.debug("Precheck Successful.");
1742                             }
1743                         }
1744
1745                         //delete temporary policy file from the bin directory
1746                         Files.deleteIfExists(Paths.get(policy.getId()));
1747
1748                     } catch (Exception e) {
1749                         acPutTransaction.rollbackTransaction();
1750                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " API PUT exception");
1751                         loggingContext.transactionEnded();
1752                         PolicyLogger.audit("Transaction Failed - See Error.log");
1753                         String message = XACMLErrorConstants.ERROR_PROCESS_FLOW +
1754                                 "Exception occurred when updating the group from API.";
1755                         LOGGER.error(message);
1756                         setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
1757                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
1758                         response.addHeader("error", ADD_GROUP_ERROR);
1759                         response.addHeader("message", message);
1760                         return;
1761                     }
1762                 }
1763
1764                 // policy file copied ok and the Group was updated on the PDP
1765                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1766                 response.addHeader("operation", "push");
1767                 response.addHeader("policyId", policyId);
1768                 response.addHeader("groupId", groupId);
1769
1770                 LOGGER.info("policy '" + policyId + "' copied to directory for group '" + groupId + "'");
1771                 loggingContext.transactionEnded();
1772                 auditLogger.info("Success");
1773                 LOGGER.info("Transaction Ended Successfully");
1774
1775             } else if (request.getParameter("default") != null) {
1776                 // Args:       group=<groupId> default=true               <= make default
1777                 // change the current default group to be the one identified in the request.
1778                 loggingContext.setServiceName("AC:PAP.setDefaultGroup");
1779                 // This is a POST operation rather than a PUT "update group" because of the side-effect that the
1780                 // current default group is also changed.
1781                 // It should never be the case that multiple groups are currently marked as the default, but protect
1782                 // against that anyway.
1783                 PolicyDBDaoTransaction setDefaultGroupTransaction = policyDBDao.getNewTransaction();
1784                 try {
1785                     setDefaultGroupTransaction.changeDefaultGroup(group, "XACMLPapServlet.doACPost");
1786                     papEngine.setDefaultGroup(group);
1787                     loggingContext.metricStarted();
1788                     setDefaultGroupTransaction.commitTransaction();
1789                     loggingContext.metricEnded();
1790                     PolicyLogger.metrics("XACMLPapServlet doACPost commitTransaction");
1791                 } catch (Exception e) {
1792                     setDefaultGroupTransaction.rollbackTransaction();
1793                     PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Unable to set group");
1794                     loggingContext.transactionEnded();
1795                     PolicyLogger.audit("Transaction Failed - See Error.log");
1796                     setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
1797                             "Unable to set group '" + groupId + "' to default");
1798                     return;
1799                 }
1800                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1801                 if (LOGGER.isDebugEnabled()) {
1802                     LOGGER.debug("Group '" + groupId + "' set to be default");
1803                 }
1804                 // Notify the Admin Consoles that something changed
1805                 // For now the AC cannot handle anything more detailed than the whole set of PDPGroups, so just
1806                 // notify on that
1807                 //TODO - Future: FIGURE OUT WHAT LEVEL TO NOTIFY: 2 groups or entire set - currently notify AC to
1808                 // update whole configuration of all groups
1809                 loggingContext.metricStarted();
1810                 notifyAC();
1811                 // This does not affect any PDPs in the existing groups, so no need to notify them of this change
1812                 loggingContext.metricEnded();
1813                 PolicyLogger.metrics("XACMLPapServlet doACPost notifyAC");
1814                 loggingContext.transactionEnded();
1815                 auditLogger.info("Success");
1816                 LOGGER.info("Transaction Ended Successfully");
1817             } else if (request.getParameter("pdpId") != null) {
1818                 doACPostTransaction = policyDBDao.getNewTransaction();
1819                 // Args:       group=<groupId> pdpId=<pdpId>               <= move PDP to group
1820                 loggingContext.setServiceName("AC:PAP.movePDP");
1821                 String pdpId = request.getParameter("pdpId");
1822                 OnapPDP pdp = papEngine.getPDP(pdpId);
1823                 OnapPDPGroup originalGroup = papEngine.getPDPGroup((OnapPDP) pdp);
1824                 try {
1825                     doACPostTransaction.movePdp(pdp, group, "XACMLPapServlet.doACPost");
1826                 } catch (Exception e) {
1827                     doACPostTransaction.rollbackTransaction();
1828                     PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet",
1829                             " Error while moving pdp in the database: "
1830                                     + "pdp=" + pdp.getId() + ",to group=" + group.getId());
1831                     throw new PAPException(e.getMessage());
1832                 }
1833                 papEngine.movePDP((OnapPDP) pdp, group);
1834                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1835                 if (LOGGER.isDebugEnabled()) {
1836                     LOGGER.debug("PDP '" + pdp.getId() + "' moved to group '" + group.getId() + "' set to be default");
1837                 }
1838                 // update the status of both the original group and the new one
1839                 ((StdPDPGroup) originalGroup).resetStatus();
1840                 ((StdPDPGroup) group).resetStatus();
1841                 // Notify the Admin Consoles that something changed
1842                 // For now the AC cannot handle anything more detailed than the whole set of PDPGroups, so just
1843                 // notify on that
1844                 loggingContext.metricStarted();
1845                 notifyAC();
1846                 loggingContext.metricEnded();
1847                 PolicyLogger.metrics("XACMLPapServlet doACPost notifyAC");
1848                 // Need to notify the PDP that it's config may have changed
1849                 pdpChanged(pdp, loggingContext);
1850                 loggingContext.metricStarted();
1851                 doACPostTransaction.commitTransaction();
1852                 loggingContext.metricEnded();
1853                 PolicyLogger.metrics("XACMLPapServlet doACPost commitTransaction");
1854                 loggingContext.transactionEnded();
1855                 auditLogger.info("Success");
1856                 PolicyLogger.audit("Transaction Ended Successfully");
1857             }
1858         } catch (PAPException e) {
1859             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC POST exception");
1860             loggingContext.transactionEnded();
1861             PolicyLogger.audit("Transaction Failed - See Error.log");
1862             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
1863         }
1864     }
1865
1866     /**
1867      * Requests from the Admin Console to GET info about the Groups and PDPs
1868      *
1869      * @param request
1870      * @param response
1871      * @param groupId
1872      * @param loggingContext
1873      * @throws ServletException
1874      * @throws IOException
1875      */
1876     private void doACGet(HttpServletRequest request, HttpServletResponse response, String groupId,
1877                          ONAPLoggingContext loggingContext) throws IOException {
1878         try {
1879             String parameterDefault = request.getParameter("default");
1880             String pdpId = request.getParameter("pdpId");
1881             String pdpGroup = request.getParameter("getPDPGroup");
1882             if ("".equals(groupId)) {
1883                 // request IS from AC but does not identify a group by name
1884                 if (parameterDefault != null) {
1885                     // Request is for the Default group (whatever its id)
1886                     loggingContext.setServiceName("AC:PAP.getDefaultGroup");
1887                     OnapPDPGroup group = papEngine.getDefaultGroup();
1888                     // convert response object to JSON and include in the response
1889                     mapperWriteValue(new ObjectMapper(), response, group);
1890                     if (LOGGER.isDebugEnabled()) {
1891                         LOGGER.debug("GET Default group req from '" + request.getRequestURL() + "'");
1892                     }
1893                     response.setStatus(HttpServletResponse.SC_OK);
1894                     response.setHeader("content-type", "application/json");
1895                     try {
1896                         response.getOutputStream().close();
1897                     } catch (IOException e) {
1898                         LOGGER.error(e);
1899                     }
1900                     loggingContext.transactionEnded();
1901                     auditLogger.info("Success");
1902                     PolicyLogger.audit("Transaction Ended Successfully");
1903                     return;
1904                 } else if (pdpId != null) {
1905                     // Request is related to a PDP
1906                     if (pdpGroup == null) {
1907                         // Request is for the (unspecified) group containing a given PDP
1908                         loggingContext.setServiceName("AC:PAP.getPDP");
1909                         OnapPDP pdp = null;
1910                         try {
1911                             pdp = papEngine.getPDP(pdpId);
1912                         } catch (PAPException e) {
1913                             LOGGER.error(e);
1914                         }
1915                         // convert response object to JSON and include in the response
1916                         mapperWriteValue(new ObjectMapper(), response, pdp);
1917                         if (LOGGER.isDebugEnabled()) {
1918                             LOGGER.debug("GET pdp '" + pdpId + "' req from '" + request.getRequestURL() + "'");
1919                         }
1920                         response.setStatus(HttpServletResponse.SC_OK);
1921                         response.setHeader("content-type", "application/json");
1922                         try {
1923                             response.getOutputStream().close();
1924                         } catch (IOException e) {
1925                             LOGGER.error(e);
1926                         }
1927                         loggingContext.transactionEnded();
1928                         auditLogger.info("Success");
1929                         PolicyLogger.audit("Transaction Ended Successfully");
1930                         return;
1931                     } else {
1932                         // Request is for the group containing a given PDP
1933                         loggingContext.setServiceName("AC:PAP.getGroupForPDP");
1934                         OnapPDPGroup group = null;
1935                         try {
1936                             OnapPDP pdp = papEngine.getPDP(pdpId);
1937                             group = papEngine.getPDPGroup((OnapPDP) pdp);
1938                         } catch (PAPException e) {
1939                             LOGGER.error(e);
1940                         }
1941                         // convert response object to JSON and include in the response
1942                         mapperWriteValue(new ObjectMapper(), response, group);
1943                         if (LOGGER.isDebugEnabled()) {
1944                             LOGGER.debug("GET PDP '" + pdpId + "' Group req from '" + request.getRequestURL() + "'");
1945                         }
1946                         response.setStatus(HttpServletResponse.SC_OK);
1947                         response.setHeader("content-type", "application/json");
1948                         try {
1949                             response.getOutputStream().close();
1950                         } catch (IOException e) {
1951                             LOGGER.error(e);
1952                         }
1953                         loggingContext.transactionEnded();
1954                         auditLogger.info("Success");
1955                         PolicyLogger.audit("Transaction Ended Successfully");
1956                         return;
1957                     }
1958                 } else {
1959                     // request is for top-level properties about all groups
1960                     loggingContext.setServiceName("AC:PAP.getAllGroups");
1961                     Set<OnapPDPGroup> groups = null;
1962                     try {
1963                         groups = papEngine.getOnapPDPGroups();
1964                     } catch (PAPException e) {
1965                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC Get exception");
1966                         loggingContext.transactionEnded();
1967                         PolicyLogger.audit("Transaction Failed - See Error.log");
1968                         setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
1969                         return;
1970                     }
1971                     // convert response object to JSON and include in the response
1972                     mapperWriteValue(new ObjectMapper(), response, groups);
1973                     if (LOGGER.isDebugEnabled()) {
1974                         LOGGER.debug("GET All groups req");
1975                     }
1976                     response.setStatus(HttpServletResponse.SC_OK);
1977                     response.setHeader("content-type", "application/json");
1978                     try {
1979                         response.getOutputStream().close();
1980                     } catch (IOException e) {
1981                         LOGGER.error(e);
1982                     }
1983                     loggingContext.transactionEnded();
1984                     auditLogger.info("Success");
1985                     PolicyLogger.audit("Transaction Ended Successfully");
1986                     return;
1987                 }
1988             }
1989             // for all other GET operations the group must exist before the operation can be done
1990             OnapPDPGroup group = null;
1991             try {
1992                 group = papEngine.getGroup(groupId);
1993             } catch (PAPException e) {
1994                 LOGGER.error(e);
1995             }
1996             if (group == null) {
1997                 String message = "Unknown groupId '" + groupId + "'";
1998                 //for fixing Header Manipulation of Fortify issue
1999                 if (!message.matches(REGEX)) {
2000                     response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
2001                     response.addHeader("error", ADD_GROUP_ERROR);
2002                     response.addHeader("message", "Group Id is not valid");
2003                     return;
2004                 }
2005                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
2006                 loggingContext.transactionEnded();
2007                 PolicyLogger.audit("Transaction Failed - See Error.log");
2008                 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
2009                 return;
2010             }
2011             // Figure out which request this is based on the parameters
2012             String policyId = request.getParameter("policyId");
2013             if (policyId != null) {
2014                 // retrieve a policy
2015                 loggingContext.setServiceName("AC:PAP.getPolicy");
2016                 // convert response object to JSON and include in the response
2017                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " GET Policy not implemented");
2018                 loggingContext.transactionEnded();
2019                 PolicyLogger.audit("Transaction Failed - See Error.log");
2020                 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "GET Policy not implemented");
2021             } else {
2022                 // No other parameters, so return the identified Group
2023                 loggingContext.setServiceName("AC:PAP.getGroup");
2024                 // convert response object to JSON and include in the response
2025                 mapperWriteValue(new ObjectMapper(), response, group);
2026                 if (LOGGER.isDebugEnabled()) {
2027                     LOGGER.debug("GET group '" + group.getId() + "' req from '" + request.getRequestURL() + "'");
2028                 }
2029                 response.setStatus(HttpServletResponse.SC_OK);
2030                 response.setHeader("content-type", "application/json");
2031                 try {
2032                     response.getOutputStream().close();
2033                 } catch (IOException e) {
2034                     LOGGER.error(e);
2035                 }
2036                 loggingContext.transactionEnded();
2037                 auditLogger.info("Success");
2038                 PolicyLogger.audit("Transaction Ended Successfully");
2039                 return;
2040             }
2041             // Currently there are no other GET calls from the AC.
2042             // The AC uses the "GET All Groups" operation to fill its local cache and uses that cache for all other
2043             // GETs without calling the PAP.
2044             // Other GETs that could be called:
2045             //                          Specific Group  (groupId=<groupId>)
2046             //                          A Policy                (groupId=<groupId> policyId=<policyId>)
2047             //                          A PDP                   (groupId=<groupId> pdpId=<pdpId>)
2048             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " UNIMPLEMENTED ");
2049             loggingContext.transactionEnded();
2050             PolicyLogger.audit("Transaction Failed - See Error.log");
2051             setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
2052         } catch (PAPException e) {
2053             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC Get exception");
2054             loggingContext.transactionEnded();
2055             PolicyLogger.audit("Transaction Failed - See Error.log");
2056             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
2057         }
2058     }
2059
2060     /**
2061      * Requests from the Admin Console to create new items or update existing ones
2062      *
2063      * @param request
2064      * @param response
2065      * @param groupId
2066      * @param loggingContext
2067      * @throws ServletException
2068      * @throws IOException
2069      */
2070     private void doACPut(HttpServletRequest request, HttpServletResponse response, String groupId,
2071                          ONAPLoggingContext loggingContext) throws IOException {
2072         PolicyDBDaoTransaction acPutTransaction = policyDBDao.getNewTransaction();
2073         try {
2074             // for PUT operations the group may or may not need to exist before the operation can be done
2075             OnapPDPGroup group = papEngine.getGroup(groupId);
2076             // determine the operation needed based on the parameters in the request
2077             // for remaining operations the group must exist before the operation can be done
2078             if (group == null) {
2079                 String message = "Unknown groupId '" + groupId + "'";
2080                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
2081                 loggingContext.transactionEnded();
2082                 PolicyLogger.audit("Transaction Failed - See Error.log");
2083                 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
2084                 return;
2085             }
2086             if (request.getParameter("policy") != null) {
2087                 //        group=<groupId> policy=<policyId> contents=policy file               <= Create new policy
2088                 // file in group dir, or replace it if it already exists (do not touch properties)
2089                 loggingContext.setServiceName("AC:PAP.putPolicy");
2090                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE +
2091                         " PARTIALLY IMPLEMENTED!!!  ACTUAL CHANGES SHOULD BE MADE BY PAP SERVLET!!! ");
2092                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
2093                 loggingContext.transactionEnded();
2094                 PolicyLogger.audit("Transaction Failed - See Error.log");
2095                 auditLogger.info("Success");
2096                 PolicyLogger.audit("Transaction Ended Successfully");
2097             } else if (request.getParameter("pdpId") != null) {
2098                 // ARGS:        group=<groupId> pdpId=<pdpId/URL>          <= create a new PDP or Update an Existing one
2099                 String pdpId = request.getParameter("pdpId");
2100                 if (papEngine.getPDP(pdpId) == null) {
2101                     loggingContext.setServiceName("AC:PAP.createPDP");
2102                 } else {
2103                     loggingContext.setServiceName("AC:PAP.updatePDP");
2104                 }
2105                 // get the request content into a String
2106                 String json = null;
2107                 // read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
2108                 try {
2109                     Scanner scanner = new Scanner(request.getInputStream());
2110                     scanner.useDelimiter("\\A");
2111                     json = scanner.hasNext() ? scanner.next() : "";
2112                     scanner.close();
2113                 } catch (IOException e) {
2114                     LOGGER.error(e);
2115                 }
2116                 LOGGER.info("JSON request from AC: " + json);
2117                 // convert Object sent as JSON into local object
2118                 ObjectMapper mapper = new ObjectMapper();
2119                 Object objectFromJSON = null;
2120                 try {
2121                     objectFromJSON = mapper.readValue(json, StdPDP.class);
2122                 } catch (Exception e) {
2123                     LOGGER.error(e);
2124                 }
2125                 if (pdpId == null ||
2126                         objectFromJSON == null ||
2127                         !(objectFromJSON instanceof StdPDP) ||
2128                         ((StdPDP) objectFromJSON).getId() == null ||
2129                         !((StdPDP) objectFromJSON).getId().equals(pdpId)) {
2130                     PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " PDP new/update had bad input. pdpId=" + pdpId +
2131                             " objectFromJSON=" + objectFromJSON);
2132                     loggingContext.transactionEnded();
2133                     PolicyLogger.audit("Transaction Failed - See Error.log");
2134                     setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
2135                             "Bad input pdpid for object:" + objectFromJSON);
2136                 }
2137                 StdPDP pdp = (StdPDP) objectFromJSON;
2138                 if (pdp != null) {
2139                     OnapPDP oPDP = null;
2140                     try {
2141                         oPDP = papEngine.getPDP(pdpId);
2142                     } catch (PAPException e) {
2143                         LOGGER.error(e);
2144                     }
2145                     if (oPDP == null) {
2146                         // this is a request to create a new PDP object
2147                         try {
2148                             acPutTransaction.addPdpToGroup(pdp.getId(), group.getId(), pdp.getName(),
2149                                     pdp.getDescription(), pdp.getJmxPort(), "XACMLPapServlet.doACPut");
2150                         } catch (Exception e) {
2151                             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet",
2152                                     " Error while adding pdp to group in the database: "
2153                                             + "pdp=" + (pdp.getId()) + ",to group=" + group.getId());
2154                             throw new PAPException(e.getMessage());
2155                         }
2156                         try {
2157                             papEngine.newPDP(pdp.getId(), group, pdp.getName(), pdp.getDescription(), pdp.getJmxPort());
2158                         } catch (PAPException e) {
2159                             LOGGER.error(e);
2160                         }
2161                     } else {
2162                         try {
2163                             acPutTransaction.updatePdp(pdp, "XACMLPapServlet.doACPut");
2164                         } catch (Exception e) {
2165                             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet",
2166                                     " Error while updating pdp in the database: "
2167                                             + "pdp=" + pdp.getId());
2168                             throw new PAPException(e.getMessage());
2169                         }
2170                         // this is a request to update the pdp
2171                         try {
2172                             papEngine.updatePDP(pdp);
2173                         } catch (PAPException e) {
2174                             LOGGER.error(e);
2175                         }
2176                     }
2177                     response.setStatus(HttpServletResponse.SC_NO_CONTENT);
2178                     if (LOGGER.isDebugEnabled()) {
2179                         LOGGER.debug("PDP '" + pdpId + "' created/updated");
2180                     }
2181                     // adjust the group's state including the new PDP
2182                     ((StdPDPGroup) group).resetStatus();
2183                     // tell the Admin Consoles there is a change
2184                     loggingContext.metricStarted();
2185                     notifyAC();
2186                     loggingContext.metricEnded();
2187                     PolicyLogger.metrics("XACMLPapServlet doACPut notifyAC");
2188                     // this might affect the PDP, so notify it of the change
2189                     pdpChanged(pdp, loggingContext);
2190                     loggingContext.metricStarted();
2191                     acPutTransaction.commitTransaction();
2192                     loggingContext.metricEnded();
2193                     PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
2194                     loggingContext.transactionEnded();
2195                     auditLogger.info("Success");
2196                     PolicyLogger.audit("Transaction Ended Successfully");
2197                 } else {
2198                     try {
2199                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "XACMLPapServlet",
2200                                 " Error while adding pdp to group in the database: "
2201                                         + "pdp=null" + ",to group=" + group.getId());
2202                         throw new PAPException("PDP is null");
2203                     } catch (Exception e) {
2204                         throw new PAPException("PDP is null" + e.getMessage() + e);
2205                     }
2206                 }
2207             } else if (request.getParameter("pipId") != null) {
2208                 //                group=<groupId> pipId=<pipEngineId> contents=pip properties              <= add a
2209                 // PIP to pip config, or replace it if it already exists (lenient operation)
2210                 loggingContext.setServiceName("AC:PAP.putPIP");
2211                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
2212                 loggingContext.transactionEnded();
2213                 PolicyLogger.audit("Transaction Failed - See Error.log");
2214                 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
2215             } else {
2216                 // Assume that this is an update of an existing PDP Group
2217                 // ARGS:        group=<groupId>         <= Update an Existing Group
2218                 loggingContext.setServiceName("AC:PAP.updateGroup");
2219                 // get the request content into a String
2220                 String json = null;
2221                 // read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
2222                 try {
2223                     Scanner scanner = new Scanner(request.getInputStream());
2224                     scanner.useDelimiter("\\A");
2225                     json = scanner.hasNext() ? scanner.next() : "";
2226                     scanner.close();
2227                 } catch (IOException e) {
2228                     LOGGER.error(e);
2229                 }
2230                 LOGGER.info("JSON request from AC: " + json);
2231                 // convert Object sent as JSON into local object
2232                 ObjectMapper mapper = new ObjectMapper();
2233                 Object objectFromJSON = null;
2234                 try {
2235                     objectFromJSON = mapper.readValue(json, StdPDPGroup.class);
2236                 } catch (Exception e) {
2237                     LOGGER.error(e);
2238                 }
2239                 if (objectFromJSON == null || !(objectFromJSON instanceof StdPDPGroup) ||
2240                         !((StdPDPGroup) objectFromJSON).getId().equals(group.getId())) {
2241                     PolicyLogger
2242                             .error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id=" + group.getId() +
2243                                     " objectFromJSON=" + objectFromJSON);
2244                     loggingContext.transactionEnded();
2245                     PolicyLogger.audit("Transaction Failed - See Error.log");
2246                     setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
2247                             "Bad input id for object:" + objectFromJSON);
2248                 }
2249                 // The Path on the PAP side is not carried on the RESTful interface with the AC
2250                 // (because it is local to the PAP)
2251                 // so we need to fill that in before submitting the group for update
2252                 if (objectFromJSON != null) {
2253                     ((StdPDPGroup) objectFromJSON).setDirectory(((StdPDPGroup) group).getDirectory());
2254                 }
2255                 try {
2256                     if ("delete".equals(((StdPDPGroup) objectFromJSON).getOperation())) {
2257                         acPutTransaction.updateGroup((StdPDPGroup) objectFromJSON, "XACMLPapServlet.doDelete");
2258                     } else {
2259                         acPutTransaction.updateGroup((StdPDPGroup) objectFromJSON, "XACMLPapServlet.doACPut");
2260                     }
2261                 } catch (Exception e) {
2262                     PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database: "
2263                             + "group=" + group.getId());
2264                     LOGGER.error(e);
2265                     throw new PAPException(e.getMessage());
2266                 }
2267
2268                 PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance();
2269                 OnapPDPGroup updatedGroup = (StdPDPGroup) objectFromJSON;
2270                 if (pushPolicyHandler.preSafetyCheck(updatedGroup, configHome)) {
2271                     LOGGER.debug("Precheck Successful.");
2272                 }
2273                 try {
2274                     papEngine.updateGroup((StdPDPGroup) objectFromJSON);
2275                 } catch (PAPException e) {
2276                     LOGGER.error(e);
2277                 }
2278                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
2279                 if (LOGGER.isDebugEnabled()) {
2280                     LOGGER.debug("Group '" + group.getId() + "' updated");
2281                 }
2282                 loggingContext.metricStarted();
2283                 acPutTransaction.commitTransaction();
2284                 loggingContext.metricEnded();
2285                 PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
2286                 // tell the Admin Consoles there is a change
2287                 loggingContext.metricStarted();
2288                 notifyAC();
2289                 loggingContext.metricEnded();
2290                 PolicyLogger.metrics("XACMLPapServlet doACPut notifyAC");
2291                 // Group changed, which might include changing the policies
2292                 groupChanged(group, loggingContext);
2293                 loggingContext.transactionEnded();
2294                 auditLogger.info("Success");
2295                 PolicyLogger.audit("Transaction Ended Successfully");
2296             }
2297         } catch (PAPException e) {
2298             LOGGER.debug(e);
2299             acPutTransaction.rollbackTransaction();
2300             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC PUT exception");
2301             loggingContext.transactionEnded();
2302             PolicyLogger.audit("Transaction Failed - See Error.log");
2303             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
2304         }
2305     }
2306
2307     /**
2308      * Requests from the Admin Console to delete/remove items
2309      *
2310      * @param request
2311      * @param response
2312      * @param groupId
2313      * @param loggingContext
2314      * @throws ServletException
2315      * @throws IOException
2316      */
2317     private void doACDelete(HttpServletRequest request, HttpServletResponse response, String groupId,
2318                             ONAPLoggingContext loggingContext) throws IOException {
2319         PolicyDBDaoTransaction removePdpOrGroupTransaction = policyDBDao.getNewTransaction();
2320         try {
2321             // for all DELETE operations the group must exist before the operation can be done
2322             loggingContext.setServiceName("AC:PAP.delete");
2323             OnapPDPGroup group = papEngine.getGroup(groupId);
2324             if (group == null) {
2325                 String message = "Unknown groupId '" + groupId + "'";
2326                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
2327                 loggingContext.transactionEnded();
2328                 PolicyLogger.audit("Transaction Failed - See Error.log");
2329                 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId + "'");
2330                 return;
2331             }
2332             // determine the operation needed based on the parameters in the request
2333             if (request.getParameter("policy") != null) {
2334                 //        group=<groupId> policy=<policyId>  [delete=<true|false>]       <= delete policy file from
2335                 // group
2336                 loggingContext.setServiceName("AC:PAP.deletePolicy");
2337                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
2338                 loggingContext.transactionEnded();
2339                 PolicyLogger.audit("Transaction Failed - See Error.log");
2340                 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
2341             } else if (request.getParameter("pdpId") != null) {
2342                 // ARGS:        group=<groupId> pdpId=<pdpId>                  <= delete PDP
2343                 String pdpId = request.getParameter("pdpId");
2344                 OnapPDP pdp = papEngine.getPDP(pdpId);
2345                 try {
2346                     removePdpOrGroupTransaction.removePdpFromGroup(pdp.getId(), "XACMLPapServlet.doACDelete");
2347                 } catch (Exception e) {
2348                     throw new PAPException(e);
2349                 }
2350                 try {
2351                     papEngine.removePDP((OnapPDP) pdp);
2352                 } catch (PAPException e) {
2353                     LOGGER.error(e);
2354                 }
2355                 // adjust the status of the group, which may have changed when we removed this PDP
2356                 ((StdPDPGroup) group).resetStatus();
2357                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
2358                 loggingContext.metricStarted();
2359                 notifyAC();
2360                 loggingContext.metricEnded();
2361                 PolicyLogger.metrics("XACMLPapServlet doACPut notifyAC");
2362                 // update the PDP and tell it that it has NO Policies (which prevents it from serving PEP Requests)
2363                 pdpChanged(pdp, loggingContext);
2364                 loggingContext.metricStarted();
2365                 removePdpOrGroupTransaction.commitTransaction();
2366                 loggingContext.metricEnded();
2367                 PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
2368                 loggingContext.transactionEnded();
2369                 auditLogger.info("Success");
2370                 PolicyLogger.audit("Transaction Ended Successfully");
2371             } else if (request.getParameter("pipId") != null) {
2372                 //        group=<groupId> pipId=<pipEngineId> <= delete PIP config for given engine
2373                 loggingContext.setServiceName("AC:PAP.deletePIPConfig");
2374                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
2375                 loggingContext.transactionEnded();
2376                 PolicyLogger.audit("Transaction Failed - See Error.log");
2377                 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
2378             } else {
2379                 // ARGS:      group=<groupId> movePDPsToGroupId=<movePDPsToGroupId>            <= delete a group and
2380                 // move all its PDPs to the given group
2381                 String moveToGroupId = request.getParameter("movePDPsToGroupId");
2382                 OnapPDPGroup moveToGroup = null;
2383                 if (moveToGroupId != null) {
2384                     try {
2385                         moveToGroup = papEngine.getGroup(moveToGroupId);
2386                     } catch (PAPException e) {
2387                         LOGGER.error(e);
2388                     }
2389                 }
2390                 // get list of PDPs in the group being deleted so we can notify them that they got changed
2391                 Set<OnapPDP> movedPDPs = new HashSet<>();
2392                 movedPDPs.addAll(group.getOnapPdps());
2393                 // do the move/remove
2394                 try {
2395                     removePdpOrGroupTransaction.deleteGroup(group, moveToGroup, "XACMLPapServlet.doACDelete");
2396                 } catch (Exception e) {
2397                     PolicyLogger.error(MessageCodes.ERROR_UNKNOWN, e, "XACMLPapServlet",
2398                             " Failed to delete PDP Group. Exception");
2399                     throw new PAPException(e.getMessage());
2400                 }
2401                 try {
2402                     papEngine.removeGroup(group, moveToGroup);
2403                 } catch (PAPException e) {
2404                     LOGGER.error(e);
2405                 }
2406                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
2407                 loggingContext.metricStarted();
2408                 notifyAC();
2409                 loggingContext.metricEnded();
2410                 PolicyLogger.metrics("XACMLPapServlet doACPut notifyAC");
2411                 // notify any PDPs in the removed set that their config may have changed
2412                 for (OnapPDP pdp : movedPDPs) {
2413                     pdpChanged(pdp, loggingContext);
2414                 }
2415                 loggingContext.metricStarted();
2416                 removePdpOrGroupTransaction.commitTransaction();
2417                 loggingContext.metricEnded();
2418                 PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
2419                 loggingContext.transactionEnded();
2420                 auditLogger.info("Success");
2421                 PolicyLogger.audit("Transaction Ended Successfully");
2422             }
2423         } catch (PAPException e) {
2424             removePdpOrGroupTransaction.rollbackTransaction();
2425             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC DELETE exception");
2426             loggingContext.transactionEnded();
2427             PolicyLogger.audit("Transaction Failed - See Error.log");
2428             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
2429         }
2430     }
2431
2432     /**
2433      * Heartbeat thread - periodically check on PDPs' status
2434      * <p>
2435      * Heartbeat with all known PDPs.
2436      * <p>
2437      * Implementation note:
2438      * <p>
2439      * The PDPs are contacted Sequentially, not in Parallel.
2440      * <p>
2441      * If we did this in parallel using multiple threads we would simultaneously use
2442      * - 1 thread and
2443      * - 1 connection
2444      * for EACH PDP.
2445      * This could become a resource problem since we already use multiple threads and connections for updating the PDPs
2446      * when user changes occur.
2447      * Using separate threads can also make it tricky dealing with timeouts on PDPs that are non-responsive.
2448      * <p>
2449      * The Sequential operation does a heartbeat request to each PDP one at a time.
2450      * This has the flaw that any PDPs that do not respond will hold up the entire heartbeat sequence until they
2451      * timeout.
2452      * If there are a lot of non-responsive PDPs and the timeout is large-ish (the default is 20 seconds)
2453      * it could take a long time to cycle through all of the PDPs.
2454      * That means that this may not notice a PDP being down in a predictable time.
2455      */
2456     private class Heartbeat implements Runnable {
2457         private PAPPolicyEngine papEngine;
2458         private Set<OnapPDP> pdps = new HashSet<>();
2459         private int heartbeatInterval;
2460         private int heartbeatTimeout;
2461
2462         public volatile boolean isRunning = false;
2463
2464         public synchronized boolean isRunning() {
2465             return this.isRunning;
2466         }
2467
2468         public synchronized void terminate() {
2469             this.isRunning = false;
2470         }
2471
2472         public Heartbeat(PAPPolicyEngine papEngine2) {
2473             papEngine = papEngine2;
2474             this.heartbeatInterval = Integer.parseInt(
2475                     XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_HEARTBEAT_INTERVAL, "10000"));
2476             this.heartbeatTimeout = Integer.parseInt(
2477                     XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_HEARTBEAT_TIMEOUT, "10000"));
2478         }
2479
2480         @Override
2481         public void run() {
2482             // Set ourselves as running
2483             synchronized (this) {
2484                 this.isRunning = true;
2485             }
2486             HashMap<String, URL> idToURLMap = new HashMap<>();
2487             try {
2488                 while (this.isRunning()) {
2489                     // Wait the given time
2490                     Thread.sleep(heartbeatInterval);
2491                     // get the list of PDPs (may have changed since last time)
2492                     pdps.clear();
2493                     synchronized (papEngine) {
2494                         try {
2495                             for (OnapPDPGroup g : papEngine.getOnapPDPGroups()) {
2496                                 for (OnapPDP p : g.getOnapPdps()) {
2497                                     pdps.add(p);
2498                                 }
2499                             }
2500                         } catch (PAPException e) {
2501                             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet",
2502                                     "Heartbeat unable to read PDPs from PAPEngine");
2503                         }
2504                     }
2505                     // Check for shutdown
2506                     if (this.isRunning() == false) {
2507                         LOGGER.info("isRunning is false, getting out of loop.");
2508                         break;
2509                     }
2510                     // try to get the summary status from each PDP
2511                     boolean changeSeen = false;
2512                     for (OnapPDP pdp : pdps) {
2513                         // Check for shutdown
2514                         if (this.isRunning() == false) {
2515                             LOGGER.info("isRunning is false, getting out of loop.");
2516                             break;
2517                         }
2518                         // the id of the PDP is its url (though we add a query parameter)
2519                         URL pdpURL = idToURLMap.get(pdp.getId());
2520                         if (pdpURL == null) {
2521                             // haven't seen this PDP before
2522                             String fullURLString = null;
2523                             try {
2524                                 // Check PDP ID
2525                                 if (CheckPDP.validateID(pdp.getId())) {
2526                                     fullURLString = pdp.getId() + "?type=hb";
2527                                     pdpURL = new URL(fullURLString);
2528                                     idToURLMap.put(pdp.getId(), pdpURL);
2529                                 }
2530                             } catch (MalformedURLException e) {
2531                                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPapServlet",
2532                                         " PDP id '" + fullURLString + "' is not a valid URL");
2533                                 continue;
2534                             }
2535                         }
2536                         // Do a GET with type HeartBeat
2537                         String newStatus = "";
2538                         HttpURLConnection connection = null;
2539                         try {
2540                             // Open up the connection
2541                             if (pdpURL != null) {
2542                                 connection = (HttpURLConnection) pdpURL.openConnection();
2543                                 // Setup our method and headers
2544                                 connection.setRequestMethod("GET");
2545                                 connection.setConnectTimeout(heartbeatTimeout);
2546                                 // Authentication
2547                                 String encoding = CheckPDP.getEncoding(pdp.getId());
2548                                 if (encoding != null) {
2549                                     connection.setRequestProperty("Authorization", "Basic " + encoding);
2550                                 }
2551                                 // Do the connect
2552                                 connection.connect();
2553                                 if (connection.getResponseCode() == 204) {
2554                                     newStatus = connection.getHeaderField(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB);
2555                                     if (LOGGER.isDebugEnabled()) {
2556                                         LOGGER.debug("Heartbeat '" + pdp.getId() + "' status='" + newStatus + "'");
2557                                     }
2558                                 } else {
2559                                     // anything else is an unexpected result
2560                                     newStatus = PDPStatus.Status.UNKNOWN.toString();
2561                                     PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR +
2562                                             " Heartbeat connect response code " + connection.getResponseCode() + ": " +
2563                                             pdp.getId());
2564                                 }
2565                             }
2566                         } catch (UnknownHostException e) {
2567                             newStatus = PDPStatus.Status.NO_SUCH_HOST.toString();
2568                             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet",
2569                                     " Heartbeat '" + pdp.getId() + "' NO_SUCH_HOST");
2570                         } catch (SocketTimeoutException e) {
2571                             newStatus = PDPStatus.Status.CANNOT_CONNECT.toString();
2572                             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet",
2573                                     " Heartbeat '" + pdp.getId() + "' connection timeout");
2574                         } catch (ConnectException e) {
2575                             newStatus = PDPStatus.Status.CANNOT_CONNECT.toString();
2576                             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet",
2577                                     " Heartbeat '" + pdp.getId() + "' cannot connect");
2578                         } catch (Exception e) {
2579                             newStatus = PDPStatus.Status.UNKNOWN.toString();
2580                             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet",
2581                                     "Heartbeat '" + pdp.getId() + "' connect exception");
2582                         } finally {
2583                             // cleanup the connection
2584                             if (connection != null)
2585                                 connection.disconnect();
2586                         }
2587                         if (!pdp.getStatus().getStatus().toString().equals(newStatus)) {
2588                             if (LOGGER.isDebugEnabled()) {
2589                                 LOGGER.debug("previous status='" + pdp.getStatus().getStatus() + "'  new Status='" +
2590                                         newStatus + "'");
2591                             }
2592                             try {
2593                                 setPDPSummaryStatus(pdp, newStatus);
2594                             } catch (PAPException e) {
2595                                 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet",
2596                                         "Unable to set state for PDP '" + pdp.getId());
2597                             }
2598                             changeSeen = true;
2599                         }
2600                     }
2601                     // Check for shutdown
2602                     if (this.isRunning() == false) {
2603                         LOGGER.info("isRunning is false, getting out of loop.");
2604                         break;
2605                     }
2606                     // if any of the PDPs changed state, tell the ACs to update
2607                     if (changeSeen) {
2608                         notifyAC();
2609                     }
2610                 }
2611             } catch (InterruptedException e) {
2612                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " Heartbeat interrupted.  Shutting down");
2613                 this.terminate();
2614                 Thread.currentThread().interrupt();
2615             }
2616         }
2617     }
2618
2619     /*
2620      * HELPER to change Group status when PDP status is changed
2621      * (Must NOT be called from a method that is synchronized on the papEngine or it may deadlock)
2622      */
2623     private void setPDPSummaryStatus(OnapPDP pdp, PDPStatus.Status newStatus) throws PAPException {
2624         setPDPSummaryStatus(pdp, newStatus.toString());
2625     }
2626
2627     private void setPDPSummaryStatus(OnapPDP pdp, String newStatus) throws PAPException {
2628         synchronized (papEngine) {
2629             StdPDPStatus status = new StdPDPStatus();
2630             status.setStatus(PDPStatus.Status.valueOf(newStatus));
2631             ((StdPDP) pdp).setStatus(status);
2632             // now adjust the group
2633             StdPDPGroup group = (StdPDPGroup) papEngine.getPDPGroup((OnapPDP) pdp);
2634             // if the PDP was just deleted it may transiently exist but not be in a group
2635             if (group != null) {
2636                 group.resetStatus();
2637             }
2638         }
2639     }
2640
2641     /*
2642      * Callback methods telling this servlet to notify PDPs of changes made by the PAP StdEngine
2643      * in the PDP group directories
2644      */
2645     @Override
2646     public void changed() {
2647         // all PDPs in all groups need to be updated/sync'd
2648         Set<OnapPDPGroup> groups;
2649         try {
2650             groups = papEngine.getOnapPDPGroups();
2651         } catch (PAPException e) {
2652             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " getPDPGroups failed");
2653             throw new IllegalAccessError(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get Groups: " + e);
2654         }
2655         for (OnapPDPGroup group : groups) {
2656             groupChanged(group);
2657         }
2658     }
2659
2660     public void changed(ONAPLoggingContext loggingContext) {
2661         // all PDPs in all groups need to be updated/sync'd
2662         Set<OnapPDPGroup> groups;
2663         try {
2664             groups = papEngine.getOnapPDPGroups();
2665         } catch (PAPException e) {
2666             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " getPDPGroups failed");
2667             throw new IllegalAccessError(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get Groups: " + e);
2668         }
2669         for (OnapPDPGroup group : groups) {
2670             groupChanged(group, loggingContext);
2671         }
2672     }
2673
2674     @Override
2675     public void groupChanged(OnapPDPGroup group) {
2676         // all PDPs within one group need to be updated/sync'd
2677         for (OnapPDP pdp : group.getOnapPdps()) {
2678             pdpChanged(pdp);
2679         }
2680     }
2681
2682     public void groupChanged(OnapPDPGroup group, ONAPLoggingContext loggingContext) {
2683         // all PDPs within one group need to be updated/sync'd
2684         for (OnapPDP pdp : group.getOnapPdps()) {
2685             pdpChanged(pdp, loggingContext);
2686         }
2687     }
2688
2689     @Override
2690     public void pdpChanged(OnapPDP pdp) {
2691         // kick off a thread to do an event notification for each PDP.
2692         // This needs to be on a separate thread so that PDPs that do not respond (down, non-existent, etc)
2693         // do not block the PSP response to the AC, which would freeze the GUI until all PDPs sequentially respond or
2694         // time-out.
2695         Thread t = new Thread(new UpdatePDPThread(pdp));
2696         if (CheckPDP.validateID(pdp.getId())) {
2697             t.start();
2698         }
2699     }
2700
2701     public void pdpChanged(OnapPDP pdp, ONAPLoggingContext loggingContext) {
2702         // kick off a thread to do an event notification for each PDP.
2703         // This needs to be on a separate thread so that PDPs that do not respond (down, non-existent, etc)
2704         // do not block the PSP response to the AC, which would freeze the GUI until all PDPs sequentially respond or
2705         // time-out.
2706         Thread t = new Thread(new UpdatePDPThread(pdp, loggingContext));
2707         if (CheckPDP.validateID(pdp.getId())) {
2708             t.start();
2709         }
2710     }
2711
2712     private class UpdatePDPThread implements Runnable {
2713         private OnapPDP pdp;
2714         private String requestId;
2715         private ONAPLoggingContext loggingContext;
2716
2717         public UpdatePDPThread(OnapPDP pdp) {
2718             this.pdp = pdp;
2719         }
2720
2721         public UpdatePDPThread(OnapPDP pdp, ONAPLoggingContext loggingContext) {
2722             this.pdp = pdp;
2723             if ((loggingContext != null) && (loggingContext.getRequestID() != null ||
2724                     Objects.equals(loggingContext.getRequestID(), ""))) {
2725                 this.requestId = loggingContext.getRequestID();
2726             }
2727             this.loggingContext = loggingContext;
2728         }
2729
2730         public void run() {
2731             // send the current configuration to one PDP
2732             HttpURLConnection connection = null;
2733             // get a new logging context for the thread
2734             try {
2735                 if (this.loggingContext == null) {
2736                     loggingContext = new ONAPLoggingContext(baseLoggingContext);
2737                 }
2738             } catch (Exception e) {
2739                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet",
2740                         " Failed to send property file to " + pdp.getId());
2741                 // Since this is a server-side error, it probably does not reflect a problem on the client,
2742                 // so do not change the PDP status.
2743                 return;
2744             }
2745             try {
2746                 loggingContext.setServiceName("PAP:PDP.putConfig");
2747                 // If a requestId was provided, use it, otherwise generate one; post to loggingContext to be used
2748                 // later when calling PDP
2749                 if ((requestId == null) || (Objects.equals(requestId, ""))) {
2750                     UUID requestID = UUID.randomUUID();
2751                     loggingContext.setRequestID(requestID.toString());
2752                     PolicyLogger
2753                             .info("requestID not provided in call to XACMLPapSrvlet (UpdatePDPThread) so we generated" +
2754                                     " one:  " +
2755                                     loggingContext.getRequestID());
2756                 } else {
2757                     loggingContext.setRequestID(requestId);
2758                     PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (UpdatePDPThread):  " +
2759                             loggingContext.getRequestID());
2760                 }
2761                 loggingContext.transactionStarted();
2762                 // the Id of the PDP is its URL
2763                 if (LOGGER.isDebugEnabled()) {
2764                     LOGGER.debug("creating url for id '" + pdp.getId() + "'");
2765                 }
2766                 //TODO - currently always send both policies and pips.  Do we care enough to add code to allow
2767                 // sending just one or the other?
2768                 //TODO          (need to change "cache=", implying getting some input saying which to change)
2769                 URL url = new URL(pdp.getId() + "?cache=all");
2770                 // Open up the connection
2771                 connection = (HttpURLConnection) url.openConnection();
2772                 // Setup our method and headers
2773                 connection.setRequestMethod("PUT");
2774                 // Authentication
2775                 String encoding = CheckPDP.getEncoding(pdp.getId());
2776                 if (encoding != null) {
2777                     connection.setRequestProperty("Authorization", "Basic " + encoding);
2778                 }
2779                 connection.setRequestProperty("Content-Type", "text/x-java-properties");
2780                 connection.setRequestProperty("X-ECOMP-RequestID", loggingContext.getRequestID());
2781                 connection.setInstanceFollowRedirects(true);
2782                 connection.setDoOutput(true);
2783                 try (OutputStream os = connection.getOutputStream()) {
2784                     OnapPDPGroup group = papEngine.getPDPGroup((OnapPDP) pdp);
2785                     // if the PDP was just deleted, there is no group, but we want to send an update anyway
2786                     if (group == null) {
2787                         // create blank properties files
2788                         Properties policyProperties = new Properties();
2789                         policyProperties.put(XACMLProperties.PROP_ROOTPOLICIES, "");
2790                         policyProperties.put(XACMLProperties.PROP_REFERENCEDPOLICIES, "");
2791                         policyProperties.store(os, "");
2792                         Properties pipProps = new Properties();
2793                         pipProps.setProperty(XACMLProperties.PROP_PIP_ENGINES, "");
2794                         pipProps.store(os, "");
2795                     } else {
2796                         // send properties from the current group
2797                         group.getPolicyProperties().store(os, "");
2798                         Properties policyLocations = new Properties();
2799                         for (PDPPolicy policy : group.getPolicies()) {
2800                             policyLocations
2801                                     .put(policy.getId() + ".url", XACMLPapServlet.papURL + "?id=" + policy.getId());
2802                         }
2803                         policyLocations.store(os, "");
2804                         group.getPipConfigProperties().store(os, "");
2805                     }
2806                 } catch (Exception e) {
2807                     PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet",
2808                             " Failed to send property file to " + pdp.getId());
2809                     // Since this is a server-side error, it probably does not reflect a problem on the client,
2810                     // so do not change the PDP status.
2811                     return;
2812                 }
2813                 // Do the connect
2814                 loggingContext.metricStarted();
2815                 connection.connect();
2816                 loggingContext.metricEnded();
2817                 PolicyLogger.metrics("XACMLPapServlet UpdatePDPThread connection connect");
2818                 if (connection.getResponseCode() == 204) {
2819                     LOGGER.info("Success. We are configured correctly.");
2820                     loggingContext.transactionEnded();
2821                     auditLogger.info("Success. PDP is configured correctly.");
2822                     PolicyLogger.audit("Transaction Success. PDP is configured correctly.");
2823                     setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE);
2824                 } else if (connection.getResponseCode() == 200) {
2825                     LOGGER.info("Success. PDP needs to update its configuration.");
2826                     loggingContext.transactionEnded();
2827                     auditLogger.info("Success. PDP needs to update its configuration.");
2828                     PolicyLogger.audit("Transaction Success. PDP is configured correctly.");
2829                     setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH);
2830                 } else {
2831                     LOGGER.warn("Failed: " + connection.getResponseCode() + "  message: " +
2832                             connection.getResponseMessage());
2833                     loggingContext.transactionEnded();
2834                     auditLogger.warn("Failed: " + connection.getResponseCode() + "  message: " +
2835                             connection.getResponseMessage());
2836                     PolicyLogger.audit("Transaction Failed: " + connection.getResponseCode() + "  message: " +
2837                             connection.getResponseMessage());
2838                     setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN);
2839                 }
2840             } catch (Exception e) {
2841                 LOGGER.debug(e);
2842                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet",
2843                         " Unable to sync config with PDP '" + pdp.getId() + "'");
2844                 loggingContext.transactionEnded();
2845                 PolicyLogger.audit("Transaction Failed: Unable to sync config with PDP '" + pdp.getId() + "': " + e);
2846                 try {
2847                     setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN);
2848                 } catch (PAPException e1) {
2849                     LOGGER.debug(e1);
2850                     PolicyLogger
2851                             .audit("Transaction Failed: Unable to set status of PDP " + pdp.getId() + " to UNKNOWN: " +
2852                                     e);
2853                     PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet",
2854                             " Unable to set status of PDP '" + pdp.getId() + "' to UNKNOWN");
2855                 }
2856             } finally {
2857                 // cleanup the connection
2858                 if (connection != null) {
2859                     connection.disconnect();
2860                 }
2861                 // tell the AC to update it's status info
2862                 notifyAC();
2863             }
2864         }
2865     }
2866
2867     /*
2868      * RESTful Interface from PAP to ACs notifying them of changes
2869      */
2870     private void notifyAC() {
2871         // kick off a thread to do one event notification for all registered ACs
2872         // This needs to be on a separate thread so that ACs can make calls back to PAP to get the updated Group data
2873         // as part of processing this message on their end.
2874         Thread t = new Thread(new NotifyACThread());
2875         t.start();
2876     }
2877
2878     private class NotifyACThread implements Runnable {
2879         public void run() {
2880             List<String> disconnectedACs = new ArrayList<>();
2881             // There should be no Concurrent exception here because the list is a CopyOnWriteArrayList.
2882             // The "for each" loop uses the collection's iterator under the covers, so it should be correct.
2883             for (String acURL : adminConsoleURLStringList) {
2884                 HttpURLConnection connection = null;
2885                 try {
2886                     acURL += "?PAPNotification=true";
2887                     //TODO - Currently we just tell AC that "Something changed" without being specific.  Do we want
2888                     // to tell it which group/pdp changed?
2889                     //TODO - If so, put correct parameters into the Query string here
2890                     acURL += "&objectType=all" + "&action=update";
2891                     if (LOGGER.isDebugEnabled()) {
2892                         LOGGER.debug("creating url for id '" + acURL + "'");
2893                     }
2894                     //TODO - currently always send both policies and pips.  Do we care enough to add code to allow
2895                     // sending just one or the other?
2896                     //TODO              (need to change "cache=", implying getting some input saying which to change)
2897                     URL url = new URL(acURL);
2898                     // Open up the connection
2899                     connection = (HttpURLConnection) url.openConnection();
2900                     // Setup our method and headers
2901                     connection.setRequestMethod("PUT");
2902                     connection.setRequestProperty("Content-Type", "text/x-java-properties");
2903                     // Adding this in. It seems the HttpUrlConnection class does NOT
2904                     // properly forward our headers for POST re-direction. It does so
2905                     // for a GET re-direction.
2906                     // So we need to handle this ourselves.
2907                     //TODO - is this needed for a PUT?  seems better to leave in for now?
2908                     connection.setInstanceFollowRedirects(false);
2909                     // Do not include any data in the PUT because this is just a
2910                     // notification to the AC.
2911                     // The AC will use GETs back to the PAP to get what it needs
2912                     // to fill in the screens.
2913                     // Do the connect
2914                     connection.connect();
2915                     if (connection.getResponseCode() == 204) {
2916                         LOGGER.info("Success. We updated correctly.");
2917                     } else {
2918                         LOGGER.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed: " + connection.getResponseCode() +
2919                                 "  message: " + connection.getResponseMessage());
2920                     }
2921
2922                 } catch (Exception e) {
2923                     PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet",
2924                             " Unable to sync config AC '" + acURL + "'");
2925                     disconnectedACs.add(acURL);
2926                 } finally {
2927                     // cleanup the connection
2928                     if (connection != null)
2929                         connection.disconnect();
2930                 }
2931             }
2932             // remove any ACs that are no longer connected
2933             if (!disconnectedACs.isEmpty()) {
2934                 adminConsoleURLStringList.removeAll(disconnectedACs);
2935             }
2936         }
2937     }
2938
2939     private void testService(ONAPLoggingContext loggingContext, HttpServletResponse response) throws IOException {
2940         LOGGER.info("Test request received");
2941         try {
2942             im.evaluateSanity();
2943             //If we make it this far, all is well
2944             String message = "GET:/pap/test called and PAP " + papResourceName + " is OK";
2945             LOGGER.info(message);
2946             loggingContext.transactionEnded();
2947             PolicyLogger.audit("Transaction Failed - See Error.log");
2948             response.setStatus(HttpServletResponse.SC_OK);
2949         } catch (ForwardProgressException | AdministrativeStateException | StandbyStatusException e) {
2950             String submsg;
2951             if (e instanceof ForwardProgressException) {
2952                 submsg = " is not making forward progress.";
2953             } else if (e instanceof AdministrativeStateException) {
2954                 submsg = " Administrative State is LOCKED.";
2955             } else {
2956                 submsg = " Standby Status is NOT PROVIDING SERVICE.";
2957             }
2958
2959             String message = "GET:/pap/test called and PAP " + papResourceName + submsg
2960                     + " Exception Message: " + e.getMessage();
2961             LOGGER.info(message, e);
2962             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
2963             loggingContext.transactionEnded();
2964             PolicyLogger.audit("Transaction Failed - See Error.log");
2965             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
2966         } catch (Exception e) {
2967             //A subsystem is not making progress, is locked, standby or is not responding
2968             String eMsg = e.getMessage();
2969             if (eMsg == null) {
2970                 eMsg = "No Exception Message";
2971             }
2972             String message = "GET:/pap/test called and PAP " + papResourceName + " has had a subsystem failure."
2973                     + " Exception Message: " + eMsg;
2974             LOGGER.info(message, e);
2975             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
2976             loggingContext.transactionEnded();
2977             PolicyLogger.audit("Transaction Failed - See Error.log");
2978             //Get the specific list of subsystems that failed
2979             String ssFailureList = null;
2980             for (String failedSS : papDependencyGroupsFlatArray) {
2981                 if (eMsg.contains(failedSS)) {
2982                     if (ssFailureList == null) {
2983                         ssFailureList = failedSS;
2984                     } else {
2985                         ssFailureList = ssFailureList.concat("," + failedSS);
2986                     }
2987                 }
2988             }
2989             if (ssFailureList == null) {
2990                 ssFailureList = "UnknownSubSystem";
2991             }
2992             response.addHeader("X-ONAP-SubsystemFailure", ssFailureList);
2993             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
2994         }
2995     }
2996
2997     /*
2998      * Authorizing the PEP Requests.
2999      */
3000     private boolean authorizeRequest(HttpServletRequest request) {
3001         String clientCredentials = request.getHeader(ENVIRONMENT_HEADER);
3002         // Check if the Client is Authorized.
3003         if (clientCredentials != null && clientCredentials.equalsIgnoreCase(environment)) {
3004             return true;
3005         } else {
3006             return false;
3007         }
3008     }
3009
3010     private static void loadWebapps() throws PAPException {
3011         if (actionHome == null || configHome == null) {
3012             Path webappsPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS));
3013             //Sanity Check
3014             if (webappsPath == null) {
3015                 PolicyLogger.error("Invalid Webapps Path Location property : " + XACMLRestProperties.PROP_PAP_WEBAPPS);
3016                 throw new PAPException(
3017                         "Invalid Webapps Path Location property : " + XACMLRestProperties.PROP_PAP_WEBAPPS);
3018             }
3019             Path webappsPathConfig = Paths.get(webappsPath.toString() + File.separator + "Config");
3020             Path webappsPathAction = Paths.get(webappsPath.toString() + File.separator + "Action");
3021             if (Files.notExists(webappsPathConfig)) {
3022                 try {
3023                     Files.createDirectories(webappsPathConfig);
3024                 } catch (IOException e) {
3025                     PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet",
3026                             "Failed to create config directory: "
3027                                     + webappsPathConfig.toAbsolutePath().toString());
3028                 }
3029             }
3030             if (Files.notExists(webappsPathAction)) {
3031                 try {
3032                     Files.createDirectories(webappsPathAction);
3033                 } catch (IOException e) {
3034                     LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to create action directory: "
3035                             + webappsPathAction.toAbsolutePath().toString(), e);
3036                 }
3037             }
3038             actionHome = webappsPathAction.toString();
3039             configHome = webappsPathConfig.toString();
3040         }
3041     }
3042
3043     public static String getConfigHome() {
3044         try {
3045             loadWebapps();
3046         } catch (PAPException e) {
3047             LOGGER.debug(e);
3048             return null;
3049         }
3050         return configHome;
3051     }
3052
3053     private static void setConfigHome() {
3054         configHome = getConfigHome();
3055     }
3056
3057     public static String getActionHome() {
3058         try {
3059             loadWebapps();
3060         } catch (PAPException e) {
3061             LOGGER.debug(e);
3062             return null;
3063         }
3064         return actionHome;
3065     }
3066
3067     private static void setActionHome() {
3068         actionHome = getActionHome();
3069     }
3070
3071     public static EntityManagerFactory getEmf() {
3072         return emf;
3073     }
3074
3075     public IntegrityAudit getIa() {
3076         return ia;
3077     }
3078
3079     public static String getPDPFile() {
3080         return XACMLPapServlet.pdpFile;
3081     }
3082
3083     public static String getPersistenceUnit() {
3084         return PERSISTENCE_UNIT;
3085     }
3086
3087     public static PAPPolicyEngine getPAPEngine() {
3088         return papEngine;
3089     }
3090
3091     public static PolicyDBDaoTransaction getDbDaoTransaction() {
3092         return policyDBDao.getNewTransaction();
3093     }
3094
3095     public static String getPapDbDriver() {
3096         return papDbDriver;
3097     }
3098
3099     public static void setPapDbDriver(String papDbDriver) {
3100         XACMLPapServlet.papDbDriver = papDbDriver;
3101     }
3102
3103     public static String getPapDbUrl() {
3104         return papDbUrl;
3105     }
3106
3107     public static void setPapDbUrl(String papDbUrl) {
3108         XACMLPapServlet.papDbUrl = papDbUrl;
3109     }
3110
3111     public static String getPapDbUser() {
3112         return papDbUser;
3113     }
3114
3115     public static void setPapDbUser(String papDbUser) {
3116         XACMLPapServlet.papDbUser = papDbUser;
3117     }
3118
3119     public static String getPapDbPassword() {
3120         return papDbPassword;
3121     }
3122
3123     public static void setPapDbPassword(String papDbPassword) {
3124         XACMLPapServlet.papDbPassword = papDbPassword;
3125     }
3126
3127     public static String getMsOnapName() {
3128         return msOnapName;
3129     }
3130
3131     public static void setMsOnapName(String msOnapName) {
3132         XACMLPapServlet.msOnapName = msOnapName;
3133     }
3134
3135     public static String getMsPolicyName() {
3136         return msPolicyName;
3137     }
3138
3139     public static void setMsPolicyName(String msPolicyName) {
3140         XACMLPapServlet.msPolicyName = msPolicyName;
3141     }
3142 }