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