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