Merge "Added changes to save original model file"
[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-2019 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         
280         try {
281             System.setProperty("msToscaModel.home", properties.getProperty("msToscaModel.home"));
282         } catch (Exception e) {
283            logger.error("ERROR: Unable to set msToscaModel.home- Please check the configuration");
284         }
285
286         startThreads(baseLoggingContext, new Thread(this));
287     }
288
289     private static void startThreads(ONAPLoggingContext baseLoggingContext, Thread thread) {
290         environment = XACMLProperties.getProperty("ENVIRONMENT", "DEVL");
291         //
292         // Kick off our thread to register with the PAP servlet.
293         //
294         if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER))) {
295             XACMLPdpServlet.registerRunnable = new XACMLPdpRegisterThread(baseLoggingContext);
296             XACMLPdpServlet.registerThread = new Thread(XACMLPdpServlet.registerRunnable);
297             XACMLPdpServlet.registerThread.start();
298         }
299         //
300         // This is our thread that manages incoming configuration
301         // changes.
302         //
303         XACMLPdpServlet.configThread = thread;
304         XACMLPdpServlet.configThread.start();
305     }
306
307     private static void setDependencyNodes(String dependencyGroups) {
308         // dependency_groups is a semicolon-delimited list of groups, and
309         // each group is a comma-separated list of nodes. For our purposes
310         // we just need a list of dependencies without regard to grouping,
311         // so split the list into nodes separated by either comma or semicolon.
312         dependencyNodes = dependencyGroups.split("[;,]");
313         for (int i = 0; i < dependencyNodes.length; i++) {
314             dependencyNodes[i] = dependencyNodes[i].trim();
315         }
316     }
317
318     private static void setPDPResourceName(Properties properties) throws ServletException {
319         pdpResourceName = properties.getProperty(XACMLRestProperties.PDP_RESOURCE_NAME);
320         if (pdpResourceName == null) {
321             PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, XACMLRestProperties.PDP_RESOURCE_NAME, "xacml.pdp");
322             throw new ServletException("pdpResourceName is null");
323         }
324     }
325
326     private static void initQueue(int queueSize) {
327         queue = new LinkedBlockingQueue<>(queueSize);
328     }
329
330     private static void setNotificationDelay() {
331         try {
332             XACMLPdpServlet.notificationDelay =
333                     Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_DELAY));
334         } catch (NumberFormatException e) {
335             logger.error("Error in notification delay format, Taking the default value.", e);
336         }
337     }
338
339     /**
340      * @see Servlet#destroy()
341      */
342     @Override
343     public void destroy() {
344         super.destroy();
345         logger.info("Destroying....");
346         //
347         // Make sure the register thread is not running
348         //
349         if (XACMLPdpServlet.registerRunnable != null) {
350             try {
351                 XACMLPdpServlet.registerRunnable.terminate();
352                 if (XACMLPdpServlet.registerThread != null) {
353                     XACMLPdpServlet.registerThread.interrupt();
354                     XACMLPdpServlet.registerThread.join();
355                 }
356             } catch (InterruptedException e) {
357                 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
358                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
359                 XACMLPdpServlet.registerThread.interrupt();
360             }
361         }
362         //
363         // Make sure the configure thread is not running
364         //
365         setConfigThreadTerminate(true);
366         try {
367             XACMLPdpServlet.configThread.interrupt();
368             XACMLPdpServlet.configThread.join();
369         } catch (InterruptedException e) {
370             logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
371             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
372             XACMLPdpServlet.configThread.interrupt();
373         }
374         logger.info("Destroyed.");
375     }
376
377     private static void setConfigThreadTerminate(boolean value) {
378         XACMLPdpServlet.configThreadTerminate = value;
379     }
380
381     /**
382      * PUT - The PAP engine sends configuration information using HTTP PUT request.
383      * 
384      * One parameter is expected:
385      * 
386      * config=[policy|pip|all]
387      * 
388      * policy - Expect a properties file that contains updated lists of the root and referenced policies that the PDP
389      * should be using for PEP requests.
390      * 
391      * Specifically should AT LEAST contain the following properties: xacml.rootPolicies xacml.referencedPolicies
392      * 
393      * In addition, any relevant information needed by the PDP to load or retrieve the policies to store in its cache.
394      *
395      * EXAMPLE: xacml.rootPolicies=PolicyA.1, PolicyB.1
396      *
397      * PolicyA.1.url=http://localhost:9090/PAP?id=b2d7b86d-d8f1-4adf-ba9d-b68b2a90bee1&version=1
398      * PolicyB.1.url=http://localhost:9090/PAP/id=be962404-27f6-41d8-9521-5acb7f0238be&version=1
399      * 
400      * xacml.referencedPolicies=RefPolicyC.1, RefPolicyD.1
401      *
402      * RefPolicyC.1.url=http://localhost:9090/PAP?id=foobar&version=1
403      * RefPolicyD.1.url=http://localhost:9090/PAP/id=example&version=1
404      * 
405      * pip - Expect a properties file that contain PIP engine configuration properties.
406      * 
407      * Specifically should AT LEAST the following property: xacml.pip.engines
408      * 
409      * In addition, any relevant information needed by the PDP to load and configure the PIPs.
410      * 
411      * EXAMPLE: xacml.pip.engines=foo,bar
412      * 
413      * foo.classname=com.foo foo.sample=abc foo.example=xyz ......
414      * 
415      * bar.classname=com.bar ......
416      * 
417      * all - Expect ALL new configuration properties for the PDP
418      * 
419      * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response)
420      */
421     @Override
422     protected void doPut(HttpServletRequest request, HttpServletResponse response)
423             throws ServletException, IOException {
424         ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
425         loggingContext.transactionStarted();
426         if ((loggingContext.getRequestID() == null) || "".equals(loggingContext.getRequestID())) {
427             UUID requestID = UUID.randomUUID();
428             loggingContext.setRequestID(requestID.toString());
429             PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doPut) so we generated one");
430         } else {
431             PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doPut)");
432         }
433         loggingContext.metricStarted();
434         loggingContext.metricEnded();
435         PolicyLogger.metrics("Metric example posted here - 1 of 2");
436         loggingContext.metricStarted();
437         loggingContext.metricEnded();
438         PolicyLogger.metrics("Metric example posted here - 2 of 2");
439         //
440         // Dump our request out
441         //
442         if (logger.isDebugEnabled()) {
443             XACMLRest.dumpRequest(request);
444         }
445
446         try {
447             im.startTransaction();
448         } catch (IntegrityMonitorException e) {
449             String message = e.toString();
450             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + e);
451             loggingContext.transactionEnded();
452             PolicyLogger.audit("Transaction Failed - See Error.log");
453             try {
454                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
455             } catch (Exception e1) {
456                 logger.error("Exception occured while sending error in response" + e1);
457             }
458             return;
459         }
460         //
461         // What is being PUT?
462         //
463         String cache = request.getParameter("cache");
464         //
465         // Should be a list of policy and pip configurations in Java properties format
466         //
467         if (cache != null && request.getContentType().equals("text/x-java-properties")) {
468             loggingContext.setServiceName("PDP.putConfig");
469             try {
470                 if (request.getContentLength() > Integer
471                         .parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", DEFAULT_MAX_CONTENT_LENGTH))) {
472                     String message = "Content-Length larger than server will accept.";
473                     logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
474                     loggingContext.transactionEnded();
475                     PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
476                     PolicyLogger.audit("Transaction Failed - See Error.log");
477                     response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
478                     im.endTransaction();
479                     return;
480                 }
481                 logger.info("XACMLPdpServlet: calling doPutConfig to add properties to the queue");
482                 this.doPutConfig(cache, request, response, loggingContext);
483                 loggingContext.transactionEnded();
484                 PolicyLogger.audit("Transaction ended");
485
486                 im.endTransaction();
487             } catch (Exception e) {
488                 logger.error("Exception Occured while getting Max Content lenght" + e);
489             }
490         } else {
491             String message = "Invalid cache: '" + cache + "' or content-type: '" + request.getContentType() + "'";
492             logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message);
493             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
494             loggingContext.transactionEnded();
495             PolicyLogger.audit("Transaction Failed - See Error.log");
496             try {
497                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
498             } catch (Exception e1) {
499                 logger.error("Exception occured while sending error in response" + e1);
500             }
501             im.endTransaction();
502             return;
503         }
504     }
505
506     protected void doPutConfig(String config, HttpServletRequest request, HttpServletResponse response,
507             ONAPLoggingContext loggingContext) throws IOException {
508         try {
509             // prevent multiple configuration changes from stacking up
510             logger.info("XACMLPdpServlet: checking remainingCapacity of Queue.");
511             if (XACMLPdpServlet.queue.remainingCapacity() <= 0) {
512                 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Queue capacity reached");
513                 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "Queue capacity reached");
514                 loggingContext.transactionEnded();
515                 PolicyLogger.audit("Transaction Failed - See Error.log");
516                 response.sendError(HttpServletResponse.SC_CONFLICT,
517                         "Multiple configuration changes waiting processing.");
518                 return;
519             }
520             //
521             // Read the properties data into an object.
522             //
523             Properties newProperties = new Properties();
524             newProperties.load(request.getInputStream());
525             // should have something in the request
526             if (newProperties.size() == 0) {
527                 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No properties in PUT");
528                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No properties in PUT");
529                 loggingContext.transactionEnded();
530                 PolicyLogger.audit("Transaction Failed - See Error.log");
531                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT must contain at least one property");
532                 return;
533             }
534             //
535             // Which set of properties are they sending us? Whatever they send gets
536             // put on the queue (if there is room).
537             // For audit logging purposes, we consider the transaction done once the
538             // the request gets put on the queue.
539             //
540             if (config.equals("policies")) {
541                 newProperties = XACMLProperties.getPolicyProperties(newProperties, true);
542                 if (newProperties.size() == 0) {
543                     logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No policy properties in PUT");
544                     PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No policy properties in PUT");
545                     loggingContext.transactionEnded();
546                     PolicyLogger.audit("Transaction Failed - See Error.log");
547                     response.sendError(HttpServletResponse.SC_BAD_REQUEST,
548                             "PUT with cache=policies must contain at least one policy property");
549                     return;
550                 }
551                 logger.info("XACMLPdpServlet: offer policies to queue. No pip properties added.");
552                 XACMLPdpServlet.queue.offer(new PutRequest(newProperties, null));
553                 loggingContext.transactionEnded();
554                 auditLogger.info("Success");
555                 PolicyLogger.audit("Success");
556             } else if (config.equals("pips")) {
557                 newProperties = XACMLProperties.getPipProperties(newProperties);
558                 if (newProperties.size() == 0) {
559                     logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No pips properties in PUT");
560                     PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No pips properties in PUT");
561                     loggingContext.transactionEnded();
562                     PolicyLogger.audit("Transaction Failed - See Error.log");
563                     response.sendError(HttpServletResponse.SC_BAD_REQUEST,
564                             "PUT with cache=pips must contain at least one pip property");
565                     return;
566                 }
567                 logger.info("XACMLPdpServlet: offer pips to queue. No policy properties added.");
568                 XACMLPdpServlet.queue.offer(new PutRequest(null, newProperties));
569                 loggingContext.transactionEnded();
570                 auditLogger.info("Success");
571                 PolicyLogger.audit("Success");
572             } else if (config.equals("all")) {
573                 Properties newPolicyProperties = XACMLProperties.getPolicyProperties(newProperties, true);
574                 if (newPolicyProperties.size() == 0) {
575                     logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No policy properties in PUT");
576                     PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No policy properties in PUT");
577                     loggingContext.transactionEnded();
578                     PolicyLogger.audit("Transaction Failed - See Error.log");
579                     response.sendError(HttpServletResponse.SC_BAD_REQUEST,
580                             "PUT with cache=all must contain at least one policy property");
581                     return;
582                 }
583                 Properties newPipProperties = XACMLProperties.getPipProperties(newProperties);
584                 if (newPipProperties.size() == 0) {
585                     logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No pips properties in PUT");
586                     PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No pips properties in PUT");
587                     loggingContext.transactionEnded();
588                     PolicyLogger.audit("Transaction Failed - See Error.log");
589                     response.sendError(HttpServletResponse.SC_BAD_REQUEST,
590                             "PUT with cache=all must contain at least one pip property");
591                     return;
592                 }
593                 logger.info("XACMLPdpServlet: offer policies and pips to queue.");
594                 XACMLPdpServlet.queue.offer(new PutRequest(newPolicyProperties, newPipProperties));
595                 loggingContext.transactionEnded();
596                 auditLogger.info("Success");
597                 PolicyLogger.audit("Success");
598
599             } else {
600                 //
601                 // Invalid value
602                 //
603                 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid config value: " + config);
604                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Invalid config value: " + config);
605                 loggingContext.transactionEnded();
606                 PolicyLogger.audit("Transaction Failed - See Error.log");
607                 response.sendError(HttpServletResponse.SC_BAD_REQUEST,
608                         "Config must be one of 'policies', 'pips', 'all'");
609                 return;
610             }
611         } catch (Exception e) {
612             logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed to process new configuration.", e);
613             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to process new configuration");
614             loggingContext.transactionEnded();
615             PolicyLogger.audit("Transaction Failed - See Error.log");
616             try {
617                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
618             } catch (Exception e1) {
619                 logger.error("Exception occured while sending error in response" + e1);
620             }
621             return;
622         }
623
624     }
625
626     /**
627      * Parameters: type=hb|config|Status
628      * 
629      * 1. HeartBeat Status HeartBeat OK - All Policies are Loaded, All PIPs are Loaded LOADING_IN_PROGRESS - Currently
630      * loading a new policy set/pip configuration LAST_UPDATE_FAILED - Need to track the items that failed during last
631      * update LOAD_FAILURE - ??? Need to determine what information is sent and how 2. Configuration 3. Status return
632      * the StdPDPStatus object in the Response content
633      * 
634      * 
635      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
636      */
637     @Override
638     protected void doGet(HttpServletRequest request, HttpServletResponse response)
639             throws ServletException, IOException {
640         ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
641         loggingContext.transactionStarted();
642         if ((loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")) {
643             UUID requestID = UUID.randomUUID();
644             loggingContext.setRequestID(requestID.toString());
645             PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doGet) so we generated one");
646         } else {
647             PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doGet)");
648         }
649         loggingContext.metricStarted();
650         loggingContext.metricEnded();
651         PolicyLogger.metrics("Metric example posted here - 1 of 2");
652         loggingContext.metricStarted();
653         loggingContext.metricEnded();
654         PolicyLogger.metrics("Metric example posted here - 2 of 2");
655
656         XACMLRest.dumpRequest(request);
657
658         String pathInfo = request.getRequestURI();
659         if (pathInfo != null && "/pdp/test".equals(pathInfo)) {
660             // health check from Global Site Selector (iDNS).
661             // DO NOT do a im.startTransaction for the test request
662             loggingContext.setServiceName("iDNS:PDP.test");
663             try {
664                 im.evaluateSanity();
665                 // If we make it this far, all is well
666                 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " is OK";
667                 PolicyLogger.debug(message);
668                 PolicyLogger.audit("Success");
669                 response.setStatus(HttpServletResponse.SC_OK);
670                 return;
671             } catch (ForwardProgressException | AdministrativeStateException | StandbyStatusException fpe) {
672                 // No forward progress is being made
673                 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " is not making forward progress."
674                         + " Exception Message: " + fpe.getMessage();
675                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + fpe);
676                 PolicyLogger.audit("Transaction Failed - See Error.log");
677                 try {
678                     response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
679                 } catch (Exception e1) {
680                     logger.error("Exception occured while sending error in response" + e1);
681                 }
682                 return;
683             } catch (Exception e) {
684                 // A subsystem is not making progress or is not responding
685                 String eMsg = e.getMessage();
686                 if (eMsg == null) {
687                     eMsg = "No Exception Message";
688                 }
689                 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " has had a subsystem failure."
690                         + " Exception Message: " + eMsg;
691                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
692                 // Get the specific list of subsystems that failed
693                 String failedNodeList = null;
694                 for (String node : dependencyNodes) {
695                     if (eMsg.contains(node)) {
696                         if (failedNodeList == null) {
697                             failedNodeList = node;
698                         } else {
699                             failedNodeList = failedNodeList.concat("," + node);
700                         }
701                     }
702                 }
703                 if (failedNodeList == null) {
704                     failedNodeList = "UnknownSubSystem";
705                 }
706                 response.addHeader("X-ONAP-SubsystemFailure", failedNodeList);
707                 try {
708                     response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
709                 } catch (Exception e1) {
710                     logger.error("Exception occured while sending error in response" + e1);
711                 }
712                 PolicyLogger.audit("Transaction Failed - See Error.log" + e);
713                 return;
714             } finally {
715                 loggingContext.transactionEnded();
716             }
717         }
718
719         try {
720             im.startTransaction();
721         } catch (IntegrityMonitorException e) {
722             String message = e.toString();
723             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
724             loggingContext.transactionEnded();
725             PolicyLogger.audit("Transaction Failed - See Error.log" + e);
726             try {
727                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
728             } catch (Exception e1) {
729                 logger.error("Exception occured while sending error in response" + e1);
730             }
731             return;
732         }
733         //
734         // What are they requesting?
735         //
736         boolean returnHB = false;
737         response.setHeader("Cache-Control", "no-cache");
738         String type = request.getParameter("type");
739         // type might be null, so use equals on string constants
740         if ("config".equals(type)) {
741             loggingContext.setServiceName("PDP.getConfig");
742             response.setContentType("text/x-java-properties");
743             try {
744                 String lists = XACMLProperties.PROP_ROOTPOLICIES + "="
745                         + XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES, "");
746                 lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "="
747                         + XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, "") + "\n";
748                 try (InputStream listInputStream = new ByteArrayInputStream(lists.getBytes());
749                         InputStream pipInputStream = Files.newInputStream(XACMLPdpLoader.getPIPConfig());
750                         OutputStream os = response.getOutputStream()) {
751                     IOUtils.copy(listInputStream, os);
752                     IOUtils.copy(pipInputStream, os);
753                 }
754                 loggingContext.transactionEnded();
755                 auditLogger.info("Success");
756                 PolicyLogger.audit("Success");
757                 response.setStatus(HttpServletResponse.SC_OK);
758             } catch (Exception e) {
759                 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed to copy property file", e);
760                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to copy property file");
761                 loggingContext.transactionEnded();
762                 PolicyLogger.audit("Transaction Failed - See Error.log");
763                 try {
764                     response.sendError(400, "Failed to copy Property file");
765                 } catch (Exception e1) {
766                     logger.error("Exception occured while sending error in response" + e1);
767                 }
768             }
769
770         } else if ("hb".equals(type)) {
771             returnHB = true;
772             response.setStatus(HttpServletResponse.SC_NO_CONTENT);
773
774         } else if ("Status".equals(type)) {
775             loggingContext.setServiceName("PDP.getStatus");
776             // convert response object to JSON and include in the response
777             synchronized (pdpStatusLock) {
778                 ObjectMapper mapper = new ObjectMapper();
779                 try {
780                     mapper.writeValue(response.getOutputStream(), status);
781                 } catch (Exception e1) {
782                     logger.error("Exception occured while writing output stream" + e1);
783                 }
784             }
785             response.setStatus(HttpServletResponse.SC_OK);
786             loggingContext.transactionEnded();
787             auditLogger.info("Success");
788             PolicyLogger.audit("Success");
789
790         } else {
791             logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid type value: " + type);
792             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Invalid type value: " + type);
793             loggingContext.transactionEnded();
794             PolicyLogger.audit("Transaction Failed - See Error.log");
795             try {
796                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "type not 'config' or 'hb'");
797             } catch (Exception e1) {
798                 logger.error("Exception occured while sending error in response" + e1);
799             }
800         }
801         if (returnHB) {
802             synchronized (pdpStatusLock) {
803                 response.addHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB, status.getStatus().toString());
804             }
805         }
806         loggingContext.transactionEnded();
807         PolicyLogger.audit("Transaction Ended");
808         im.endTransaction();
809
810     }
811
812     /**
813      * POST - We expect XACML requests to be posted by PEP applications. They can be in the form of XML or JSON
814      * according to the XACML 3.0 Specifications for both.
815      * 
816      * 
817      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
818      */
819     @Override
820     protected void doPost(HttpServletRequest request, HttpServletResponse response)
821             throws ServletException, IOException {
822
823         ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
824         loggingContext.transactionStarted();
825         loggingContext.setServiceName("PDP.decide");
826         if ((loggingContext.getRequestID() == null) || ("".equals(loggingContext.getRequestID()))) {
827             UUID requestID = UUID.randomUUID();
828             loggingContext.setRequestID(requestID.toString());
829             PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doPost) so we generated one");
830         } else {
831             PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doPost)");
832         }
833         loggingContext.metricStarted();
834         loggingContext.metricEnded();
835         PolicyLogger.metrics("Metric example posted here - 1 of 2");
836         loggingContext.metricStarted();
837         loggingContext.metricEnded();
838         PolicyLogger.metrics("Metric example posted here - 2 of 2");
839         monitor.pdpEvaluationAttempts();
840
841         try {
842             im.startTransaction();
843         } catch (IntegrityMonitorException e) {
844             String message = e.toString();
845             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + e);
846             loggingContext.transactionEnded();
847             PolicyLogger.audit("Transaction Failed - See Error.log");
848             try {
849                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
850             } catch (Exception e1) {
851                 logger.error("Exception occured while sending error in response" + e1);
852             }
853             return;
854         }
855         //
856         // no point in doing any work if we know from the get-go that we cannot do anything with the request
857         //
858         if (status.getLoadedRootPolicies().isEmpty()) {
859             logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Request from PEP at " + request.getRequestURI()
860                     + " for service when PDP has No Root Policies loaded");
861             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, "Request from PEP at " + request.getRequestURI()
862                     + " for service when PDP has No Root Policies loaded");
863             loggingContext.transactionEnded();
864             PolicyLogger.audit("Transaction Failed - See Error.log");
865             try {
866                 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
867             } catch (Exception e1) {
868                 logger.error("Exception occured while sending error in response" + e1);
869             }
870             im.endTransaction();
871             return;
872         }
873
874         XACMLRest.dumpRequest(request);
875         //
876         // Set our no-cache header
877         //
878         response.setHeader("Cache-Control", "no-cache");
879         //
880         // They must send a Content-Type
881         //
882         if (request.getContentType() == null) {
883             logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Must specify a Content-Type");
884             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Must specify a Content-Type");
885             loggingContext.transactionEnded();
886             PolicyLogger.audit("Transaction Failed - See Error.log");
887             try {
888                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "no content-type given");
889             } catch (Exception e1) {
890                 logger.error("Exception occured while sending error in response" + e1);
891             }
892             im.endTransaction();
893             return;
894         }
895         //
896         // Limit the Content-Length to something reasonable
897         //
898         try {
899             if (request.getContentLength() > Integer
900                     .parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", "32767"))) {
901                 String message = "Content-Length larger than server will accept.";
902                 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
903                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
904                 loggingContext.transactionEnded();
905                 PolicyLogger.audit("Transaction Failed - See Error.log");
906                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
907                 im.endTransaction();
908                 return;
909             }
910         } catch (Exception e) {
911             logger.error("Exception occured while getting max content length" + e);
912         }
913
914         if (request.getContentLength() <= 0) {
915             String message = "Content-Length is negative";
916             logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
917             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
918             loggingContext.transactionEnded();
919             PolicyLogger.audit("Transaction Failed - See Error.log");
920             try {
921                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
922             } catch (Exception e1) {
923                 logger.error("Exception occured while sending error in response" + e1);
924             }
925             im.endTransaction();
926             return;
927         }
928         ContentType contentType = null;
929         try {
930             contentType = ContentType.parse(request.getContentType());
931         } catch (Exception e) {
932             String message = "Parsing Content-Type: " + request.getContentType() + ", error=" + e.getMessage();
933             logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message, e);
934             loggingContext.transactionEnded();
935             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, message);
936             PolicyLogger.audit("Transaction Failed - See Error.log");
937             try {
938                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
939             } catch (Exception e1) {
940                 logger.error("Exception occured while sending error in response" + e1);
941             }
942             im.endTransaction();
943             return;
944         }
945         //
946         // What exactly did they send us?
947         //
948         String incomingRequestString = null;
949         Request pdpRequest = null;
950         if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())
951                 || contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType())
952                 || contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
953             //
954             // Read in the string
955             //
956             StringBuilder buffer = new StringBuilder();
957             BufferedReader reader = null;
958             try {
959                 reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
960             } catch (IOException e) {
961                 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error during reading input stream", e);
962                 return;
963             }
964             String line;
965             try {
966                 while ((line = reader.readLine()) != null) {
967                     buffer.append(line);
968                 }
969             } catch (Exception e) {
970                 logger.error("Exception Occured while reading line" + e);
971             }
972
973             incomingRequestString = buffer.toString();
974             logger.info(incomingRequestString);
975             //
976             // Parse into a request
977             //
978             try {
979                 if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
980                     pdpRequest = JSONRequest.load(incomingRequestString);
981                 } else if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType())
982                         || "application/xacml+xml".equalsIgnoreCase(contentType.getMimeType())) {
983                     pdpRequest = DOMRequest.load(incomingRequestString);
984                 }
985             } catch (Exception e) {
986                 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Could not parse request", e);
987                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "Could not parse request");
988                 loggingContext.transactionEnded();
989                 PolicyLogger.audit("Transaction Failed - See Error.log");
990                 try {
991                     response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
992                 } catch (Exception e1) {
993                     logger.error("Exception occured while sending error in response" + e1);
994                 }
995                 im.endTransaction();
996                 return;
997             }
998         } else {
999             String message = "unsupported content type" + request.getContentType();
1000             logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
1001             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
1002             loggingContext.transactionEnded();
1003             PolicyLogger.audit("Transaction Failed - See Error.log");
1004             try {
1005                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
1006             } catch (Exception e1) {
1007                 logger.error("Exception occured while sending error in response" + e1);
1008             }
1009             im.endTransaction();
1010             return;
1011         }
1012         //
1013         // Did we successfully get and parse a request?
1014         //
1015         if (pdpRequest == null || pdpRequest.getRequestAttributes() == null
1016                 || pdpRequest.getRequestAttributes().isEmpty()) {
1017             String message = "Zero Attributes found in the request";
1018             logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
1019             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
1020             loggingContext.transactionEnded();
1021             PolicyLogger.audit("Transaction Failed - See Error.log");
1022             try {
1023                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
1024             } catch (Exception e1) {
1025                 logger.error("Exception occured while sending error in response" + e1);
1026             }
1027             im.endTransaction();
1028             return;
1029         }
1030         //
1031         // Run it
1032         //
1033         try {
1034             //
1035             // Authenticating the Request here.
1036             //
1037             if (!authorizeRequest(request)) {
1038                 String message =
1039                         "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
1040                 logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + message);
1041                 PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS, message);
1042                 loggingContext.transactionEnded();
1043                 PolicyLogger.audit("Transaction Failed - See Error.log");
1044                 response.sendError(HttpServletResponse.SC_FORBIDDEN, message);
1045                 im.endTransaction();
1046                 return;
1047             }
1048             //
1049             // Get the pointer to the PDP Engine
1050             //
1051             PDPEngine myEngine = null;
1052             synchronized (pdpEngineLock) {
1053                 myEngine = XACMLPdpServlet.pdpEngine;
1054             }
1055             if (myEngine == null) {
1056                 String message = "No engine loaded.";
1057                 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message);
1058                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
1059                 loggingContext.transactionEnded();
1060                 PolicyLogger.audit("Transaction Failed - See Error.log");
1061                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1062                 im.endTransaction();
1063                 return;
1064             }
1065             //
1066             // Send the request and save the response
1067             //
1068             long lTimeStart;
1069             long lTimeEnd;
1070             Response pdpResponse = null;
1071
1072             synchronized (pdpEngineLock) {
1073                 myEngine = XACMLPdpServlet.pdpEngine;
1074                 try {
1075                     PolicyList.clearPolicyList();
1076                     lTimeStart = System.currentTimeMillis();
1077                     pdpResponse = myEngine.decide(pdpRequest);
1078                     lTimeEnd = System.currentTimeMillis();
1079                 } catch (PDPException e) {
1080                     String message = "Exception during decide: " + e.getMessage();
1081                     logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message + e);
1082                     PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
1083                     loggingContext.transactionEnded();
1084                     PolicyLogger.audit("Transaction Failed - See Error.log");
1085                     try {
1086                         response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1087                     } catch (Exception e1) {
1088                         logger.error("Exception occured while sending error in response" + e1);
1089                     }
1090                     im.endTransaction();
1091                     return;
1092                 }
1093             }
1094             monitor.computeLatency(lTimeEnd - lTimeStart);
1095             requestLogger.info(lTimeStart + "=" + incomingRequestString);
1096             for (String policy : PolicyList.getpolicyList()) {
1097                 monitor.policyCountAdd(policy, 1);
1098             }
1099
1100
1101             logger.info("PolicyID triggered in Request: " + PolicyList.getpolicyList());
1102
1103             // need to go through the list and find out if the value is unique and then add it other wise
1104             // monitor.policyCountAdd(PolicyList.getpolicyList(), 1);
1105
1106             if (logger.isDebugEnabled()) {
1107                 logger.debug("Request time: " + (lTimeEnd - lTimeStart) + "ms");
1108             }
1109             //
1110             // Convert Response to appropriate Content-Type
1111             //
1112             if (pdpResponse == null) {
1113                 requestLogger.info(lTimeStart + "=" + "{}");
1114                 try {
1115                     throw new PDPException("Failed to get response from PDP engine.");
1116                 } catch (Exception e1) {
1117                     logger.error("Exception occured while throwing Exception" + e1);
1118                 }
1119             }
1120             //
1121             // Set our content-type
1122             //
1123             response.setContentType(contentType.getMimeType());
1124             //
1125             // Convert the PDP response object to a String to
1126             // return to our caller as well as dump to our loggers.
1127             //
1128             String outgoingResponseString = "";
1129             try {
1130                 if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
1131                     //
1132                     // Get it as a String. This is not very efficient but we need to log our
1133                     // results for auditing.
1134                     //
1135                     outgoingResponseString = JSONResponse.toString(pdpResponse, logger.isDebugEnabled());
1136                     if (logger.isDebugEnabled()) {
1137                         logger.debug(outgoingResponseString);
1138                         //
1139                         // Get rid of whitespace
1140                         //
1141                         outgoingResponseString = JSONResponse.toString(pdpResponse, false);
1142                     }
1143                 } else if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType())
1144                         || contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
1145                     //
1146                     // Get it as a String. This is not very efficient but we need to log our
1147                     // results for auditing.
1148                     //
1149                     outgoingResponseString = DOMResponse.toString(pdpResponse, logger.isDebugEnabled());
1150                     if (logger.isDebugEnabled()) {
1151                         logger.debug(outgoingResponseString);
1152                         //
1153                         // Get rid of whitespace
1154                         //
1155                         outgoingResponseString = DOMResponse.toString(pdpResponse, false);
1156                     }
1157                 }
1158                 // adding the jmx values for NA, Permit and Deny
1159                 //
1160                 if (outgoingResponseString.contains("NotApplicable")
1161                         || outgoingResponseString.contains("Decision not a Permit")) {
1162                     monitor.pdpEvaluationNA();
1163                 }
1164
1165                 if (outgoingResponseString.contains("Permit")
1166                         && !outgoingResponseString.contains("Decision not a Permit")) {
1167                     monitor.pdpEvaluationPermit();
1168                 }
1169
1170                 if (outgoingResponseString.contains("Deny")) {
1171                     monitor.pdpEvaluationDeny();
1172                 }
1173                 //
1174                 // lTimeStart is used as an ID within the requestLogger to match up
1175                 // request's with responses.
1176                 //
1177                 requestLogger.info(lTimeStart + "=" + outgoingResponseString);
1178                 response.getWriter().print(outgoingResponseString);
1179             } catch (Exception e) {
1180                 logger.error("Exception Occured" + e);
1181             }
1182         } catch (Exception e) {
1183             String message = "Exception executing request: " + e;
1184             logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message, e);
1185             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, message);
1186             loggingContext.transactionEnded();
1187             PolicyLogger.audit("Transaction Failed - See Error.log");
1188             try {
1189                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1190             } catch (Exception e1) {
1191                 logger.error("Exception occured while sending error in response" + e1);
1192             }
1193             return;
1194         }
1195
1196         monitor.pdpEvaluationSuccess();
1197         response.setStatus(HttpServletResponse.SC_OK);
1198
1199         loggingContext.transactionEnded();
1200         auditLogger.info("Success");
1201         PolicyLogger.audit("Success");
1202
1203     }
1204
1205     /*
1206      * Added for Authorizing the PEP Requests for Environment check.
1207      */
1208     private boolean authorizeRequest(HttpServletRequest request) {
1209         // Get the client Credentials from the Request header.
1210         HttpServletRequest httpServletRequest = request;
1211         String clientCredentials = httpServletRequest.getHeader(ENVIORNMENT_HEADER);
1212         if (clientCredentials != null && clientCredentials.equalsIgnoreCase(environment)) {
1213             return true;
1214         } else {
1215             return false;
1216         }
1217     }
1218
1219     @Override
1220     public void run() {
1221         //
1222         // Keep running until we are told to terminate
1223         //
1224         try {
1225             // variable not used, but constructor has needed side-effects so don't remove:
1226             while (!XACMLPdpServlet.configThreadTerminate) {
1227                 logger.info("XACMLPdpServlet: Taking requests from the queue");
1228                 PutRequest request = XACMLPdpServlet.queue.take();
1229                 logger.info("XACMLPdpServlet: Taking requests from the queue COMPLETED");
1230                 StdPDPStatus newStatus = new StdPDPStatus();
1231
1232                 PDPEngine newEngine = null;
1233                 synchronized (pdpStatusLock) {
1234                     XACMLPdpServlet.status.setStatus(Status.UPDATING_CONFIGURATION);
1235
1236                     logger.info("created new PDPEngine");
1237                     newEngine =
1238                             XACMLPdpLoader.loadEngine(newStatus, request.policyProperties, request.pipConfigProperties);
1239                 }
1240                 if (newEngine != null) {
1241                     logger.info("XACMLPdpServlet: newEngine created, assigning newEngine to the pdpEngine.");
1242                     synchronized (XACMLPdpServlet.pdpEngineLock) {
1243                         XACMLPdpServlet.pdpEngine = newEngine;
1244                         try {
1245                             logger.info("Saving configuration.");
1246                             if (request.policyProperties != null) {
1247                                 logger.info("Saving configuration: Policy Properties: " + request.policyProperties);
1248                                 try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPDPPolicyCache())) {
1249                                     request.policyProperties.store(os, "");
1250                                 }
1251                             }
1252                             if (request.pipConfigProperties != null) {
1253                                 logger.info("Saving configuration: PIP Properties: " + request.pipConfigProperties);
1254                                 try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPIPConfig())) {
1255                                     request.pipConfigProperties.store(os, "");
1256                                 }
1257                             }
1258                             newStatus.setStatus(Status.UP_TO_DATE);
1259                         } catch (Exception e) {
1260                             logger.error(
1261                                     XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to store new properties." + e);
1262                             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "Failed to store new properties");
1263                             newStatus.setStatus(Status.LOAD_ERRORS);
1264                             newStatus.addLoadWarning("Unable to save configuration: " + e.getMessage());
1265                         }
1266                     }
1267                 } else {
1268                     newStatus.setStatus(Status.LAST_UPDATE_FAILED);
1269                 }
1270                 synchronized (pdpStatusLock) {
1271                     XACMLPdpServlet.status.set(newStatus);
1272                 }
1273                 logger.info("New PDP Servlet Status: " + newStatus.getStatus());
1274                 if (Status.UP_TO_DATE.equals(newStatus.getStatus())) {
1275                     // Notification will be Sent Here.
1276                     XACMLPdpLoader.sendNotification();
1277                 }
1278             }
1279         } catch (InterruptedException e) {
1280             logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "interrupted" + e);
1281             PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, "interrupted");
1282             Thread.currentThread().interrupt();
1283         }
1284     }
1285
1286     public static PDPEngine getPDPEngine() {
1287         PDPEngine myEngine = null;
1288         synchronized (pdpEngineLock) {
1289             myEngine = XACMLPdpServlet.pdpEngine;
1290         }
1291         return myEngine;
1292     }
1293
1294     public static Constructor<?> getCreateUpdatePolicyConstructor() {
1295         return createUpdatePolicyConstructor;
1296     }
1297
1298     public static Object getPDPEngineLock() {
1299         return pdpEngineLock;
1300     }
1301
1302     private static void setCreateUpdatePolicyConstructor(String createUpdateResourceName) throws ServletException {
1303         try {
1304             Class<?> createUpdateclass = Class.forName(createUpdateResourceName);
1305             createUpdatePolicyConstructor =
1306                     createUpdateclass.getConstructor(PolicyParameters.class, String.class, boolean.class);
1307         } catch (Exception e) {
1308             PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, "createUpdatePolicy.impl.className",
1309                     "xacml.pdp.init" + e);
1310             throw new ServletException(
1311                     "Could not find the Class name : " + createUpdateResourceName + "\n" + e.getMessage());
1312         }
1313     }
1314 }