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