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