2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.policy.pdp.rest;
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;
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;
47 import org.apache.commons.io.IOUtils;
48 import org.apache.commons.logging.Log;
49 import org.apache.commons.logging.LogFactory;
50 import org.apache.http.entity.ContentType;
51 import org.onap.policy.api.PolicyParameters;
52 import org.onap.policy.common.im.AdministrativeStateException;
53 import org.onap.policy.common.im.ForwardProgressException;
54 import org.onap.policy.common.im.IntegrityMonitor;
55 import org.onap.policy.common.im.IntegrityMonitorException;
56 import org.onap.policy.common.im.IntegrityMonitorProperties;
57 import org.onap.policy.common.im.StandbyStatusException;
58 import org.onap.policy.common.logging.ONAPLoggingContext;
59 import org.onap.policy.common.logging.ONAPLoggingUtils;
60 import org.onap.policy.common.logging.eelf.MessageCodes;
61 import org.onap.policy.common.logging.eelf.PolicyLogger;
62 import org.onap.policy.pdp.rest.jmx.PdpRestMonitor;
63 import org.onap.policy.rest.XACMLRest;
64 import org.onap.policy.rest.XACMLRestProperties;
65 import org.onap.policy.xacml.api.XACMLErrorConstants;
66 import org.onap.policy.xacml.pdp.std.functions.PolicyList;
67 import org.onap.policy.xacml.std.pap.StdPDPStatus;
69 import com.att.research.xacml.api.Request;
70 import com.att.research.xacml.api.Response;
71 import com.att.research.xacml.api.pap.PDPStatus.Status;
72 import com.att.research.xacml.api.pdp.PDPEngine;
73 import com.att.research.xacml.api.pdp.PDPException;
74 import com.att.research.xacml.std.dom.DOMRequest;
75 import com.att.research.xacml.std.dom.DOMResponse;
76 import com.att.research.xacml.std.json.JSONRequest;
77 import com.att.research.xacml.std.json.JSONResponse;
78 import com.att.research.xacml.util.XACMLProperties;
79 import com.fasterxml.jackson.databind.ObjectMapper;
82 * Servlet implementation class XacmlPdpServlet
84 * This is an implementation of the XACML 3.0 RESTful Interface with added features to support
85 * simple PAP RESTful API for policy publishing and PIP configuration changes.
87 * If you are running this the first time, then we recommend you look at the xacml.pdp.properties file.
88 * This properties file has all the default parameter settings. If you are running the servlet as is,
89 * then we recommend setting up you're container to run it on port 8080 with context "/pdp". Wherever
90 * the default working directory is set to, a "config" directory will be created that holds the policy
91 * and pip cache. This setting is located in the xacml.pdp.properties file.
93 * When you are ready to customize, you can create a separate xacml.pdp.properties on you're local file
94 * system and setup the parameters as you wish. Just set the Java VM System variable to point to that file:
96 * -Dxacml.properties=/opt/app/xacml/etc/xacml.pdp.properties
98 * Or if you only want to change one or two properties, simply set the Java VM System variable for that property.
100 * -Dxacml.rest.pdp.register=false
105 description = "Implements the XACML PDP RESTful API and client PAP API.",
106 urlPatterns = { "/" },
109 @WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pdp.properties", description = "The location of the PDP xacml.pdp.properties file holding configuration information.")
111 public class XACMLPdpServlet extends HttpServlet implements Runnable {
112 private static final long serialVersionUID = 1L;
113 private static final String DEFAULT_MAX_CONTENT_LENGTH = "999999999"; //32767
114 private static final String CREATE_UPDATE_POLICY_SERVICE = "org.onap.policy.pdp.rest.api.services.CreateUpdatePolicyServiceImpl";
116 // Our application debug log
118 private static final Log logger = LogFactory.getLog(XACMLPdpServlet.class);
120 // This logger is specifically only for Xacml requests and their corresponding response.
121 // It's output ideally should be sent to a separate file from the application logger.
123 private static final Log requestLogger = LogFactory.getLog("xacml.request");
126 private static final Log auditLogger = LogFactory.getLog("auditLogger");
128 private static final PdpRestMonitor monitor = PdpRestMonitor.getSingleton();
131 // This thread may getting invoked on startup, to let the PAP know
132 // that we are up and running.
134 private static transient Thread registerThread = null;
135 private static transient XACMLPdpRegisterThread registerRunnable = null;
137 // This is our PDP engine pointer. There is a synchronized lock used
138 // for access to the pointer. In case we are servicing PEP requests while
139 // an update is occurring from the PAP.
141 private static PDPEngine pdpEngine = null;
142 private static final Object pdpEngineLock = new Object();
144 // This is our PDP's status. What policies are loaded (or not) and
145 // what PIP configurations are loaded (or not).
146 // There is a synchronized lock used for access to the object.
148 private static volatile StdPDPStatus status = new StdPDPStatus();
149 private static final Object pdpStatusLock = new Object();
150 private static Constructor<?> createUpdatePolicyConstructor;
152 private static final String ENVIORNMENT_HEADER = "Environment";
153 private static String environment = null;
155 // Queue of PUT requests
157 public static class PutRequest {
158 private Properties policyProperties = null;
159 private Properties pipConfigProperties = null;
161 PutRequest(Properties policies, Properties pips) {
162 this.policyProperties = policies;
163 this.pipConfigProperties = pips;
166 protected static volatile BlockingQueue<PutRequest> queue = null;
167 // For notification Delay.
168 private static int notificationDelay = 0;
169 public static int getNotificationDelay(){
170 return XACMLPdpServlet.notificationDelay;
173 private static String pdpResourceName;
174 private static String[] dependencyNodes = null;
177 // This is our configuration thread that attempts to load
178 // a new configuration request.
180 private static transient Thread configThread = null;
181 private static volatile boolean configThreadTerminate = false;
182 private transient ONAPLoggingContext baseLoggingContext = null;
183 private transient IntegrityMonitor im;
184 public IntegrityMonitor getIm() {
188 public void setIm(IntegrityMonitor im) {
193 * Default constructor.
195 public XACMLPdpServlet() {
196 //Default constructor.
200 * @see Servlet#init(ServletConfig)
203 public void init(ServletConfig config) throws ServletException {
204 String createUpdateResourceName = null;
205 String dependencyGroups = null;
209 XACMLRest.xacmlInit(config);
210 // Load the Notification Delay.
211 setNotificationDelay();
212 // Load Queue size. Not sure if we really need to have the queue bounded, we should look further into this
213 int queueSize = 50; // Set default Queue Size here.
214 queueSize = Integer.parseInt(XACMLProperties.getProperty("REQUEST_BUFFER_SIZE",String.valueOf(queueSize)));
215 initQueue(queueSize);
216 // Load our engine - this will use the latest configuration
217 // that was saved to disk and set our initial status object.
219 PDPEngine engine = XACMLPdpLoader.loadEngine(XACMLPdpServlet.status, null, null);
220 if (engine != null) {
221 synchronized(pdpEngineLock) {
224 // Notification will be Sent Here.
225 XACMLPdpLoader.sendNotification();
230 baseLoggingContext = new ONAPLoggingContext();
231 // fixed data that will be the same in all logging output goes here
233 String hostname = InetAddress.getLocalHost().getCanonicalHostName();
234 baseLoggingContext.setServer(hostname);
235 } catch (UnknownHostException e) {
236 logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get hostname for logging"+e);
239 Properties properties;
241 properties = XACMLProperties.getProperties();
242 } catch (IOException e) {
243 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e,
244 "Error loading properties with: XACMLProperties.getProperties()");
245 throw new ServletException(e.getMessage(), e.getCause());
247 if(properties.getProperty(XACMLRestProperties.PDP_RESOURCE_NAME)==null){
248 XACMLProperties.reloadProperties();
250 properties = XACMLProperties.getProperties();
251 } catch (IOException e) {
252 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e,
253 "Error loading properties with: XACMLProperties.getProperties()");
254 throw new ServletException(e.getMessage(), e.getCause());
256 PolicyLogger.info("\n Properties Given : \n" + properties.toString());
258 setPDPResourceName(properties);
259 dependencyGroups = properties.getProperty(IntegrityMonitorProperties.DEPENDENCY_GROUPS);
260 if(dependencyGroups == null){
261 PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, IntegrityMonitorProperties.DEPENDENCY_GROUPS, "xacml.pdp");
262 throw new ServletException("dependency_groups is null");
264 setDependencyNodes(dependencyGroups);
267 // CreateUpdatePolicy ResourceName
268 createUpdateResourceName = properties.getProperty("createUpdatePolicy.impl.className", CREATE_UPDATE_POLICY_SERVICE);
269 setCreateUpdatePolicyConstructor(createUpdateResourceName);
271 // Create an IntegrityMonitor
273 logger.info("Creating IntegrityMonitor");
274 im = IntegrityMonitor.getInstance(pdpResourceName, properties);
275 } catch (Exception e) {
276 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to create IntegrityMonitor" +e);
277 throw new ServletException(e);
279 startThreads(baseLoggingContext, new Thread(this));
282 private static void startThreads(ONAPLoggingContext baseLoggingContext, Thread thread) {
283 environment = XACMLProperties.getProperty("ENVIRONMENT", "DEVL");
285 // Kick off our thread to register with the PAP servlet.
287 if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER))) {
288 XACMLPdpServlet.registerRunnable = new XACMLPdpRegisterThread(baseLoggingContext);
289 XACMLPdpServlet.registerThread = new Thread(XACMLPdpServlet.registerRunnable);
290 XACMLPdpServlet.registerThread.start();
293 // This is our thread that manages incoming configuration
296 XACMLPdpServlet.configThread = thread;
297 XACMLPdpServlet.configThread.start();
300 private static void setDependencyNodes(String dependencyGroups) {
301 // dependency_groups is a semicolon-delimited list of groups, and
302 // each group is a comma-separated list of nodes. For our purposes
303 // we just need a list of dependencies without regard to grouping,
304 // so split the list into nodes separated by either comma or semicolon.
305 dependencyNodes = dependencyGroups.split("[;,]");
306 for (int i = 0 ; i < dependencyNodes.length ; i++){
307 dependencyNodes[i] = dependencyNodes[i].trim();
311 private static void setPDPResourceName(Properties properties) throws ServletException {
312 pdpResourceName = properties.getProperty(XACMLRestProperties.PDP_RESOURCE_NAME);
313 if(pdpResourceName == null){
314 PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, XACMLRestProperties.PDP_RESOURCE_NAME, "xacml.pdp");
315 throw new ServletException("pdpResourceName is null");
319 private static void initQueue(int queueSize) {
320 queue = new LinkedBlockingQueue<>(queueSize);
323 private static void setNotificationDelay() {
325 XACMLPdpServlet.notificationDelay = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_DELAY));
326 }catch(NumberFormatException e){
327 logger.error("Error in notification delay format, Taking the default value.", e);
332 * @see Servlet#destroy()
335 public void destroy() {
337 logger.info("Destroying....");
339 // Make sure the register thread is not running
341 if (XACMLPdpServlet.registerRunnable != null) {
343 XACMLPdpServlet.registerRunnable.terminate();
344 if (XACMLPdpServlet.registerThread != null) {
345 XACMLPdpServlet.registerThread.interrupt();
346 XACMLPdpServlet.registerThread.join();
348 } catch (InterruptedException e) {
349 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
350 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
351 XACMLPdpServlet.registerThread.interrupt();
355 // Make sure the configure thread is not running
357 setConfigThreadTerminate(true);
359 XACMLPdpServlet.configThread.interrupt();
360 XACMLPdpServlet.configThread.join();
361 } catch (InterruptedException e) {
362 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
363 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
364 XACMLPdpServlet.configThread.interrupt();
366 logger.info("Destroyed.");
369 private static void setConfigThreadTerminate(boolean value) {
370 XACMLPdpServlet.configThreadTerminate = value;
374 * PUT - The PAP engine sends configuration information using HTTP PUT request.
376 * One parameter is expected:
378 * config=[policy|pip|all]
380 * policy - Expect a properties file that contains updated lists of the root and referenced policies that the PDP should
381 * be using for PEP requests.
383 * Specifically should AT LEAST contain the following properties:
385 * xacml.referencedPolicies
387 * In addition, any relevant information needed by the PDP to load or retrieve the policies to store in its cache.
390 * xacml.rootPolicies=PolicyA.1, PolicyB.1
392 * PolicyA.1.url=http://localhost:9090/PAP?id=b2d7b86d-d8f1-4adf-ba9d-b68b2a90bee1&version=1
393 * PolicyB.1.url=http://localhost:9090/PAP/id=be962404-27f6-41d8-9521-5acb7f0238be&version=1
395 * xacml.referencedPolicies=RefPolicyC.1, RefPolicyD.1
397 * RefPolicyC.1.url=http://localhost:9090/PAP?id=foobar&version=1
398 * RefPolicyD.1.url=http://localhost:9090/PAP/id=example&version=1
400 * pip - Expect a properties file that contain PIP engine configuration properties.
402 * Specifically should AT LEAST the following property:
405 * In addition, any relevant information needed by the PDP to load and configure the PIPs.
408 * xacml.pip.engines=foo,bar
410 * foo.classname=com.foo
415 * bar.classname=com.bar
418 * all - Expect ALL new configuration properties for the PDP
420 * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response)
423 protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
424 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
425 loggingContext.transactionStarted();
426 if ((loggingContext.getRequestID() == null) || "".equals(loggingContext.getRequestID())){
427 UUID requestID = UUID.randomUUID();
428 loggingContext.setRequestID(requestID.toString());
429 PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doPut) so we generated one");
431 PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doPut)");
433 loggingContext.metricStarted();
434 loggingContext.metricEnded();
435 PolicyLogger.metrics("Metric example posted here - 1 of 2");
436 loggingContext.metricStarted();
437 loggingContext.metricEnded();
438 PolicyLogger.metrics("Metric example posted here - 2 of 2");
440 // Dump our request out
442 if (logger.isDebugEnabled()) {
443 XACMLRest.dumpRequest(request);
447 im.startTransaction();
449 catch (IntegrityMonitorException e) {
450 String message = e.toString();
451 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + e);
452 loggingContext.transactionEnded();
453 PolicyLogger.audit("Transaction Failed - See Error.log");
455 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
456 }catch(Exception e1){
457 logger.error("Exception occured while sending error in response" +e1);
462 // What is being PUT?
464 String cache = request.getParameter("cache");
466 // Should be a list of policy and pip configurations in Java properties format
468 if (cache != null && request.getContentType().equals("text/x-java-properties")) {
469 loggingContext.setServiceName("PDP.putConfig");
471 if (request.getContentLength() > Integer.parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", DEFAULT_MAX_CONTENT_LENGTH))) {
472 String message = "Content-Length larger than server will accept.";
473 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
474 loggingContext.transactionEnded();
475 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
476 PolicyLogger.audit("Transaction Failed - See Error.log");
477 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
481 logger.info("XACMLPdpServlet: calling doPutConfig to add properties to the queue");
482 this.doPutConfig(cache, request, response, loggingContext);
483 loggingContext.transactionEnded();
484 PolicyLogger.audit("Transaction ended");
488 logger.error("Exception Occured while getting Max Content lenght"+e);
491 String message = "Invalid cache: '" + cache + "' or content-type: '" + request.getContentType() + "'";
492 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message);
493 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
494 loggingContext.transactionEnded();
495 PolicyLogger.audit("Transaction Failed - See Error.log");
497 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
498 }catch(Exception e1){
499 logger.error("Exception occured while sending error in response" +e1);
506 protected void doPutConfig(String config, HttpServletRequest request, HttpServletResponse response, ONAPLoggingContext loggingContext) throws ServletException, IOException {
508 // prevent multiple configuration changes from stacking up
509 logger.info("XACMLPdpServlet: checking remainingCapacity of Queue.");
510 if (XACMLPdpServlet.queue.remainingCapacity() <= 0) {
511 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Queue capacity reached");
512 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "Queue capacity reached");
513 loggingContext.transactionEnded();
514 PolicyLogger.audit("Transaction Failed - See Error.log");
515 response.sendError(HttpServletResponse.SC_CONFLICT, "Multiple configuration changes waiting processing.");
519 // Read the properties data into an object.
521 Properties newProperties = new Properties();
522 newProperties.load(request.getInputStream());
523 // should have something in the request
524 if (newProperties.size() == 0) {
525 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No properties in PUT");
526 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No properties in PUT");
527 loggingContext.transactionEnded();
528 PolicyLogger.audit("Transaction Failed - See Error.log");
529 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT must contain at least one property");
533 // Which set of properties are they sending us? Whatever they send gets
534 // put on the queue (if there is room).
535 // For audit logging purposes, we consider the transaction done once the
536 // the request gets put on the queue.
538 if (config.equals("policies")) {
539 newProperties = XACMLProperties.getPolicyProperties(newProperties, true);
540 if (newProperties.size() == 0) {
541 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No policy properties in PUT");
542 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No policy properties in PUT");
543 loggingContext.transactionEnded();
544 PolicyLogger.audit("Transaction Failed - See Error.log");
545 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=policies must contain at least one policy property");
548 logger.info("XACMLPdpServlet: offer policies to queue. No pip properties added.");
549 XACMLPdpServlet.queue.offer(new PutRequest(newProperties, null));
550 loggingContext.transactionEnded();
551 auditLogger.info("Success");
552 PolicyLogger.audit("Success");
553 } else if (config.equals("pips")) {
554 newProperties = XACMLProperties.getPipProperties(newProperties);
555 if (newProperties.size() == 0) {
556 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No pips properties in PUT");
557 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No pips properties in PUT");
558 loggingContext.transactionEnded();
559 PolicyLogger.audit("Transaction Failed - See Error.log");
560 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=pips must contain at least one pip property");
563 logger.info("XACMLPdpServlet: offer pips to queue. No policy properties added.");
564 XACMLPdpServlet.queue.offer(new PutRequest(null, newProperties));
565 loggingContext.transactionEnded();
566 auditLogger.info("Success");
567 PolicyLogger.audit("Success");
568 } else if (config.equals("all")) {
569 Properties newPolicyProperties = XACMLProperties.getPolicyProperties(newProperties, true);
570 if (newPolicyProperties.size() == 0) {
571 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No policy properties in PUT");
572 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No policy properties in PUT");
573 loggingContext.transactionEnded();
574 PolicyLogger.audit("Transaction Failed - See Error.log");
575 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=all must contain at least one policy property");
578 Properties newPipProperties = XACMLProperties.getPipProperties(newProperties);
579 if (newPipProperties.size() == 0) {
580 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No pips properties in PUT");
581 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No pips properties in PUT");
582 loggingContext.transactionEnded();
583 PolicyLogger.audit("Transaction Failed - See Error.log");
584 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=all must contain at least one pip property");
587 logger.info("XACMLPdpServlet: offer policies and pips to queue.");
588 XACMLPdpServlet.queue.offer(new PutRequest(newPolicyProperties, newPipProperties));
589 loggingContext.transactionEnded();
590 auditLogger.info("Success");
591 PolicyLogger.audit("Success");
597 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid config value: " + config);
598 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Invalid config value: " + config);
599 loggingContext.transactionEnded();
600 PolicyLogger.audit("Transaction Failed - See Error.log");
601 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Config must be one of 'policies', 'pips', 'all'");
604 } catch (Exception e) {
605 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed to process new configuration.", e);
606 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to process new configuration");
607 loggingContext.transactionEnded();
608 PolicyLogger.audit("Transaction Failed - See Error.log");
610 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
611 }catch(Exception e1){
612 logger.error("Exception occured while sending error in response" +e1);
620 * Parameters: type=hb|config|Status
622 * 1. HeartBeat Status
624 * OK - All Policies are Loaded, All PIPs are Loaded
625 * LOADING_IN_PROGRESS - Currently loading a new policy set/pip configuration
626 * LAST_UPDATE_FAILED - Need to track the items that failed during last update
627 * LOAD_FAILURE - ??? Need to determine what information is sent and how
630 * return the StdPDPStatus object in the Response content
633 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
636 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
637 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
638 loggingContext.transactionStarted();
639 if ((loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")){
640 UUID requestID = UUID.randomUUID();
641 loggingContext.setRequestID(requestID.toString());
642 PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doGet) so we generated one");
644 PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doGet)");
646 loggingContext.metricStarted();
647 loggingContext.metricEnded();
648 PolicyLogger.metrics("Metric example posted here - 1 of 2");
649 loggingContext.metricStarted();
650 loggingContext.metricEnded();
651 PolicyLogger.metrics("Metric example posted here - 2 of 2");
653 XACMLRest.dumpRequest(request);
655 String pathInfo = request.getRequestURI();
656 if (pathInfo != null){
657 // health check from Global Site Selector (iDNS).
658 // DO NOT do a im.startTransaction for the test request
659 if (pathInfo.equals("/pdp/test")) {
660 loggingContext.setServiceName("iDNS:PDP.test");
663 //If we make it this far, all is well
664 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " is OK";
665 PolicyLogger.debug(message);
666 loggingContext.transactionEnded();
667 PolicyLogger.audit("Success");
668 response.setStatus(HttpServletResponse.SC_OK);
670 } catch (ForwardProgressException fpe){
671 //No forward progress is being made
672 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " is not making forward progress."
673 + " Exception Message: " + fpe.getMessage();
674 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + fpe);
675 loggingContext.transactionEnded();
676 PolicyLogger.audit("Transaction Failed - See Error.log");
678 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
679 }catch(Exception e1){
680 logger.error("Exception occured while sending error in response" +e1);
683 }catch (AdministrativeStateException ase){
684 //Administrative State is locked
685 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " Administrative State is LOCKED "
686 + " Exception Message: " + ase.getMessage();
687 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + ase);
688 loggingContext.transactionEnded();
689 PolicyLogger.audit("Transaction Failed - See Error.log");
691 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
692 }catch(Exception e1){
693 logger.error("Exception occured while sending error in response" +e1);
696 }catch (StandbyStatusException sse){
697 //Administrative State is locked
698 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " Standby Status is NOT PROVIDING SERVICE "
699 + " Exception Message: " + sse.getMessage();
700 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + sse);
701 loggingContext.transactionEnded();
702 PolicyLogger.audit("Transaction Failed - See Error.log");
704 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
705 }catch(Exception e1){
706 logger.error("Exception occured while sending error in response" +e1);
709 } catch (Exception e) {
710 //A subsystem is not making progress or is not responding
711 String eMsg = e.getMessage();
713 eMsg = "No Exception Message";
715 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " has had a subsystem failure."
716 + " Exception Message: " + eMsg;
717 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message );
718 //Get the specific list of subsystems that failed
719 String failedNodeList = null;
720 for(String node : dependencyNodes){
721 if(eMsg.contains(node)){
722 if(failedNodeList == null){
723 failedNodeList = node;
725 failedNodeList = failedNodeList.concat(","+node);
729 if(failedNodeList == null){
730 failedNodeList = "UnknownSubSystem";
732 response.addHeader("X-ONAP-SubsystemFailure", failedNodeList);
734 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
735 }catch(Exception e1){
736 logger.error("Exception occured while sending error in response" +e1);
738 loggingContext.transactionEnded();
739 PolicyLogger.audit("Transaction Failed - See Error.log" + e);
746 im.startTransaction();
748 catch (IntegrityMonitorException e) {
749 String message = e.toString();
750 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
751 loggingContext.transactionEnded();
752 PolicyLogger.audit("Transaction Failed - See Error.log" +e);
754 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
755 }catch(Exception e1){
756 logger.error("Exception occured while sending error in response" +e1);
761 // What are they requesting?
763 boolean returnHB = false;
764 response.setHeader("Cache-Control", "no-cache");
765 String type = request.getParameter("type");
766 // type might be null, so use equals on string constants
767 if ("config".equals(type)) {
768 loggingContext.setServiceName("PDP.getConfig");
769 response.setContentType("text/x-java-properties");
771 String lists = XACMLProperties.PROP_ROOTPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES, "");
772 lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, "") + "\n";
773 try (InputStream listInputStream = new ByteArrayInputStream(lists.getBytes());
774 InputStream pipInputStream = Files.newInputStream(XACMLPdpLoader.getPIPConfig());
775 OutputStream os = response.getOutputStream()) {
776 IOUtils.copy(listInputStream, os);
777 IOUtils.copy(pipInputStream, os);
779 loggingContext.transactionEnded();
780 auditLogger.info("Success");
781 PolicyLogger.audit("Success");
782 response.setStatus(HttpServletResponse.SC_OK);
783 } catch (Exception e) {
784 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed to copy property file", e);
785 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to copy property file");
786 loggingContext.transactionEnded();
787 PolicyLogger.audit("Transaction Failed - See Error.log");
789 response.sendError(400, "Failed to copy Property file");
790 }catch(Exception e1){
791 logger.error("Exception occured while sending error in response" +e1);
795 } else if ("hb".equals(type)) {
797 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
799 } else if ("Status".equals(type)) {
800 loggingContext.setServiceName("PDP.getStatus");
801 // convert response object to JSON and include in the response
802 synchronized(pdpStatusLock) {
803 ObjectMapper mapper = new ObjectMapper();
805 mapper.writeValue(response.getOutputStream(), status);
806 }catch(Exception e1){
807 logger.error("Exception occured while writing output stream" +e1);
810 response.setStatus(HttpServletResponse.SC_OK);
811 loggingContext.transactionEnded();
812 auditLogger.info("Success");
813 PolicyLogger.audit("Success");
816 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid type value: " + type);
817 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Invalid type value: " + type);
818 loggingContext.transactionEnded();
819 PolicyLogger.audit("Transaction Failed - See Error.log");
821 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "type not 'config' or 'hb'");
822 }catch(Exception e1){
823 logger.error("Exception occured while sending error in response" +e1);
827 synchronized(pdpStatusLock) {
828 response.addHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB, status.getStatus().toString());
831 loggingContext.transactionEnded();
832 PolicyLogger.audit("Transaction Ended");
838 * POST - We expect XACML requests to be posted by PEP applications. They can be in the form of XML or JSON according
839 * to the XACML 3.0 Specifications for both.
842 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
845 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
847 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
848 loggingContext.transactionStarted();
849 loggingContext.setServiceName("PDP.decide");
850 if ((loggingContext.getRequestID() == null) || ("".equals(loggingContext.getRequestID()))){
851 UUID requestID = UUID.randomUUID();
852 loggingContext.setRequestID(requestID.toString());
853 PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doPost) so we generated one");
855 PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doPost)");
857 loggingContext.metricStarted();
858 loggingContext.metricEnded();
859 PolicyLogger.metrics("Metric example posted here - 1 of 2");
860 loggingContext.metricStarted();
861 loggingContext.metricEnded();
862 PolicyLogger.metrics("Metric example posted here - 2 of 2");
863 monitor.pdpEvaluationAttempts();
866 im.startTransaction();
868 catch (IntegrityMonitorException e) {
869 String message = e.toString();
870 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + e);
871 loggingContext.transactionEnded();
872 PolicyLogger.audit("Transaction Failed - See Error.log");
874 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
875 }catch(Exception e1){
876 logger.error("Exception occured while sending error in response" +e1);
881 // no point in doing any work if we know from the get-go that we cannot do anything with the request
883 if (status.getLoadedRootPolicies().isEmpty()) {
884 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Request from PEP at " + request.getRequestURI() + " for service when PDP has No Root Policies loaded");
885 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, "Request from PEP at " + request.getRequestURI() + " for service when PDP has No Root Policies loaded");
886 loggingContext.transactionEnded();
887 PolicyLogger.audit("Transaction Failed - See Error.log");
889 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
890 }catch(Exception e1){
891 logger.error("Exception occured while sending error in response" +e1);
897 XACMLRest.dumpRequest(request);
899 // Set our no-cache header
901 response.setHeader("Cache-Control", "no-cache");
903 // They must send a Content-Type
905 if (request.getContentType() == null) {
906 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Must specify a Content-Type");
907 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Must specify a Content-Type");
908 loggingContext.transactionEnded();
909 PolicyLogger.audit("Transaction Failed - See Error.log");
911 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "no content-type given");
912 }catch(Exception e1){
913 logger.error("Exception occured while sending error in response" +e1);
919 // Limit the Content-Length to something reasonable
922 if (request.getContentLength() > Integer.parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", "32767"))) {
923 String message = "Content-Length larger than server will accept.";
924 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
925 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
926 loggingContext.transactionEnded();
927 PolicyLogger.audit("Transaction Failed - See Error.log");
928 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
933 logger.error("Exception occured while getting max content length"+e);
936 if (request.getContentLength() <= 0) {
937 String message = "Content-Length is negative";
938 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
939 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
940 loggingContext.transactionEnded();
941 PolicyLogger.audit("Transaction Failed - See Error.log");
943 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
944 }catch(Exception e1){
945 logger.error("Exception occured while sending error in response" +e1);
950 ContentType contentType = null;
952 contentType = ContentType.parse(request.getContentType());
954 catch (Exception e) {
955 String message = "Parsing Content-Type: " + request.getContentType() + ", error=" + e.getMessage();
956 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message, e);
957 loggingContext.transactionEnded();
958 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, message);
959 PolicyLogger.audit("Transaction Failed - See Error.log");
961 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
962 }catch(Exception e1){
963 logger.error("Exception occured while sending error in response" +e1);
969 // What exactly did they send us?
971 String incomingRequestString = null;
972 Request pdpRequest = null;
973 if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType()) ||
974 contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
975 contentType.getMimeType().equalsIgnoreCase("application/xacml+xml") ) {
977 // Read in the string
979 StringBuilder buffer = new StringBuilder();
980 BufferedReader reader = null;
982 reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
983 }catch(IOException e){
984 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error during reading input stream",e);
989 while((line = reader.readLine()) != null){
993 logger.error("Exception Occured while reading line"+e);
996 incomingRequestString = buffer.toString();
997 logger.info(incomingRequestString);
999 // Parse into a request
1002 if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
1003 pdpRequest = JSONRequest.load(incomingRequestString);
1004 } else if ( contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
1005 contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
1006 pdpRequest = DOMRequest.load(incomingRequestString);
1009 catch(Exception e) {
1010 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Could not parse request", e);
1011 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "Could not parse request");
1012 loggingContext.transactionEnded();
1013 PolicyLogger.audit("Transaction Failed - See Error.log");
1015 response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
1016 }catch(Exception e1){
1017 logger.error("Exception occured while sending error in response" +e1);
1019 im.endTransaction();
1023 String message = "unsupported content type" + request.getContentType();
1024 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
1025 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
1026 loggingContext.transactionEnded();
1027 PolicyLogger.audit("Transaction Failed - See Error.log");
1029 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
1030 }catch(Exception e1){
1031 logger.error("Exception occured while sending error in response" +e1);
1033 im.endTransaction();
1037 // Did we successfully get and parse a request?
1039 if (pdpRequest == null || pdpRequest.getRequestAttributes() == null || pdpRequest.getRequestAttributes().size() <= 0) {
1040 String message = "Zero Attributes found in the request";
1041 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
1042 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
1043 loggingContext.transactionEnded();
1044 PolicyLogger.audit("Transaction Failed - See Error.log");
1046 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
1047 }catch(Exception e1){
1048 logger.error("Exception occured while sending error in response" +e1);
1050 im.endTransaction();
1058 // Authenticating the Request here.
1060 if(!authorizeRequest(request)){
1061 String message = "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
1062 logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + message );
1063 PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS, message);
1064 loggingContext.transactionEnded();
1065 PolicyLogger.audit("Transaction Failed - See Error.log");
1066 response.sendError(HttpServletResponse.SC_FORBIDDEN, message);
1067 im.endTransaction();
1071 // Get the pointer to the PDP Engine
1073 PDPEngine myEngine = null;
1074 synchronized(pdpEngineLock) {
1075 myEngine = XACMLPdpServlet.pdpEngine;
1077 if (myEngine == null) {
1078 String message = "No engine loaded.";
1079 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message);
1080 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
1081 loggingContext.transactionEnded();
1082 PolicyLogger.audit("Transaction Failed - See Error.log");
1083 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1084 im.endTransaction();
1088 // Send the request and save the response
1092 Response pdpResponse = null;
1094 synchronized(pdpEngineLock) {
1095 myEngine = XACMLPdpServlet.pdpEngine;
1097 PolicyList.clearPolicyList();
1098 lTimeStart = System.currentTimeMillis();
1099 pdpResponse = myEngine.decide(pdpRequest);
1100 lTimeEnd = System.currentTimeMillis();
1101 } catch (PDPException e) {
1102 String message = "Exception during decide: " + e.getMessage();
1103 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message +e);
1104 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
1105 loggingContext.transactionEnded();
1106 PolicyLogger.audit("Transaction Failed - See Error.log");
1108 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1109 }catch(Exception e1){
1110 logger.error("Exception occured while sending error in response" +e1);
1112 im.endTransaction();
1116 monitor.computeLatency(lTimeEnd - lTimeStart);
1117 requestLogger.info(lTimeStart + "=" + incomingRequestString);
1118 for(String policy : PolicyList.getpolicyList()){
1119 monitor.policyCountAdd(policy, 1);
1123 logger.info("PolicyID triggered in Request: " + PolicyList.getpolicyList());
1125 //need to go through the list and find out if the value is unique and then add it other wise
1126 // monitor.policyCountAdd(PolicyList.getpolicyList(), 1);
1128 if (logger.isDebugEnabled()) {
1129 logger.debug("Request time: " + (lTimeEnd - lTimeStart) + "ms");
1132 // Convert Response to appropriate Content-Type
1134 if (pdpResponse == null) {
1135 requestLogger.info(lTimeStart + "=" + "{}");
1137 throw new PDPException("Failed to get response from PDP engine.");
1138 }catch(Exception e1){
1139 logger.error("Exception occured while throwing Exception" +e1);
1143 // Set our content-type
1145 response.setContentType(contentType.getMimeType());
1147 // Convert the PDP response object to a String to
1148 // return to our caller as well as dump to our loggers.
1150 String outgoingResponseString = "";
1152 if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
1154 // Get it as a String. This is not very efficient but we need to log our
1155 // results for auditing.
1157 outgoingResponseString = JSONResponse.toString(pdpResponse, logger.isDebugEnabled());
1158 if (logger.isDebugEnabled()) {
1159 logger.debug(outgoingResponseString);
1161 // Get rid of whitespace
1163 outgoingResponseString = JSONResponse.toString(pdpResponse, false);
1165 } else if ( contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
1166 contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
1168 // Get it as a String. This is not very efficient but we need to log our
1169 // results for auditing.
1171 outgoingResponseString = DOMResponse.toString(pdpResponse, logger.isDebugEnabled());
1172 if (logger.isDebugEnabled()) {
1173 logger.debug(outgoingResponseString);
1175 // Get rid of whitespace
1177 outgoingResponseString = DOMResponse.toString(pdpResponse, false);
1180 // adding the jmx values for NA, Permit and Deny
1182 if (outgoingResponseString.contains("NotApplicable") || outgoingResponseString.contains("Decision not a Permit")){
1183 monitor.pdpEvaluationNA();
1186 if (outgoingResponseString.contains("Permit") && !outgoingResponseString.contains("Decision not a Permit")){
1187 monitor.pdpEvaluationPermit();
1190 if (outgoingResponseString.contains("Deny")){
1191 monitor.pdpEvaluationDeny();
1194 // lTimeStart is used as an ID within the requestLogger to match up
1195 // request's with responses.
1197 requestLogger.info(lTimeStart + "=" + outgoingResponseString);
1198 response.getWriter().print(outgoingResponseString);
1199 }catch(Exception e){
1200 logger.error("Exception Occured"+e );
1203 catch (Exception e) {
1204 String message = "Exception executing request: " + e;
1205 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message, e);
1206 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, message);
1207 loggingContext.transactionEnded();
1208 PolicyLogger.audit("Transaction Failed - See Error.log");
1210 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1211 }catch(Exception e1){
1212 logger.error("Exception occured while sending error in response" +e1);
1217 monitor.pdpEvaluationSuccess();
1218 response.setStatus(HttpServletResponse.SC_OK);
1220 loggingContext.transactionEnded();
1221 auditLogger.info("Success");
1222 PolicyLogger.audit("Success");
1227 * Added for Authorizing the PEP Requests for Environment check.
1229 private boolean authorizeRequest(HttpServletRequest request) {
1230 // Get the client Credentials from the Request header.
1231 HttpServletRequest httpServletRequest = request;
1232 String clientCredentials = httpServletRequest.getHeader(ENVIORNMENT_HEADER);
1233 if(clientCredentials!=null && clientCredentials.equalsIgnoreCase(environment)){
1243 // Keep running until we are told to terminate
1246 // variable not used, but constructor has needed side-effects so don't remove:
1247 while (! XACMLPdpServlet.configThreadTerminate) {
1248 logger.info("XACMLPdpServlet: Taking requests from the queue");
1249 PutRequest request = XACMLPdpServlet.queue.take();
1250 logger.info("XACMLPdpServlet: Taking requests from the queue COMPLETED");
1251 StdPDPStatus newStatus = new StdPDPStatus();
1253 PDPEngine newEngine = null;
1254 synchronized(pdpStatusLock) {
1255 XACMLPdpServlet.status.setStatus(Status.UPDATING_CONFIGURATION);
1257 logger.info("created new PDPEngine");
1258 newEngine = XACMLPdpLoader.loadEngine(newStatus, request.policyProperties, request.pipConfigProperties);
1260 if (newEngine != null) {
1261 logger.info("XACMLPdpServlet: newEngine created, assigning newEngine to the pdpEngine.");
1262 synchronized(XACMLPdpServlet.pdpEngineLock) {
1263 XACMLPdpServlet.pdpEngine = newEngine;
1265 logger.info("Saving configuration.");
1266 if (request.policyProperties != null) {
1267 logger.info("Saving configuration: Policy Properties: " + request.policyProperties);
1268 try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPDPPolicyCache())) {
1269 request.policyProperties.store(os, "");
1272 if (request.pipConfigProperties != null) {
1273 logger.info("Saving configuration: PIP Properties: " + request.pipConfigProperties);
1274 try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPIPConfig())) {
1275 request.pipConfigProperties.store(os, "");
1278 newStatus.setStatus(Status.UP_TO_DATE);
1279 } catch (Exception e) {
1280 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to store new properties."+e);
1281 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "Failed to store new properties");
1282 newStatus.setStatus(Status.LOAD_ERRORS);
1283 newStatus.addLoadWarning("Unable to save configuration: " + e.getMessage());
1287 newStatus.setStatus(Status.LAST_UPDATE_FAILED);
1289 synchronized(pdpStatusLock) {
1290 XACMLPdpServlet.status.set(newStatus);
1292 logger.info("New PDP Servlet Status: " + newStatus.getStatus());
1293 if (Status.UP_TO_DATE.equals(newStatus.getStatus())) {
1294 // Notification will be Sent Here.
1295 XACMLPdpLoader.sendNotification();
1298 } catch (InterruptedException e) {
1299 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "interrupted"+e);
1300 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, "interrupted");
1301 Thread.currentThread().interrupt();
1305 public static PDPEngine getPDPEngine(){
1306 PDPEngine myEngine = null;
1307 synchronized(pdpEngineLock) {
1308 myEngine = XACMLPdpServlet.pdpEngine;
1313 public static Constructor<?> getCreateUpdatePolicyConstructor(){
1314 return createUpdatePolicyConstructor;
1317 private static void setCreateUpdatePolicyConstructor(String createUpdateResourceName) throws ServletException{
1319 Class<?> createUpdateclass = Class.forName(createUpdateResourceName);
1320 createUpdatePolicyConstructor = createUpdateclass.getConstructor(PolicyParameters.class, String.class, boolean.class);
1321 }catch(Exception e){
1322 PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, "createUpdatePolicy.impl.className", "xacml.pdp.init" +e);
1323 throw new ServletException("Could not find the Class name : " +createUpdateResourceName + "\n" +e.getMessage());