2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.pdp.rest;
23 import java.io.BufferedReader;
24 import java.io.ByteArrayInputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.InputStreamReader;
28 import java.io.OutputStream;
29 import java.lang.reflect.Constructor;
30 import java.net.InetAddress;
31 import java.net.UnknownHostException;
32 import java.nio.file.Files;
33 import java.util.Properties;
34 import java.util.UUID;
35 import java.util.concurrent.BlockingQueue;
36 import java.util.concurrent.LinkedBlockingQueue;
38 import javax.servlet.Servlet;
39 import javax.servlet.ServletConfig;
40 import javax.servlet.ServletException;
41 import javax.servlet.annotation.WebInitParam;
42 import javax.servlet.annotation.WebServlet;
43 import javax.servlet.http.HttpServlet;
44 import javax.servlet.http.HttpServletRequest;
45 import javax.servlet.http.HttpServletResponse;
47 import org.apache.commons.io.IOUtils;
48 import org.apache.commons.logging.Log;
49 import org.apache.commons.logging.LogFactory;
50 import org.apache.http.entity.ContentType;
51 import org.onap.policy.api.PolicyParameters;
52 import org.onap.policy.common.im.AdministrativeStateException;
53 import org.onap.policy.common.im.ForwardProgressException;
54 import org.onap.policy.common.im.IntegrityMonitor;
55 import org.onap.policy.common.im.IntegrityMonitorProperties;
56 import org.onap.policy.common.im.StandbyStatusException;
57 import org.onap.policy.common.logging.ONAPLoggingContext;
58 import org.onap.policy.common.logging.ONAPLoggingUtils;
59 import org.onap.policy.common.logging.eelf.MessageCodes;
60 import org.onap.policy.common.logging.eelf.PolicyLogger;
61 import org.onap.policy.pdp.rest.jmx.PdpRestMonitor;
62 import org.onap.policy.rest.XACMLRest;
63 import org.onap.policy.rest.XACMLRestProperties;
64 import org.onap.policy.xacml.api.XACMLErrorConstants;
65 import org.onap.policy.xacml.pdp.std.functions.PolicyList;
66 import org.onap.policy.xacml.std.pap.StdPDPStatus;
68 import com.att.research.xacml.api.Request;
69 import com.att.research.xacml.api.Response;
70 import com.att.research.xacml.api.pap.PDPStatus.Status;
71 import com.att.research.xacml.api.pdp.PDPEngine;
72 import com.att.research.xacml.api.pdp.PDPException;
73 import com.att.research.xacml.std.dom.DOMRequest;
74 import com.att.research.xacml.std.dom.DOMResponse;
75 import com.att.research.xacml.std.json.JSONRequest;
76 import com.att.research.xacml.std.json.JSONResponse;
77 import com.att.research.xacml.util.XACMLProperties;
78 import com.fasterxml.jackson.databind.ObjectMapper;
81 * Servlet implementation class XacmlPdpServlet
83 * This is an implementation of the XACML 3.0 RESTful Interface with added features to support
84 * simple PAP RESTful API for policy publishing and PIP configuration changes.
86 * If you are running this the first time, then we recommend you look at the xacml.pdp.properties file.
87 * This properties file has all the default parameter settings. If you are running the servlet as is,
88 * then we recommend setting up you're container to run it on port 8080 with context "/pdp". Wherever
89 * the default working directory is set to, a "config" directory will be created that holds the policy
90 * and pip cache. This setting is located in the xacml.pdp.properties file.
92 * When you are ready to customize, you can create a separate xacml.pdp.properties on you're local file
93 * system and setup the parameters as you wish. Just set the Java VM System variable to point to that file:
95 * -Dxacml.properties=/opt/app/xacml/etc/xacml.pdp.properties
97 * Or if you only want to change one or two properties, simply set the Java VM System variable for that property.
99 * -Dxacml.rest.pdp.register=false
104 description = "Implements the XACML PDP RESTful API and client PAP API.",
105 urlPatterns = { "/" },
108 @WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pdp.properties", description = "The location of the PDP xacml.pdp.properties file holding configuration information.")
110 public class XACMLPdpServlet extends HttpServlet implements Runnable {
111 private static final long serialVersionUID = 1L;
112 private static final String DEFAULT_MAX_CONTENT_LENGTH = "999999999"; //32767
113 private static final String CREATE_UPDATE_POLICY_SERVICE = "org.onap.policy.pdp.rest.api.services.CreateUpdatePolicyServiceImpl";
115 // Our application debug log
117 private static final Log logger = LogFactory.getLog(XACMLPdpServlet.class);
119 // This logger is specifically only for Xacml requests and their corresponding response.
120 // It's output ideally should be sent to a separate file from the application logger.
122 private static final Log requestLogger = LogFactory.getLog("xacml.request");
125 private static final Log auditLogger = LogFactory.getLog("auditLogger");
127 private static final PdpRestMonitor monitor = PdpRestMonitor.getSingleton();
130 // This thread may getting invoked on startup, to let the PAP know
131 // that we are up and running.
133 private static transient Thread registerThread = null;
134 private static transient XACMLPdpRegisterThread registerRunnable = null;
136 // This is our PDP engine pointer. There is a synchronized lock used
137 // for access to the pointer. In case we are servicing PEP requests while
138 // an update is occurring from the PAP.
140 private static PDPEngine pdpEngine = null;
141 private static final Object pdpEngineLock = new Object();
143 // This is our PDP's status. What policies are loaded (or not) and
144 // what PIP configurations are loaded (or not).
145 // There is a synchronized lock used for access to the object.
147 private static volatile StdPDPStatus status = new StdPDPStatus();
148 private static final Object pdpStatusLock = new Object();
149 private static Constructor<?> createUpdatePolicyConstructor;
151 private static final String ENVIORNMENT_HEADER = "Environment";
152 private static String environment = null;
154 // Queue of PUT requests
156 public static class PutRequest {
157 private Properties policyProperties = null;
158 private Properties pipConfigProperties = null;
160 PutRequest(Properties policies, Properties pips) {
161 this.policyProperties = policies;
162 this.pipConfigProperties = pips;
165 protected static volatile BlockingQueue<PutRequest> queue = null;
166 // For notification Delay.
167 private static int notificationDelay = 0;
168 public static int getNotificationDelay(){
169 return XACMLPdpServlet.notificationDelay;
172 private static String pdpResourceName;
173 private static String[] dependencyNodes = null;
176 // This is our configuration thread that attempts to load
177 // a new configuration request.
179 private static transient Thread configThread = null;
180 private static volatile boolean configThreadTerminate = false;
181 private transient ONAPLoggingContext baseLoggingContext = null;
182 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, "xacml.pdp");
261 throw new ServletException("dependency_groups is null");
263 setDependencyNodes(dependencyGroups);
266 // CreateUpdatePolicy ResourceName
267 createUpdateResourceName = properties.getProperty("createUpdatePolicy.impl.className", CREATE_UPDATE_POLICY_SERVICE);
268 setCreateUpdatePolicyConstructor(createUpdateResourceName);
270 // Create an IntegrityMonitor
272 logger.info("Creating IntegrityMonitor");
273 im = IntegrityMonitor.getInstance(pdpResourceName, properties);
274 } catch (Exception e) {
275 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to create IntegrityMonitor" +e);
276 throw new ServletException(e);
278 startThreads(baseLoggingContext, new Thread(this));
281 private static void startThreads(ONAPLoggingContext baseLoggingContext, Thread thread) {
282 environment = XACMLProperties.getProperty("ENVIRONMENT", "DEVL");
284 // Kick off our thread to register with the PAP servlet.
286 if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER))) {
287 XACMLPdpServlet.registerRunnable = new XACMLPdpRegisterThread(baseLoggingContext);
288 XACMLPdpServlet.registerThread = new Thread(XACMLPdpServlet.registerRunnable);
289 XACMLPdpServlet.registerThread.start();
292 // This is our thread that manages incoming configuration
295 XACMLPdpServlet.configThread = thread;
296 XACMLPdpServlet.configThread.start();
299 private static void setDependencyNodes(String dependencyGroups) {
300 // dependency_groups is a semicolon-delimited list of groups, and
301 // each group is a comma-separated list of nodes. For our purposes
302 // we just need a list of dependencies without regard to grouping,
303 // so split the list into nodes separated by either comma or semicolon.
304 dependencyNodes = dependencyGroups.split("[;,]");
305 for (int i = 0 ; i < dependencyNodes.length ; i++){
306 dependencyNodes[i] = dependencyNodes[i].trim();
310 private static void setPDPResourceName(Properties properties) throws ServletException {
311 pdpResourceName = properties.getProperty(XACMLRestProperties.PDP_RESOURCE_NAME);
312 if(pdpResourceName == null){
313 PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, XACMLRestProperties.PDP_RESOURCE_NAME, "xacml.pdp");
314 throw new ServletException("pdpResourceName is null");
318 private static void initQueue(int queueSize) {
319 queue = new LinkedBlockingQueue<>(queueSize);
322 private static void setNotificationDelay() {
324 XACMLPdpServlet.notificationDelay = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_DELAY));
325 }catch(NumberFormatException e){
326 logger.error("Error in notification delay format, Taking the default value.", e);
331 * @see Servlet#destroy()
334 public void destroy() {
336 logger.info("Destroying....");
338 // Make sure the register thread is not running
340 if (XACMLPdpServlet.registerRunnable != null) {
342 XACMLPdpServlet.registerRunnable.terminate();
343 if (XACMLPdpServlet.registerThread != null) {
344 XACMLPdpServlet.registerThread.interrupt();
345 XACMLPdpServlet.registerThread.join();
347 } catch (InterruptedException e) {
348 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
349 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
350 XACMLPdpServlet.registerThread.interrupt();
354 // Make sure the configure thread is not running
356 setConfigThreadTerminate(true);
358 XACMLPdpServlet.configThread.interrupt();
359 XACMLPdpServlet.configThread.join();
360 } catch (InterruptedException e) {
361 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
362 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
363 XACMLPdpServlet.configThread.interrupt();
365 logger.info("Destroyed.");
368 private static void setConfigThreadTerminate(boolean value) {
369 XACMLPdpServlet.configThreadTerminate = value;
373 * PUT - The PAP engine sends configuration information using HTTP PUT request.
375 * One parameter is expected:
377 * config=[policy|pip|all]
379 * policy - Expect a properties file that contains updated lists of the root and referenced policies that the PDP should
380 * be using for PEP requests.
382 * Specifically should AT LEAST contain the following properties:
384 * xacml.referencedPolicies
386 * In addition, any relevant information needed by the PDP to load or retrieve the policies to store in its cache.
389 * xacml.rootPolicies=PolicyA.1, PolicyB.1
391 * PolicyA.1.url=http://localhost:9090/PAP?id=b2d7b86d-d8f1-4adf-ba9d-b68b2a90bee1&version=1
392 * PolicyB.1.url=http://localhost:9090/PAP/id=be962404-27f6-41d8-9521-5acb7f0238be&version=1
394 * xacml.referencedPolicies=RefPolicyC.1, RefPolicyD.1
396 * RefPolicyC.1.url=http://localhost:9090/PAP?id=foobar&version=1
397 * RefPolicyD.1.url=http://localhost:9090/PAP/id=example&version=1
399 * pip - Expect a properties file that contain PIP engine configuration properties.
401 * Specifically should AT LEAST the following property:
404 * In addition, any relevant information needed by the PDP to load and configure the PIPs.
407 * xacml.pip.engines=foo,bar
409 * foo.classname=com.foo
414 * bar.classname=com.bar
417 * all - Expect ALL new configuration properties for the PDP
419 * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response)
422 protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
423 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
424 loggingContext.transactionStarted();
425 if ((loggingContext.getRequestID() == null) || "".equals(loggingContext.getRequestID())){
426 UUID requestID = UUID.randomUUID();
427 loggingContext.setRequestID(requestID.toString());
428 PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doPut) so we generated one");
430 PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doPut)");
432 loggingContext.metricStarted();
433 loggingContext.metricEnded();
434 PolicyLogger.metrics("Metric example posted here - 1 of 2");
435 loggingContext.metricStarted();
436 loggingContext.metricEnded();
437 PolicyLogger.metrics("Metric example posted here - 2 of 2");
439 // Dump our request out
441 if (logger.isDebugEnabled()) {
442 XACMLRest.dumpRequest(request);
446 im.startTransaction();
448 catch (AdministrativeStateException | StandbyStatusException e) {
449 String message = e.toString();
450 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + e);
451 loggingContext.transactionEnded();
452 PolicyLogger.audit("Transaction Failed - See Error.log");
454 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
455 }catch(Exception e1){
456 logger.error("Exception occured while sending error in response" +e1);
461 // What is being PUT?
463 String cache = request.getParameter("cache");
465 // Should be a list of policy and pip configurations in Java properties format
467 if (cache != null && request.getContentType().equals("text/x-java-properties")) {
468 loggingContext.setServiceName("PDP.putConfig");
470 if (request.getContentLength() > Integer.parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", DEFAULT_MAX_CONTENT_LENGTH))) {
471 String message = "Content-Length larger than server will accept.";
472 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
473 loggingContext.transactionEnded();
474 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
475 PolicyLogger.audit("Transaction Failed - See Error.log");
476 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
480 logger.info("XACMLPdpServlet: calling doPutConfig to add properties to the queue");
481 this.doPutConfig(cache, request, response, loggingContext);
482 loggingContext.transactionEnded();
483 PolicyLogger.audit("Transaction ended");
487 logger.error("Exception Occured while getting Max Content lenght"+e);
490 String message = "Invalid cache: '" + cache + "' or content-type: '" + request.getContentType() + "'";
491 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message);
492 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
493 loggingContext.transactionEnded();
494 PolicyLogger.audit("Transaction Failed - See Error.log");
496 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
497 }catch(Exception e1){
498 logger.error("Exception occured while sending error in response" +e1);
505 protected void doPutConfig(String config, HttpServletRequest request, HttpServletResponse response, ONAPLoggingContext loggingContext) throws ServletException, IOException {
507 // prevent multiple configuration changes from stacking up
508 logger.info("XACMLPdpServlet: checking remainingCapacity of Queue.");
509 if (XACMLPdpServlet.queue.remainingCapacity() <= 0) {
510 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Queue capacity reached");
511 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "Queue capacity reached");
512 loggingContext.transactionEnded();
513 PolicyLogger.audit("Transaction Failed - See Error.log");
514 response.sendError(HttpServletResponse.SC_CONFLICT, "Multiple configuration changes waiting processing.");
518 // Read the properties data into an object.
520 Properties newProperties = new Properties();
521 newProperties.load(request.getInputStream());
522 // should have something in the request
523 if (newProperties.size() == 0) {
524 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No properties in PUT");
525 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No properties in PUT");
526 loggingContext.transactionEnded();
527 PolicyLogger.audit("Transaction Failed - See Error.log");
528 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT must contain at least one property");
532 // Which set of properties are they sending us? Whatever they send gets
533 // put on the queue (if there is room).
534 // For audit logging purposes, we consider the transaction done once the
535 // the request gets put on the queue.
537 if (config.equals("policies")) {
538 newProperties = XACMLProperties.getPolicyProperties(newProperties, true);
539 if (newProperties.size() == 0) {
540 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No policy properties in PUT");
541 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No policy properties in PUT");
542 loggingContext.transactionEnded();
543 PolicyLogger.audit("Transaction Failed - See Error.log");
544 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=policies must contain at least one policy property");
547 logger.info("XACMLPdpServlet: offer policies to queue. No pip properties added.");
548 XACMLPdpServlet.queue.offer(new PutRequest(newProperties, null));
549 loggingContext.transactionEnded();
550 auditLogger.info("Success");
551 PolicyLogger.audit("Success");
552 } else if (config.equals("pips")) {
553 newProperties = XACMLProperties.getPipProperties(newProperties);
554 if (newProperties.size() == 0) {
555 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No pips properties in PUT");
556 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No pips properties in PUT");
557 loggingContext.transactionEnded();
558 PolicyLogger.audit("Transaction Failed - See Error.log");
559 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=pips must contain at least one pip property");
562 logger.info("XACMLPdpServlet: offer pips to queue. No policy properties added.");
563 XACMLPdpServlet.queue.offer(new PutRequest(null, newProperties));
564 loggingContext.transactionEnded();
565 auditLogger.info("Success");
566 PolicyLogger.audit("Success");
567 } else if (config.equals("all")) {
568 Properties newPolicyProperties = XACMLProperties.getPolicyProperties(newProperties, true);
569 if (newPolicyProperties.size() == 0) {
570 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No policy properties in PUT");
571 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No policy properties in PUT");
572 loggingContext.transactionEnded();
573 PolicyLogger.audit("Transaction Failed - See Error.log");
574 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=all must contain at least one policy property");
577 Properties newPipProperties = XACMLProperties.getPipProperties(newProperties);
578 if (newPipProperties.size() == 0) {
579 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No pips properties in PUT");
580 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "No pips properties in PUT");
581 loggingContext.transactionEnded();
582 PolicyLogger.audit("Transaction Failed - See Error.log");
583 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "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, "Config must be one of 'policies', 'pips', 'all'");
603 } catch (Exception e) {
604 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed to process new configuration.", e);
605 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to process new configuration");
606 loggingContext.transactionEnded();
607 PolicyLogger.audit("Transaction Failed - See Error.log");
609 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
610 }catch(Exception e1){
611 logger.error("Exception occured while sending error in response" +e1);
619 * Parameters: type=hb|config|Status
621 * 1. HeartBeat Status
623 * OK - All Policies are Loaded, All PIPs are Loaded
624 * LOADING_IN_PROGRESS - Currently loading a new policy set/pip configuration
625 * LAST_UPDATE_FAILED - Need to track the items that failed during last update
626 * LOAD_FAILURE - ??? Need to determine what information is sent and how
629 * return the StdPDPStatus object in the Response content
632 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
635 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
636 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
637 loggingContext.transactionStarted();
638 if ((loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")){
639 UUID requestID = UUID.randomUUID();
640 loggingContext.setRequestID(requestID.toString());
641 PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doGet) so we generated one");
643 PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doGet)");
645 loggingContext.metricStarted();
646 loggingContext.metricEnded();
647 PolicyLogger.metrics("Metric example posted here - 1 of 2");
648 loggingContext.metricStarted();
649 loggingContext.metricEnded();
650 PolicyLogger.metrics("Metric example posted here - 2 of 2");
652 XACMLRest.dumpRequest(request);
654 String pathInfo = request.getRequestURI();
655 if (pathInfo != null){
656 // health check from Global Site Selector (iDNS).
657 // DO NOT do a im.startTransaction for the test request
658 if (pathInfo.equals("/pdp/test")) {
659 loggingContext.setServiceName("iDNS:PDP.test");
662 //If we make it this far, all is well
663 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " is OK";
664 PolicyLogger.debug(message);
665 loggingContext.transactionEnded();
666 PolicyLogger.audit("Success");
667 response.setStatus(HttpServletResponse.SC_OK);
669 } catch (ForwardProgressException fpe){
670 //No forward progress is being made
671 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " is not making forward progress."
672 + " Exception Message: " + fpe.getMessage();
673 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + fpe);
674 loggingContext.transactionEnded();
675 PolicyLogger.audit("Transaction Failed - See Error.log");
677 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
678 }catch(Exception e1){
679 logger.error("Exception occured while sending error in response" +e1);
682 }catch (AdministrativeStateException ase){
683 //Administrative State is locked
684 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " Administrative State is LOCKED "
685 + " Exception Message: " + ase.getMessage();
686 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + ase);
687 loggingContext.transactionEnded();
688 PolicyLogger.audit("Transaction Failed - See Error.log");
690 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
691 }catch(Exception e1){
692 logger.error("Exception occured while sending error in response" +e1);
695 }catch (StandbyStatusException sse){
696 //Administrative State is locked
697 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " Standby Status is NOT PROVIDING SERVICE "
698 + " Exception Message: " + sse.getMessage();
699 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + sse);
700 loggingContext.transactionEnded();
701 PolicyLogger.audit("Transaction Failed - See Error.log");
703 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
704 }catch(Exception e1){
705 logger.error("Exception occured while sending error in response" +e1);
708 } catch (Exception e) {
709 //A subsystem is not making progress or is not responding
710 String eMsg = e.getMessage();
712 eMsg = "No Exception Message";
714 String message = "GET:/pdp/test called and PDP " + pdpResourceName + " has had a subsystem failure."
715 + " Exception Message: " + eMsg;
716 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message );
717 //Get the specific list of subsystems that failed
718 String failedNodeList = null;
719 for(String node : dependencyNodes){
720 if(eMsg.contains(node)){
721 if(failedNodeList == null){
722 failedNodeList = node;
724 failedNodeList = failedNodeList.concat(","+node);
728 if(failedNodeList == null){
729 failedNodeList = "UnknownSubSystem";
731 response.addHeader("X-ONAP-SubsystemFailure", failedNodeList);
733 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
734 }catch(Exception e1){
735 logger.error("Exception occured while sending error in response" +e1);
737 loggingContext.transactionEnded();
738 PolicyLogger.audit("Transaction Failed - See Error.log" + e);
745 im.startTransaction();
747 catch (AdministrativeStateException | StandbyStatusException e) {
748 String message = e.toString();
749 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
750 loggingContext.transactionEnded();
751 PolicyLogger.audit("Transaction Failed - See Error.log" +e);
753 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
754 }catch(Exception e1){
755 logger.error("Exception occured while sending error in response" +e1);
760 // What are they requesting?
762 boolean returnHB = false;
763 response.setHeader("Cache-Control", "no-cache");
764 String type = request.getParameter("type");
765 // type might be null, so use equals on string constants
766 if ("config".equals(type)) {
767 loggingContext.setServiceName("PDP.getConfig");
768 response.setContentType("text/x-java-properties");
770 String lists = XACMLProperties.PROP_ROOTPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES, "");
771 lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, "") + "\n";
772 try (InputStream listInputStream = new ByteArrayInputStream(lists.getBytes());
773 InputStream pipInputStream = Files.newInputStream(XACMLPdpLoader.getPIPConfig());
774 OutputStream os = response.getOutputStream()) {
775 IOUtils.copy(listInputStream, os);
776 IOUtils.copy(pipInputStream, os);
778 loggingContext.transactionEnded();
779 auditLogger.info("Success");
780 PolicyLogger.audit("Success");
781 response.setStatus(HttpServletResponse.SC_OK);
782 } catch (Exception e) {
783 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed to copy property file", e);
784 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to copy property file");
785 loggingContext.transactionEnded();
786 PolicyLogger.audit("Transaction Failed - See Error.log");
788 response.sendError(400, "Failed to copy Property file");
789 }catch(Exception e1){
790 logger.error("Exception occured while sending error in response" +e1);
794 } else if ("hb".equals(type)) {
796 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
798 } else if ("Status".equals(type)) {
799 loggingContext.setServiceName("PDP.getStatus");
800 // convert response object to JSON and include in the response
801 synchronized(pdpStatusLock) {
802 ObjectMapper mapper = new ObjectMapper();
804 mapper.writeValue(response.getOutputStream(), status);
805 }catch(Exception e1){
806 logger.error("Exception occured while writing output stream" +e1);
809 response.setStatus(HttpServletResponse.SC_OK);
810 loggingContext.transactionEnded();
811 auditLogger.info("Success");
812 PolicyLogger.audit("Success");
815 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid type value: " + type);
816 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "Invalid type value: " + type);
817 loggingContext.transactionEnded();
818 PolicyLogger.audit("Transaction Failed - See Error.log");
820 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "type not 'config' or 'hb'");
821 }catch(Exception e1){
822 logger.error("Exception occured while sending error in response" +e1);
826 synchronized(pdpStatusLock) {
827 response.addHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB, status.getStatus().toString());
830 loggingContext.transactionEnded();
831 PolicyLogger.audit("Transaction Ended");
837 * POST - We expect XACML requests to be posted by PEP applications. They can be in the form of XML or JSON according
838 * to the XACML 3.0 Specifications for both.
841 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
844 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
846 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
847 loggingContext.transactionStarted();
848 loggingContext.setServiceName("PDP.decide");
849 if ((loggingContext.getRequestID() == null) || ("".equals(loggingContext.getRequestID()))){
850 UUID requestID = UUID.randomUUID();
851 loggingContext.setRequestID(requestID.toString());
852 PolicyLogger.info("requestID not provided in call to XACMLPdpSrvlet (doPost) so we generated one");
854 PolicyLogger.info("requestID was provided in call to XACMLPdpSrvlet (doPost)");
856 loggingContext.metricStarted();
857 loggingContext.metricEnded();
858 PolicyLogger.metrics("Metric example posted here - 1 of 2");
859 loggingContext.metricStarted();
860 loggingContext.metricEnded();
861 PolicyLogger.metrics("Metric example posted here - 2 of 2");
862 monitor.pdpEvaluationAttempts();
865 im.startTransaction();
867 catch (AdministrativeStateException | StandbyStatusException e) {
868 String message = e.toString();
869 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message + e);
870 loggingContext.transactionEnded();
871 PolicyLogger.audit("Transaction Failed - See Error.log");
873 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
874 }catch(Exception e1){
875 logger.error("Exception occured while sending error in response" +e1);
880 // no point in doing any work if we know from the get-go that we cannot do anything with the request
882 if (status.getLoadedRootPolicies().isEmpty()) {
883 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Request from PEP at " + request.getRequestURI() + " for service when PDP has No Root Policies loaded");
884 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, "Request from PEP at " + request.getRequestURI() + " 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.parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", "32767"))) {
922 String message = "Content-Length larger than server will accept.";
923 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
924 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
925 loggingContext.transactionEnded();
926 PolicyLogger.audit("Transaction Failed - See Error.log");
927 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
932 logger.error("Exception occured while getting max content length"+e);
935 if (request.getContentLength() <= 0) {
936 String message = "Content-Length is negative";
937 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
938 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, message);
939 loggingContext.transactionEnded();
940 PolicyLogger.audit("Transaction Failed - See Error.log");
942 response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
943 }catch(Exception e1){
944 logger.error("Exception occured while sending error in response" +e1);
949 ContentType contentType = null;
951 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){
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);
1008 catch(Exception e) {
1009 logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Could not parse request", e);
1010 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "Could not parse request");
1011 loggingContext.transactionEnded();
1012 PolicyLogger.audit("Transaction Failed - See Error.log");
1014 response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
1015 }catch(Exception e1){
1016 logger.error("Exception occured while sending error in response" +e1);
1018 im.endTransaction();
1022 String message = "unsupported content type" + request.getContentType();
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();
1036 // Did we successfully get and parse a request?
1038 if (pdpRequest == null || pdpRequest.getRequestAttributes() == null || 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)){
1060 String message = "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
1061 logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + message );
1062 PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS, message);
1063 loggingContext.transactionEnded();
1064 PolicyLogger.audit("Transaction Failed - See Error.log");
1065 response.sendError(HttpServletResponse.SC_FORBIDDEN, message);
1066 im.endTransaction();
1070 // Get the pointer to the PDP Engine
1072 PDPEngine myEngine = null;
1073 synchronized(pdpEngineLock) {
1074 myEngine = XACMLPdpServlet.pdpEngine;
1076 if (myEngine == null) {
1077 String message = "No engine loaded.";
1078 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message);
1079 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
1080 loggingContext.transactionEnded();
1081 PolicyLogger.audit("Transaction Failed - See Error.log");
1082 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1083 im.endTransaction();
1087 // Send the request and save the response
1091 Response pdpResponse = null;
1093 synchronized(pdpEngineLock) {
1094 myEngine = XACMLPdpServlet.pdpEngine;
1096 PolicyList.clearPolicyList();
1097 lTimeStart = System.currentTimeMillis();
1098 pdpResponse = myEngine.decide(pdpRequest);
1099 lTimeEnd = System.currentTimeMillis();
1100 } catch (PDPException e) {
1101 String message = "Exception during decide: " + e.getMessage();
1102 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message +e);
1103 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, message);
1104 loggingContext.transactionEnded();
1105 PolicyLogger.audit("Transaction Failed - See Error.log");
1107 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1108 }catch(Exception e1){
1109 logger.error("Exception occured while sending error in response" +e1);
1111 im.endTransaction();
1115 monitor.computeLatency(lTimeEnd - lTimeStart);
1116 requestLogger.info(lTimeStart + "=" + incomingRequestString);
1117 for(String policy : PolicyList.getpolicyList()){
1118 monitor.policyCountAdd(policy, 1);
1122 logger.info("PolicyID triggered in Request: " + PolicyList.getpolicyList());
1124 //need to go through the list and find out if the value is unique and then add it other wise
1125 // monitor.policyCountAdd(PolicyList.getpolicyList(), 1);
1127 if (logger.isDebugEnabled()) {
1128 logger.debug("Request time: " + (lTimeEnd - lTimeStart) + "ms");
1131 // Convert Response to appropriate Content-Type
1133 if (pdpResponse == null) {
1134 requestLogger.info(lTimeStart + "=" + "{}");
1136 throw new PDPException("Failed to get response from PDP engine.");
1137 }catch(Exception e1){
1138 logger.error("Exception occured while throwing Exception" +e1);
1142 // Set our content-type
1144 response.setContentType(contentType.getMimeType());
1146 // Convert the PDP response object to a String to
1147 // return to our caller as well as dump to our loggers.
1149 String outgoingResponseString = "";
1151 if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
1153 // Get it as a String. This is not very efficient but we need to log our
1154 // results for auditing.
1156 outgoingResponseString = JSONResponse.toString(pdpResponse, logger.isDebugEnabled());
1157 if (logger.isDebugEnabled()) {
1158 logger.debug(outgoingResponseString);
1160 // Get rid of whitespace
1162 outgoingResponseString = JSONResponse.toString(pdpResponse, false);
1164 } else if ( contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
1165 contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
1167 // Get it as a String. This is not very efficient but we need to log our
1168 // results for auditing.
1170 outgoingResponseString = DOMResponse.toString(pdpResponse, logger.isDebugEnabled());
1171 if (logger.isDebugEnabled()) {
1172 logger.debug(outgoingResponseString);
1174 // Get rid of whitespace
1176 outgoingResponseString = DOMResponse.toString(pdpResponse, false);
1179 // adding the jmx values for NA, Permit and Deny
1181 if (outgoingResponseString.contains("NotApplicable") || outgoingResponseString.contains("Decision not a Permit")){
1182 monitor.pdpEvaluationNA();
1185 if (outgoingResponseString.contains("Permit") && !outgoingResponseString.contains("Decision not a Permit")){
1186 monitor.pdpEvaluationPermit();
1189 if (outgoingResponseString.contains("Deny")){
1190 monitor.pdpEvaluationDeny();
1193 // lTimeStart is used as an ID within the requestLogger to match up
1194 // request's with responses.
1196 requestLogger.info(lTimeStart + "=" + outgoingResponseString);
1197 response.getWriter().print(outgoingResponseString);
1198 }catch(Exception e){
1199 logger.error("Exception Occured"+e );
1202 catch (Exception e) {
1203 String message = "Exception executing request: " + e;
1204 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + message, e);
1205 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, message);
1206 loggingContext.transactionEnded();
1207 PolicyLogger.audit("Transaction Failed - See Error.log");
1209 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1210 }catch(Exception e1){
1211 logger.error("Exception occured while sending error in response" +e1);
1216 monitor.pdpEvaluationSuccess();
1217 response.setStatus(HttpServletResponse.SC_OK);
1219 loggingContext.transactionEnded();
1220 auditLogger.info("Success");
1221 PolicyLogger.audit("Success");
1226 * Added for Authorizing the PEP Requests for Environment check.
1228 private boolean authorizeRequest(HttpServletRequest request) {
1229 // Get the client Credentials from the Request header.
1230 HttpServletRequest httpServletRequest = request;
1231 String clientCredentials = httpServletRequest.getHeader(ENVIORNMENT_HEADER);
1232 if(clientCredentials!=null && clientCredentials.equalsIgnoreCase(environment)){
1242 // Keep running until we are told to terminate
1245 // variable not used, but constructor has needed side-effects so don't remove:
1246 while (! XACMLPdpServlet.configThreadTerminate) {
1247 logger.info("XACMLPdpServlet: Taking requests from the queue");
1248 PutRequest request = XACMLPdpServlet.queue.take();
1249 logger.info("XACMLPdpServlet: Taking requests from the queue COMPLETED");
1250 StdPDPStatus newStatus = new StdPDPStatus();
1252 PDPEngine newEngine = null;
1253 synchronized(pdpStatusLock) {
1254 XACMLPdpServlet.status.setStatus(Status.UPDATING_CONFIGURATION);
1256 logger.info("created new PDPEngine");
1257 newEngine = XACMLPdpLoader.loadEngine(newStatus, request.policyProperties, request.pipConfigProperties);
1259 if (newEngine != null) {
1260 logger.info("XACMLPdpServlet: newEngine created, assigning newEngine to the pdpEngine.");
1261 synchronized(XACMLPdpServlet.pdpEngineLock) {
1262 XACMLPdpServlet.pdpEngine = newEngine;
1264 logger.info("Saving configuration.");
1265 if (request.policyProperties != null) {
1266 logger.info("Saving configuration: Policy Properties: " + request.policyProperties);
1267 try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPDPPolicyCache())) {
1268 request.policyProperties.store(os, "");
1271 if (request.pipConfigProperties != null) {
1272 logger.info("Saving configuration: PIP Properties: " + request.pipConfigProperties);
1273 try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPIPConfig())) {
1274 request.pipConfigProperties.store(os, "");
1277 newStatus.setStatus(Status.UP_TO_DATE);
1278 } catch (Exception e) {
1279 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to store new properties."+e);
1280 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "Failed to store new properties");
1281 newStatus.setStatus(Status.LOAD_ERRORS);
1282 newStatus.addLoadWarning("Unable to save configuration: " + e.getMessage());
1286 newStatus.setStatus(Status.LAST_UPDATE_FAILED);
1288 synchronized(pdpStatusLock) {
1289 XACMLPdpServlet.status.set(newStatus);
1291 logger.info("New PDP Servlet Status: " + newStatus.getStatus());
1292 if (Status.UP_TO_DATE.equals(newStatus.getStatus())) {
1293 // Notification will be Sent Here.
1294 XACMLPdpLoader.sendNotification();
1297 } catch (InterruptedException e) {
1298 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "interrupted"+e);
1299 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, "interrupted");
1300 Thread.currentThread().interrupt();
1304 public static PDPEngine getPDPEngine(){
1305 PDPEngine myEngine = null;
1306 synchronized(pdpEngineLock) {
1307 myEngine = XACMLPdpServlet.pdpEngine;
1312 public static Constructor<?> getCreateUpdatePolicyConstructor(){
1313 return createUpdatePolicyConstructor;
1316 private static void setCreateUpdatePolicyConstructor(String createUpdateResourceName) throws ServletException{
1318 Class<?> createUpdateclass = Class.forName(createUpdateResourceName);
1319 createUpdatePolicyConstructor = createUpdateclass.getConstructor(PolicyParameters.class, String.class, boolean.class);
1320 }catch(Exception e){
1321 PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, "createUpdatePolicy.impl.className", "xacml.pdp.init" +e);
1322 throw new ServletException("Could not find the Class name : " +createUpdateResourceName + "\n" +e.getMessage());