Fixes for sonar critical issues
[policy/engine.git] / ONAP-PDP-REST / src / main / java / org / onap / policy / pdp / rest / XACMLPdpServlet.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-PDP-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.pdp.rest;
22
23 import java.io.BufferedReader;
24 import java.io.ByteArrayInputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.InputStreamReader;
28 import java.io.OutputStream;
29 import java.lang.reflect.Constructor;
30 import java.net.InetAddress;
31 import java.net.UnknownHostException;
32 import java.nio.file.Files;
33 import java.util.Properties;
34 import java.util.UUID;
35 import java.util.concurrent.BlockingQueue;
36 import java.util.concurrent.LinkedBlockingQueue;
37
38 import javax.servlet.Servlet;
39 import javax.servlet.ServletConfig;
40 import javax.servlet.ServletException;
41 import javax.servlet.annotation.WebInitParam;
42 import javax.servlet.annotation.WebServlet;
43 import javax.servlet.http.HttpServlet;
44 import javax.servlet.http.HttpServletRequest;
45 import javax.servlet.http.HttpServletResponse;
46
47 import org.apache.commons.io.IOUtils;
48 import org.apache.commons.logging.Log;
49 import org.apache.commons.logging.LogFactory;
50 import org.apache.http.entity.ContentType;
51 import org.onap.policy.api.PolicyParameters;
52 import org.onap.policy.common.im.AdministrativeStateException;
53 import org.onap.policy.common.im.ForwardProgressException;
54 import org.onap.policy.common.im.IntegrityMonitor;
55 import org.onap.policy.common.im.IntegrityMonitorProperties;
56 import org.onap.policy.common.im.StandbyStatusException;
57 import org.onap.policy.common.logging.ONAPLoggingContext;
58 import org.onap.policy.common.logging.ONAPLoggingUtils;
59 import org.onap.policy.common.logging.eelf.MessageCodes;
60 import org.onap.policy.common.logging.eelf.PolicyLogger;
61 import org.onap.policy.pdp.rest.jmx.PdpRestMonitor;
62 import org.onap.policy.rest.XACMLRest;
63 import org.onap.policy.rest.XACMLRestProperties;
64 import org.onap.policy.xacml.api.XACMLErrorConstants;
65 import org.onap.policy.xacml.pdp.std.functions.PolicyList;
66 import org.onap.policy.xacml.std.pap.StdPDPStatus;
67
68 import com.att.research.xacml.api.Request;
69 import com.att.research.xacml.api.Response;
70 import com.att.research.xacml.api.pap.PDPStatus.Status;
71 import com.att.research.xacml.api.pdp.PDPEngine;
72 import com.att.research.xacml.api.pdp.PDPException;
73 import com.att.research.xacml.std.dom.DOMRequest;
74 import com.att.research.xacml.std.dom.DOMResponse;
75 import com.att.research.xacml.std.json.JSONRequest;
76 import com.att.research.xacml.std.json.JSONResponse;
77 import com.att.research.xacml.util.XACMLProperties;
78 import com.fasterxml.jackson.databind.ObjectMapper;
79
80 /**
81  * Servlet implementation class XacmlPdpServlet
82  * 
83  * This is an implementation of the XACML 3.0 RESTful Interface with added features to support
84  * simple PAP RESTful API for policy publishing and PIP configuration changes.
85  * 
86  * If you are running this the first time, then we recommend you look at the xacml.pdp.properties file.
87  * This properties file has all the default parameter settings. If you are running the servlet as is,
88  * then we recommend setting up you're container to run it on port 8080 with context "/pdp". Wherever
89  * the default working directory is set to, a "config" directory will be created that holds the policy
90  * and pip cache. This setting is located in the xacml.pdp.properties file.
91  * 
92  * When you are ready to customize, you can create a separate xacml.pdp.properties on you're local file
93  * system and setup the parameters as you wish. Just set the Java VM System variable to point to that file:
94  * 
95  * -Dxacml.properties=/opt/app/xacml/etc/xacml.pdp.properties
96  * 
97  * Or if you only want to change one or two properties, simply set the Java VM System variable for that property.
98  * 
99  * -Dxacml.rest.pdp.register=false
100  *
101  *
102  */
103 @WebServlet(
104                 description = "Implements the XACML PDP RESTful API and client PAP API.", 
105                 urlPatterns = { "/" }, 
106                 loadOnStartup=1,
107                 initParams = { 
108                                 @WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pdp.properties", description = "The location of the PDP xacml.pdp.properties file holding configuration information.")
109                 })
110 public class XACMLPdpServlet extends HttpServlet implements Runnable {
111         private static final long serialVersionUID = 1L;
112         private static final String DEFAULT_MAX_CONTENT_LENGTH = "999999999"; //32767
113         private static final String CREATE_UPDATE_POLICY_SERVICE = "org.onap.policy.pdp.rest.api.services.CreateUpdatePolicyServiceImpl";
114         //
115         // Our application debug log
116         //
117         private static final Log logger = LogFactory.getLog(XACMLPdpServlet.class);
118         //
119         // This logger is specifically only for Xacml requests and their corresponding response.
120         // It's output ideally should be sent to a separate file from the application logger.
121         //
122         private static final Log requestLogger = LogFactory.getLog("xacml.request");
123         // 
124         // audit logger
125         private static final Log auditLogger = LogFactory.getLog("auditLogger");
126
127         private static final PdpRestMonitor monitor = PdpRestMonitor.getSingleton();
128
129         //
130         // This thread may getting invoked on startup, to let the PAP know
131         // that we are up and running.
132         //
133         private static transient Thread registerThread = null;
134         private static transient XACMLPdpRegisterThread registerRunnable = null;
135         //
136         // This is our PDP engine pointer. There is a synchronized lock used
137         // for access to the pointer. In case we are servicing PEP requests while
138         // an update is occurring from the PAP.
139         //
140         private static PDPEngine pdpEngine      = null;
141         private static final Object pdpEngineLock = new Object();
142         //
143         // This is our PDP's status. What policies are loaded (or not) and
144         // what PIP configurations are loaded (or not).
145         // There is a synchronized lock used for access to the object.
146         //
147         private static volatile StdPDPStatus status = new StdPDPStatus();
148         private static final Object pdpStatusLock = new Object();
149         private static Constructor<?> createUpdatePolicyConstructor;
150
151         private static final String ENVIORNMENT_HEADER = "Environment";
152         private static String environment = null;
153         //
154         // Queue of PUT requests
155         //
156         public static class PutRequest {
157                 private Properties policyProperties = null;
158                 private Properties pipConfigProperties = null;
159
160                 PutRequest(Properties policies, Properties pips) {
161                         this.policyProperties = policies;
162                         this.pipConfigProperties = pips;
163                 }
164         }
165         protected static volatile BlockingQueue<PutRequest> queue = null;
166         // For notification Delay.
167         private static int notificationDelay = 0;
168         public static int getNotificationDelay(){
169                 return XACMLPdpServlet.notificationDelay;
170         }
171
172         private static String pdpResourceName;
173         private static String[] dependencyNodes = null;
174
175         //
176         // This is our configuration thread that attempts to load
177         // a new configuration request.
178         //
179         private static transient Thread configThread = null;
180         private static volatile boolean configThreadTerminate = false;
181         private transient ONAPLoggingContext baseLoggingContext = null;
182         private transient IntegrityMonitor im;
183         /**
184          * Default constructor. 
185          */
186         public XACMLPdpServlet() {
187                 //Default constructor.
188         }
189
190         /**
191          * @see Servlet#init(ServletConfig)
192          */
193         @Override
194         public void init(ServletConfig config) throws ServletException {
195                 String createUpdateResourceName = null;
196                 String dependencyGroups = null;
197                 //
198                 // Initialize
199                 //
200                 XACMLRest.xacmlInit(config);
201                 // Load the Notification Delay.
202                 setNotificationDelay();
203                 // Load Queue size. 
204                 int queueSize = 5; // Set default Queue Size here. 
205                 queueSize = Integer.parseInt(XACMLProperties.getProperty("REQUEST_BUFFER_SIZE",String.valueOf(queueSize)));
206                 initQueue(queueSize);
207                 // Load our engine - this will use the latest configuration
208                 // that was saved to disk and set our initial status object.
209                 //
210                 PDPEngine engine = XACMLPdpLoader.loadEngine(XACMLPdpServlet.status, null, null);
211                 if (engine != null) {
212                         synchronized(pdpEngineLock) {
213                                 pdpEngine = engine;
214                         }
215                         // Notification will be Sent Here.
216                         XACMLPdpLoader.sendNotification();
217                 }
218                 //
219                 // Logging stuff....
220                 //
221                 baseLoggingContext = new ONAPLoggingContext();
222                 // fixed data that will be the same in all logging output goes here
223                 try {
224                         String ipaddress = InetAddress.getLocalHost().getHostAddress();
225                         baseLoggingContext.setServer(ipaddress);
226                 } catch (UnknownHostException e) {
227                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get hostname for logging"+e);
228                 }
229
230                 Properties properties;
231                 try {
232                         properties = XACMLProperties.getProperties();
233                 } catch (IOException e) {
234                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e,
235                                         "Error loading properties with: XACMLProperties.getProperties()");
236                         throw new ServletException(e.getMessage(), e.getCause());
237                 }
238                 if(properties.getProperty(XACMLRestProperties.PDP_RESOURCE_NAME)==null){
239                         XACMLProperties.reloadProperties();
240                         try {
241                                 properties = XACMLProperties.getProperties();
242                         } catch (IOException e) {
243                                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e,
244                                                 "Error loading properties with: XACMLProperties.getProperties()");
245                                 throw new ServletException(e.getMessage(), e.getCause());
246                         }
247                         PolicyLogger.info("\n Properties Given : \n" + properties.toString());
248                 }
249                 setPDPResourceName(properties);
250                 dependencyGroups = properties.getProperty(IntegrityMonitorProperties.DEPENDENCY_GROUPS);
251                 if(dependencyGroups == null){
252                         PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, IntegrityMonitorProperties.DEPENDENCY_GROUPS, "xacml.pdp");
253                         throw new ServletException("dependency_groups is null");
254                 }
255                 setDependencyNodes(dependencyGroups);
256                 
257
258                 // CreateUpdatePolicy ResourceName  
259                 createUpdateResourceName = properties.getProperty("createUpdatePolicy.impl.className", CREATE_UPDATE_POLICY_SERVICE);
260                 setCreateUpdatePolicyConstructor(createUpdateResourceName);
261
262                 // Create an IntegrityMonitor
263                 try {
264                         logger.info("Creating IntegrityMonitor");
265                         im = IntegrityMonitor.getInstance(pdpResourceName, properties);
266                 } catch (Exception e) { 
267                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to create IntegrityMonitor" +e);
268                         throw new ServletException(e);
269                 }
270                 startThreads(baseLoggingContext, new Thread(this));
271         }
272
273         private static void startThreads(ONAPLoggingContext baseLoggingContext, Thread thread) {
274             environment = XACMLProperties.getProperty("ENVIRONMENT", "DEVL");
275         //
276         // Kick off our thread to register with the PAP servlet.
277         //
278         if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER))) {
279             XACMLPdpServlet.registerRunnable = new XACMLPdpRegisterThread(baseLoggingContext);
280             XACMLPdpServlet.registerThread = new Thread(XACMLPdpServlet.registerRunnable);
281             XACMLPdpServlet.registerThread.start();
282         }
283         //
284         // This is our thread that manages incoming configuration
285         // changes.
286         //
287         XACMLPdpServlet.configThread = thread;
288         XACMLPdpServlet.configThread.start();
289     }
290
291     private static void setDependencyNodes(String dependencyGroups) {
292             // dependency_groups is a semicolon-delimited list of groups, and
293         // each group is a comma-separated list of nodes. For our purposes
294         // we just need a list of dependencies without regard to grouping,
295         // so split the list into nodes separated by either comma or semicolon.
296         dependencyNodes = dependencyGroups.split("[;,]");
297         for (int i = 0 ; i < dependencyNodes.length ; i++){
298             dependencyNodes[i] = dependencyNodes[i].trim();
299         }
300     }
301
302     private static void setPDPResourceName(Properties properties) throws ServletException {
303             pdpResourceName = properties.getProperty(XACMLRestProperties.PDP_RESOURCE_NAME);
304         if(pdpResourceName == null){
305             PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, XACMLRestProperties.PDP_RESOURCE_NAME, "xacml.pdp");
306             throw new ServletException("pdpResourceName is null");
307         }
308     }
309
310     private static void initQueue(int queueSize) {
311             queue = new LinkedBlockingQueue<>(queueSize);
312     }
313
314     private static void setNotificationDelay() {
315         try{
316             XACMLPdpServlet.notificationDelay = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_DELAY));
317         }catch(NumberFormatException e){
318             logger.error("Error in notification delay format, Taking the default value.", e);
319         }
320     }
321
322     /**
323          * @see Servlet#destroy()
324          */
325         @Override
326         public void destroy() {
327                 super.destroy();
328                 logger.info("Destroying....");
329                 //
330                 // Make sure the register thread is not running
331                 //
332                 if (XACMLPdpServlet.registerRunnable != null) {
333                         try {
334                                 XACMLPdpServlet.registerRunnable.terminate();
335                                 if (XACMLPdpServlet.registerThread != null) {
336                                         XACMLPdpServlet.registerThread.interrupt();
337                                         XACMLPdpServlet.registerThread.join();
338                                 }
339                         } catch (InterruptedException e) {
340                                 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
341                                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
342                                 XACMLPdpServlet.registerThread.interrupt();
343                         }
344                 }
345                 //
346                 // Make sure the configure thread is not running
347                 //
348                 setConfigThreadTerminate(true);
349                 try {
350                         XACMLPdpServlet.configThread.interrupt();
351                         XACMLPdpServlet.configThread.join();
352                 } catch (InterruptedException e) {
353                         logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
354                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
355                         XACMLPdpServlet.configThread.interrupt();
356                 }
357                 logger.info("Destroyed.");
358         }
359
360         private static void setConfigThreadTerminate(boolean value) {
361             XACMLPdpServlet.configThreadTerminate = value;
362     }
363
364     /**
365          * PUT - The PAP engine sends configuration information using HTTP PUT request.
366          * 
367          * One parameter is expected:
368          * 
369          * config=[policy|pip|all]
370          * 
371          *      policy - Expect a properties file that contains updated lists of the root and referenced policies that the PDP should
372          *                       be using for PEP requests.
373          * 
374          *              Specifically should AT LEAST contain the following properties:
375          *              xacml.rootPolicies
376          *              xacml.referencedPolicies
377          * 
378          *              In addition, any relevant information needed by the PDP to load or retrieve the policies to store in its cache.
379          *
380          *              EXAMPLE:
381          *                      xacml.rootPolicies=PolicyA.1, PolicyB.1
382          *
383          *                      PolicyA.1.url=http://localhost:9090/PAP?id=b2d7b86d-d8f1-4adf-ba9d-b68b2a90bee1&version=1
384          *                      PolicyB.1.url=http://localhost:9090/PAP/id=be962404-27f6-41d8-9521-5acb7f0238be&version=1
385          *      
386          *                      xacml.referencedPolicies=RefPolicyC.1, RefPolicyD.1
387          *
388          *                      RefPolicyC.1.url=http://localhost:9090/PAP?id=foobar&version=1
389          *                      RefPolicyD.1.url=http://localhost:9090/PAP/id=example&version=1
390          *      
391          * pip - Expect a properties file that contain PIP engine configuration properties.
392          * 
393          *              Specifically should AT LEAST the following property:
394          *                      xacml.pip.engines
395          * 
396          *              In addition, any relevant information needed by the PDP to load and configure the PIPs.
397          * 
398          *              EXAMPLE:
399          *                      xacml.pip.engines=foo,bar
400          * 
401          *                      foo.classname=com.foo
402          *                      foo.sample=abc
403          *                      foo.example=xyz
404          *                      ......
405          * 
406          *                      bar.classname=com.bar
407          *                      ......
408          * 
409          * all - Expect ALL new configuration properties for the PDP
410          * 
411          * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response)
412          */
413         @Override
414         protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
415                 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
416                 loggingContext.transactionStarted();
417                 if ((loggingContext.getRequestID() == null) || "".equals(loggingContext.getRequestID())){
418                         UUID requestID = UUID.randomUUID();
419                         loggingContext.setRequestID(requestID.toString());
420                         PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doPut) so we generated one");
421                 } else {
422                         PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doPut)");
423                 }
424                 loggingContext.metricStarted();
425                 loggingContext.metricEnded();
426                 PolicyLogger.metrics("Metric example posted here - 1 of 2");
427                 loggingContext.metricStarted();
428                 loggingContext.metricEnded();
429                 PolicyLogger.metrics("Metric example posted here - 2 of 2");
430                 //
431                 // Dump our request out
432                 //
433                 if (logger.isDebugEnabled()) {
434                         XACMLRest.dumpRequest(request);
435                 }
436
437                 try {
438                         im.startTransaction();
439                 }
440                 catch (AdministrativeStateException | StandbyStatusException e) {
441                         String message = e.toString();
442                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + e);
443                         loggingContext.transactionEnded();
444                         PolicyLogger.audit("Transaction Failed - See Error.log");
445                         try{
446                                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
447                         }catch(Exception e1){
448                                 logger.error("Exception occured while sending error in response" +e1);
449                         }
450                         return;
451                 }
452                 //
453                 // What is being PUT?
454                 //
455                 String cache = request.getParameter("cache");
456                 //
457                 // Should be a list of policy and pip configurations in Java properties format
458                 //
459                 if (cache != null && request.getContentType().equals("text/x-java-properties")) {
460                         loggingContext.setServiceName("PDP.putConfig");
461                         try{
462                                 if (request.getContentLength() > Integer.parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", DEFAULT_MAX_CONTENT_LENGTH))) {
463                                         String message = "Content-Length larger than server will accept.";
464                                         logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
465                                         loggingContext.transactionEnded();
466                                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
467                                         PolicyLogger.audit("Transaction Failed - See Error.log");
468                                         response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
469                                         im.endTransaction();
470                                         return;
471                                 }
472                                 this.doPutConfig(cache, request, response, loggingContext);
473                                 loggingContext.transactionEnded();
474                                 PolicyLogger.audit("Transaction ended");
475
476                                 im.endTransaction();
477                         }catch(Exception e){
478                                 logger.error("Exception Occured while getting Max Content lenght"+e);
479                         }
480                 } else {
481                         String message = "Invalid cache: '" + cache + "' or content-type: '" + request.getContentType() + "'";
482                         logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message);
483                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
484                         loggingContext.transactionEnded();
485                         PolicyLogger.audit("Transaction Failed - See Error.log");
486                         try{
487                                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
488                         }catch(Exception e1){
489                                 logger.error("Exception occured while sending error in response" +e1);
490                         }
491                         im.endTransaction();
492                         return;
493                 }
494         }
495
496         protected void doPutConfig(String config, HttpServletRequest request, HttpServletResponse response, ONAPLoggingContext loggingContext)  throws ServletException, IOException {
497                 try {
498                         // prevent multiple configuration changes from stacking up
499                         if (XACMLPdpServlet.queue.remainingCapacity() <= 0) {
500                                 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Queue capacity reached");
501                                 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "Queue capacity reached");
502                                 loggingContext.transactionEnded();
503                                 PolicyLogger.audit("Transaction Failed - See Error.log");
504                                 response.sendError(HttpServletResponse.SC_CONFLICT, "Multiple configuration changes waiting processing.");
505                                 return;
506                         }
507                         //
508                         // Read the properties data into an object.
509                         //
510                         Properties newProperties = new Properties();
511                         newProperties.load(request.getInputStream());
512                         // should have something in the request
513                         if (newProperties.size() == 0) {
514                                 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No properties in PUT");
515                                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No properties in PUT");
516                                 loggingContext.transactionEnded();
517                                 PolicyLogger.audit("Transaction Failed - See Error.log");
518                                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT must contain at least one property");
519                                 return;
520                         }
521                         //
522                         // Which set of properties are they sending us? Whatever they send gets
523                         // put on the queue (if there is room).
524                         // For audit logging purposes, we consider the transaction done once the
525                         // the request gets put on the queue.
526                         //
527                         if (config.equals("policies")) {
528                                 newProperties = XACMLProperties.getPolicyProperties(newProperties, true);
529                                 if (newProperties.size() == 0) {
530                                         logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No policy properties in PUT");
531                                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No policy properties in PUT");
532                                         loggingContext.transactionEnded();
533                                         PolicyLogger.audit("Transaction Failed - See Error.log");
534                                         response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=policies must contain at least one policy property");
535                                         return;
536                                 }
537                                 XACMLPdpServlet.queue.offer(new PutRequest(newProperties, null));
538                                 loggingContext.transactionEnded();
539                                 auditLogger.info("Success");
540                                 PolicyLogger.audit("Success");
541                         } else if (config.equals("pips")) {
542                                 newProperties = XACMLProperties.getPipProperties(newProperties);
543                                 if (newProperties.size() == 0) {
544                                         logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No pips properties in PUT");
545                                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No pips properties in PUT");
546                                         loggingContext.transactionEnded();
547                                         PolicyLogger.audit("Transaction Failed - See Error.log");
548                                         response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=pips must contain at least one pip property");
549                                         return;
550                                 }
551                                 XACMLPdpServlet.queue.offer(new PutRequest(null, newProperties));
552                                 loggingContext.transactionEnded();
553                                 auditLogger.info("Success");
554                                 PolicyLogger.audit("Success");
555                         } else if (config.equals("all")) {
556                                 Properties newPolicyProperties = XACMLProperties.getPolicyProperties(newProperties, true);
557                                 if (newPolicyProperties.size() == 0) {
558                                         logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No policy properties in PUT");
559                                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No policy properties in PUT");
560                                         loggingContext.transactionEnded();
561                                         PolicyLogger.audit("Transaction Failed - See Error.log");
562                                         response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=all must contain at least one policy property");
563                                         return;
564                                 }
565                                 Properties newPipProperties = XACMLProperties.getPipProperties(newProperties);
566                                 if (newPipProperties.size() == 0) {
567                                         logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No pips properties in PUT");
568                                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No pips properties in PUT");
569                                         loggingContext.transactionEnded();
570                                         PolicyLogger.audit("Transaction Failed - See Error.log");
571                                         response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=all must contain at least one pip property");
572                                         return;
573                                 }
574                                 XACMLPdpServlet.queue.offer(new PutRequest(newPolicyProperties, newPipProperties));
575                                 loggingContext.transactionEnded();
576                                 auditLogger.info("Success");
577                                 PolicyLogger.audit("Success");
578                         } else {
579                                 //
580                                 // Invalid value
581                                 //
582                                 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid config value: " + config);
583                                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Invalid config value: " + config);
584                                 loggingContext.transactionEnded();
585                                 PolicyLogger.audit("Transaction Failed - See Error.log");
586                                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Config must be one of 'policies', 'pips', 'all'");
587                                 return;
588                         }
589                 } catch (Exception e) {
590                         logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed to process new configuration.", e);
591                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to process new configuration");
592                         loggingContext.transactionEnded();
593                         PolicyLogger.audit("Transaction Failed - See Error.log");
594                         try{
595                                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
596                         }catch(Exception e1){
597                                 logger.error("Exception occured while sending error in response" +e1);
598                         }
599                         return;
600                 }
601
602         }
603
604         /**
605          * Parameters: type=hb|config|Status
606          * 
607          * 1. HeartBeat Status 
608          * HeartBeat
609          *              OK - All Policies are Loaded, All PIPs are Loaded
610          *      LOADING_IN_PROGRESS - Currently loading a new policy set/pip configuration
611          *      LAST_UPDATE_FAILED - Need to track the items that failed during last update
612          *      LOAD_FAILURE - ??? Need to determine what information is sent and how 
613          * 2. Configuration
614          * 3. Status
615          *              return the StdPDPStatus object in the Response content
616          * 
617          * 
618          * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
619          */
620         @Override
621         protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
622                 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
623                 loggingContext.transactionStarted();
624                 if ((loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")){
625                         UUID requestID = UUID.randomUUID();
626                         loggingContext.setRequestID(requestID.toString());
627                         PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doGet) so we generated one");
628                 } else {
629                         PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doGet)");
630                 }
631                 loggingContext.metricStarted();
632                 loggingContext.metricEnded();
633                 PolicyLogger.metrics("Metric example posted here - 1 of 2");
634                 loggingContext.metricStarted();
635                 loggingContext.metricEnded();
636                 PolicyLogger.metrics("Metric example posted here - 2 of 2");
637
638                 XACMLRest.dumpRequest(request);
639
640                 String pathInfo = request.getRequestURI();
641                 if (pathInfo != null){
642                         // health check from Global Site Selector (iDNS).
643                         // DO NOT do a im.startTransaction for the test request
644                         if (pathInfo.equals("/pdp/test")) {
645                                 loggingContext.setServiceName("iDNS:PDP.test");
646                                 try {
647                                         im.evaluateSanity();
648                                         //If we make it this far, all is well
649                                         String message = "GET:/pdp/test called and PDP " + pdpResourceName + " is OK";
650                                         PolicyLogger.debug(message);
651                                         loggingContext.transactionEnded();
652                                         PolicyLogger.audit("Success");
653                                         response.setStatus(HttpServletResponse.SC_OK);
654                                         return;
655                                 } catch (ForwardProgressException fpe){
656                                         //No forward progress is being made
657                                         String message = "GET:/pdp/test called and PDP " + pdpResourceName + " is not making forward progress."
658                                                         + " Exception Message: " + fpe.getMessage();
659                                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + fpe);
660                                         loggingContext.transactionEnded();
661                                         PolicyLogger.audit("Transaction Failed - See Error.log");
662                                         try{
663                                                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
664                                         }catch(Exception e1){
665                                                 logger.error("Exception occured while sending error in response" +e1);
666                                         }
667                                         return;
668                                 }catch (AdministrativeStateException ase){
669                                         //Administrative State is locked
670                                         String message = "GET:/pdp/test called and PDP " + pdpResourceName + " Administrative State is LOCKED "
671                                                         + " Exception Message: " + ase.getMessage();
672                                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + ase);
673                                         loggingContext.transactionEnded();
674                                         PolicyLogger.audit("Transaction Failed - See Error.log");
675                                         try{
676                                                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
677                                         }catch(Exception e1){
678                                                 logger.error("Exception occured while sending error in response" +e1);
679                                         }
680                                         return;
681                                 }catch (StandbyStatusException sse){
682                                         //Administrative State is locked
683                                         String message = "GET:/pdp/test called and PDP " + pdpResourceName + " Standby Status is NOT PROVIDING SERVICE "
684                                                         + " Exception Message: " + sse.getMessage();
685                                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + sse);
686                                         loggingContext.transactionEnded();
687                                         PolicyLogger.audit("Transaction Failed - See Error.log");
688                                         try{
689                                                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
690                                         }catch(Exception e1){
691                                                 logger.error("Exception occured while sending error in response" +e1);
692                                         }
693                                         return;
694                                 } catch (Exception e) {
695                                         //A subsystem is not making progress or is not responding
696                                         String eMsg = e.getMessage();
697                                         if(eMsg == null){
698                                                 eMsg = "No Exception Message";
699                                         }
700                                         String message = "GET:/pdp/test called and PDP " + pdpResourceName + " has had a subsystem failure."
701                                                         + " Exception Message: " + eMsg;
702                                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message );
703                                         //Get the specific list of subsystems that failed
704                                         String failedNodeList = null;
705                                         for(String node : dependencyNodes){
706                                                 if(eMsg.contains(node)){
707                                                         if(failedNodeList == null){
708                                                                 failedNodeList = node;
709                                                         }else{
710                                                                 failedNodeList = failedNodeList.concat(","+node);
711                                                         }
712                                                 }
713                                         }
714                                         if(failedNodeList == null){
715                                                 failedNodeList = "UnknownSubSystem";
716                                         }
717                                         response.addHeader("X-ONAP-SubsystemFailure", failedNodeList);
718                                         try{
719                                                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
720                                         }catch(Exception e1){
721                                                 logger.error("Exception occured while sending error in response" +e1);
722                                         }
723                                         loggingContext.transactionEnded();
724                                         PolicyLogger.audit("Transaction Failed - See Error.log" + e);
725                                         return;
726                                 }
727                         }
728                 }
729
730                 try {
731                         im.startTransaction();
732                 }
733                 catch (AdministrativeStateException | StandbyStatusException e) {
734                         String message = e.toString();
735                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
736                         loggingContext.transactionEnded();
737                         PolicyLogger.audit("Transaction Failed - See Error.log" +e);
738                         try{
739                                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
740                         }catch(Exception e1){
741                                 logger.error("Exception occured while sending error in response" +e1);
742                         }
743                         return;
744                 }
745                 //
746                 // What are they requesting?
747                 //
748                 boolean returnHB = false;
749                 response.setHeader("Cache-Control", "no-cache");
750                 String type = request.getParameter("type");
751                 // type might be null, so use equals on string constants
752                 if ("config".equals(type)) {
753                         loggingContext.setServiceName("PDP.getConfig");
754                         response.setContentType("text/x-java-properties");
755                         try {
756                                 String lists = XACMLProperties.PROP_ROOTPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES, "");
757                                 lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, "") + "\n";
758                                 try (InputStream listInputStream = new ByteArrayInputStream(lists.getBytes());
759                                                 InputStream pipInputStream = Files.newInputStream(XACMLPdpLoader.getPIPConfig());
760                                                 OutputStream os = response.getOutputStream()) {
761                                         IOUtils.copy(listInputStream, os);
762                                         IOUtils.copy(pipInputStream, os);
763                                 }
764                                 loggingContext.transactionEnded();
765                                 auditLogger.info("Success");
766                                 PolicyLogger.audit("Success");
767                                 response.setStatus(HttpServletResponse.SC_OK);
768                         } catch (Exception e) {
769                                 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed to copy property file", e);
770                                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to copy property file");
771                                 loggingContext.transactionEnded();
772                                 PolicyLogger.audit("Transaction Failed - See Error.log");
773                                 try{
774                                         response.sendError(400, "Failed to copy Property file");
775                                 }catch(Exception e1){
776                                         logger.error("Exception occured while sending error in response" +e1);
777                                 }
778                         }
779
780                 } else if ("hb".equals(type)) {
781                         returnHB = true;
782                         response.setStatus(HttpServletResponse.SC_NO_CONTENT);
783
784                 } else if ("Status".equals(type)) {
785                         loggingContext.setServiceName("PDP.getStatus");
786                         // convert response object to JSON and include in the response
787                         synchronized(pdpStatusLock) {
788                                 ObjectMapper mapper = new ObjectMapper();
789                                 try{
790                                         mapper.writeValue(response.getOutputStream(),  status);
791                                 }catch(Exception e1){
792                                         logger.error("Exception occured while writing output stream" +e1);
793                                 }
794                         }
795                         response.setStatus(HttpServletResponse.SC_OK);
796                         loggingContext.transactionEnded();
797                         auditLogger.info("Success");
798                         PolicyLogger.audit("Success");
799
800                 } else {
801                         logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid type value: " + type);
802                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Invalid type value: " + type);
803                         loggingContext.transactionEnded();
804                         PolicyLogger.audit("Transaction Failed - See Error.log");
805                         try{
806                                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "type not 'config' or 'hb'");
807                         }catch(Exception e1){
808                                 logger.error("Exception occured while sending error in response" +e1);
809                         }
810                 }
811                 if (returnHB) {
812                         synchronized(pdpStatusLock) {
813                                 response.addHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB, status.getStatus().toString());
814                         }
815                 }
816                 loggingContext.transactionEnded();
817                 PolicyLogger.audit("Transaction Ended");
818                 im.endTransaction();
819
820         }
821
822         /**
823          * POST - We expect XACML requests to be posted by PEP applications. They can be in the form of XML or JSON according
824          * to the XACML 3.0 Specifications for both.
825          * 
826          * 
827          * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
828          */
829         @Override
830         protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
831
832                 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
833                 loggingContext.transactionStarted();
834                 loggingContext.setServiceName("PDP.decide");
835                 if ((loggingContext.getRequestID() == null) || ("".equals(loggingContext.getRequestID()))){
836                         UUID requestID = UUID.randomUUID();
837                         loggingContext.setRequestID(requestID.toString());
838                         PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doPost) so we generated one");
839                 } else {
840                         PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doPost)");
841                 }
842                 loggingContext.metricStarted();
843                 loggingContext.metricEnded();
844                 PolicyLogger.metrics("Metric example posted here - 1 of 2");
845                 loggingContext.metricStarted();
846                 loggingContext.metricEnded();
847                 PolicyLogger.metrics("Metric example posted here - 2 of 2");
848                 monitor.pdpEvaluationAttempts();
849
850                 try {
851                         im.startTransaction();
852                 }
853                 catch (AdministrativeStateException | StandbyStatusException e) {
854                         String message = e.toString();
855                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + e);
856                         loggingContext.transactionEnded();
857                         PolicyLogger.audit("Transaction Failed - See Error.log");
858                         try{
859                                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
860                         }catch(Exception e1){
861                                 logger.error("Exception occured while sending error in response" +e1);
862                         }
863                         return;
864                 }
865                 //
866                 // no point in doing any work if we know from the get-go that we cannot do anything with the request
867                 //
868                 if (status.getLoadedRootPolicies().isEmpty()) {
869                         logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Request from PEP at " + request.getRequestURI() + " for service when PDP has No Root Policies loaded");
870                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, "Request from PEP at " + request.getRequestURI() + " for service when PDP has No Root Policies loaded");
871                         loggingContext.transactionEnded();
872                         PolicyLogger.audit("Transaction Failed - See Error.log");
873                         try{
874                                 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
875                         }catch(Exception e1){
876                                 logger.error("Exception occured while sending error in response" +e1);
877                         }
878                         im.endTransaction();
879                         return;
880                 }
881
882                 XACMLRest.dumpRequest(request);
883                 //
884                 // Set our no-cache header
885                 //
886                 response.setHeader("Cache-Control", "no-cache");
887                 //
888                 // They must send a Content-Type
889                 //
890                 if (request.getContentType() == null) {
891                         logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Must specify a Content-Type");
892                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Must specify a Content-Type");
893                         loggingContext.transactionEnded();
894                         PolicyLogger.audit("Transaction Failed - See Error.log");
895                         try{
896                                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "no content-type given");
897                         }catch(Exception e1){
898                                 logger.error("Exception occured while sending error in response" +e1);
899                         }
900                         im.endTransaction();
901                         return;
902                 }
903                 //
904                 // Limit the Content-Length to something reasonable
905                 //
906                 try{
907                         if (request.getContentLength() > Integer.parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", "32767"))) {
908                                 String message = "Content-Length larger than server will accept.";
909                                 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
910                                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
911                                 loggingContext.transactionEnded();
912                                 PolicyLogger.audit("Transaction Failed - See Error.log");
913                                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
914                                 im.endTransaction();
915                                 return;
916                         }
917                 }catch(Exception e){
918                         logger.error("Exception occured while getting max content length"+e);
919                 }
920                 
921                 if (request.getContentLength() <= 0) {
922                         String message = "Content-Length is negative";
923                         logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
924                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
925                         loggingContext.transactionEnded();
926                         PolicyLogger.audit("Transaction Failed - See Error.log");
927                         try{
928                                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
929                         }catch(Exception e1){
930                                 logger.error("Exception occured while sending error in response" +e1);
931                         }
932                         im.endTransaction();
933                         return;
934                 }
935                 ContentType contentType = null;
936                 try {
937                         contentType = ContentType.parse(request.getContentType());
938                 }
939                 catch (Exception e) {
940                         String message = "Parsing Content-Type: " + request.getContentType() + ", error=" + e.getMessage();
941                         logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message, e);
942                         loggingContext.transactionEnded();
943                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, message);
944                         PolicyLogger.audit("Transaction Failed - See Error.log");
945                         try{
946                                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
947                         }catch(Exception e1){
948                                 logger.error("Exception occured while sending error in response" +e1);
949                         }
950                         im.endTransaction();
951                         return;
952                 }
953                 //
954                 // What exactly did they send us?
955                 //
956                 String incomingRequestString = null;
957                 Request pdpRequest = null;
958                 if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType()) ||
959                                 contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
960                                 contentType.getMimeType().equalsIgnoreCase("application/xacml+xml") ) {
961                         //
962                         // Read in the string
963                         //
964                         StringBuilder buffer = new StringBuilder();
965                         BufferedReader reader = null;
966                         try{
967                             reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
968                         }catch(IOException e){
969                             logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error during reading input stream",e);
970                             return;
971                         }
972                         String line;
973                         try{
974                                 while((line = reader.readLine()) != null){
975                                         buffer.append(line);
976                                 }
977                         }catch(Exception e){
978                                 logger.error("Exception Occured while reading line"+e);
979                         }
980                         
981                         incomingRequestString = buffer.toString();
982                         logger.info(incomingRequestString);
983                         //
984                         // Parse into a request
985                         //
986                         try {
987                                 if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
988                                         pdpRequest = JSONRequest.load(incomingRequestString);
989                                 } else if (     contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
990                                                 contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
991                                         pdpRequest = DOMRequest.load(incomingRequestString);
992                                 }
993                         }
994                         catch(Exception e) {
995                                 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Could not parse request", e);
996                                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "Could not parse request");
997                                 loggingContext.transactionEnded();
998                                 PolicyLogger.audit("Transaction Failed - See Error.log");
999                                 try{
1000                                         response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
1001                                 }catch(Exception e1){
1002                                         logger.error("Exception occured while sending error in response" +e1);
1003                                 }
1004                                 im.endTransaction();
1005                                 return;
1006                         }
1007                 } else {
1008                         String message = "unsupported content type" + request.getContentType();
1009                         logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
1010                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
1011                         loggingContext.transactionEnded();
1012                         PolicyLogger.audit("Transaction Failed - See Error.log");
1013                         try{
1014                                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
1015                         }catch(Exception e1){
1016                                 logger.error("Exception occured while sending error in response" +e1);
1017                         }
1018                         im.endTransaction();
1019                         return;
1020                 }
1021                 //
1022                 // Did we successfully get and parse a request?
1023                 //
1024                 if (pdpRequest == null || pdpRequest.getRequestAttributes() == null || pdpRequest.getRequestAttributes().size() <= 0) {
1025                         String message = "Zero Attributes found in the request";
1026                         logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
1027                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
1028                         loggingContext.transactionEnded();
1029                         PolicyLogger.audit("Transaction Failed - See Error.log");
1030                         try{
1031                                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
1032                         }catch(Exception e1){
1033                                 logger.error("Exception occured while sending error in response" +e1);
1034                         }
1035                         im.endTransaction();
1036                         return;
1037                 }
1038                 //
1039                 // Run it
1040                 //
1041                 try {
1042                         //
1043                         // Authenticating the Request here. 
1044                         //
1045                         if(!authorizeRequest(request)){
1046                                 String message = "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
1047                                 logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + message );
1048                                 PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS, message);
1049                                 loggingContext.transactionEnded();
1050                                 PolicyLogger.audit("Transaction Failed - See Error.log");
1051                                 response.sendError(HttpServletResponse.SC_FORBIDDEN, message);
1052                                 im.endTransaction();
1053                                 return;
1054                         }
1055                         //
1056                         // Get the pointer to the PDP Engine
1057                         //
1058                         PDPEngine myEngine = null;
1059                         synchronized(pdpEngineLock) {
1060                                 myEngine = XACMLPdpServlet.pdpEngine;
1061                         }
1062                         if (myEngine == null) {
1063                                 String message = "No engine loaded.";
1064                                 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message);
1065                                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
1066                                 loggingContext.transactionEnded();
1067                                 PolicyLogger.audit("Transaction Failed - See Error.log");
1068                                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1069                                 im.endTransaction();
1070                                 return;
1071                         }
1072                         //
1073                         // Send the request and save the response
1074                         //
1075                         long lTimeStart;
1076                         long lTimeEnd;
1077                         Response pdpResponse    = null;
1078
1079                         synchronized(pdpEngineLock) {
1080                                 myEngine = XACMLPdpServlet.pdpEngine;
1081                                 try {
1082                                         PolicyList.clearPolicyList();
1083                                         lTimeStart = System.currentTimeMillis();                
1084                                         pdpResponse     = myEngine.decide(pdpRequest);
1085                                         lTimeEnd = System.currentTimeMillis();
1086                                 } catch (PDPException e) {
1087                                         String message = "Exception during decide: " + e.getMessage();
1088                                         logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message +e);
1089                                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
1090                                         loggingContext.transactionEnded();
1091                                         PolicyLogger.audit("Transaction Failed - See Error.log");
1092                                         try{
1093                                                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1094                                         }catch(Exception e1){
1095                                                 logger.error("Exception occured while sending error in response" +e1);
1096                                         }
1097                                         im.endTransaction();
1098                                         return;
1099                                 }
1100                         }
1101                         monitor.computeLatency(lTimeEnd - lTimeStart);  
1102                         requestLogger.info(lTimeStart + "=" + incomingRequestString);
1103                         for(String policy : PolicyList.getpolicyList()){
1104                                 monitor.policyCountAdd(policy, 1);
1105                         }
1106
1107
1108                         logger.info("PolicyID triggered in Request: " + PolicyList.getpolicyList());
1109
1110                         //need to go through the list and find out if the value is unique and then add it other wise 
1111                         //                      monitor.policyCountAdd(PolicyList.getpolicyList(), 1);
1112
1113                         if (logger.isDebugEnabled()) {
1114                                 logger.debug("Request time: " + (lTimeEnd - lTimeStart) + "ms");
1115                         }
1116                         //
1117                         // Convert Response to appropriate Content-Type
1118                         //
1119                         if (pdpResponse == null) {
1120                                 requestLogger.info(lTimeStart + "=" + "{}");
1121                                 try{
1122                                         throw new PDPException("Failed to get response from PDP engine.");
1123                                 }catch(Exception e1){
1124                                         logger.error("Exception occured while throwing Exception" +e1);
1125                                 }
1126                         }
1127                         //
1128                         // Set our content-type
1129                         //
1130                         response.setContentType(contentType.getMimeType());
1131                         //
1132                         // Convert the PDP response object to a String to
1133                         // return to our caller as well as dump to our loggers.
1134                         //
1135                         String outgoingResponseString = "";
1136                         try{
1137                                 if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
1138                                         //
1139                                         // Get it as a String. This is not very efficient but we need to log our
1140                                         // results for auditing.
1141                                         //
1142                                         outgoingResponseString = JSONResponse.toString(pdpResponse, logger.isDebugEnabled());
1143                                         if (logger.isDebugEnabled()) {
1144                                                 logger.debug(outgoingResponseString);
1145                                                 //
1146                                                 // Get rid of whitespace
1147                                                 //
1148                                                 outgoingResponseString = JSONResponse.toString(pdpResponse, false);
1149                                         }
1150                                 } else if (     contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
1151                                                 contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
1152                                         //
1153                                         // Get it as a String. This is not very efficient but we need to log our
1154                                         // results for auditing.
1155                                         //
1156                                         outgoingResponseString = DOMResponse.toString(pdpResponse, logger.isDebugEnabled());
1157                                         if (logger.isDebugEnabled()) {
1158                                                 logger.debug(outgoingResponseString);
1159                                                 //
1160                                                 // Get rid of whitespace
1161                                                 //
1162                                                 outgoingResponseString = DOMResponse.toString(pdpResponse, false);
1163                                         }
1164                                 }       
1165                                 //      adding the jmx values for NA, Permit and Deny
1166                                 //
1167                                 if (outgoingResponseString.contains("NotApplicable") || outgoingResponseString.contains("Decision not a Permit")){
1168                                         monitor.pdpEvaluationNA();
1169                                 }
1170
1171                                 if (outgoingResponseString.contains("Permit") && !outgoingResponseString.contains("Decision not a Permit")){
1172                                         monitor.pdpEvaluationPermit();
1173                                 }
1174
1175                                 if (outgoingResponseString.contains("Deny")){
1176                                         monitor.pdpEvaluationDeny();
1177                                 }
1178                                 //
1179                                 // lTimeStart is used as an ID within the requestLogger to match up
1180                                 // request's with responses.
1181                                 //
1182                                 requestLogger.info(lTimeStart + "=" + outgoingResponseString);
1183                                 response.getWriter().print(outgoingResponseString);
1184                         }catch(Exception e){
1185                                 logger.error("Exception Occured"+e );
1186                         }
1187                 }
1188                 catch (Exception e) {
1189                         String message = "Exception executing request: " + e;
1190                         logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message, e);
1191                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, message);
1192                         loggingContext.transactionEnded();
1193                         PolicyLogger.audit("Transaction Failed - See Error.log");
1194                         try{
1195                                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1196                         }catch(Exception e1){
1197                                 logger.error("Exception occured while sending error in response" +e1);
1198                         }
1199                         return;
1200                 }
1201
1202                 monitor.pdpEvaluationSuccess();
1203                 response.setStatus(HttpServletResponse.SC_OK);
1204
1205                 loggingContext.transactionEnded();
1206                 auditLogger.info("Success");
1207                 PolicyLogger.audit("Success");
1208
1209         }
1210
1211         /*
1212          * Added for Authorizing the PEP Requests for Environment check. 
1213          */
1214         private boolean authorizeRequest(HttpServletRequest request) {
1215                 // Get the client Credentials from the Request header. 
1216                 HttpServletRequest httpServletRequest = request;
1217                 String clientCredentials = httpServletRequest.getHeader(ENVIORNMENT_HEADER);
1218                 if(clientCredentials!=null && clientCredentials.equalsIgnoreCase(environment)){
1219                         return true;
1220                 }else{
1221                         return false;
1222                 }
1223         }
1224
1225         @Override
1226         public void run() {
1227                 //
1228                 // Keep running until we are told to terminate
1229                 //
1230                 try {
1231                         // variable not used, but constructor has needed side-effects so don't remove:
1232                         while (! XACMLPdpServlet.configThreadTerminate) {
1233                                 PutRequest request = XACMLPdpServlet.queue.take();
1234                                 StdPDPStatus newStatus = new StdPDPStatus();
1235                                 
1236                                 PDPEngine newEngine = null;
1237                                 synchronized(pdpStatusLock) {
1238                                         XACMLPdpServlet.status.setStatus(Status.UPDATING_CONFIGURATION);
1239                                         newEngine = XACMLPdpLoader.loadEngine(newStatus, request.policyProperties, request.pipConfigProperties);
1240                                 }
1241                                 if (newEngine != null) {
1242                                         synchronized(XACMLPdpServlet.pdpEngineLock) {
1243                                                 XACMLPdpServlet.pdpEngine = newEngine;
1244                                                 try {
1245                                                         logger.info("Saving configuration.");
1246                                                         if (request.policyProperties != null) {
1247                                                                 try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPDPPolicyCache())) {
1248                                                                         request.policyProperties.store(os, "");
1249                                                                 }
1250                                                         }
1251                                                         if (request.pipConfigProperties != null) {
1252                                                                 try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPIPConfig())) {
1253                                                                         request.pipConfigProperties.store(os, "");
1254                                                                 }
1255                                                         }
1256                                                         newStatus.setStatus(Status.UP_TO_DATE);
1257                                                 } catch (Exception e) {
1258                                                         logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to store new properties."+e);
1259                                                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "Failed to store new properties");
1260                                                         newStatus.setStatus(Status.LOAD_ERRORS);
1261                                                         newStatus.addLoadWarning("Unable to save configuration: " + e.getMessage());
1262                                                 }
1263                                         }
1264                                         // Notification will be Sent Here.
1265                                         XACMLPdpLoader.sendNotification();
1266                                 } else {
1267                                         newStatus.setStatus(Status.LAST_UPDATE_FAILED);
1268                                 }
1269                                 synchronized(pdpStatusLock) {
1270                                         XACMLPdpServlet.status.set(newStatus);
1271                                 }
1272                         }
1273                 } catch (InterruptedException e) {
1274                         logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "interrupted"+e);
1275                         PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, "interrupted");
1276                         Thread.currentThread().interrupt();
1277                 }
1278         }       
1279
1280         public static PDPEngine getPDPEngine(){
1281                 PDPEngine myEngine = null;
1282                 synchronized(pdpEngineLock) {
1283                         myEngine = XACMLPdpServlet.pdpEngine;
1284                 }
1285                 return myEngine;
1286         }
1287
1288         public static Constructor<?> getCreateUpdatePolicyConstructor(){
1289                 return createUpdatePolicyConstructor;
1290         }
1291         
1292         private static void setCreateUpdatePolicyConstructor(String createUpdateResourceName) throws ServletException{
1293                 try{
1294                         Class<?> createUpdateclass = Class.forName(createUpdateResourceName);
1295                         createUpdatePolicyConstructor = createUpdateclass.getConstructor(PolicyParameters.class, String.class, boolean.class);
1296                 }catch(Exception e){
1297                         PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, "createUpdatePolicy.impl.className", "xacml.pdp.init" +e);
1298                         throw new ServletException("Could not find the Class name : " +createUpdateResourceName + "\n" +e.getMessage());
1299                 }
1300         }
1301 }