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;
37 import javax.servlet.Servlet;
38 import javax.servlet.ServletConfig;
39 import javax.servlet.ServletException;
40 import javax.servlet.annotation.WebInitParam;
41 import javax.servlet.annotation.WebServlet;
42 import javax.servlet.http.HttpServlet;
43 import javax.servlet.http.HttpServletRequest;
44 import javax.servlet.http.HttpServletResponse;
45 import org.apache.commons.io.IOUtils;
46 import org.apache.commons.logging.Log;
47 import org.apache.commons.logging.LogFactory;
48 import org.apache.http.entity.ContentType;
49 import org.onap.policy.api.PolicyParameters;
50 import org.onap.policy.common.im.AdministrativeStateException;
51 import org.onap.policy.common.im.ForwardProgressException;
52 import org.onap.policy.common.im.IntegrityMonitor;
53 import org.onap.policy.common.im.IntegrityMonitorException;
54 import org.onap.policy.common.im.IntegrityMonitorProperties;
55 import org.onap.policy.common.im.StandbyStatusException;
56 import org.onap.policy.common.logging.ONAPLoggingContext;
57 import org.onap.policy.common.logging.ONAPLoggingUtils;
58 import org.onap.policy.common.logging.eelf.MessageCodes;
59 import org.onap.policy.common.logging.eelf.PolicyLogger;
60 import org.onap.policy.pdp.rest.jmx.PdpRestMonitor;
61 import org.onap.policy.rest.XACMLRest;
62 import org.onap.policy.rest.XACMLRestProperties;
63 import org.onap.policy.xacml.api.XACMLErrorConstants;
64 import org.onap.policy.xacml.pdp.std.functions.PolicyList;
65 import org.onap.policy.xacml.std.pap.StdPDPStatus;
66 import com.att.research.xacml.api.Request;
67 import com.att.research.xacml.api.Response;
68 import com.att.research.xacml.api.pap.PDPStatus.Status;
69 import com.att.research.xacml.api.pdp.PDPEngine;
70 import com.att.research.xacml.api.pdp.PDPException;
71 import com.att.research.xacml.std.dom.DOMRequest;
72 import com.att.research.xacml.std.dom.DOMResponse;
73 import com.att.research.xacml.std.json.JSONRequest;
74 import com.att.research.xacml.std.json.JSONResponse;
75 import com.att.research.xacml.util.XACMLProperties;
76 import com.fasterxml.jackson.databind.ObjectMapper;
79 * Servlet implementation class XacmlPdpServlet
81 * This is an implementation of the XACML 3.0 RESTful Interface with added features to support simple PAP RESTful API
82 * for policy publishing and PIP configuration changes.
84 * If you are running this the first time, then we recommend you look at the xacml.pdp.properties file. This properties
85 * file has all the default parameter settings. If you are running the servlet as is, then we recommend setting up
86 * you're container to run it on port 8080 with context "/pdp". Wherever the default working directory is set to, a
87 * "config" directory will be created that holds the policy and pip cache. This setting is located in the
88 * xacml.pdp.properties file.
90 * When you are ready to customize, you can create a separate xacml.pdp.properties on you're local file system and setup
91 * the parameters as you wish. Just set the Java VM System variable to point to that file:
93 * -Dxacml.properties=/opt/app/xacml/etc/xacml.pdp.properties
95 * Or if you only want to change one or two properties, simply set the Java VM System variable for that property.
97 * -Dxacml.rest.pdp.register=false
101 @WebServlet(description = "Implements the XACML PDP RESTful API and client PAP API.", urlPatterns = {"/"},
102 loadOnStartup = 1, initParams = {@WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pdp.properties",
103 description = "The location of the PDP xacml.pdp.properties file holding configuration information.")})
104 public class XACMLPdpServlet extends HttpServlet implements Runnable {
105 private static final long serialVersionUID = 1L;
106 private static final String DEFAULT_MAX_CONTENT_LENGTH = "999999999"; // 32767
107 private static final String CREATE_UPDATE_POLICY_SERVICE =
108 "org.onap.policy.pdp.rest.api.services.CreateUpdatePolicyServiceImpl";
110 // Our application debug log
112 private static final Log logger = LogFactory.getLog(XACMLPdpServlet.class);
114 // This logger is specifically only for Xacml requests and their corresponding response.
115 // It's output ideally should be sent to a separate file from the application logger.
117 private static final Log requestLogger = LogFactory.getLog("xacml.request");
120 private static final Log auditLogger = LogFactory.getLog("auditLogger");
122 public static final PdpRestMonitor monitor = PdpRestMonitor.getSingleton();
125 // This thread may getting invoked on startup, to let the PAP know
126 // that we are up and running.
128 private static transient Thread registerThread = null;
129 private static transient XACMLPdpRegisterThread registerRunnable = null;
131 // This is our PDP engine pointer. There is a synchronized lock used
132 // for access to the pointer. In case we are servicing PEP requests while
133 // an update is occurring from the PAP.
135 private static PDPEngine pdpEngine = null;
136 private static final Object pdpEngineLock = new Object();
138 // This is our PDP's status. What policies are loaded (or not) and
139 // what PIP configurations are loaded (or not).
140 // There is a synchronized lock used for access to the object.
142 private static volatile StdPDPStatus status = new StdPDPStatus();
143 private static final Object pdpStatusLock = new Object();
144 private static Constructor<?> createUpdatePolicyConstructor;
146 private static final String ENVIORNMENT_HEADER = "Environment";
147 private static String environment = null;
150 // Queue of PUT requests
152 public static class PutRequest {
153 private Properties policyProperties = null;
154 private Properties pipConfigProperties = null;
156 PutRequest(Properties policies, Properties pips) {
157 this.policyProperties = policies;
158 this.pipConfigProperties = pips;
162 protected static volatile BlockingQueue<PutRequest> queue = null;
163 // For notification Delay.
164 private static int notificationDelay = 0;
166 public static int getNotificationDelay() {
167 return XACMLPdpServlet.notificationDelay;
170 private static String pdpResourceName;
171 private static String[] dependencyNodes = null;
174 // This is our configuration thread that attempts to load
175 // a new configuration request.
177 private static transient Thread configThread = null;
178 private static volatile boolean configThreadTerminate = false;
179 private transient ONAPLoggingContext baseLoggingContext = null;
180 private transient IntegrityMonitor im;
182 public IntegrityMonitor getIm() {
186 public void setIm(IntegrityMonitor im) {
191 * Default constructor.
193 public XACMLPdpServlet() {
194 // Default constructor.
198 * @see Servlet#init(ServletConfig)
201 public void init(ServletConfig config) throws ServletException {
202 String createUpdateResourceName = null;
203 String dependencyGroups = null;
207 XACMLRest.xacmlInit(config);
208 // Load the Notification Delay.
209 setNotificationDelay();
210 // Load Queue size. Not sure if we really need to have the queue bounded, we should look further into this
211 int queueSize = 50; // Set default Queue Size here.
212 queueSize = Integer.parseInt(XACMLProperties.getProperty("REQUEST_BUFFER_SIZE", String.valueOf(queueSize)));
213 initQueue(queueSize);
214 // Load our engine - this will use the latest configuration
215 // that was saved to disk and set our initial status object.
217 PDPEngine engine = XACMLPdpLoader.loadEngine(XACMLPdpServlet.status, null, null);
218 if (engine != null) {
219 synchronized (pdpEngineLock) {
222 // Notification will be Sent Here.
223 XACMLPdpLoader.sendNotification();
228 baseLoggingContext = new ONAPLoggingContext();
229 // fixed data that will be the same in all logging output goes here
231 String hostname = InetAddress.getLocalHost().getCanonicalHostName();
232 baseLoggingContext.setServer(hostname);
233 } catch (UnknownHostException e) {
234 logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get hostname for logging" + e);
237 Properties properties;
239 properties = XACMLProperties.getProperties();
240 } catch (IOException e) {
241 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e,
242 "Error loading properties with: XACMLProperties.getProperties()");
243 throw new ServletException(e.getMessage(), e.getCause());
245 if (properties.getProperty(XACMLRestProperties.PDP_RESOURCE_NAME) == null) {
246 XACMLProperties.reloadProperties();
248 properties = XACMLProperties.getProperties();
249 } catch (IOException e) {
250 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e,
251 "Error loading properties with: XACMLProperties.getProperties()");
252 throw new ServletException(e.getMessage(), e.getCause());
254 PolicyLogger.info("\n Properties Given : \n" + properties.toString());
256 setPDPResourceName(properties);
257 dependencyGroups = properties.getProperty(IntegrityMonitorProperties.DEPENDENCY_GROUPS);
258 if (dependencyGroups == null) {
259 PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, IntegrityMonitorProperties.DEPENDENCY_GROUPS,
261 throw new ServletException("dependency_groups is null");
263 setDependencyNodes(dependencyGroups);
266 // CreateUpdatePolicy ResourceName
267 createUpdateResourceName =
268 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 =
326 Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_DELAY));
327 } catch (NumberFormatException e) {
328 logger.error("Error in notification delay format, Taking the default value.", e);
333 * @see Servlet#destroy()
336 public void destroy() {
338 logger.info("Destroying....");
340 // Make sure the register thread is not running
342 if (XACMLPdpServlet.registerRunnable != null) {
344 XACMLPdpServlet.registerRunnable.terminate();
345 if (XACMLPdpServlet.registerThread != null) {
346 XACMLPdpServlet.registerThread.interrupt();
347 XACMLPdpServlet.registerThread.join();
349 } catch (InterruptedException e) {
350 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
351 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
352 XACMLPdpServlet.registerThread.interrupt();
356 // Make sure the configure thread is not running
358 setConfigThreadTerminate(true);
360 XACMLPdpServlet.configThread.interrupt();
361 XACMLPdpServlet.configThread.join();
362 } catch (InterruptedException e) {
363 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
364 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
365 XACMLPdpServlet.configThread.interrupt();
367 logger.info("Destroyed.");
370 private static void setConfigThreadTerminate(boolean value) {
371 XACMLPdpServlet.configThreadTerminate = value;
375 * PUT - The PAP engine sends configuration information using HTTP PUT request.
377 * One parameter is expected:
379 * config=[policy|pip|all]
381 * policy - Expect a properties file that contains updated lists of the root and referenced policies that the PDP
382 * should be using for PEP requests.
384 * Specifically should AT LEAST contain the following properties: xacml.rootPolicies xacml.referencedPolicies
386 * In addition, any relevant information needed by the PDP to load or retrieve the policies to store in its cache.
388 * EXAMPLE: xacml.rootPolicies=PolicyA.1, PolicyB.1
390 * PolicyA.1.url=http://localhost:9090/PAP?id=b2d7b86d-d8f1-4adf-ba9d-b68b2a90bee1&version=1
391 * PolicyB.1.url=http://localhost:9090/PAP/id=be962404-27f6-41d8-9521-5acb7f0238be&version=1
393 * xacml.referencedPolicies=RefPolicyC.1, RefPolicyD.1
395 * RefPolicyC.1.url=http://localhost:9090/PAP?id=foobar&version=1
396 * RefPolicyD.1.url=http://localhost:9090/PAP/id=example&version=1
398 * pip - Expect a properties file that contain PIP engine configuration properties.
400 * Specifically should AT LEAST the following property: xacml.pip.engines
402 * In addition, any relevant information needed by the PDP to load and configure the PIPs.
404 * EXAMPLE: xacml.pip.engines=foo,bar
406 * foo.classname=com.foo foo.sample=abc foo.example=xyz ......
408 * bar.classname=com.bar ......
410 * all - Expect ALL new configuration properties for the PDP
412 * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response)
415 protected void doPut(HttpServletRequest request, HttpServletResponse response)
416 throws ServletException, IOException {
417 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
418 loggingContext.transactionStarted();
419 if ((loggingContext.getRequestID() == null) || "".equals(loggingContext.getRequestID())) {
420 UUID requestID = UUID.randomUUID();
421 loggingContext.setRequestID(requestID.toString());
422 PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doPut) so we generated one");
424 PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doPut)");
426 loggingContext.metricStarted();
427 loggingContext.metricEnded();
428 PolicyLogger.metrics("Metric example posted here - 1 of 2");
429 loggingContext.metricStarted();
430 loggingContext.metricEnded();
431 PolicyLogger.metrics("Metric example posted here - 2 of 2");
433 // Dump our request out
435 if (logger.isDebugEnabled()) {
436 XACMLRest.dumpRequest(request);
440 im.startTransaction();
441 } catch (IntegrityMonitorException e) {
442 String message = e.toString();
443 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + e);
444 loggingContext.transactionEnded();
445 PolicyLogger.audit("Transaction Failed - See Error.log");
447 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
448 } catch (Exception e1) {
449 logger.error("Exception occured while sending error in response" + e1);
454 // What is being PUT?
456 String cache = request.getParameter("cache");
458 // Should be a list of policy and pip configurations in Java properties format
460 if (cache != null && request.getContentType().equals("text/x-java-properties")) {
461 loggingContext.setServiceName("PDP.putConfig");
463 if (request.getContentLength() > Integer
464 .parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", DEFAULT_MAX_CONTENT_LENGTH))) {
465 String message = "Content-Length larger than server will accept.";
466 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
467 loggingContext.transactionEnded();
468 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
469 PolicyLogger.audit("Transaction Failed - See Error.log");
470 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
474 logger.info("XACMLPdpServlet: calling doPutConfig to add properties to the queue");
475 this.doPutConfig(cache, request, response, loggingContext);
476 loggingContext.transactionEnded();
477 PolicyLogger.audit("Transaction ended");
480 } catch (Exception e) {
481 logger.error("Exception Occured while getting Max Content lenght" + e);
484 String message = "Invalid cache: '" + cache + "' or content-type: '" + request.getContentType() + "'";
485 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message);
486 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
487 loggingContext.transactionEnded();
488 PolicyLogger.audit("Transaction Failed - See Error.log");
490 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
491 } catch (Exception e1) {
492 logger.error("Exception occured while sending error in response" + e1);
499 protected void doPutConfig(String config, HttpServletRequest request, HttpServletResponse response,
500 ONAPLoggingContext loggingContext) throws ServletException, IOException {
502 // prevent multiple configuration changes from stacking up
503 logger.info("XACMLPdpServlet: checking remainingCapacity of Queue.");
504 if (XACMLPdpServlet.queue.remainingCapacity() <= 0) {
505 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Queue capacity reached");
506 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "Queue capacity reached");
507 loggingContext.transactionEnded();
508 PolicyLogger.audit("Transaction Failed - See Error.log");
509 response.sendError(HttpServletResponse.SC_CONFLICT,
510 "Multiple configuration changes waiting processing.");
514 // Read the properties data into an object.
516 Properties newProperties = new Properties();
517 newProperties.load(request.getInputStream());
518 // should have something in the request
519 if (newProperties.size() == 0) {
520 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No properties in PUT");
521 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No properties in PUT");
522 loggingContext.transactionEnded();
523 PolicyLogger.audit("Transaction Failed - See Error.log");
524 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT must contain at least one property");
528 // Which set of properties are they sending us? Whatever they send gets
529 // put on the queue (if there is room).
530 // For audit logging purposes, we consider the transaction done once the
531 // the request gets put on the queue.
533 if (config.equals("policies")) {
534 newProperties = XACMLProperties.getPolicyProperties(newProperties, true);
535 if (newProperties.size() == 0) {
536 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No policy properties in PUT");
537 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No policy properties in PUT");
538 loggingContext.transactionEnded();
539 PolicyLogger.audit("Transaction Failed - See Error.log");
540 response.sendError(HttpServletResponse.SC_BAD_REQUEST,
541 "PUT with cache=policies must contain at least one policy property");
544 logger.info("XACMLPdpServlet: offer policies to queue. No pip properties added.");
545 XACMLPdpServlet.queue.offer(new PutRequest(newProperties, null));
546 loggingContext.transactionEnded();
547 auditLogger.info("Success");
548 PolicyLogger.audit("Success");
549 } else if (config.equals("pips")) {
550 newProperties = XACMLProperties.getPipProperties(newProperties);
551 if (newProperties.size() == 0) {
552 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No pips properties in PUT");
553 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No pips properties in PUT");
554 loggingContext.transactionEnded();
555 PolicyLogger.audit("Transaction Failed - See Error.log");
556 response.sendError(HttpServletResponse.SC_BAD_REQUEST,
557 "PUT with cache=pips must contain at least one pip property");
560 logger.info("XACMLPdpServlet: offer pips to queue. No policy properties added.");
561 XACMLPdpServlet.queue.offer(new PutRequest(null, newProperties));
562 loggingContext.transactionEnded();
563 auditLogger.info("Success");
564 PolicyLogger.audit("Success");
565 } else if (config.equals("all")) {
566 Properties newPolicyProperties = XACMLProperties.getPolicyProperties(newProperties, true);
567 if (newPolicyProperties.size() == 0) {
568 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No policy properties in PUT");
569 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No policy properties in PUT");
570 loggingContext.transactionEnded();
571 PolicyLogger.audit("Transaction Failed - See Error.log");
572 response.sendError(HttpServletResponse.SC_BAD_REQUEST,
573 "PUT with cache=all must contain at least one policy property");
576 Properties newPipProperties = XACMLProperties.getPipProperties(newProperties);
577 if (newPipProperties.size() == 0) {
578 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No pips properties in PUT");
579 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No pips properties in PUT");
580 loggingContext.transactionEnded();
581 PolicyLogger.audit("Transaction Failed - See Error.log");
582 response.sendError(HttpServletResponse.SC_BAD_REQUEST,
583 "PUT with cache=all must contain at least one pip property");
586 logger.info("XACMLPdpServlet: offer policies and pips to queue.");
587 XACMLPdpServlet.queue.offer(new PutRequest(newPolicyProperties, newPipProperties));
588 loggingContext.transactionEnded();
589 auditLogger.info("Success");
590 PolicyLogger.audit("Success");
596 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid config value: " + config);
597 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Invalid config value: " + config);
598 loggingContext.transactionEnded();
599 PolicyLogger.audit("Transaction Failed - See Error.log");
600 response.sendError(HttpServletResponse.SC_BAD_REQUEST,
601 "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 HeartBeat OK - All Policies are Loaded, All PIPs are Loaded LOADING_IN_PROGRESS - Currently
623 * loading a new policy set/pip configuration LAST_UPDATE_FAILED - Need to track the items that failed during last
624 * update LOAD_FAILURE - ??? Need to determine what information is sent and how 2. Configuration 3. Status return
625 * the StdPDPStatus object in the Response content
628 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
631 protected void doGet(HttpServletRequest request, HttpServletResponse response)
632 throws ServletException, IOException {
633 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
634 loggingContext.transactionStarted();
635 if ((loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")) {
636 UUID requestID = UUID.randomUUID();
637 loggingContext.setRequestID(requestID.toString());
638 PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doGet) so we generated one");
640 PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doGet)");
642 loggingContext.metricStarted();
643 loggingContext.metricEnded();
644 PolicyLogger.metrics("Metric example posted here - 1 of 2");
645 loggingContext.metricStarted();
646 loggingContext.metricEnded();
647 PolicyLogger.metrics("Metric example posted here - 2 of 2");
649 XACMLRest.dumpRequest(request);
651 String pathInfo = request.getRequestURI();
652 if (pathInfo != null) {
653 // health check from Global Site Selector (iDNS).
654 // DO NOT do a im.startTransaction for the test request
655 if (pathInfo.equals("/pdp/test")) {
656 loggingContext.setServiceName("iDNS:PDP.test");
659 // If we make it this far, all is well
660 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " is OK";
661 PolicyLogger.debug(message);
662 loggingContext.transactionEnded();
663 PolicyLogger.audit("Success");
664 response.setStatus(HttpServletResponse.SC_OK);
666 } catch (ForwardProgressException fpe) {
667 // No forward progress is being made
668 String message = "GET:/pdp/test called and PDP " + pdpResourceName
669 + " is not making forward progress." + " Exception Message: " + fpe.getMessage();
670 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + fpe);
671 loggingContext.transactionEnded();
672 PolicyLogger.audit("Transaction Failed - See Error.log");
674 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
675 } catch (Exception e1) {
676 logger.error("Exception occured while sending error in response" + e1);
679 } catch (AdministrativeStateException ase) {
680 // Administrative State is locked
681 String message = "GET:/pdp/test called and PDP " + pdpResourceName
682 + " Administrative State is LOCKED " + " Exception Message: " + ase.getMessage();
683 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + ase);
684 loggingContext.transactionEnded();
685 PolicyLogger.audit("Transaction Failed - See Error.log");
687 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
688 } catch (Exception e1) {
689 logger.error("Exception occured while sending error in response" + e1);
692 } catch (StandbyStatusException sse) {
693 // Administrative State is locked
694 String message = "GET:/pdp/test called and PDP " + pdpResourceName
695 + " Standby Status is NOT PROVIDING SERVICE " + " Exception Message: " + sse.getMessage();
696 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + sse);
697 loggingContext.transactionEnded();
698 PolicyLogger.audit("Transaction Failed - See Error.log");
700 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
701 } catch (Exception e1) {
702 logger.error("Exception occured while sending error in response" + e1);
705 } catch (Exception e) {
706 // A subsystem is not making progress or is not responding
707 String eMsg = e.getMessage();
709 eMsg = "No Exception Message";
711 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " has had a subsystem failure."
712 + " Exception Message: " + eMsg;
713 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
714 // Get the specific list of subsystems that failed
715 String failedNodeList = null;
716 for (String node : dependencyNodes) {
717 if (eMsg.contains(node)) {
718 if (failedNodeList == null) {
719 failedNodeList = node;
721 failedNodeList = failedNodeList.concat("," + node);
725 if (failedNodeList == null) {
726 failedNodeList = "UnknownSubSystem";
728 response.addHeader("X-ONAP-SubsystemFailure", failedNodeList);
730 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
731 } catch (Exception e1) {
732 logger.error("Exception occured while sending error in response" + e1);
734 loggingContext.transactionEnded();
735 PolicyLogger.audit("Transaction Failed - See Error.log" + e);
742 im.startTransaction();
743 } catch (IntegrityMonitorException e) {
744 String message = e.toString();
745 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
746 loggingContext.transactionEnded();
747 PolicyLogger.audit("Transaction Failed - See Error.log" + e);
749 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
750 } catch (Exception e1) {
751 logger.error("Exception occured while sending error in response" + e1);
756 // What are they requesting?
758 boolean returnHB = false;
759 response.setHeader("Cache-Control", "no-cache");
760 String type = request.getParameter("type");
761 // type might be null, so use equals on string constants
762 if ("config".equals(type)) {
763 loggingContext.setServiceName("PDP.getConfig");
764 response.setContentType("text/x-java-properties");
766 String lists = XACMLProperties.PROP_ROOTPOLICIES + "="
767 + XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES, "");
768 lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "="
769 + XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, "") + "\n";
770 try (InputStream listInputStream = new ByteArrayInputStream(lists.getBytes());
771 InputStream pipInputStream = Files.newInputStream(XACMLPdpLoader.getPIPConfig());
772 OutputStream os = response.getOutputStream()) {
773 IOUtils.copy(listInputStream, os);
774 IOUtils.copy(pipInputStream, os);
776 loggingContext.transactionEnded();
777 auditLogger.info("Success");
778 PolicyLogger.audit("Success");
779 response.setStatus(HttpServletResponse.SC_OK);
780 } catch (Exception e) {
781 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed to copy property file", e);
782 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to copy property file");
783 loggingContext.transactionEnded();
784 PolicyLogger.audit("Transaction Failed - See Error.log");
786 response.sendError(400, "Failed to copy Property file");
787 } catch (Exception e1) {
788 logger.error("Exception occured while sending error in response" + e1);
792 } else if ("hb".equals(type)) {
794 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
796 } else if ("Status".equals(type)) {
797 loggingContext.setServiceName("PDP.getStatus");
798 // convert response object to JSON and include in the response
799 synchronized (pdpStatusLock) {
800 ObjectMapper mapper = new ObjectMapper();
802 mapper.writeValue(response.getOutputStream(), status);
803 } catch (Exception e1) {
804 logger.error("Exception occured while writing output stream" + e1);
807 response.setStatus(HttpServletResponse.SC_OK);
808 loggingContext.transactionEnded();
809 auditLogger.info("Success");
810 PolicyLogger.audit("Success");
813 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid type value: " + type);
814 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Invalid type value: " + type);
815 loggingContext.transactionEnded();
816 PolicyLogger.audit("Transaction Failed - See Error.log");
818 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "type not 'config' or 'hb'");
819 } catch (Exception e1) {
820 logger.error("Exception occured while sending error in response" + e1);
824 synchronized (pdpStatusLock) {
825 response.addHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB, status.getStatus().toString());
828 loggingContext.transactionEnded();
829 PolicyLogger.audit("Transaction Ended");
835 * POST - We expect XACML requests to be posted by PEP applications. They can be in the form of XML or JSON
836 * according to the XACML 3.0 Specifications for both.
839 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
842 protected void doPost(HttpServletRequest request, HttpServletResponse response)
843 throws ServletException, IOException {
845 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
846 loggingContext.transactionStarted();
847 loggingContext.setServiceName("PDP.decide");
848 if ((loggingContext.getRequestID() == null) || ("".equals(loggingContext.getRequestID()))) {
849 UUID requestID = UUID.randomUUID();
850 loggingContext.setRequestID(requestID.toString());
851 PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doPost) so we generated one");
853 PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doPost)");
855 loggingContext.metricStarted();
856 loggingContext.metricEnded();
857 PolicyLogger.metrics("Metric example posted here - 1 of 2");
858 loggingContext.metricStarted();
859 loggingContext.metricEnded();
860 PolicyLogger.metrics("Metric example posted here - 2 of 2");
861 monitor.pdpEvaluationAttempts();
864 im.startTransaction();
865 } catch (IntegrityMonitorException e) {
866 String message = e.toString();
867 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + e);
868 loggingContext.transactionEnded();
869 PolicyLogger.audit("Transaction Failed - See Error.log");
871 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
872 } catch (Exception e1) {
873 logger.error("Exception occured while sending error in response" + e1);
878 // no point in doing any work if we know from the get-go that we cannot do anything with the request
880 if (status.getLoadedRootPolicies().isEmpty()) {
881 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Request from PEP at " + request.getRequestURI()
882 + " for service when PDP has No Root Policies loaded");
883 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, "Request from PEP at " + request.getRequestURI()
884 + " for service when PDP has No Root Policies loaded");
885 loggingContext.transactionEnded();
886 PolicyLogger.audit("Transaction Failed - See Error.log");
888 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
889 } catch (Exception e1) {
890 logger.error("Exception occured while sending error in response" + e1);
896 XACMLRest.dumpRequest(request);
898 // Set our no-cache header
900 response.setHeader("Cache-Control", "no-cache");
902 // They must send a Content-Type
904 if (request.getContentType() == null) {
905 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Must specify a Content-Type");
906 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Must specify a Content-Type");
907 loggingContext.transactionEnded();
908 PolicyLogger.audit("Transaction Failed - See Error.log");
910 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "no content-type given");
911 } catch (Exception e1) {
912 logger.error("Exception occured while sending error in response" + e1);
918 // Limit the Content-Length to something reasonable
921 if (request.getContentLength() > Integer
922 .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);
932 } catch (Exception e) {
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());
953 } catch (Exception e) {
954 String message = "Parsing Content-Type: " + request.getContentType() + ", error=" + e.getMessage();
955 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message, e);
956 loggingContext.transactionEnded();
957 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, message);
958 PolicyLogger.audit("Transaction Failed - See Error.log");
960 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
961 } catch (Exception e1) {
962 logger.error("Exception occured while sending error in response" + e1);
968 // What exactly did they send us?
970 String incomingRequestString = null;
971 Request pdpRequest = null;
972 if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())
973 || contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType())
974 || contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
976 // Read in the string
978 StringBuilder buffer = new StringBuilder();
979 BufferedReader reader = null;
981 reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
982 } catch (IOException e) {
983 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error during reading input stream", e);
988 while ((line = reader.readLine()) != null) {
991 } catch (Exception e) {
992 logger.error("Exception Occured while reading line" + e);
995 incomingRequestString = buffer.toString();
996 logger.info(incomingRequestString);
998 // Parse into a request
1001 if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
1002 pdpRequest = JSONRequest.load(incomingRequestString);
1003 } else if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType())
1004 || contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
1005 pdpRequest = DOMRequest.load(incomingRequestString);
1007 } catch (Exception e) {
1008 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Could not parse request", e);
1009 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "Could not parse request");
1010 loggingContext.transactionEnded();
1011 PolicyLogger.audit("Transaction Failed - See Error.log");
1013 response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
1014 } catch (Exception e1) {
1015 logger.error("Exception occured while sending error in response" + e1);
1017 im.endTransaction();
1021 String message = "unsupported content type" + request.getContentType();
1022 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
1023 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
1024 loggingContext.transactionEnded();
1025 PolicyLogger.audit("Transaction Failed - See Error.log");
1027 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
1028 } catch (Exception e1) {
1029 logger.error("Exception occured while sending error in response" + e1);
1031 im.endTransaction();
1035 // Did we successfully get and parse a request?
1037 if (pdpRequest == null || pdpRequest.getRequestAttributes() == null
1038 || pdpRequest.getRequestAttributes().size() <= 0) {
1039 String message = "Zero Attributes found in the request";
1040 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
1041 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
1042 loggingContext.transactionEnded();
1043 PolicyLogger.audit("Transaction Failed - See Error.log");
1045 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
1046 } catch (Exception e1) {
1047 logger.error("Exception occured while sending error in response" + e1);
1049 im.endTransaction();
1057 // Authenticating the Request here.
1059 if (!authorizeRequest(request)) {
1061 "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")
1183 || outgoingResponseString.contains("Decision not a Permit")) {
1184 monitor.pdpEvaluationNA();
1187 if (outgoingResponseString.contains("Permit")
1188 && !outgoingResponseString.contains("Decision not a Permit")) {
1189 monitor.pdpEvaluationPermit();
1192 if (outgoingResponseString.contains("Deny")) {
1193 monitor.pdpEvaluationDeny();
1196 // lTimeStart is used as an ID within the requestLogger to match up
1197 // request's with responses.
1199 requestLogger.info(lTimeStart + "=" + outgoingResponseString);
1200 response.getWriter().print(outgoingResponseString);
1201 } catch (Exception e) {
1202 logger.error("Exception Occured" + e);
1204 } catch (Exception e) {
1205 String message = "Exception executing request: " + e;
1206 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message, e);
1207 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, message);
1208 loggingContext.transactionEnded();
1209 PolicyLogger.audit("Transaction Failed - See Error.log");
1211 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1212 } catch (Exception e1) {
1213 logger.error("Exception occured while sending error in response" + e1);
1218 monitor.pdpEvaluationSuccess();
1219 response.setStatus(HttpServletResponse.SC_OK);
1221 loggingContext.transactionEnded();
1222 auditLogger.info("Success");
1223 PolicyLogger.audit("Success");
1228 * Added for Authorizing the PEP Requests for Environment check.
1230 private boolean authorizeRequest(HttpServletRequest request) {
1231 // Get the client Credentials from the Request header.
1232 HttpServletRequest httpServletRequest = request;
1233 String clientCredentials = httpServletRequest.getHeader(ENVIORNMENT_HEADER);
1234 if (clientCredentials != null && clientCredentials.equalsIgnoreCase(environment)) {
1244 // Keep running until we are told to terminate
1247 // variable not used, but constructor has needed side-effects so don't remove:
1248 while (!XACMLPdpServlet.configThreadTerminate) {
1249 logger.info("XACMLPdpServlet: Taking requests from the queue");
1250 PutRequest request = XACMLPdpServlet.queue.take();
1251 logger.info("XACMLPdpServlet: Taking requests from the queue COMPLETED");
1252 StdPDPStatus newStatus = new StdPDPStatus();
1254 PDPEngine newEngine = null;
1255 synchronized (pdpStatusLock) {
1256 XACMLPdpServlet.status.setStatus(Status.UPDATING_CONFIGURATION);
1258 logger.info("created new PDPEngine");
1260 XACMLPdpLoader.loadEngine(newStatus, request.policyProperties, request.pipConfigProperties);
1262 if (newEngine != null) {
1263 logger.info("XACMLPdpServlet: newEngine created, assigning newEngine to the pdpEngine.");
1264 synchronized (XACMLPdpServlet.pdpEngineLock) {
1265 XACMLPdpServlet.pdpEngine = newEngine;
1267 logger.info("Saving configuration.");
1268 if (request.policyProperties != null) {
1269 logger.info("Saving configuration: Policy Properties: " + request.policyProperties);
1270 try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPDPPolicyCache())) {
1271 request.policyProperties.store(os, "");
1274 if (request.pipConfigProperties != null) {
1275 logger.info("Saving configuration: PIP Properties: " + request.pipConfigProperties);
1276 try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPIPConfig())) {
1277 request.pipConfigProperties.store(os, "");
1280 newStatus.setStatus(Status.UP_TO_DATE);
1281 } catch (Exception e) {
1283 XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to store new properties." + e);
1284 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "Failed to store new properties");
1285 newStatus.setStatus(Status.LOAD_ERRORS);
1286 newStatus.addLoadWarning("Unable to save configuration: " + e.getMessage());
1290 newStatus.setStatus(Status.LAST_UPDATE_FAILED);
1292 synchronized (pdpStatusLock) {
1293 XACMLPdpServlet.status.set(newStatus);
1295 logger.info("New PDP Servlet Status: " + newStatus.getStatus());
1296 if (Status.UP_TO_DATE.equals(newStatus.getStatus())) {
1297 // Notification will be Sent Here.
1298 XACMLPdpLoader.sendNotification();
1301 } catch (InterruptedException e) {
1302 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "interrupted" + e);
1303 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, "interrupted");
1304 Thread.currentThread().interrupt();
1308 public static PDPEngine getPDPEngine() {
1309 PDPEngine myEngine = null;
1310 synchronized (pdpEngineLock) {
1311 myEngine = XACMLPdpServlet.pdpEngine;
1316 public static Constructor<?> getCreateUpdatePolicyConstructor() {
1317 return createUpdatePolicyConstructor;
1320 public static Object getPDPEngineLock() {
1321 return pdpEngineLock;
1324 private static void setCreateUpdatePolicyConstructor(String createUpdateResourceName) throws ServletException {
1326 Class<?> createUpdateclass = Class.forName(createUpdateResourceName);
1327 createUpdatePolicyConstructor =
1328 createUpdateclass.getConstructor(PolicyParameters.class, String.class, boolean.class);
1329 } catch (Exception e) {
1330 PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, "createUpdatePolicy.impl.className",
1331 "xacml.pdp.init" + e);
1332 throw new ServletException(
1333 "Could not find the Class name : " + createUpdateResourceName + "\n" + e.getMessage());