2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
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 com.att.research.xacml.api.Request;
24 import com.att.research.xacml.api.Response;
25 import com.att.research.xacml.api.pap.PDPStatus.Status;
26 import com.att.research.xacml.api.pdp.PDPEngine;
27 import com.att.research.xacml.api.pdp.PDPException;
28 import com.att.research.xacml.std.dom.DOMRequest;
29 import com.att.research.xacml.std.dom.DOMResponse;
30 import com.att.research.xacml.std.json.JSONRequest;
31 import com.att.research.xacml.std.json.JSONResponse;
32 import com.att.research.xacml.util.XACMLProperties;
33 import com.fasterxml.jackson.databind.ObjectMapper;
34 import java.io.BufferedReader;
35 import java.io.ByteArrayInputStream;
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.io.InputStreamReader;
39 import java.io.OutputStream;
40 import java.lang.reflect.Constructor;
41 import java.net.InetAddress;
42 import java.net.UnknownHostException;
43 import java.nio.file.Files;
44 import java.util.Properties;
45 import java.util.UUID;
46 import java.util.concurrent.BlockingQueue;
47 import java.util.concurrent.LinkedBlockingQueue;
48 import javax.servlet.Servlet;
49 import javax.servlet.ServletConfig;
50 import javax.servlet.ServletException;
51 import javax.servlet.annotation.WebInitParam;
52 import javax.servlet.annotation.WebServlet;
53 import javax.servlet.http.HttpServlet;
54 import javax.servlet.http.HttpServletRequest;
55 import javax.servlet.http.HttpServletResponse;
56 import org.apache.commons.io.IOUtils;
57 import org.apache.commons.logging.Log;
58 import org.apache.commons.logging.LogFactory;
59 import org.apache.http.entity.ContentType;
60 import org.onap.policy.api.PolicyParameters;
61 import org.onap.policy.common.im.AdministrativeStateException;
62 import org.onap.policy.common.im.ForwardProgressException;
63 import org.onap.policy.common.im.IntegrityMonitor;
64 import org.onap.policy.common.im.IntegrityMonitorException;
65 import org.onap.policy.common.im.IntegrityMonitorProperties;
66 import org.onap.policy.common.im.StandbyStatusException;
67 import org.onap.policy.common.logging.ONAPLoggingContext;
68 import org.onap.policy.common.logging.ONAPLoggingUtils;
69 import org.onap.policy.common.logging.eelf.MessageCodes;
70 import org.onap.policy.common.logging.eelf.PolicyLogger;
71 import org.onap.policy.pdp.rest.jmx.PdpRestMonitor;
72 import org.onap.policy.rest.XACMLRest;
73 import org.onap.policy.rest.XACMLRestProperties;
74 import org.onap.policy.utils.PeCryptoUtils;
75 import org.onap.policy.xacml.api.XACMLErrorConstants;
76 import org.onap.policy.xacml.pdp.std.functions.PolicyList;
77 import org.onap.policy.xacml.std.pap.StdPDPStatus;
80 * Servlet implementation class XacmlPdpServlet
82 * This is an implementation of the XACML 3.0 RESTful Interface with added features to support simple PAP RESTful API
83 * for policy publishing and PIP configuration changes.
85 * If you are running this the first time, then we recommend you look at the xacml.pdp.properties file. This properties
86 * file has all the default parameter settings. If you are running the servlet as is, then we recommend setting up
87 * you're container to run it on port 8080 with context "/pdp". Wherever the default working directory is set to, a
88 * "config" directory will be created that holds the policy and pip cache. This setting is located in the
89 * xacml.pdp.properties file.
91 * When you are ready to customize, you can create a separate xacml.pdp.properties on you're local file system and setup
92 * the parameters as you wish. Just set the Java VM System variable to point to that file:
94 * -Dxacml.properties=/opt/app/xacml/etc/xacml.pdp.properties
96 * Or if you only want to change one or two properties, simply set the Java VM System variable for that property.
98 * -Dxacml.rest.pdp.register=false
102 @WebServlet(description = "Implements the XACML PDP RESTful API and client PAP API.", urlPatterns = {"/"},
103 loadOnStartup = 1, initParams = {@WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pdp.properties",
104 description = "The location of the PDP xacml.pdp.properties file holding configuration information.")})
105 public class XACMLPdpServlet extends HttpServlet implements Runnable {
106 private static final long serialVersionUID = 1L;
107 private static final String DEFAULT_MAX_CONTENT_LENGTH = "999999999"; // 32767
108 private static final String CREATE_UPDATE_POLICY_SERVICE =
109 "org.onap.policy.pdp.rest.api.services.CreateUpdatePolicyServiceImpl";
111 // Our application debug log
113 private static final Log logger = LogFactory.getLog(XACMLPdpServlet.class);
115 // This logger is specifically only for Xacml requests and their corresponding response.
116 // It's output ideally should be sent to a separate file from the application logger.
118 private static final Log requestLogger = LogFactory.getLog("xacml.request");
121 private static final Log auditLogger = LogFactory.getLog("auditLogger");
123 public static final PdpRestMonitor monitor = PdpRestMonitor.getSingleton();
126 // This thread may getting invoked on startup, to let the PAP know
127 // that we are up and running.
129 private static transient Thread registerThread = null;
130 private static transient XACMLPdpRegisterThread registerRunnable = null;
132 // This is our PDP engine pointer. There is a synchronized lock used
133 // for access to the pointer. In case we are servicing PEP requests while
134 // an update is occurring from the PAP.
136 private static PDPEngine pdpEngine = null;
137 private static final Object pdpEngineLock = new Object();
139 // This is our PDP's status. What policies are loaded (or not) and
140 // what PIP configurations are loaded (or not).
141 // There is a synchronized lock used for access to the object.
143 private static volatile StdPDPStatus status = new StdPDPStatus();
144 private static final Object pdpStatusLock = new Object();
145 private static Constructor<?> createUpdatePolicyConstructor;
147 private static final String ENVIORNMENT_HEADER = "Environment";
148 private static String environment = null;
151 // Queue of PUT requests
153 public static class PutRequest {
154 private Properties policyProperties = null;
155 private Properties pipConfigProperties = null;
157 PutRequest(Properties policies, Properties pips) {
158 this.policyProperties = policies;
159 this.pipConfigProperties = pips;
163 protected static volatile BlockingQueue<PutRequest> queue = null;
164 // For notification Delay.
165 private static int notificationDelay = 0;
167 public static int getNotificationDelay() {
168 return XACMLPdpServlet.notificationDelay;
171 private static String pdpResourceName;
172 private static String[] dependencyNodes = null;
175 // This is our configuration thread that attempts to load
176 // a new configuration request.
178 private static transient Thread configThread = null;
179 private static volatile boolean configThreadTerminate = false;
180 private transient ONAPLoggingContext baseLoggingContext = null;
181 private transient IntegrityMonitor im;
183 public IntegrityMonitor getIm() {
187 public void setIm(IntegrityMonitor im) {
192 * Default constructor.
194 public XACMLPdpServlet() {
195 // Default constructor.
199 * @see Servlet#init(ServletConfig)
202 public void init(ServletConfig config) throws ServletException {
203 String createUpdateResourceName = null;
204 String dependencyGroups = null;
208 XACMLRest.xacmlInit(config);
209 // Load the Notification Delay.
210 setNotificationDelay();
211 // Load Queue size. Not sure if we really need to have the queue bounded, we should look further into this
212 int queueSize = 50; // Set default Queue Size here.
213 queueSize = Integer.parseInt(XACMLProperties.getProperty("REQUEST_BUFFER_SIZE", String.valueOf(queueSize)));
214 initQueue(queueSize);
215 // Load our engine - this will use the latest configuration
216 // that was saved to disk and set our initial status object.
218 PDPEngine engine = XACMLPdpLoader.loadEngine(XACMLPdpServlet.status, null, null);
219 if (engine != null) {
220 synchronized (pdpEngineLock) {
223 // Notification will be Sent Here.
224 XACMLPdpLoader.sendNotification();
229 baseLoggingContext = new ONAPLoggingContext();
230 // fixed data that will be the same in all logging output goes here
232 String hostname = InetAddress.getLocalHost().getCanonicalHostName();
233 baseLoggingContext.setServer(hostname);
234 } catch (UnknownHostException e) {
235 logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get hostname for logging" + e);
238 Properties properties;
240 properties = XACMLProperties.getProperties();
241 } catch (IOException e) {
242 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e,
243 "Error loading properties with: XACMLProperties.getProperties()");
244 throw new ServletException(e.getMessage(), e.getCause());
246 if (properties.getProperty(XACMLRestProperties.PDP_RESOURCE_NAME) == null) {
247 XACMLProperties.reloadProperties();
249 properties = XACMLProperties.getProperties();
250 } catch (IOException e) {
251 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e,
252 "Error loading properties with: XACMLProperties.getProperties()");
253 throw new ServletException(e.getMessage(), e.getCause());
255 PolicyLogger.info("\n Properties Given : \n" + properties.toString());
257 setPDPResourceName(properties);
258 dependencyGroups = properties.getProperty(IntegrityMonitorProperties.DEPENDENCY_GROUPS);
259 if (dependencyGroups == null) {
260 PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, IntegrityMonitorProperties.DEPENDENCY_GROUPS,
262 throw new ServletException("dependency_groups is null");
264 setDependencyNodes(dependencyGroups);
267 // CreateUpdatePolicy ResourceName
268 createUpdateResourceName =
269 properties.getProperty("createUpdatePolicy.impl.className", CREATE_UPDATE_POLICY_SERVICE);
270 setCreateUpdatePolicyConstructor(createUpdateResourceName);
272 PeCryptoUtils.initAesKey(properties.getProperty(XACMLRestProperties.PROP_AES_KEY));
274 // Create an IntegrityMonitor
276 logger.info("Creating IntegrityMonitor");
277 properties.setProperty("javax.persistence.jdbc.password",
278 PeCryptoUtils.decrypt(properties.getProperty("javax.persistence.jdbc.password", "")));
279 im = IntegrityMonitor.getInstance(pdpResourceName, properties);
280 } catch (Exception e) {
281 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to create IntegrityMonitor" + e);
282 throw new ServletException(e);
286 System.setProperty("msToscaModel.home", properties.getProperty("msToscaModel.home"));
287 } catch (Exception e) {
288 logger.error("ERROR: Unable to set msToscaModel.home- Please check the configuration");
291 startThreads(baseLoggingContext, new Thread(this));
294 private static void startThreads(ONAPLoggingContext baseLoggingContext, Thread thread) {
295 environment = XACMLProperties.getProperty("ENVIRONMENT", "DEVL");
297 // Kick off our thread to register with the PAP servlet.
299 if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER))) {
300 XACMLPdpServlet.registerRunnable = new XACMLPdpRegisterThread(baseLoggingContext);
301 XACMLPdpServlet.registerThread = new Thread(XACMLPdpServlet.registerRunnable);
302 XACMLPdpServlet.registerThread.start();
305 // This is our thread that manages incoming configuration
308 XACMLPdpServlet.configThread = thread;
309 XACMLPdpServlet.configThread.start();
312 private static void setDependencyNodes(String dependencyGroups) {
313 // dependency_groups is a semicolon-delimited list of groups, and
314 // each group is a comma-separated list of nodes. For our purposes
315 // we just need a list of dependencies without regard to grouping,
316 // so split the list into nodes separated by either comma or semicolon.
317 dependencyNodes = dependencyGroups.split("[;,]");
318 for (int i = 0; i < dependencyNodes.length; i++) {
319 dependencyNodes[i] = dependencyNodes[i].trim();
323 private static void setPDPResourceName(Properties properties) throws ServletException {
324 pdpResourceName = properties.getProperty(XACMLRestProperties.PDP_RESOURCE_NAME);
325 if (pdpResourceName == null) {
326 PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, XACMLRestProperties.PDP_RESOURCE_NAME, "xacml.pdp");
327 throw new ServletException("pdpResourceName is null");
331 private static void initQueue(int queueSize) {
332 queue = new LinkedBlockingQueue<>(queueSize);
335 private static void setNotificationDelay() {
337 XACMLPdpServlet.notificationDelay =
338 Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_DELAY));
339 } catch (NumberFormatException e) {
340 logger.error("Error in notification delay format, Taking the default value.", e);
345 * @see Servlet#destroy()
348 public void destroy() {
350 logger.info("Destroying....");
352 // Make sure the register thread is not running
354 if (XACMLPdpServlet.registerRunnable != null) {
356 XACMLPdpServlet.registerRunnable.terminate();
357 if (XACMLPdpServlet.registerThread != null) {
358 XACMLPdpServlet.registerThread.interrupt();
359 XACMLPdpServlet.registerThread.join();
361 } catch (InterruptedException e) {
362 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
363 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
364 XACMLPdpServlet.registerThread.interrupt();
368 // Make sure the configure thread is not running
370 setConfigThreadTerminate(true);
372 XACMLPdpServlet.configThread.interrupt();
373 XACMLPdpServlet.configThread.join();
374 } catch (InterruptedException e) {
375 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
376 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
377 XACMLPdpServlet.configThread.interrupt();
379 logger.info("Destroyed.");
382 private static void setConfigThreadTerminate(boolean value) {
383 XACMLPdpServlet.configThreadTerminate = value;
387 * PUT - The PAP engine sends configuration information using HTTP PUT request.
389 * One parameter is expected:
391 * config=[policy|pip|all]
393 * policy - Expect a properties file that contains updated lists of the root and referenced policies that the PDP
394 * should be using for PEP requests.
396 * Specifically should AT LEAST contain the following properties: xacml.rootPolicies xacml.referencedPolicies
398 * In addition, any relevant information needed by the PDP to load or retrieve the policies to store in its cache.
400 * EXAMPLE: xacml.rootPolicies=PolicyA.1, PolicyB.1
402 * PolicyA.1.url=http://localhost:9090/PAP?id=b2d7b86d-d8f1-4adf-ba9d-b68b2a90bee1&version=1
403 * PolicyB.1.url=http://localhost:9090/PAP/id=be962404-27f6-41d8-9521-5acb7f0238be&version=1
405 * xacml.referencedPolicies=RefPolicyC.1, RefPolicyD.1
407 * RefPolicyC.1.url=http://localhost:9090/PAP?id=foobar&version=1
408 * RefPolicyD.1.url=http://localhost:9090/PAP/id=example&version=1
410 * pip - Expect a properties file that contain PIP engine configuration properties.
412 * Specifically should AT LEAST the following property: xacml.pip.engines
414 * In addition, any relevant information needed by the PDP to load and configure the PIPs.
416 * EXAMPLE: xacml.pip.engines=foo,bar
418 * foo.classname=com.foo foo.sample=abc foo.example=xyz ......
420 * bar.classname=com.bar ......
422 * all - Expect ALL new configuration properties for the PDP
424 * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response)
427 protected void doPut(HttpServletRequest request, HttpServletResponse response)
428 throws ServletException, IOException {
429 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
430 loggingContext.transactionStarted();
431 if ((loggingContext.getRequestID() == null) || "".equals(loggingContext.getRequestID())) {
432 UUID requestID = UUID.randomUUID();
433 loggingContext.setRequestID(requestID.toString());
434 PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doPut) so we generated one");
436 PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doPut)");
438 loggingContext.metricStarted();
439 loggingContext.metricEnded();
440 PolicyLogger.metrics("Metric example posted here - 1 of 2");
441 loggingContext.metricStarted();
442 loggingContext.metricEnded();
443 PolicyLogger.metrics("Metric example posted here - 2 of 2");
445 // Dump our request out
447 if (logger.isDebugEnabled()) {
448 XACMLRest.dumpRequest(request);
452 im.startTransaction();
453 } catch (IntegrityMonitorException e) {
454 String message = e.toString();
455 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + e);
456 loggingContext.transactionEnded();
457 PolicyLogger.audit("Transaction Failed - See Error.log");
459 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
460 } catch (Exception e1) {
461 logger.error("Exception occured while sending error in response" + e1);
466 // What is being PUT?
468 String cache = request.getParameter("cache");
470 // Should be a list of policy and pip configurations in Java properties format
472 if (cache != null && request.getContentType().equals("text/x-java-properties")) {
473 loggingContext.setServiceName("PDP.putConfig");
475 if (request.getContentLength() > Integer
476 .parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", DEFAULT_MAX_CONTENT_LENGTH))) {
477 String message = "Content-Length larger than server will accept.";
478 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
479 loggingContext.transactionEnded();
480 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
481 PolicyLogger.audit("Transaction Failed - See Error.log");
482 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
486 logger.info("XACMLPdpServlet: calling doPutConfig to add properties to the queue");
487 this.doPutConfig(cache, request, response, loggingContext);
488 loggingContext.transactionEnded();
489 PolicyLogger.audit("Transaction ended");
492 } catch (Exception e) {
493 logger.error("Exception Occured while getting Max Content lenght" + e);
496 String message = "Invalid cache: '" + cache + "' or content-type: '" + request.getContentType() + "'";
497 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message);
498 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
499 loggingContext.transactionEnded();
500 PolicyLogger.audit("Transaction Failed - See Error.log");
502 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
503 } catch (Exception e1) {
504 logger.error("Exception occured while sending error in response" + e1);
511 protected void doPutConfig(String config, HttpServletRequest request, HttpServletResponse response,
512 ONAPLoggingContext loggingContext) throws IOException {
514 // prevent multiple configuration changes from stacking up
515 logger.info("XACMLPdpServlet: checking remainingCapacity of Queue.");
516 if (XACMLPdpServlet.queue.remainingCapacity() <= 0) {
517 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Queue capacity reached");
518 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "Queue capacity reached");
519 loggingContext.transactionEnded();
520 PolicyLogger.audit("Transaction Failed - See Error.log");
521 response.sendError(HttpServletResponse.SC_CONFLICT,
522 "Multiple configuration changes waiting processing.");
526 // Read the properties data into an object.
528 Properties newProperties = new Properties();
529 newProperties.load(request.getInputStream());
530 // should have something in the request
531 if (newProperties.size() == 0) {
532 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No properties in PUT");
533 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No properties in PUT");
534 loggingContext.transactionEnded();
535 PolicyLogger.audit("Transaction Failed - See Error.log");
536 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT must contain at least one property");
540 // Which set of properties are they sending us? Whatever they send gets
541 // put on the queue (if there is room).
542 // For audit logging purposes, we consider the transaction done once the
543 // the request gets put on the queue.
545 if (config.equals("policies")) {
546 newProperties = XACMLProperties.getPolicyProperties(newProperties, true);
547 if (newProperties.size() == 0) {
548 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No policy properties in PUT");
549 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No policy properties in PUT");
550 loggingContext.transactionEnded();
551 PolicyLogger.audit("Transaction Failed - See Error.log");
552 response.sendError(HttpServletResponse.SC_BAD_REQUEST,
553 "PUT with cache=policies must contain at least one policy property");
556 logger.info("XACMLPdpServlet: offer policies to queue. No pip properties added.");
557 XACMLPdpServlet.queue.offer(new PutRequest(newProperties, null));
558 loggingContext.transactionEnded();
559 auditLogger.info("Success");
560 PolicyLogger.audit("Success");
561 } else if (config.equals("pips")) {
562 newProperties = XACMLProperties.getPipProperties(newProperties);
563 if (newProperties.size() == 0) {
564 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No pips properties in PUT");
565 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No pips properties in PUT");
566 loggingContext.transactionEnded();
567 PolicyLogger.audit("Transaction Failed - See Error.log");
568 response.sendError(HttpServletResponse.SC_BAD_REQUEST,
569 "PUT with cache=pips must contain at least one pip property");
572 logger.info("XACMLPdpServlet: offer pips to queue. No policy properties added.");
573 XACMLPdpServlet.queue.offer(new PutRequest(null, newProperties));
574 loggingContext.transactionEnded();
575 auditLogger.info("Success");
576 PolicyLogger.audit("Success");
577 } else if (config.equals("all")) {
578 Properties newPolicyProperties = XACMLProperties.getPolicyProperties(newProperties, true);
579 if (newPolicyProperties.size() == 0) {
580 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No policy properties in PUT");
581 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No policy properties in PUT");
582 loggingContext.transactionEnded();
583 PolicyLogger.audit("Transaction Failed - See Error.log");
584 response.sendError(HttpServletResponse.SC_BAD_REQUEST,
585 "PUT with cache=all must contain at least one policy property");
588 Properties newPipProperties = XACMLProperties.getPipProperties(newProperties);
589 if (newPipProperties.size() == 0) {
590 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No pips properties in PUT");
591 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No pips properties in PUT");
592 loggingContext.transactionEnded();
593 PolicyLogger.audit("Transaction Failed - See Error.log");
594 response.sendError(HttpServletResponse.SC_BAD_REQUEST,
595 "PUT with cache=all must contain at least one pip property");
598 logger.info("XACMLPdpServlet: offer policies and pips to queue.");
599 XACMLPdpServlet.queue.offer(new PutRequest(newPolicyProperties, newPipProperties));
600 loggingContext.transactionEnded();
601 auditLogger.info("Success");
602 PolicyLogger.audit("Success");
608 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid config value: " + config);
609 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Invalid config value: " + config);
610 loggingContext.transactionEnded();
611 PolicyLogger.audit("Transaction Failed - See Error.log");
612 response.sendError(HttpServletResponse.SC_BAD_REQUEST,
613 "Config must be one of 'policies', 'pips', 'all'");
616 } catch (Exception e) {
617 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed to process new configuration.", e);
618 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to process new configuration");
619 loggingContext.transactionEnded();
620 PolicyLogger.audit("Transaction Failed - See Error.log");
622 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
623 } catch (Exception e1) {
624 logger.error("Exception occured while sending error in response" + e1);
632 * Parameters: type=hb|config|Status
634 * 1. HeartBeat Status HeartBeat OK - All Policies are Loaded, All PIPs are Loaded LOADING_IN_PROGRESS - Currently
635 * loading a new policy set/pip configuration LAST_UPDATE_FAILED - Need to track the items that failed during last
636 * update LOAD_FAILURE - ??? Need to determine what information is sent and how 2. Configuration 3. Status return
637 * the StdPDPStatus object in the Response content
640 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
643 protected void doGet(HttpServletRequest request, HttpServletResponse response)
644 throws ServletException, IOException {
645 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
646 loggingContext.transactionStarted();
647 if ((loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")) {
648 UUID requestID = UUID.randomUUID();
649 loggingContext.setRequestID(requestID.toString());
650 PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doGet) so we generated one");
652 PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doGet)");
654 loggingContext.metricStarted();
655 loggingContext.metricEnded();
656 PolicyLogger.metrics("Metric example posted here - 1 of 2");
657 loggingContext.metricStarted();
658 loggingContext.metricEnded();
659 PolicyLogger.metrics("Metric example posted here - 2 of 2");
661 XACMLRest.dumpRequest(request);
663 String pathInfo = request.getRequestURI();
664 if (pathInfo != null && "/pdp/test".equals(pathInfo)) {
665 // health check from Global Site Selector (iDNS).
666 // DO NOT do a im.startTransaction for the test request
667 loggingContext.setServiceName("iDNS:PDP.test");
670 // If we make it this far, all is well
671 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " is OK";
672 PolicyLogger.debug(message);
673 PolicyLogger.audit("Success");
674 response.setStatus(HttpServletResponse.SC_OK);
676 } catch (ForwardProgressException | AdministrativeStateException | StandbyStatusException fpe) {
677 // No forward progress is being made
678 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " is not making forward progress."
679 + " Exception Message: " + fpe.getMessage();
680 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + fpe);
681 PolicyLogger.audit("Transaction Failed - See Error.log");
683 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
684 } catch (Exception e1) {
685 logger.error("Exception occured while sending error in response" + e1);
688 } catch (Exception e) {
689 // A subsystem is not making progress or is not responding
690 String eMsg = e.getMessage();
692 eMsg = "No Exception Message";
694 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " has had a subsystem failure."
695 + " Exception Message: " + eMsg;
696 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
697 // Get the specific list of subsystems that failed
698 String failedNodeList = null;
699 for (String node : dependencyNodes) {
700 if (eMsg.contains(node)) {
701 if (failedNodeList == null) {
702 failedNodeList = node;
704 failedNodeList = failedNodeList.concat("," + node);
708 if (failedNodeList == null) {
709 failedNodeList = "UnknownSubSystem";
711 response.addHeader("X-ONAP-SubsystemFailure", failedNodeList);
713 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
714 } catch (Exception e1) {
715 logger.error("Exception occured while sending error in response" + e1);
717 PolicyLogger.audit("Transaction Failed - See Error.log" + e);
720 loggingContext.transactionEnded();
725 im.startTransaction();
726 } catch (IntegrityMonitorException e) {
727 String message = e.toString();
728 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
729 loggingContext.transactionEnded();
730 PolicyLogger.audit("Transaction Failed - See Error.log" + e);
732 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
733 } catch (Exception e1) {
734 logger.error("Exception occured while sending error in response" + e1);
739 // What are they requesting?
741 boolean returnHB = false;
742 response.setHeader("Cache-Control", "no-cache");
743 String type = request.getParameter("type");
744 // type might be null, so use equals on string constants
745 if ("config".equals(type)) {
746 loggingContext.setServiceName("PDP.getConfig");
747 response.setContentType("text/x-java-properties");
749 String lists = XACMLProperties.PROP_ROOTPOLICIES + "="
750 + XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES, "");
751 lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "="
752 + XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, "") + "\n";
753 try (InputStream listInputStream = new ByteArrayInputStream(lists.getBytes());
754 InputStream pipInputStream = Files.newInputStream(XACMLPdpLoader.getPIPConfig());
755 OutputStream os = response.getOutputStream()) {
756 IOUtils.copy(listInputStream, os);
757 IOUtils.copy(pipInputStream, os);
759 loggingContext.transactionEnded();
760 auditLogger.info("Success");
761 PolicyLogger.audit("Success");
762 response.setStatus(HttpServletResponse.SC_OK);
763 } catch (Exception e) {
764 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed to copy property file", e);
765 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to copy property file");
766 loggingContext.transactionEnded();
767 PolicyLogger.audit("Transaction Failed - See Error.log");
769 response.sendError(400, "Failed to copy Property file");
770 } catch (Exception e1) {
771 logger.error("Exception occured while sending error in response" + e1);
775 } else if ("hb".equals(type)) {
777 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
779 } else if ("Status".equals(type)) {
780 loggingContext.setServiceName("PDP.getStatus");
781 // convert response object to JSON and include in the response
782 synchronized (pdpStatusLock) {
783 ObjectMapper mapper = new ObjectMapper();
785 mapper.writeValue(response.getOutputStream(), status);
786 } catch (Exception e1) {
787 logger.error("Exception occured while writing output stream" + e1);
790 response.setStatus(HttpServletResponse.SC_OK);
791 loggingContext.transactionEnded();
792 auditLogger.info("Success");
793 PolicyLogger.audit("Success");
796 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid type value: " + type);
797 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Invalid type value: " + type);
798 loggingContext.transactionEnded();
799 PolicyLogger.audit("Transaction Failed - See Error.log");
801 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "type not 'config' or 'hb'");
802 } catch (Exception e1) {
803 logger.error("Exception occured while sending error in response" + e1);
807 synchronized (pdpStatusLock) {
808 response.addHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB, status.getStatus().toString());
811 loggingContext.transactionEnded();
812 PolicyLogger.audit("Transaction Ended");
818 * POST - We expect XACML requests to be posted by PEP applications. They can be in the form of XML or JSON
819 * according to the XACML 3.0 Specifications for both.
822 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
825 protected void doPost(HttpServletRequest request, HttpServletResponse response)
826 throws ServletException, IOException {
828 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
829 loggingContext.transactionStarted();
830 loggingContext.setServiceName("PDP.decide");
831 if ((loggingContext.getRequestID() == null) || ("".equals(loggingContext.getRequestID()))) {
832 UUID requestID = UUID.randomUUID();
833 loggingContext.setRequestID(requestID.toString());
834 PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doPost) so we generated one");
836 PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doPost)");
838 loggingContext.metricStarted();
839 loggingContext.metricEnded();
840 PolicyLogger.metrics("Metric example posted here - 1 of 2");
841 loggingContext.metricStarted();
842 loggingContext.metricEnded();
843 PolicyLogger.metrics("Metric example posted here - 2 of 2");
844 monitor.pdpEvaluationAttempts();
847 im.startTransaction();
848 } catch (IntegrityMonitorException e) {
849 String message = e.toString();
850 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + e);
851 loggingContext.transactionEnded();
852 PolicyLogger.audit("Transaction Failed - See Error.log");
854 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
855 } catch (Exception e1) {
856 logger.error("Exception occured while sending error in response" + e1);
861 // no point in doing any work if we know from the get-go that we cannot do anything with the request
863 if (status.getLoadedRootPolicies().isEmpty()) {
864 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Request from PEP at " + request.getRequestURI()
865 + " for service when PDP has No Root Policies loaded");
866 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, "Request from PEP at " + request.getRequestURI()
867 + " for service when PDP has No Root Policies loaded");
868 loggingContext.transactionEnded();
869 PolicyLogger.audit("Transaction Failed - See Error.log");
871 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
872 } catch (Exception e1) {
873 logger.error("Exception occured while sending error in response" + e1);
879 XACMLRest.dumpRequest(request);
881 // Set our no-cache header
883 response.setHeader("Cache-Control", "no-cache");
885 // They must send a Content-Type
887 if (request.getContentType() == null) {
888 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Must specify a Content-Type");
889 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Must specify a Content-Type");
890 loggingContext.transactionEnded();
891 PolicyLogger.audit("Transaction Failed - See Error.log");
893 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "no content-type given");
894 } catch (Exception e1) {
895 logger.error("Exception occured while sending error in response" + e1);
901 // Limit the Content-Length to something reasonable
904 if (request.getContentLength() > Integer
905 .parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", "32767"))) {
906 String message = "Content-Length larger than server will accept.";
907 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
908 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
909 loggingContext.transactionEnded();
910 PolicyLogger.audit("Transaction Failed - See Error.log");
911 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
915 } catch (Exception e) {
916 logger.error("Exception occured while getting max content length" + e);
919 if (request.getContentLength() <= 0) {
920 String message = "Content-Length is negative";
921 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
922 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
923 loggingContext.transactionEnded();
924 PolicyLogger.audit("Transaction Failed - See Error.log");
926 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
927 } catch (Exception e1) {
928 logger.error("Exception occured while sending error in response" + e1);
933 ContentType contentType = null;
935 contentType = ContentType.parse(request.getContentType());
936 } catch (Exception e) {
937 String message = "Parsing Content-Type: " + request.getContentType() + ", error=" + e.getMessage();
938 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message, e);
939 loggingContext.transactionEnded();
940 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, message);
941 PolicyLogger.audit("Transaction Failed - See Error.log");
943 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
944 } catch (Exception e1) {
945 logger.error("Exception occured while sending error in response" + e1);
951 // What exactly did they send us?
953 String incomingRequestString = null;
954 Request pdpRequest = null;
955 if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())
956 || contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType())
957 || contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
959 // Read in the string
961 StringBuilder buffer = new StringBuilder();
962 BufferedReader reader = null;
964 reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
965 } catch (IOException e) {
966 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error during reading input stream", e);
971 while ((line = reader.readLine()) != null) {
974 } catch (Exception e) {
975 logger.error("Exception Occured while reading line" + e);
978 incomingRequestString = buffer.toString();
979 logger.info(incomingRequestString);
981 // Parse into a request
984 if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
985 pdpRequest = JSONRequest.load(incomingRequestString);
986 } else if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType())
987 || "application/xacml+xml".equalsIgnoreCase(contentType.getMimeType())) {
988 pdpRequest = DOMRequest.load(incomingRequestString);
990 } catch (Exception e) {
991 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Could not parse request", e);
992 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "Could not parse request");
993 loggingContext.transactionEnded();
994 PolicyLogger.audit("Transaction Failed - See Error.log");
996 response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
997 } catch (Exception e1) {
998 logger.error("Exception occured while sending error in response" + e1);
1000 im.endTransaction();
1004 String message = "unsupported content type" + request.getContentType();
1005 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
1006 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
1007 loggingContext.transactionEnded();
1008 PolicyLogger.audit("Transaction Failed - See Error.log");
1010 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
1011 } catch (Exception e1) {
1012 logger.error("Exception occured while sending error in response" + e1);
1014 im.endTransaction();
1018 // Did we successfully get and parse a request?
1020 if (pdpRequest == null || pdpRequest.getRequestAttributes() == null
1021 || pdpRequest.getRequestAttributes().isEmpty()) {
1022 String message = "Zero Attributes found in the request";
1023 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
1024 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
1025 loggingContext.transactionEnded();
1026 PolicyLogger.audit("Transaction Failed - See Error.log");
1028 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
1029 } catch (Exception e1) {
1030 logger.error("Exception occured while sending error in response" + e1);
1032 im.endTransaction();
1040 // Authenticating the Request here.
1042 if (!authorizeRequest(request)) {
1044 "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
1045 logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + message);
1046 PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS, message);
1047 loggingContext.transactionEnded();
1048 PolicyLogger.audit("Transaction Failed - See Error.log");
1049 response.sendError(HttpServletResponse.SC_FORBIDDEN, message);
1050 im.endTransaction();
1054 // Get the pointer to the PDP Engine
1056 PDPEngine myEngine = null;
1057 synchronized (pdpEngineLock) {
1058 myEngine = XACMLPdpServlet.pdpEngine;
1060 if (myEngine == null) {
1061 String message = "No engine loaded.";
1062 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message);
1063 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
1064 loggingContext.transactionEnded();
1065 PolicyLogger.audit("Transaction Failed - See Error.log");
1066 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1067 im.endTransaction();
1071 // Send the request and save the response
1075 Response pdpResponse = null;
1077 synchronized (pdpEngineLock) {
1078 myEngine = XACMLPdpServlet.pdpEngine;
1080 PolicyList.clearPolicyList();
1081 lTimeStart = System.currentTimeMillis();
1082 pdpResponse = myEngine.decide(pdpRequest);
1083 lTimeEnd = System.currentTimeMillis();
1084 } catch (PDPException e) {
1085 String message = "Exception during decide: " + e.getMessage();
1086 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message + e);
1087 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
1088 loggingContext.transactionEnded();
1089 PolicyLogger.audit("Transaction Failed - See Error.log");
1091 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1092 } catch (Exception e1) {
1093 logger.error("Exception occured while sending error in response" + e1);
1095 im.endTransaction();
1099 monitor.computeLatency(lTimeEnd - lTimeStart);
1100 requestLogger.info(lTimeStart + "=" + incomingRequestString);
1101 for (String policy : PolicyList.getpolicyList()) {
1102 monitor.policyCountAdd(policy, 1);
1106 logger.info("PolicyID triggered in Request: " + PolicyList.getpolicyList());
1108 // need to go through the list and find out if the value is unique and then add it other wise
1109 // monitor.policyCountAdd(PolicyList.getpolicyList(), 1);
1111 if (logger.isDebugEnabled()) {
1112 logger.debug("Request time: " + (lTimeEnd - lTimeStart) + "ms");
1115 // Convert Response to appropriate Content-Type
1117 if (pdpResponse == null) {
1118 requestLogger.info(lTimeStart + "=" + "{}");
1120 throw new PDPException("Failed to get response from PDP engine.");
1121 } catch (Exception e1) {
1122 logger.error("Exception occured while throwing Exception" + e1);
1126 // Set our content-type
1128 response.setContentType(contentType.getMimeType());
1130 // Convert the PDP response object to a String to
1131 // return to our caller as well as dump to our loggers.
1133 String outgoingResponseString = "";
1135 if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
1137 // Get it as a String. This is not very efficient but we need to log our
1138 // results for auditing.
1140 outgoingResponseString = JSONResponse.toString(pdpResponse, logger.isDebugEnabled());
1141 if (logger.isDebugEnabled()) {
1142 logger.debug(outgoingResponseString);
1144 // Get rid of whitespace
1146 outgoingResponseString = JSONResponse.toString(pdpResponse, false);
1148 } else if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType())
1149 || contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
1151 // Get it as a String. This is not very efficient but we need to log our
1152 // results for auditing.
1154 outgoingResponseString = DOMResponse.toString(pdpResponse, logger.isDebugEnabled());
1155 if (logger.isDebugEnabled()) {
1156 logger.debug(outgoingResponseString);
1158 // Get rid of whitespace
1160 outgoingResponseString = DOMResponse.toString(pdpResponse, false);
1163 // adding the jmx values for NA, Permit and Deny
1165 if (outgoingResponseString.contains("NotApplicable")
1166 || outgoingResponseString.contains("Decision not a Permit")) {
1167 monitor.pdpEvaluationNA();
1170 if (outgoingResponseString.contains("Permit")
1171 && !outgoingResponseString.contains("Decision not a Permit")) {
1172 monitor.pdpEvaluationPermit();
1175 if (outgoingResponseString.contains("Deny")) {
1176 monitor.pdpEvaluationDeny();
1179 // lTimeStart is used as an ID within the requestLogger to match up
1180 // request's with responses.
1182 requestLogger.info(lTimeStart + "=" + outgoingResponseString);
1183 response.getWriter().print(outgoingResponseString);
1184 } catch (Exception e) {
1185 logger.error("Exception Occured" + e);
1187 } catch (Exception e) {
1188 String message = "Exception executing request: " + e;
1189 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message, e);
1190 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, message);
1191 loggingContext.transactionEnded();
1192 PolicyLogger.audit("Transaction Failed - See Error.log");
1194 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1195 } catch (Exception e1) {
1196 logger.error("Exception occured while sending error in response" + e1);
1201 monitor.pdpEvaluationSuccess();
1202 response.setStatus(HttpServletResponse.SC_OK);
1204 loggingContext.transactionEnded();
1205 auditLogger.info("Success");
1206 PolicyLogger.audit("Success");
1211 * Added for Authorizing the PEP Requests for Environment check.
1213 private boolean authorizeRequest(HttpServletRequest request) {
1214 // Get the client Credentials from the Request header.
1215 HttpServletRequest httpServletRequest = request;
1216 String clientCredentials = httpServletRequest.getHeader(ENVIORNMENT_HEADER);
1217 if (clientCredentials != null && clientCredentials.equalsIgnoreCase(environment)) {
1227 // Keep running until we are told to terminate
1230 // variable not used, but constructor has needed side-effects so don't remove:
1231 while (!XACMLPdpServlet.configThreadTerminate) {
1232 logger.info("XACMLPdpServlet: Taking requests from the queue");
1233 PutRequest request = XACMLPdpServlet.queue.take();
1234 logger.info("XACMLPdpServlet: Taking requests from the queue COMPLETED");
1235 StdPDPStatus newStatus = new StdPDPStatus();
1237 PDPEngine newEngine = null;
1238 synchronized (pdpStatusLock) {
1239 XACMLPdpServlet.status.setStatus(Status.UPDATING_CONFIGURATION);
1241 logger.info("created new PDPEngine");
1243 XACMLPdpLoader.loadEngine(newStatus, request.policyProperties, request.pipConfigProperties);
1245 if (newEngine != null) {
1246 logger.info("XACMLPdpServlet: newEngine created, assigning newEngine to the pdpEngine.");
1247 synchronized (XACMLPdpServlet.pdpEngineLock) {
1248 XACMLPdpServlet.pdpEngine = newEngine;
1250 logger.info("Saving configuration.");
1251 if (request.policyProperties != null) {
1252 logger.info("Saving configuration: Policy Properties: " + request.policyProperties);
1253 try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPDPPolicyCache())) {
1254 request.policyProperties.store(os, "");
1257 if (request.pipConfigProperties != null) {
1258 logger.info("Saving configuration: PIP Properties: " + request.pipConfigProperties);
1259 try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPIPConfig())) {
1260 request.pipConfigProperties.store(os, "");
1263 newStatus.setStatus(Status.UP_TO_DATE);
1264 } catch (Exception e) {
1266 XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to store new properties." + e);
1267 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "Failed to store new properties");
1268 newStatus.setStatus(Status.LOAD_ERRORS);
1269 newStatus.addLoadWarning("Unable to save configuration: " + e.getMessage());
1273 newStatus.setStatus(Status.LAST_UPDATE_FAILED);
1275 synchronized (pdpStatusLock) {
1276 XACMLPdpServlet.status.set(newStatus);
1278 logger.info("New PDP Servlet Status: " + newStatus.getStatus());
1279 if (Status.UP_TO_DATE.equals(newStatus.getStatus())) {
1280 // Notification will be Sent Here.
1281 XACMLPdpLoader.sendNotification();
1284 } catch (InterruptedException e) {
1285 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "interrupted" + e);
1286 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, "interrupted");
1287 Thread.currentThread().interrupt();
1291 public static PDPEngine getPDPEngine() {
1292 PDPEngine myEngine = null;
1293 synchronized (pdpEngineLock) {
1294 myEngine = XACMLPdpServlet.pdpEngine;
1299 public static Constructor<?> getCreateUpdatePolicyConstructor() {
1300 return createUpdatePolicyConstructor;
1303 public static Object getPDPEngineLock() {
1304 return pdpEngineLock;
1307 private static void setCreateUpdatePolicyConstructor(String createUpdateResourceName) throws ServletException {
1309 Class<?> createUpdateclass = Class.forName(createUpdateResourceName);
1310 createUpdatePolicyConstructor =
1311 createUpdateclass.getConstructor(PolicyParameters.class, String.class, boolean.class);
1312 } catch (Exception e) {
1313 PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, "createUpdatePolicy.impl.className",
1314 "xacml.pdp.init" + e);
1315 throw new ServletException(
1316 "Could not find the Class name : " + createUpdateResourceName + "\n" + e.getMessage());