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