2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 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.pap.xacml.rest;
24 import java.io.FileInputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.io.UnsupportedEncodingException;
29 import java.net.ConnectException;
30 import java.net.HttpURLConnection;
31 import java.net.InetAddress;
32 import java.net.MalformedURLException;
33 import java.net.SocketTimeoutException;
35 import java.net.URLDecoder;
36 import java.net.UnknownHostException;
37 import java.nio.file.Files;
38 import java.nio.file.Path;
39 import java.nio.file.Paths;
40 import java.util.ArrayList;
41 import java.util.HashMap;
42 import java.util.HashSet;
43 import java.util.Iterator;
44 import java.util.List;
45 import java.util.Properties;
47 import java.util.UUID;
48 import java.util.concurrent.CopyOnWriteArrayList;
50 import javax.persistence.EntityManagerFactory;
51 import javax.persistence.Persistence;
52 import javax.persistence.PersistenceException;
53 import javax.servlet.Servlet;
54 import javax.servlet.ServletConfig;
55 import javax.servlet.ServletException;
56 import javax.servlet.annotation.WebInitParam;
57 import javax.servlet.annotation.WebServlet;
58 import javax.servlet.http.HttpServlet;
59 import javax.servlet.http.HttpServletRequest;
60 import javax.servlet.http.HttpServletResponse;
62 import org.apache.commons.io.IOUtils;
63 import org.onap.policy.common.ia.IntegrityAudit;
64 import org.onap.policy.common.im.AdministrativeStateException;
65 import org.onap.policy.common.im.ForwardProgressException;
66 import org.onap.policy.common.im.IntegrityMonitor;
67 import org.onap.policy.common.im.IntegrityMonitorProperties;
68 import org.onap.policy.common.im.StandbyStatusException;
69 import org.onap.policy.common.logging.ONAPLoggingContext;
70 import org.onap.policy.common.logging.ONAPLoggingUtils;
71 import org.onap.policy.common.logging.eelf.MessageCodes;
72 import org.onap.policy.common.logging.eelf.PolicyLogger;
73 import org.onap.policy.common.logging.flexlogger.FlexLogger;
74 import org.onap.policy.common.logging.flexlogger.Logger;
75 import org.onap.policy.pap.xacml.rest.components.PolicyDBDao;
76 import org.onap.policy.pap.xacml.rest.components.PolicyDBDaoTransaction;
77 import org.onap.policy.pap.xacml.rest.handler.APIRequestHandler;
78 import org.onap.policy.pap.xacml.rest.handler.PushPolicyHandler;
79 import org.onap.policy.pap.xacml.rest.handler.SavePolicyHandler;
80 import org.onap.policy.pap.xacml.restAuth.CheckPDP;
81 import org.onap.policy.rest.XACMLRest;
82 import org.onap.policy.rest.XACMLRestProperties;
83 import org.onap.policy.utils.PolicyUtils;
84 import org.onap.policy.xacml.api.XACMLErrorConstants;
85 import org.onap.policy.xacml.api.pap.ONAPPapEngineFactory;
86 import org.onap.policy.xacml.api.pap.OnapPDP;
87 import org.onap.policy.xacml.api.pap.OnapPDPGroup;
88 import org.onap.policy.xacml.api.pap.PAPPolicyEngine;
89 import org.onap.policy.xacml.std.pap.StdPAPPolicy;
90 import org.onap.policy.xacml.std.pap.StdPDP;
91 import org.onap.policy.xacml.std.pap.StdPDPGroup;
92 import org.onap.policy.xacml.std.pap.StdPDPItemSetChangeNotifier.StdItemSetChangeListener;
93 import org.onap.policy.xacml.std.pap.StdPDPPolicy;
94 import org.onap.policy.xacml.std.pap.StdPDPStatus;
96 import com.att.research.xacml.api.pap.PAPException;
97 import com.att.research.xacml.api.pap.PDPPolicy;
98 import com.att.research.xacml.api.pap.PDPStatus;
99 import com.att.research.xacml.util.FactoryException;
100 import com.att.research.xacml.util.XACMLProperties;
101 import com.fasterxml.jackson.databind.ObjectMapper;
102 import com.google.common.base.Splitter;
105 * Servlet implementation class XacmlPapServlet
108 description = "Implements the XACML PAP RESTful API.",
109 urlPatterns = { "/" },
112 @WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pap.properties", description = "The location of the properties file holding configuration information.")
114 public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeListener, Runnable {
115 private static final long serialVersionUID = 1L;
116 private static final String localIp = "127.0.0.1";
117 private static final Logger LOGGER = FlexLogger.getLogger(XACMLPapServlet.class);
118 // audit (transaction) LOGGER
119 private static final Logger auditLogger = FlexLogger.getLogger("auditLogger");
120 //Persistence Unit for JPA
121 private static final String PERSISTENCE_UNIT = "XACML-PAP-REST";
122 private static final String AUDIT_PAP_PERSISTENCE_UNIT = "auditPapPU";
124 private static final String ENVIRONMENT_HEADER = "Environment";
126 * List of Admin Console URLs.
127 * Used to send notifications when configuration changes.
129 * The CopyOnWriteArrayList *should* protect from concurrency errors.
130 * This list is seldom changed but often read, so the costs of this approach make sense.
132 private static final CopyOnWriteArrayList<String> adminConsoleURLStringList = new CopyOnWriteArrayList<>();
134 private static String configHome;
135 private static String actionHome;
137 * This PAP instance's own URL.
138 * Need this when creating URLs to send to the PDPs so they can GET the Policy files from this process.
140 private static String papURL = null;
141 // The heartbeat thread.
142 private static Heartbeat heartbeat = null;
143 private static Thread heartbeatThread = null;
144 //The entity manager factory for JPA access
145 private static EntityManagerFactory emf;
146 private static PolicyDBDao policyDBDao;
148 * papEngine - This is our engine workhorse that manages the PDP Groups and Nodes.
150 private static PAPPolicyEngine papEngine = null;
152 * These are the parameters needed for DB access from the PAP
154 private static int papIntegrityAuditPeriodSeconds = -1;
155 private static String papDbDriver = null;
156 private static String papDbUrl = null;
157 private static String papDbUser = null;
158 private static String papDbPassword = null;
159 private static String papResourceName = null;
160 private static String[] papDependencyGroupsFlatArray = null;
161 private static String environment = null;
162 private static String pdpFile = null;
164 private transient IntegrityMonitor im;
165 private transient IntegrityAudit ia;
167 //MicroService Model Properties
168 private static String msOnapName;
169 private static String msPolicyName;
171 * This thread may be invoked upon startup to initiate sending PDP policy/pip configuration when
172 * this servlet starts. Its configurable by the admin.
174 private transient static Thread initiateThread = null;
175 private transient ONAPLoggingContext baseLoggingContext = null;
178 * @see HttpServlet#HttpServlet()
180 public XACMLPapServlet() {
185 * @see Servlet#init(ServletConfig)
187 public void init(ServletConfig config) throws ServletException {
190 baseLoggingContext = new ONAPLoggingContext();
191 // fixed data that will be the same in all logging output goes here
193 String hostname = InetAddress.getLocalHost().getCanonicalHostName();
194 baseLoggingContext.setServer(hostname);
195 } catch (UnknownHostException e) {
196 LOGGER.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get hostname for logging", e);
199 XACMLRest.xacmlInit(config);
200 // Load the properties
201 XACMLRest.loadXacmlProperties(null, null);
203 * Retrieve the property values
205 setCommonProperties();
206 String papSiteName = XACMLProperties.getProperty(XACMLRestProperties.PAP_SITE_NAME);
207 if(papSiteName == null){
208 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE,"XACMLPapServlet", " ERROR: Bad papSiteName property entry");
209 throw new PAPException("papSiteName is null");
211 String papNodeType = XACMLProperties.getProperty(XACMLRestProperties.PAP_NODE_TYPE);
212 if(papNodeType == null){
213 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE,"XACMLPapServlet", " ERROR: Bad papNodeType property entry");
214 throw new PAPException("papNodeType is null");
216 //Integer will throw an exception of anything is missing or unrecognized
217 int papTransWait = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT));
218 int papTransTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_TIMEOUT));
219 int papAuditTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_TIMEOUT));
220 //Boolean will default to false if anything is missing or unrecognized
221 boolean papAuditFlag = Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_RUN_AUDIT_FLAG));
222 boolean papFileSystemAudit = Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_FLAG));
223 String papDependencyGroups = XACMLProperties.getProperty(XACMLRestProperties.PAP_DEPENDENCY_GROUPS);
224 if(papDependencyGroups == null){
225 throw new PAPException("papDependencyGroups is null");
227 setPAPDependencyGroups(papDependencyGroups);
228 //Integer will throw an exception of anything is missing or unrecognized
229 int fpMonitorInterval = Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.FP_MONITOR_INTERVAL));
230 int failedCounterThreshold = Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.FAILED_COUNTER_THRESHOLD));
231 int testTransInterval = Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.TEST_TRANS_INTERVAL));
232 int writeFpcInterval = Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.WRITE_FPC_INTERVAL));
233 LOGGER.debug("\n\n\n**************************************"
234 + "\n*************************************"
236 + "\n papDbDriver = " + papDbDriver
237 + "\n papDbUrl = " + papDbUrl
238 + "\n papDbUser = " + papDbUser
239 + "\n papDbPassword = " + papDbPassword
240 + "\n papTransWait = " + papTransWait
241 + "\n papTransTimeout = " + papTransTimeout
242 + "\n papAuditTimeout = " + papAuditTimeout
243 + "\n papAuditFlag = " + papAuditFlag
244 + "\n papFileSystemAudit = " + papFileSystemAudit
245 + "\n papResourceName = " + papResourceName
246 + "\n fpMonitorInterval = " + fpMonitorInterval
247 + "\n failedCounterThreshold = " + failedCounterThreshold
248 + "\n testTransInterval = " + testTransInterval
249 + "\n writeFpcInterval = " + writeFpcInterval
250 + "\n papSiteName = " + papSiteName
251 + "\n papNodeType = " + papNodeType
252 + "\n papDependencyGroupsList = " + papDependencyGroups
253 + "\n papIntegrityAuditPeriodSeconds = " + papIntegrityAuditPeriodSeconds
254 + "\n\n*************************************"
255 + "\n**************************************");
256 // Pull custom persistence settings
257 Properties properties;
259 properties = XACMLProperties.getProperties();
260 LOGGER.debug("\n\n\n**************************************"
261 + "\n**************************************"
263 + "properties = " + properties
264 + "\n\n**************************************");
265 } catch (IOException e) {
266 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPapServlet", " Error loading properties with: "
267 + "XACMLProperties.getProperties()");
268 throw new ServletException(e.getMessage(), e.getCause());
270 // Create an IntegrityMonitor
271 im = IntegrityMonitor.getInstance(papResourceName,properties);
272 // Create an IntegrityAudit
273 ia = new IntegrityAudit(papResourceName, AUDIT_PAP_PERSISTENCE_UNIT, properties);
274 ia.startAuditThread();
275 // Create the entity manager factory
277 // we are about to call the PDPs and give them their configuration.
278 // To do that we need to have the URL of this PAP so we can construct the Policy file URLs
279 setPAPURL(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL));
280 //Create the policyDBDao
282 // Load our PAP engine, first create a factory
283 ONAPPapEngineFactory factory = ONAPPapEngineFactory.newInstance(XACMLProperties.getProperty(XACMLProperties.PROP_PAP_PAPENGINEFACTORY));
284 // The factory knows how to go about creating a PAP Engine
285 setPAPEngine((PAPPolicyEngine) factory.newEngine());
286 PolicyDBDaoTransaction addNewGroup = null;
288 if(((org.onap.policy.xacml.std.pap.StdEngine)papEngine).wasDefaultGroupJustAdded){
289 addNewGroup = policyDBDao.getNewTransaction();
290 OnapPDPGroup group = papEngine.getDefaultGroup();
291 addNewGroup.createGroup(group.getId(), group.getName(), group.getDescription(), "automaticallyAdded");
292 addNewGroup.commitTransaction();
293 addNewGroup = policyDBDao.getNewTransaction();
294 addNewGroup.changeDefaultGroup(group, "automaticallyAdded");
295 addNewGroup.commitTransaction();
297 } catch(Exception e){
298 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " Error creating new default group in the database");
299 if(addNewGroup != null){
300 addNewGroup.rollbackTransaction();
303 policyDBDao.setPapEngine((PAPPolicyEngine) XACMLPapServlet.papEngine);
304 if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_RUN_AUDIT_FLAG))){
305 //get an AuditTransaction to lock out all other transactions
306 PolicyDBDaoTransaction auditTrans = policyDBDao.getNewAuditTransaction();
307 policyDBDao.auditLocalDatabase(XACMLPapServlet.papEngine);
308 //release the transaction lock
312 // Sanity check for URL.
313 if (XACMLPapServlet.papURL == null) {
314 throw new PAPException("The property " + XACMLRestProperties.PROP_PAP_URL + " is not valid: " + XACMLPapServlet.papURL);
316 // Configurable - have the PAP servlet initiate sending the latest PDP policy/pip configuration
317 // to all its known PDP nodes.
318 if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_INITIATE_PDP_CONFIG))) {
319 startInitiateThreadService(new Thread(this));
321 // After startup, the PAP does Heartbeat's to each of the PDPs periodically
322 startHeartBeatService(new Heartbeat((PAPPolicyEngine) XACMLPapServlet.papEngine));
324 } catch (FactoryException | PAPException e) {
325 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Failed to create engine");
326 throw new ServletException (XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP not initialized; error: "+e);
327 } catch (Exception e) {
328 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Failed to create engine - unexpected error");
329 throw new ServletException (XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP not initialized; unexpected error: "+e);
333 private static void startInitiateThreadService(Thread thread) {
334 initiateThread = thread;
335 initiateThread.start();
338 private static void startHeartBeatService(Heartbeat heartbeat) {
339 XACMLPapServlet.heartbeat = heartbeat;
340 XACMLPapServlet.heartbeatThread = new Thread(XACMLPapServlet.heartbeat);
341 XACMLPapServlet.heartbeatThread.start();
344 private static void setPolicyDBDao() throws ServletException {
346 policyDBDao = PolicyDBDao.getPolicyDBDaoInstance(getEmf());
347 } catch (Exception e) {
348 throw new ServletException("Unable to Create Policy DBDao Instance",e);
352 private static void setEMF(Properties properties) throws ServletException {
353 emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT, properties);
355 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Error creating entity manager factory with persistence unit: "
357 throw new ServletException("Unable to create Entity Manager Factory");
361 private static void setPAPURL(String papURL) {
362 XACMLPapServlet.papURL = papURL;
365 private static void setPAPEngine(PAPPolicyEngine newEngine) {
366 XACMLPapServlet.papEngine = newEngine;
369 private static void setPAPDependencyGroups(String papDependencyGroups) throws PAPException {
371 //Now we have flattened the array into a simple comma-separated list
372 papDependencyGroupsFlatArray = papDependencyGroups.split("[;,]");
373 //clean up the entries
374 for (int i = 0 ; i < papDependencyGroupsFlatArray.length ; i ++){
375 papDependencyGroupsFlatArray[i] = papDependencyGroupsFlatArray[i].trim();
378 if(XACMLProperties.getProperty(XACMLRestProperties.PAP_INTEGRITY_AUDIT_PERIOD_SECONDS) != null){
379 papIntegrityAuditPeriodSeconds = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PAP_INTEGRITY_AUDIT_PERIOD_SECONDS).trim());
382 String msg = "integrity_audit_period_seconds ";
383 LOGGER.error("\n\nERROR: " + msg + "Bad property entry: " + e.getMessage() + "\n");
384 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR: " + msg +"Bad property entry");
388 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR: Bad property entry");
389 throw new PAPException(e);
393 private static void setCommonProperties() throws PAPException {
396 papDbDriver = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_DRIVER);
397 if(papDbDriver == null){
398 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE,"XACMLPapServlet", " ERROR: Bad papDbDriver property entry");
399 throw new PAPException("papDbDriver is null");
401 setPapDbDriver(papDbDriver);
402 papDbUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_URL);
403 if(papDbUrl == null){
404 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE,"XACMLPapServlet", " ERROR: Bad papDbUrl property entry");
405 throw new PAPException("papDbUrl is null");
407 setPapDbUrl(papDbUrl);
408 papDbUser = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_USER);
409 if(papDbUser == null){
410 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE,"XACMLPapServlet", " ERROR: Bad papDbUser property entry");
411 throw new PAPException("papDbUser is null");
413 setPapDbUser(papDbUser);
414 papDbPassword = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_PASSWORD);
415 if(papDbPassword == null){
416 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE,"XACMLPapServlet", " ERROR: Bad papDbPassword property entry");
417 throw new PAPException("papDbPassword is null");
419 setPapDbPassword(papDbPassword);
420 papResourceName = XACMLProperties.getProperty(XACMLRestProperties.PAP_RESOURCE_NAME);
421 if(papResourceName == null){
422 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE,"XACMLPapServlet", " ERROR: Bad papResourceName property entry");
423 throw new PAPException("papResourceName is null");
425 environment = XACMLProperties.getProperty("ENVIRONMENT", "DEVL");
426 //Micro Service Properties
427 msOnapName=XACMLProperties.getProperty("xacml.policy.msOnapName");
428 setMsOnapName(msOnapName);
429 msPolicyName=XACMLProperties.getProperty("xacml.policy.msPolicyName");
430 setMsPolicyName(msPolicyName);
431 // PDPId File location
432 XACMLPapServlet.pdpFile = XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_IDFILE);
433 if (XACMLPapServlet.pdpFile == null) {
434 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " The PDP Id Authentication File Property is not valid: "
435 + XACMLRestProperties.PROP_PDP_IDFILE);
436 throw new PAPException("The PDP Id Authentication File Property :"+ XACMLRestProperties.PROP_PDP_IDFILE+ " is not Valid. ");
441 * Thread used only during PAP startup to initiate change messages to all known PDPs.
442 * This must be on a separate thread so that any GET requests from the PDPs during this update can be serviced.
446 // send the current configuration to all the PDPs that we know about
451 * @see Servlet#destroy()
453 * Depending on how this servlet is run, we may or may not care about cleaning up the resources.
454 * For now we assume that we do care.
457 public void destroy() {
458 // Make sure our threads are destroyed
459 if (XACMLPapServlet.heartbeatThread != null) {
460 // stop the heartbeat
462 if (XACMLPapServlet.heartbeat != null) {
463 XACMLPapServlet.heartbeat.terminate();
465 XACMLPapServlet.heartbeatThread.interrupt();
466 XACMLPapServlet.heartbeatThread.join();
467 } catch (InterruptedException e) {
468 XACMLPapServlet.heartbeatThread.interrupt();
469 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Error stopping heartbeat");
472 if (initiateThread != null) {
474 initiateThread.interrupt();
475 initiateThread.join();
476 } catch (InterruptedException e) {
477 initiateThread.interrupt();
478 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Error stopping thread");
485 * - PDP nodes to register themselves with the PAP, and
486 * - Admin Console to make changes in the PDP Groups.
488 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
490 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
491 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
492 loggingContext.transactionStarted();
493 loggingContext.setServiceName("PAP.post");
494 if ((loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")){
495 UUID requestID = UUID.randomUUID();
496 loggingContext.setRequestID(requestID.toString());
497 PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doPost) so we generated one");
499 PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doPost)");
501 PolicyDBDaoTransaction pdpTransaction = null;
503 im.startTransaction();
504 } catch (AdministrativeStateException ae){
505 String message = "POST interface called for PAP " + papResourceName + " but it has an Administrative"
506 + " state of " + im.getStateManager().getAdminState()
507 + "\n Exception Message: " + ae.getMessage();
508 LOGGER.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message, ae);
509 loggingContext.transactionEnded();
510 PolicyLogger.audit("Transaction Failed - See Error.log");
511 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
513 }catch (StandbyStatusException se) {
514 String message = "POST interface called for PAP " + papResourceName + " but it has a Standby Status"
515 + " of " + im.getStateManager().getStandbyStatus()
516 + "\n Exception Message: " + se.getMessage();
517 LOGGER.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message, se);
518 loggingContext.transactionEnded();
519 PolicyLogger.audit("Transaction Failed - See Error.log");
520 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
524 XACMLRest.dumpRequest(request);
525 // since getParameter reads the content string, explicitly get the content before doing that.
526 // Simply getting the inputStream seems to protect it against being consumed by getParameter.
527 request.getInputStream();
528 String groupId = request.getParameter("groupId");
529 String apiflag = request.getParameter("apiflag");
530 if(groupId != null) {
531 // Is this from the Admin Console or API?
532 if(apiflag!=null && apiflag.equalsIgnoreCase("api")) {
533 // this is from the API so we need to check the client credentials before processing the request
534 if(!authorizeRequest(request)){
535 String message = "PEP not Authorized for making this Request!!";
536 PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
537 loggingContext.transactionEnded();
538 PolicyLogger.audit("Transaction Failed - See Error.log");
539 setResponseError(response,HttpServletResponse.SC_FORBIDDEN, message);
544 doACPost(request, response, groupId, loggingContext);
545 loggingContext.transactionEnded();
546 PolicyLogger.audit("Transaction Ended Successfully");
550 // Request is from a PDP asking for its config.
551 loggingContext.setServiceName("PDP:PAP.register");
553 String id = this.getPDPID(request);
554 String jmxport = this.getPDPJMX(request);
555 LOGGER.info("Request(doPost) from PDP coming up: " + id);
556 // Get the PDP Object
557 OnapPDP pdp = XACMLPapServlet.papEngine.getPDP(id);
560 LOGGER.info("Unknown PDP: " + id);
562 if(CheckPDP.validateID(id)){
563 pdpTransaction = policyDBDao.getNewTransaction();
565 pdpTransaction.addPdpToGroup(id, XACMLPapServlet.papEngine.getDefaultGroup().getId(), id, "Registered on first startup", Integer.parseInt(jmxport), "PDP autoregister");
566 XACMLPapServlet.papEngine.newPDP(id, XACMLPapServlet.papEngine.getDefaultGroup(), id, "Registered on first startup", Integer.parseInt(jmxport));
567 } catch (NullPointerException | PAPException | IllegalArgumentException | IllegalStateException | PersistenceException e) {
568 pdpTransaction.rollbackTransaction();
569 String message = "Failed to create new PDP for id: " + id;
570 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " " + message);
571 loggingContext.transactionEnded();
572 PolicyLogger.audit("Transaction Failed - See Error.log");
573 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
577 // get the PDP we just created
578 pdp = XACMLPapServlet.papEngine.getPDP(id);
580 if(pdpTransaction != null){
581 pdpTransaction.rollbackTransaction();
583 String message = "Failed to create new PDP for id: " + id;
584 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " " + message);
585 loggingContext.transactionEnded();
586 PolicyLogger.audit("Transaction Failed - See Error.log");
587 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
592 String message = "PDP is Unauthorized to Connect to PAP: "+ id;
593 PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
594 loggingContext.transactionEnded();
595 setResponseError(response, HttpServletResponse.SC_UNAUTHORIZED, "PDP not Authorized to connect to this PAP. Please contact the PAP Admin for registration.");
596 PolicyLogger.audit("Transaction Failed - See Error.log");
601 pdpTransaction.commitTransaction();
602 } catch(Exception e){
603 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", "Could not commit transaction to put pdp in the database");
606 if (jmxport != null && jmxport != ""){
607 ((StdPDP) pdp).setJmxPort(Integer.valueOf(jmxport));
609 // Get the PDP's Group
610 OnapPDPGroup group = XACMLPapServlet.papEngine.getPDPGroup((OnapPDP) pdp);
612 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " PDP not associated with any group, even the default");
613 loggingContext.transactionEnded();
614 PolicyLogger.audit("Transaction Failed - See Error.log");
615 setResponseError(response, HttpServletResponse.SC_UNAUTHORIZED, "PDP not associated with any group, even the default");
619 // Determine what group the PDP node is in and get
620 // its policy/pip properties.
621 Properties policies = group.getPolicyProperties();
622 Properties pipconfig = group.getPipConfigProperties();
623 // Get the current policy/pip configuration that the PDP has
624 Properties pdpProperties = new Properties();
625 pdpProperties.load(request.getInputStream());
626 LOGGER.info("PDP Current Properties: " + pdpProperties.toString());
627 LOGGER.info("Policies: " + (policies != null ? policies.toString() : "null"));
628 LOGGER.info("Pip config: " + (pipconfig != null ? pipconfig.toString() : "null"));
629 // Validate the node's properties
630 boolean isCurrent = this.isPDPCurrent(policies, pipconfig, pdpProperties);
631 // Send back current configuration
632 if (isCurrent == false) {
633 // Tell the PDP we are sending back the current policies/pip config
634 LOGGER.info("PDP configuration NOT current.");
635 if (policies != null) {
636 // Put URL's into the properties in case the PDP needs to
638 this.populatePolicyURL(request.getRequestURL(), policies);
639 // Copy the properties to the output stream
640 policies.store(response.getOutputStream(), "");
642 if (pipconfig != null) {
643 // Copy the properties to the output stream
644 pipconfig.store(response.getOutputStream(), "");
646 // We are good - and we are sending them information
647 response.setStatus(HttpServletResponse.SC_OK);
648 setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH);
650 // Tell them they are good
651 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
652 setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE);
654 // tell the AC that something changed
656 loggingContext.transactionEnded();
657 auditLogger.info("Success");
658 PolicyLogger.audit("Transaction Ended Successfully");
659 } catch (PAPException | IOException | NumberFormatException e) {
660 if(pdpTransaction != null){
661 pdpTransaction.rollbackTransaction();
663 LOGGER.debug(XACMLErrorConstants.ERROR_PROCESS_FLOW + "POST exception: " + e, e);
664 loggingContext.transactionEnded();
665 PolicyLogger.audit("Transaction Failed - See Error.log");
666 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
670 //Catch anything that fell through
671 loggingContext.transactionEnded();
672 PolicyLogger.audit("Transaction Ended");
676 private void setResponseError(HttpServletResponse response,int responseCode, String message) {
678 response.sendError(responseCode, message);
679 } catch (IOException e) {
680 LOGGER.error("Error setting Error response Header ", e);
686 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
688 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
689 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
690 loggingContext.transactionStarted();
691 loggingContext.setServiceName("PAP.get");
692 if ((loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")){
693 UUID requestID = UUID.randomUUID();
694 loggingContext.setRequestID(requestID.toString());
695 PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doGet) so we generated one");
697 PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doGet)");
700 XACMLRest.dumpRequest(request);
701 String pathInfo = request.getRequestURI();
702 LOGGER.info("path info: " + pathInfo);
703 if (pathInfo != null){
704 //DO NOT do a im.startTransaction for the test request
705 if (pathInfo.equals("/pap/test")) {
707 testService(loggingContext, response);
708 } catch (IOException e) {
714 //This im.startTransaction() covers all other Get transactions
716 im.startTransaction();
717 } catch (AdministrativeStateException ae){
718 String message = "GET interface called for PAP " + papResourceName + " but it has an Administrative"
719 + " state of " + im.getStateManager().getAdminState()
720 + "\n Exception Message: " + ae.getMessage();
721 LOGGER.info(message, ae);
722 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
723 loggingContext.transactionEnded();
724 PolicyLogger.audit("Transaction Failed - See Error.log");
725 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
727 }catch (StandbyStatusException se) {
728 String message = "GET interface called for PAP " + papResourceName + " but it has a Standby Status"
729 + " of " + im.getStateManager().getStandbyStatus()
730 + "\n Exception Message: " + se.getMessage();
731 LOGGER.info(message, se);
732 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
733 loggingContext.transactionEnded();
734 PolicyLogger.audit("Transaction Failed - See Error.log");
735 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
738 // Request from the API to get the gitPath
739 String apiflag = request.getParameter("apiflag");
741 if(authorizeRequest(request)){
742 APIRequestHandler apiRequestHandler = new APIRequestHandler();
743 apiRequestHandler.doGet(request,response, apiflag);
744 loggingContext.transactionEnded();
745 PolicyLogger.audit("Transaction Ended Successfully");
749 String message = "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
750 PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
751 loggingContext.transactionEnded();
752 PolicyLogger.audit("Transaction Failed - See Error.log");
753 setResponseError(response, HttpServletResponse.SC_FORBIDDEN, message);
758 // Is this from the Admin Console?
759 String groupId = request.getParameter("groupId");
760 if (groupId != null) {
761 // this is from the Admin Console, so handle separately
762 doACGet(request, response, groupId, loggingContext);
763 loggingContext.transactionEnded();
764 PolicyLogger.audit("Transaction Ended Successfully");
769 String id = this.getPDPID(request);
770 LOGGER.info("doGet from: " + id);
771 // Get the PDP Object
772 OnapPDP pdp = XACMLPapServlet.papEngine.getPDP(id);
775 // Check if request came from localhost
776 if (request.getRemoteHost().equals("localhost") ||
777 request.getRemoteHost().equals(localIp) ||
778 request.getRemoteHost().equals(request.getLocalAddr())) {
779 // Return status information - basically all the groups
780 loggingContext.setServiceName("PAP.getGroups");
781 Set<OnapPDPGroup> groups = papEngine.getOnapPDPGroups();
782 // convert response object to JSON and include in the response
783 ObjectMapper mapper = new ObjectMapper();
784 mapper.writeValue(response.getOutputStream(), groups);
785 response.setHeader("content-type", "application/json");
786 response.setStatus(HttpServletResponse.SC_OK);
787 loggingContext.transactionEnded();
788 PolicyLogger.audit("Transaction Ended Successfully");
792 String message = "Unknown PDP: " + id + " from " + request.getRemoteHost() + " us: " + request.getLocalAddr();
793 PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
794 loggingContext.transactionEnded();
795 PolicyLogger.audit("Transaction Failed - See Error.log");
796 setResponseError(response, HttpServletResponse.SC_UNAUTHORIZED, message);
800 loggingContext.setServiceName("PAP.getPolicy");
801 // Get the PDP's Group
802 OnapPDPGroup group = XACMLPapServlet.papEngine.getPDPGroup((OnapPDP) pdp);
804 String message = "No group associated with pdp " + pdp.getId();
805 LOGGER.warn(XACMLErrorConstants.ERROR_PERMISSIONS + message);
806 loggingContext.transactionEnded();
807 PolicyLogger.audit("Transaction Failed - See Error.log");
808 setResponseError(response, HttpServletResponse.SC_UNAUTHORIZED, message);
812 // Which policy do they want?
813 String policyId = request.getParameter("id");
814 if (policyId == null) {
815 String message = "Did not specify an id for the policy";
816 LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
817 loggingContext.transactionEnded();
818 PolicyLogger.audit("Transaction Failed - See Error.log");
819 setResponseError(response,HttpServletResponse.SC_NOT_FOUND, message);
823 PDPPolicy policy = group.getPolicy(policyId);
824 if (policy == null) {
825 String message = "Unknown policy: " + policyId;
826 LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
827 loggingContext.transactionEnded();
828 PolicyLogger.audit("Transaction Failed - See Error.log");
829 setResponseError(response,HttpServletResponse.SC_NOT_FOUND, message);
833 LOGGER.warn("PolicyDebugging: Policy Validity: " + policy.isValid() + "\n "
834 + "Policy Name : " + policy.getName() + "\n Policy URI: " + policy.getLocation().toString());
835 try (InputStream is = new FileInputStream(((StdPDPGroup)group).getDirectory().toString()+File.separator+policyId); OutputStream os = response.getOutputStream()) {
836 // Send the policy back
837 IOUtils.copy(is, os);
838 response.setStatus(HttpServletResponse.SC_OK);
839 loggingContext.transactionEnded();
840 auditLogger.info("Success");
841 PolicyLogger.audit("Transaction Ended Successfully");
842 } catch (IOException e) {
843 String message = "Failed to open policy id " + policyId;
845 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
846 loggingContext.transactionEnded();
847 PolicyLogger.audit("Transaction Failed - See Error.log");
848 setResponseError(response,HttpServletResponse.SC_NOT_FOUND, message);
850 } catch (PAPException | IOException e) {
852 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN, e, "XACMLPapServlet", " GET exception");
853 loggingContext.transactionEnded();
854 PolicyLogger.audit("Transaction Failed - See Error.log");
855 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
859 loggingContext.transactionEnded();
860 PolicyLogger.audit("Transaction Ended");
865 * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response)
867 protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
868 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
869 loggingContext.transactionStarted();
870 loggingContext.setServiceName("PAP.put");
871 if ((loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")){
872 UUID requestID = UUID.randomUUID();
873 loggingContext.setRequestID(requestID.toString());
874 PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doPut) so we generated one");
876 PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doPut)");
879 im.startTransaction();
880 } catch (AdministrativeStateException | StandbyStatusException e) {
881 String message = "PUT interface called for PAP " + papResourceName;
882 if (e instanceof AdministrativeStateException) {
883 message += " but it has an Administrative state of "
884 + im.getStateManager().getAdminState();
885 } else if (e instanceof StandbyStatusException) {
886 message += " but it has a Standby Status of "
887 + im.getStateManager().getStandbyStatus();
890 message += "\n Exception Message: " + e.getMessage();
892 LOGGER.info(message, e);
893 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
894 loggingContext.transactionEnded();
895 PolicyLogger.audit("Transaction Failed - See Error.log");
896 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
900 XACMLRest.dumpRequest(request);
901 //need to check if request is from the API or Admin console
902 String apiflag = request.getParameter("apiflag");
903 //This would occur if a PolicyDBDao notification was received
904 String policyDBDaoRequestUrl = request.getParameter("policydbdaourl");
905 if(policyDBDaoRequestUrl != null){
906 String policyDBDaoRequestEntityId = request.getParameter("entityid");
907 //String policyDBDaoRequestEntityType = request.getParameter("entitytype");
908 String policyDBDaoRequestEntityType = request.getParameter("entitytype");
909 String policyDBDaoRequestExtraData = request.getParameter("extradata");
910 if(policyDBDaoRequestEntityId == null || policyDBDaoRequestEntityType == null){
911 setResponseError(response,400, "entityid or entitytype not supplied");
912 loggingContext.transactionEnded();
913 PolicyLogger.audit("Transaction Ended Successfully");
917 policyDBDao.handleIncomingHttpNotification(policyDBDaoRequestUrl,policyDBDaoRequestEntityId,policyDBDaoRequestEntityType,policyDBDaoRequestExtraData,this);
918 response.setStatus(200);
919 loggingContext.transactionEnded();
920 PolicyLogger.audit("Transaction Ended Successfully");
925 * Request for ImportService
927 String importService = request.getParameter("importService");
928 if (importService != null) {
929 if(authorizeRequest(request)){
930 APIRequestHandler apiRequestHandler = new APIRequestHandler();
931 apiRequestHandler.doPut(request, response, importService);
935 String message = "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
936 LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS + message );
937 loggingContext.transactionEnded();
938 PolicyLogger.audit("Transaction Failed - See Error.log");
939 setResponseError(response,HttpServletResponse.SC_FORBIDDEN, message);
943 //This would occur if we received a notification of a policy rename from AC
944 String oldPolicyName = request.getParameter("oldPolicyName");
945 String newPolicyName = request.getParameter("newPolicyName");
946 if(oldPolicyName != null && newPolicyName != null){
947 if(LOGGER.isDebugEnabled()){
948 LOGGER.debug("\nXACMLPapServlet.doPut() - before decoding"
949 + "\npolicyToCreateUpdate = " + " ");
953 oldPolicyName = URLDecoder.decode(oldPolicyName, "UTF-8");
954 newPolicyName = URLDecoder.decode(newPolicyName, "UTF-8");
955 if(LOGGER.isDebugEnabled()){
956 LOGGER.debug("\nXACMLPapServlet.doPut() - after decoding"
957 + "\npolicyToCreateUpdate = " + " ");
959 } catch(UnsupportedEncodingException e){
960 PolicyLogger.error("\nXACMLPapServlet.doPut() - Unsupported URL encoding of policyToCreateUpdate (UTF-8)"
961 + "\npolicyToCreateUpdate = " + " ");
962 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR,"policyToCreateUpdate encoding not supported"
963 + "\nfailure with the following exception: " + e);
964 loggingContext.transactionEnded();
965 PolicyLogger.audit("Transaction Failed - See error.log");
969 //send it to PolicyDBDao
970 PolicyDBDaoTransaction renameTransaction = policyDBDao.getNewTransaction();
972 renameTransaction.renamePolicy(oldPolicyName,newPolicyName, "XACMLPapServlet.doPut");
974 renameTransaction.rollbackTransaction();
975 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR,"createUpdateTransaction.createPolicy(policyToCreateUpdate, XACMLPapServlet.doPut) "
976 + "\nfailure with the following exception: " + e);
977 loggingContext.transactionEnded();
978 PolicyLogger.audit("Transaction Failed - See error.log");
982 renameTransaction.commitTransaction();
983 response.setStatus(HttpServletResponse.SC_OK);
984 loggingContext.transactionEnded();
985 PolicyLogger.audit("Transaction Ended Successfully");
990 // See if this is Admin Console registering itself with us
992 String acURLString = request.getParameter("adminConsoleURL");
993 if (acURLString != null) {
994 loggingContext.setServiceName("AC:PAP.register");
995 // remember this Admin Console for future updates
996 if ( ! adminConsoleURLStringList.contains(acURLString)) {
997 adminConsoleURLStringList.add(acURLString);
999 if (LOGGER.isDebugEnabled()) {
1000 LOGGER.debug("Admin Console registering with URL: " + acURLString);
1002 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1003 loggingContext.transactionEnded();
1004 auditLogger.info("Success");
1005 PolicyLogger.audit("Transaction Ended Successfully");
1006 im.endTransaction();
1010 * This is to update the PDP Group with the policy/policies being pushed
1011 * Part of a 2 step process to push policies to the PDP that can now be done
1012 * From both the Admin Console and the PolicyEngine API
1014 String groupId = request.getParameter("groupId");
1015 if (groupId != null) {
1017 if(!authorizeRequest(request)){
1018 String message = "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
1019 PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
1020 loggingContext.transactionEnded();
1021 PolicyLogger.audit("Transaction Failed - See Error.log");
1022 setResponseError(response,HttpServletResponse.SC_FORBIDDEN, message);
1025 if(apiflag.equalsIgnoreCase("addPolicyToGroup")){
1026 updateGroupsFromAPI(request, response, groupId, loggingContext);
1027 loggingContext.transactionEnded();
1028 PolicyLogger.audit("Transaction Ended Successfully");
1029 im.endTransaction();
1033 // this is from the Admin Console, so handle separately
1034 doACPut(request, response, groupId, loggingContext);
1035 loggingContext.transactionEnded();
1036 PolicyLogger.audit("Transaction Ended Successfully");
1037 im.endTransaction();
1041 // Request is for policy validation and creation
1043 if (apiflag != null && apiflag.equalsIgnoreCase("admin")){
1044 // this request is from the Admin Console
1045 SavePolicyHandler savePolicyHandler = SavePolicyHandler.getInstance();
1046 savePolicyHandler.doPolicyAPIPut(request, response);
1047 loggingContext.transactionEnded();
1048 PolicyLogger.audit("Transaction Ended Successfully");
1049 im.endTransaction();
1051 } else if (apiflag != null && apiflag.equalsIgnoreCase("api")) {
1052 // this request is from the Policy Creation API
1053 if(authorizeRequest(request)){
1054 APIRequestHandler apiRequestHandler = new APIRequestHandler();
1055 apiRequestHandler.doPut(request, response, request.getHeader("ClientScope"));
1056 loggingContext.transactionEnded();
1057 PolicyLogger.audit("Transaction Ended Successfully");
1058 im.endTransaction();
1061 String message = "PEP not Authorized for making this Request!!";
1062 PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
1063 loggingContext.transactionEnded();
1064 PolicyLogger.audit("Transaction Failed - See Error.log");
1065 setResponseError(response,HttpServletResponse.SC_FORBIDDEN, message);
1066 im.endTransaction();
1070 // We do not expect anything from anywhere else.
1071 // This method is here in case we ever need to support other operations.
1072 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Request does not have groupId or apiflag");
1073 loggingContext.transactionEnded();
1074 PolicyLogger.audit("Transaction Failed - See Error.log");
1075 setResponseError(response,HttpServletResponse.SC_BAD_REQUEST, "Request does not have groupId or apiflag");
1076 loggingContext.transactionEnded();
1077 PolicyLogger.audit("Transaction Failed - See error.log");
1078 im.endTransaction();
1082 * @see HttpServlet#doDelete(HttpServletRequest request, HttpServletResponse response)
1084 protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
1085 ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
1086 loggingContext.transactionStarted();
1087 loggingContext.setServiceName("PAP.delete");
1088 if ((loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")){
1089 UUID requestID = UUID.randomUUID();
1090 loggingContext.setRequestID(requestID.toString());
1091 PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doDelete) so we generated one");
1093 PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doDelete)");
1096 im.startTransaction();
1097 } catch (AdministrativeStateException ae){
1098 String message = "DELETE interface called for PAP " + papResourceName + " but it has an Administrative"
1099 + " state of " + im.getStateManager().getAdminState()
1100 + "\n Exception Message: " + ae.getMessage();
1101 LOGGER.info(message, ae);
1102 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
1103 loggingContext.transactionEnded();
1104 PolicyLogger.audit("Transaction Failed - See Error.log");
1105 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1107 }catch (StandbyStatusException se) {
1108 String message = "PUT interface called for PAP " + papResourceName + " but it has a Standby Status"
1109 + " of " + im.getStateManager().getStandbyStatus()
1110 + "\n Exception Message: " + se.getMessage();
1111 LOGGER.info(message, se);
1112 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
1113 loggingContext.transactionEnded();
1114 PolicyLogger.audit("Transaction Failed - See Error.log");
1115 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1118 XACMLRest.dumpRequest(request);
1119 String groupId = request.getParameter("groupId");
1120 String apiflag = request.getParameter("apiflag");
1121 if (groupId != null) {
1122 // Is this from the Admin Console or API?
1124 if(!authorizeRequest(request)){
1125 String message = "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
1126 PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
1127 loggingContext.transactionEnded();
1128 PolicyLogger.audit("Transaction Failed - See Error.log");
1129 setResponseError(response,HttpServletResponse.SC_FORBIDDEN, message);
1132 APIRequestHandler apiRequestHandler = new APIRequestHandler();
1134 apiRequestHandler.doDelete(request, response, loggingContext, apiflag);
1135 } catch (Exception e) {
1136 LOGGER.error("Exception Occured"+e);
1138 if(apiRequestHandler.getNewGroup()!=null){
1139 groupChanged(apiRequestHandler.getNewGroup());
1143 // this is from the Admin Console, so handle separately
1144 doACDelete(request, response, groupId, loggingContext);
1145 loggingContext.transactionEnded();
1146 PolicyLogger.audit("Transaction Ended Successfully");
1147 im.endTransaction();
1150 //Catch anything that fell through
1151 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Request does not have groupId");
1152 loggingContext.transactionEnded();
1153 PolicyLogger.audit("Transaction Failed - See Error.log");
1154 setResponseError(response,HttpServletResponse.SC_BAD_REQUEST, "Request does not have groupId");
1155 im.endTransaction();
1158 private boolean isPDPCurrent(Properties policies, Properties pipconfig, Properties pdpProperties) {
1159 String localRootPolicies = policies.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
1160 String localReferencedPolicies = policies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
1161 if (localRootPolicies == null || localReferencedPolicies == null) {
1162 LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing property on PAP server: RootPolicies="+localRootPolicies+" ReferencedPolicies="+localReferencedPolicies);
1165 // Compare the policies and pipconfig properties to the pdpProperties
1167 // the policy properties includes only xacml.rootPolicies and
1168 // xacml.referencedPolicies without any .url entries
1169 Properties pdpPolicies = XACMLProperties.getPolicyProperties(pdpProperties, false);
1170 Properties pdpPipConfig = XACMLProperties.getPipProperties(pdpProperties);
1171 if (localRootPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_ROOTPOLICIES)) &&
1172 localReferencedPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES)) &&
1173 pdpPipConfig.equals(pipconfig)) {
1174 // The PDP is current
1177 } catch (Exception e) {
1178 // we get here if the PDP did not include either xacml.rootPolicies or xacml.pip.engines,
1179 // or if there are policies that do not have a corresponding ".url" property.
1180 // Either of these cases means that the PDP is not up-to-date, so just drop-through to return false.
1181 PolicyLogger.error(MessageCodes.ERROR_SCHEMA_INVALID, e, "XACMLPapServlet", " PDP Error");
1186 private void populatePolicyURL(StringBuffer urlPath, Properties policies) {
1187 String lists[] = new String[2];
1188 lists[0] = policies.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
1189 lists[1] = policies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
1190 for (String list : lists) {
1191 if (list != null && list.isEmpty() == false) {
1192 for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(list)) {
1193 String url = urlPath + "?id=" + id;
1194 LOGGER.info("Policy URL for " + id + ": " + url);
1195 policies.setProperty(id + ".url", url);
1201 protected String getPDPID(HttpServletRequest request) {
1202 String pdpURL = request.getHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID);
1203 if (pdpURL == null || pdpURL.isEmpty()) {
1204 // Should send back its port for identification
1205 LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + "PDP did not send custom header");
1211 protected String getPDPJMX(HttpServletRequest request) {
1212 String pdpJMMX = request.getHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_JMX_PORT);
1213 if (pdpJMMX == null || pdpJMMX.isEmpty()) {
1214 // Should send back its port for identification
1215 LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + "PDP did not send custom header for JMX Port so the value of 0 is assigned");
1222 * Requests from the PolicyEngine API to update the PDP Group with pushed policy
1227 * @param loggingContext
1228 * @throws ServletException
1229 * @throws IOException
1231 public void updateGroupsFromAPI(HttpServletRequest request, HttpServletResponse response, String groupId, ONAPLoggingContext loggingContext) throws IOException {
1232 PolicyDBDaoTransaction acPutTransaction = policyDBDao.getNewTransaction();
1234 // for PUT operations the group may or may not need to exist before the operation can be done
1235 StdPDPGroup group = (StdPDPGroup) papEngine.getGroup(groupId);
1236 // get the request input stream content into a String
1238 java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
1239 scanner.useDelimiter("\\A");
1240 json = scanner.hasNext() ? scanner.next() : "";
1242 PolicyLogger.info("JSON request from PolicyEngine API: " + json);
1243 // convert Object sent as JSON into local object
1244 StdPDPPolicy policy = PolicyUtils.jsonStringToObject(json, StdPDPPolicy.class);
1245 Set<PDPPolicy> policies = new HashSet<>();
1247 policies.add(policy);
1249 //Get the current policies from the Group and Add the new one
1250 Set<PDPPolicy> currentPoliciesInGroup = new HashSet<>();
1251 currentPoliciesInGroup = group.getPolicies();
1252 //If the selected policy is in the group we must remove it because the name is default
1253 Iterator<PDPPolicy> policyIterator = policies.iterator();
1254 LOGGER.debug("policyIterator....." + policies);
1255 while (policyIterator.hasNext()) {
1256 PDPPolicy selPolicy = policyIterator.next();
1257 for (PDPPolicy existingPolicy : currentPoliciesInGroup) {
1258 if (existingPolicy.getId().equals(selPolicy.getId())) {
1259 group.removePolicyFromGroup(existingPolicy);
1260 LOGGER.debug("Removing policy: " + existingPolicy);
1265 //Update the PDP Group after removing old version of policy
1266 Set<PDPPolicy> updatedPoliciesInGroup = new HashSet<>();
1267 updatedPoliciesInGroup = group.getPolicies();
1268 //need to remove the policy with default name from group
1269 for (PDPPolicy updatedPolicy : currentPoliciesInGroup) {
1270 if (updatedPolicy.getName().equalsIgnoreCase("default")) {
1271 group.removePolicyFromGroup(updatedPolicy);
1275 if(updatedPoliciesInGroup!=null){
1276 policies.addAll(updatedPoliciesInGroup);
1278 group.setPolicies(policies);
1279 // Assume that this is an update of an existing PDP Group
1280 loggingContext.setServiceName("PolicyEngineAPI:PAP.updateGroup");
1282 acPutTransaction.updateGroup(group, "XACMLPapServlet.doACPut");
1283 } catch(Exception e){
1284 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Error while updating group in the database: "
1285 +"group="+group.getId());
1286 throw new PAPException(e.getMessage());
1288 papEngine.updateGroup(group);
1289 String policyId = "empty";
1291 policyId = policy.getId();
1293 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1294 response.addHeader("operation", "push");
1295 response.addHeader("policyId", policyId);
1296 response.addHeader("groupId", groupId);
1297 if (LOGGER.isDebugEnabled()) {
1298 LOGGER.debug("Group '" + group.getId() + "' updated");
1300 acPutTransaction.commitTransaction();
1302 // Group changed, which might include changing the policies
1303 groupChanged(group);
1304 loggingContext.transactionEnded();
1305 auditLogger.info("Success");
1307 if (policy != null && ((policy.getId().contains("Config_MS_")) || (policy.getId().contains("BRMS_Param")))) {
1308 PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance();
1309 if (pushPolicyHandler.preSafetyCheck(policy, configHome)) {
1310 LOGGER.debug("Precheck Successful.");
1314 PolicyLogger.audit("Transaction Ended Successfully");
1316 } catch (PAPException e) {
1317 acPutTransaction.rollbackTransaction();
1318 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " API PUT exception");
1319 loggingContext.transactionEnded();
1320 PolicyLogger.audit("Transaction Failed - See Error.log");
1321 String message = XACMLErrorConstants.ERROR_PROCESS_FLOW + "Exception in request to update group from API - See Error.log on on the PAP.";
1322 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
1323 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
1324 response.addHeader("error","addGroupError");
1325 response.addHeader("message", message);
1331 * Requests from the Admin Console for operations not on single specific objects
1336 * @param loggingContext
1337 * @throws ServletException
1338 * @throws IOException
1340 private void doACPost(HttpServletRequest request, HttpServletResponse response, String groupId, ONAPLoggingContext loggingContext) throws ServletException, IOException {
1341 PolicyDBDaoTransaction doACPostTransaction = null;
1343 String groupName = request.getParameter("groupName");
1344 String groupDescription = request.getParameter("groupDescription");
1345 String apiflag = request.getParameter("apiflag");
1346 if (groupName != null && groupDescription != null) {
1347 // Args: group=<groupId> groupName=<name> groupDescription=<description> <= create a new group
1348 loggingContext.setServiceName("AC:PAP.createGroup");
1349 String unescapedName = URLDecoder.decode(groupName, "UTF-8");
1350 String unescapedDescription = URLDecoder.decode(groupDescription, "UTF-8");
1351 PolicyDBDaoTransaction newGroupTransaction = policyDBDao.getNewTransaction();
1353 newGroupTransaction.createGroup(PolicyDBDao.createNewPDPGroupId(unescapedName), unescapedName, unescapedDescription,"XACMLPapServlet.doACPost");
1354 papEngine.newGroup(unescapedName, unescapedDescription);
1355 newGroupTransaction.commitTransaction();
1356 } catch (Exception e) {
1357 newGroupTransaction.rollbackTransaction();
1358 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Unable to create new group");
1359 loggingContext.transactionEnded();
1361 PolicyLogger.audit("Transaction Failed - See Error.log");
1362 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unable to create new group '" + groupId + "'");
1365 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1366 if (LOGGER.isDebugEnabled()) {
1367 LOGGER.debug("New Group '" + groupId + "' created");
1369 // tell the Admin Consoles there is a change
1371 // new group by definition has no PDPs, so no need to notify them of changes
1372 loggingContext.transactionEnded();
1373 PolicyLogger.audit("Transaction Failed - See Error.log");
1374 auditLogger.info("Success");
1375 PolicyLogger.audit("Transaction Ended Successfully");
1378 // for all remaining POST operations the group must exist before the operation can be done
1379 OnapPDPGroup group = papEngine.getGroup(groupId);
1380 if (group == null) {
1381 String message = "Unknown groupId '" + groupId + "'";
1382 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
1383 loggingContext.transactionEnded();
1384 PolicyLogger.audit("Transaction Failed - See Error.log");
1386 response.addHeader("error", "unknownGroupId");
1387 response.addHeader("operation", "push");
1388 response.addHeader("message", message);
1389 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
1391 setResponseError(response,HttpServletResponse.SC_NOT_FOUND, message);
1395 // determine the operation needed based on the parameters in the request
1396 if (request.getParameter("policyId") != null) {
1397 // Args: group=<groupId> policy=<policyId> <= copy file
1398 // copy a policy from the request contents into a file in the group's directory on this machine
1400 loggingContext.setServiceName("PolicyEngineAPI:PAP.postPolicy");
1402 loggingContext.setServiceName("AC:PAP.postPolicy");
1404 String policyId = request.getParameter("policyId");
1405 PolicyDBDaoTransaction addPolicyToGroupTransaction = policyDBDao.getNewTransaction();
1407 InputStream is = null;
1409 if (apiflag != null){
1410 // get the request content into a String if the request is from API
1412 // read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
1413 java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
1414 scanner.useDelimiter("\\A");
1415 json = scanner.hasNext() ? scanner.next() : "";
1417 LOGGER.info("JSON request from API: " + json);
1418 // convert Object sent as JSON into local object
1419 ObjectMapper mapper = new ObjectMapper();
1420 Object objectFromJSON = mapper.readValue(json, StdPAPPolicy.class);
1421 StdPAPPolicy policy = (StdPAPPolicy) objectFromJSON;
1422 temp = new File(policy.getLocation());
1423 is = new FileInputStream(temp);
1425 is = request.getInputStream();
1427 addPolicyToGroupTransaction.addPolicyToGroup(group.getId(), policyId,"XACMLPapServlet.doACPost");
1428 if (apiflag != null){
1429 ((StdPDPGroup) group).copyPolicyToFile(policyId,"API", is);
1432 if (policyId.endsWith(".xml")) {
1433 name = policyId.replace(".xml", "");
1434 name = name.substring(0, name.lastIndexOf("."));
1436 ((StdPDPGroup) group).copyPolicyToFile(policyId, name, is);
1438 if(is!=null && temp!=null){
1442 addPolicyToGroupTransaction.commitTransaction();
1443 } catch (Exception e) {
1444 addPolicyToGroupTransaction.rollbackTransaction();
1445 String message = "Policy '" + policyId + "' not copied to group '" + groupId +"': " + e;
1446 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " " + message);
1447 loggingContext.transactionEnded();
1448 PolicyLogger.audit("Transaction Failed - See Error.log");
1450 response.addHeader("error", "policyCopyError");
1451 response.addHeader("message", message);
1452 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
1454 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
1458 // policy file copied ok and the Group was updated on the PDP
1459 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1460 response.addHeader("operation", "push");
1461 response.addHeader("policyId", policyId);
1462 response.addHeader("groupId", groupId);
1463 if (LOGGER.isDebugEnabled()) {
1464 LOGGER.debug("policy '" + policyId + "' copied to directory for group '" + groupId + "'");
1466 loggingContext.transactionEnded();
1467 auditLogger.info("Success");
1468 PolicyLogger.audit("Transaction Ended Successfully");
1470 } else if (request.getParameter("default") != null) {
1471 // Args: group=<groupId> default=true <= make default
1472 // change the current default group to be the one identified in the request.
1473 loggingContext.setServiceName("AC:PAP.setDefaultGroup");
1474 // This is a POST operation rather than a PUT "update group" because of the side-effect that the current default group is also changed.
1475 // It should never be the case that multiple groups are currently marked as the default, but protect against that anyway.
1476 PolicyDBDaoTransaction setDefaultGroupTransaction = policyDBDao.getNewTransaction();
1478 setDefaultGroupTransaction.changeDefaultGroup(group, "XACMLPapServlet.doACPost");
1479 papEngine.SetDefaultGroup(group);
1480 setDefaultGroupTransaction.commitTransaction();
1481 } catch (Exception e) {
1482 setDefaultGroupTransaction.rollbackTransaction();
1483 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Unable to set group");
1484 loggingContext.transactionEnded();
1486 PolicyLogger.audit("Transaction Failed - See Error.log");
1487 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unable to set group '" + groupId + "' to default");
1490 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1491 if (LOGGER.isDebugEnabled()) {
1492 LOGGER.debug("Group '" + groupId + "' set to be default");
1494 // Notify the Admin Consoles that something changed
1495 // For now the AC cannot handle anything more detailed than the whole set of PDPGroups, so just notify on that
1496 //TODO - Future: FIGURE OUT WHAT LEVEL TO NOTIFY: 2 groups or entire set - currently notify AC to update whole configuration of all groups
1498 // This does not affect any PDPs in the existing groups, so no need to notify them of this change
1499 loggingContext.transactionEnded();
1500 auditLogger.info("Success");
1501 PolicyLogger.audit("Transaction Ended Successfully");
1503 } else if (request.getParameter("pdpId") != null) {
1504 doACPostTransaction = policyDBDao.getNewTransaction();
1505 // Args: group=<groupId> pdpId=<pdpId> <= move PDP to group
1506 loggingContext.setServiceName("AC:PAP.movePDP");
1507 String pdpId = request.getParameter("pdpId");
1508 OnapPDP pdp = papEngine.getPDP(pdpId);
1509 OnapPDPGroup originalGroup = papEngine.getPDPGroup((OnapPDP) pdp);
1511 doACPostTransaction.movePdp(pdp, group, "XACMLPapServlet.doACPost");
1512 }catch(Exception e){
1513 doACPostTransaction.rollbackTransaction();
1514 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet",
1515 " Error while moving pdp in the database: "
1516 +"pdp="+pdp.getId()+",to group="+group.getId());
1517 throw new PAPException(e.getMessage());
1519 papEngine.movePDP((OnapPDP) pdp, group);
1520 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1521 if (LOGGER.isDebugEnabled()) {
1522 LOGGER.debug("PDP '" + pdp.getId() +"' moved to group '" + group.getId() + "' set to be default");
1524 // update the status of both the original group and the new one
1525 ((StdPDPGroup)originalGroup).resetStatus();
1526 ((StdPDPGroup)group).resetStatus();
1527 // Notify the Admin Consoles that something changed
1528 // For now the AC cannot handle anything more detailed than the whole set of PDPGroups, so just notify on that
1530 // Need to notify the PDP that it's config may have changed
1532 doACPostTransaction.commitTransaction();
1533 loggingContext.transactionEnded();
1534 auditLogger.info("Success");
1535 PolicyLogger.audit("Transaction Ended Successfully");
1538 } catch (PAPException e) {
1539 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC POST exception");
1540 loggingContext.transactionEnded();
1541 PolicyLogger.audit("Transaction Failed - See Error.log");
1542 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
1548 * Requests from the Admin Console to GET info about the Groups and PDPs
1553 * @param loggingContext
1554 * @throws ServletException
1555 * @throws IOException
1557 private void doACGet(HttpServletRequest request, HttpServletResponse response, String groupId, ONAPLoggingContext loggingContext) throws ServletException, IOException {
1559 String parameterDefault = request.getParameter("default");
1560 String pdpId = request.getParameter("pdpId");
1561 String pdpGroup = request.getParameter("getPDPGroup");
1562 if ("".equals(groupId)) {
1563 // request IS from AC but does not identify a group by name
1564 if (parameterDefault != null) {
1565 // Request is for the Default group (whatever its id)
1566 loggingContext.setServiceName("AC:PAP.getDefaultGroup");
1567 OnapPDPGroup group = papEngine.getDefaultGroup();
1568 // convert response object to JSON and include in the response
1569 ObjectMapper mapper = new ObjectMapper();
1570 mapper.writeValue(response.getOutputStream(), group);
1571 if (LOGGER.isDebugEnabled()) {
1572 LOGGER.debug("GET Default group req from '" + request.getRequestURL() + "'");
1574 response.setStatus(HttpServletResponse.SC_OK);
1575 response.setHeader("content-type", "application/json");
1576 response.getOutputStream().close();
1577 loggingContext.transactionEnded();
1578 auditLogger.info("Success");
1579 PolicyLogger.audit("Transaction Ended Successfully");
1581 } else if (pdpId != null) {
1582 // Request is related to a PDP
1583 if (pdpGroup == null) {
1584 // Request is for the (unspecified) group containing a given PDP
1585 loggingContext.setServiceName("AC:PAP.getPDP");
1586 OnapPDP pdp = papEngine.getPDP(pdpId);
1587 // convert response object to JSON and include in the response
1588 ObjectMapper mapper = new ObjectMapper();
1589 mapper.writeValue(response.getOutputStream(), pdp);
1590 if (LOGGER.isDebugEnabled()) {
1591 LOGGER.debug("GET pdp '" + pdpId + "' req from '" + request.getRequestURL() + "'");
1593 response.setStatus(HttpServletResponse.SC_OK);
1594 response.setHeader("content-type", "application/json");
1595 response.getOutputStream().close();
1596 loggingContext.transactionEnded();
1597 auditLogger.info("Success");
1598 PolicyLogger.audit("Transaction Ended Successfully");
1601 // Request is for the group containing a given PDP
1602 loggingContext.setServiceName("AC:PAP.getGroupForPDP");
1603 OnapPDP pdp = papEngine.getPDP(pdpId);
1604 OnapPDPGroup group = papEngine.getPDPGroup((OnapPDP) pdp);
1605 // convert response object to JSON and include in the response
1606 ObjectMapper mapper = new ObjectMapper();
1607 mapper.writeValue(response.getOutputStream(), group);
1608 if (LOGGER.isDebugEnabled()) {
1609 LOGGER.debug("GET PDP '" + pdpId + "' Group req from '" + request.getRequestURL() + "'");
1611 response.setStatus(HttpServletResponse.SC_OK);
1612 response.setHeader("content-type", "application/json");
1613 response.getOutputStream().close();
1614 loggingContext.transactionEnded();
1615 auditLogger.info("Success");
1616 PolicyLogger.audit("Transaction Ended Successfully");
1620 // request is for top-level properties about all groups
1621 loggingContext.setServiceName("AC:PAP.getAllGroups");
1622 Set<OnapPDPGroup> groups = papEngine.getOnapPDPGroups();
1623 // convert response object to JSON and include in the response
1624 ObjectMapper mapper = new ObjectMapper();
1625 mapper.writeValue(response.getOutputStream(), groups);
1626 if (LOGGER.isDebugEnabled()) {
1627 LOGGER.debug("GET All groups req");
1629 response.setStatus(HttpServletResponse.SC_OK);
1630 response.setHeader("content-type", "application/json");
1631 response.getOutputStream().close();
1632 loggingContext.transactionEnded();
1633 auditLogger.info("Success");
1634 PolicyLogger.audit("Transaction Ended Successfully");
1638 // for all other GET operations the group must exist before the operation can be done
1639 OnapPDPGroup group = papEngine.getGroup(groupId);
1640 if (group == null) {
1641 String message = "Unknown groupId '" + groupId + "'";
1642 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
1643 loggingContext.transactionEnded();
1645 PolicyLogger.audit("Transaction Failed - See Error.log");
1646 setResponseError(response,HttpServletResponse.SC_NOT_FOUND, message);
1649 // Figure out which request this is based on the parameters
1650 String policyId = request.getParameter("policyId");
1651 if (policyId != null) {
1652 // retrieve a policy
1653 loggingContext.setServiceName("AC:PAP.getPolicy");
1654 // convert response object to JSON and include in the response
1655 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " GET Policy not implemented");
1656 loggingContext.transactionEnded();
1657 PolicyLogger.audit("Transaction Failed - See Error.log");
1658 setResponseError(response,HttpServletResponse.SC_BAD_REQUEST, "GET Policy not implemented");
1660 // No other parameters, so return the identified Group
1661 loggingContext.setServiceName("AC:PAP.getGroup");
1662 // convert response object to JSON and include in the response
1663 ObjectMapper mapper = new ObjectMapper();
1664 mapper.writeValue(response.getOutputStream(), group);
1665 if (LOGGER.isDebugEnabled()) {
1666 LOGGER.debug("GET group '" + group.getId() + "' req from '" + request.getRequestURL() + "'");
1668 response.setStatus(HttpServletResponse.SC_OK);
1669 response.setHeader("content-type", "application/json");
1670 response.getOutputStream().close();
1671 loggingContext.transactionEnded();
1672 auditLogger.info("Success");
1673 PolicyLogger.audit("Transaction Ended Successfully");
1676 // Currently there are no other GET calls from the AC.
1677 // The AC uses the "GET All Groups" operation to fill its local cache and uses that cache for all other GETs without calling the PAP.
1678 // Other GETs that could be called:
1679 // Specific Group (groupId=<groupId>)
1680 // A Policy (groupId=<groupId> policyId=<policyId>)
1681 // A PDP (groupId=<groupId> pdpId=<pdpId>)
1682 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " UNIMPLEMENTED ");
1683 loggingContext.transactionEnded();
1684 PolicyLogger.audit("Transaction Failed - See Error.log");
1685 setResponseError(response,HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
1686 } catch (PAPException e) {
1687 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC Get exception");
1688 loggingContext.transactionEnded();
1689 PolicyLogger.audit("Transaction Failed - See Error.log");
1690 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
1696 * Requests from the Admin Console to create new items or update existing ones
1701 * @param loggingContext
1702 * @throws ServletException
1703 * @throws IOException
1705 private void doACPut(HttpServletRequest request, HttpServletResponse response, String groupId, ONAPLoggingContext loggingContext) throws ServletException, IOException {
1706 PolicyDBDaoTransaction acPutTransaction = policyDBDao.getNewTransaction();
1708 // for PUT operations the group may or may not need to exist before the operation can be done
1709 OnapPDPGroup group = papEngine.getGroup(groupId);
1710 // determine the operation needed based on the parameters in the request
1711 // for remaining operations the group must exist before the operation can be done
1712 if (group == null) {
1713 String message = "Unknown groupId '" + groupId + "'";
1714 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
1715 loggingContext.transactionEnded();
1716 PolicyLogger.audit("Transaction Failed - See Error.log");
1717 setResponseError(response,HttpServletResponse.SC_NOT_FOUND, message);
1720 if (request.getParameter("policy") != null) {
1721 // group=<groupId> policy=<policyId> contents=policy file <= Create new policy file in group dir, or replace it if it already exists (do not touch properties)
1722 loggingContext.setServiceName("AC:PAP.putPolicy");
1723 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " PARTIALLY IMPLEMENTED!!! ACTUAL CHANGES SHOULD BE MADE BY PAP SERVLET!!! ");
1724 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1725 loggingContext.transactionEnded();
1726 PolicyLogger.audit("Transaction Failed - See Error.log");
1727 auditLogger.info("Success");
1728 PolicyLogger.audit("Transaction Ended Successfully");
1730 } else if (request.getParameter("pdpId") != null) {
1731 // ARGS: group=<groupId> pdpId=<pdpId/URL> <= create a new PDP or Update an Existing one
1732 String pdpId = request.getParameter("pdpId");
1733 if (papEngine.getPDP(pdpId) == null) {
1734 loggingContext.setServiceName("AC:PAP.createPDP");
1736 loggingContext.setServiceName("AC:PAP.updatePDP");
1738 // get the request content into a String
1740 // read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
1741 java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
1742 scanner.useDelimiter("\\A");
1743 json = scanner.hasNext() ? scanner.next() : "";
1745 LOGGER.info("JSON request from AC: " + json);
1746 // convert Object sent as JSON into local object
1747 ObjectMapper mapper = new ObjectMapper();
1748 Object objectFromJSON = mapper.readValue(json, StdPDP.class);
1749 if (pdpId == null ||
1750 objectFromJSON == null ||
1751 ! (objectFromJSON instanceof StdPDP) ||
1752 ((StdPDP)objectFromJSON).getId() == null ||
1753 ! ((StdPDP)objectFromJSON).getId().equals(pdpId)) {
1754 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " PDP new/update had bad input. pdpId=" + pdpId + " objectFromJSON="+objectFromJSON);
1755 loggingContext.transactionEnded();
1756 PolicyLogger.audit("Transaction Failed - See Error.log");
1757 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Bad input, pdpid="+pdpId+" object="+objectFromJSON);
1759 StdPDP pdp = (StdPDP) objectFromJSON;
1761 if (papEngine.getPDP(pdpId) == null) {
1762 // this is a request to create a new PDP object
1764 acPutTransaction.addPdpToGroup(pdp.getId(), group.getId(), pdp.getName(),
1765 pdp.getDescription(), pdp.getJmxPort(),"XACMLPapServlet.doACPut");
1766 } catch(Exception e){
1767 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Error while adding pdp to group in the database: "
1768 +"pdp="+ (pdp.getId()) +",to group="+group.getId());
1769 throw new PAPException(e.getMessage());
1771 papEngine.newPDP(pdp.getId(), group, pdp.getName(), pdp.getDescription(), pdp.getJmxPort());
1774 acPutTransaction.updatePdp(pdp, "XACMLPapServlet.doACPut");
1775 } catch(Exception e){
1776 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Error while updating pdp in the database: "
1777 +"pdp="+ pdp.getId());
1778 throw new PAPException(e.getMessage());
1780 // this is a request to update the pdp
1781 papEngine.updatePDP(pdp);
1783 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1784 if (LOGGER.isDebugEnabled()) {
1785 LOGGER.debug("PDP '" + pdpId + "' created/updated");
1787 // adjust the group's state including the new PDP
1788 ((StdPDPGroup)group).resetStatus();
1789 // tell the Admin Consoles there is a change
1791 // this might affect the PDP, so notify it of the change
1793 acPutTransaction.commitTransaction();
1794 loggingContext.transactionEnded();
1795 auditLogger.info("Success");
1796 PolicyLogger.audit("Transaction Ended Successfully");
1800 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "XACMLPapServlet", " Error while adding pdp to group in the database: "
1801 +"pdp=null" + ",to group="+group.getId());
1802 throw new PAPException("PDP is null");
1803 } catch(Exception e){
1804 throw new PAPException("PDP is null" + e.getMessage() +e);
1807 } else if (request.getParameter("pipId") != null) {
1808 // group=<groupId> pipId=<pipEngineId> contents=pip properties <= add a PIP to pip config, or replace it if it already exists (lenient operation)
1809 loggingContext.setServiceName("AC:PAP.putPIP");
1810 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
1811 loggingContext.transactionEnded();
1812 PolicyLogger.audit("Transaction Failed - See Error.log");
1813 setResponseError(response,HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
1816 // Assume that this is an update of an existing PDP Group
1817 // ARGS: group=<groupId> <= Update an Existing Group
1818 loggingContext.setServiceName("AC:PAP.updateGroup");
1819 // get the request content into a String
1821 // read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
1822 java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
1823 scanner.useDelimiter("\\A");
1824 json = scanner.hasNext() ? scanner.next() : "";
1826 LOGGER.info("JSON request from AC: " + json);
1827 // convert Object sent as JSON into local object
1828 ObjectMapper mapper = new ObjectMapper();
1829 Object objectFromJSON = mapper.readValue(json, StdPDPGroup.class);
1830 if (objectFromJSON == null || ! (objectFromJSON instanceof StdPDPGroup) ||
1831 ! ((StdPDPGroup)objectFromJSON).getId().equals(group.getId())) {
1832 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id=" + group.getId() + " objectFromJSON="+objectFromJSON);
1833 loggingContext.transactionEnded();
1834 PolicyLogger.audit("Transaction Failed - See Error.log");
1835 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Bad input, id="+group.getId() +" object="+objectFromJSON);
1837 // The Path on the PAP side is not carried on the RESTful interface with the AC
1838 // (because it is local to the PAP)
1839 // so we need to fill that in before submitting the group for update
1840 if(objectFromJSON != null){
1841 ((StdPDPGroup)objectFromJSON).setDirectory(((StdPDPGroup)group).getDirectory());
1844 acPutTransaction.updateGroup((StdPDPGroup)objectFromJSON, "XACMLPapServlet.doACPut");
1845 } catch(Exception e){
1846 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database: "
1847 +"group="+group.getId());
1848 throw new PAPException(e.getMessage());
1851 PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance();
1852 OnapPDPGroup updatedGroup = (StdPDPGroup)objectFromJSON;
1853 if (pushPolicyHandler.preSafetyCheck(updatedGroup, configHome)) {
1854 LOGGER.debug("Precheck Successful.");
1857 papEngine.updateGroup((StdPDPGroup)objectFromJSON);
1859 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1860 if (LOGGER.isDebugEnabled()) {
1861 LOGGER.debug("Group '" + group.getId() + "' updated");
1863 acPutTransaction.commitTransaction();
1864 // tell the Admin Consoles there is a change
1866 // Group changed, which might include changing the policies
1867 groupChanged(group);
1868 loggingContext.transactionEnded();
1869 auditLogger.info("Success");
1870 PolicyLogger.audit("Transaction Ended Successfully");
1873 } catch (PAPException e) {
1875 acPutTransaction.rollbackTransaction();
1876 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC PUT exception");
1877 loggingContext.transactionEnded();
1878 PolicyLogger.audit("Transaction Failed - See Error.log");
1879 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
1885 * Requests from the Admin Console to delete/remove items
1890 * @param loggingContext
1891 * @throws ServletException
1892 * @throws IOException
1894 private void doACDelete(HttpServletRequest request, HttpServletResponse response, String groupId, ONAPLoggingContext loggingContext) throws ServletException, IOException {
1895 //This code is to allow deletes to propagate to the database since delete is not implemented
1896 String isDeleteNotify = request.getParameter("isDeleteNotify");
1897 if(isDeleteNotify != null){
1898 String policyToDelete = request.getParameter("policyToDelete");
1900 policyToDelete = URLDecoder.decode(policyToDelete,"UTF-8");
1901 } catch(UnsupportedEncodingException e){
1902 PolicyLogger.error("Unsupported URL encoding of policyToDelete (UTF-8");
1903 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR,"policyToDelete encoding not supported");
1906 PolicyDBDaoTransaction deleteTransaction = policyDBDao.getNewTransaction();
1908 deleteTransaction.deletePolicy(policyToDelete);
1909 } catch(Exception e){
1910 deleteTransaction.rollbackTransaction();
1911 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR,"deleteTransaction.deleteTransaction(policyToDelete) "
1912 + "\nfailure with the following exception: " + e);
1915 deleteTransaction.commitTransaction();
1916 response.setStatus(HttpServletResponse.SC_OK);
1919 PolicyDBDaoTransaction removePdpOrGroupTransaction = policyDBDao.getNewTransaction();
1921 // for all DELETE operations the group must exist before the operation can be done
1922 loggingContext.setServiceName("AC:PAP.delete");
1923 OnapPDPGroup group = papEngine.getGroup(groupId);
1924 if (group == null) {
1925 String message = "Unknown groupId '" + groupId + "'";
1926 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
1927 loggingContext.transactionEnded();
1928 PolicyLogger.audit("Transaction Failed - See Error.log");
1929 setResponseError(response,HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId +"'");
1932 // determine the operation needed based on the parameters in the request
1933 if (request.getParameter("policy") != null) {
1934 // group=<groupId> policy=<policyId> [delete=<true|false>] <= delete policy file from group
1935 loggingContext.setServiceName("AC:PAP.deletePolicy");
1936 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
1937 loggingContext.transactionEnded();
1938 PolicyLogger.audit("Transaction Failed - See Error.log");
1939 setResponseError(response,HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
1941 } else if (request.getParameter("pdpId") != null) {
1942 // ARGS: group=<groupId> pdpId=<pdpId> <= delete PDP
1943 String pdpId = request.getParameter("pdpId");
1944 OnapPDP pdp = papEngine.getPDP(pdpId);
1946 removePdpOrGroupTransaction.removePdpFromGroup(pdp.getId(),"XACMLPapServlet.doACDelete");
1947 } catch(Exception e){
1948 throw new PAPException();
1950 papEngine.removePDP((OnapPDP) pdp);
1951 // adjust the status of the group, which may have changed when we removed this PDP
1952 ((StdPDPGroup)group).resetStatus();
1953 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1955 // update the PDP and tell it that it has NO Policies (which prevents it from serving PEP Requests)
1957 removePdpOrGroupTransaction.commitTransaction();
1958 loggingContext.transactionEnded();
1959 auditLogger.info("Success");
1960 PolicyLogger.audit("Transaction Ended Successfully");
1962 } else if (request.getParameter("pipId") != null) {
1963 // group=<groupId> pipId=<pipEngineId> <= delete PIP config for given engine
1964 loggingContext.setServiceName("AC:PAP.deletePIPConfig");
1965 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
1966 loggingContext.transactionEnded();
1967 PolicyLogger.audit("Transaction Failed - See Error.log");
1968 setResponseError(response,HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
1971 // ARGS: group=<groupId> movePDPsToGroupId=<movePDPsToGroupId> <= delete a group and move all its PDPs to the given group
1972 String moveToGroupId = request.getParameter("movePDPsToGroupId");
1973 OnapPDPGroup moveToGroup = null;
1974 if (moveToGroupId != null) {
1975 moveToGroup = papEngine.getGroup(moveToGroupId);
1977 // get list of PDPs in the group being deleted so we can notify them that they got changed
1978 Set<OnapPDP> movedPDPs = new HashSet<>();
1979 movedPDPs.addAll(group.getOnapPdps());
1980 // do the move/remove
1982 removePdpOrGroupTransaction.deleteGroup(group, moveToGroup,"XACMLPapServlet.doACDelete");
1983 } catch(Exception e){
1984 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN, e, "XACMLPapServlet", " Failed to delete PDP Group. Exception");
1985 throw new PAPException(e.getMessage());
1987 papEngine.removeGroup(group, moveToGroup);
1988 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
1990 // notify any PDPs in the removed set that their config may have changed
1991 for (OnapPDP pdp : movedPDPs) {
1994 removePdpOrGroupTransaction.commitTransaction();
1995 loggingContext.transactionEnded();
1996 auditLogger.info("Success");
1997 PolicyLogger.audit("Transaction Ended Successfully");
2000 } catch (PAPException e) {
2001 removePdpOrGroupTransaction.rollbackTransaction();
2002 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC DELETE exception");
2003 loggingContext.transactionEnded();
2004 PolicyLogger.audit("Transaction Failed - See Error.log");
2005 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
2011 * Heartbeat thread - periodically check on PDPs' status
2013 * Heartbeat with all known PDPs.
2015 * Implementation note:
2017 * The PDPs are contacted Sequentially, not in Parallel.
2019 * If we did this in parallel using multiple threads we would simultaneously use
2023 * This could become a resource problem since we already use multiple threads and connections for updating the PDPs
2024 * when user changes occur.
2025 * Using separate threads can also make it tricky dealing with timeouts on PDPs that are non-responsive.
2027 * The Sequential operation does a heartbeat request to each PDP one at a time.
2028 * This has the flaw that any PDPs that do not respond will hold up the entire heartbeat sequence until they timeout.
2029 * If there are a lot of non-responsive PDPs and the timeout is large-ish (the default is 20 seconds)
2030 * it could take a long time to cycle through all of the PDPs.
2031 * That means that this may not notice a PDP being down in a predictable time.
2033 private class Heartbeat implements Runnable {
2034 private PAPPolicyEngine papEngine;
2035 private Set<OnapPDP> pdps = new HashSet<>();
2036 private int heartbeatInterval;
2037 private int heartbeatTimeout;
2039 public volatile boolean isRunning = false;
2041 public synchronized boolean isRunning() {
2042 return this.isRunning;
2045 public synchronized void terminate() {
2046 this.isRunning = false;
2049 public Heartbeat(PAPPolicyEngine papEngine2) {
2050 papEngine = papEngine2;
2051 this.heartbeatInterval = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_HEARTBEAT_INTERVAL, "10000"));
2052 this.heartbeatTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_HEARTBEAT_TIMEOUT, "10000"));
2057 // Set ourselves as running
2058 synchronized(this) {
2059 this.isRunning = true;
2061 HashMap<String, URL> idToURLMap = new HashMap<>();
2063 while (this.isRunning()) {
2064 // Wait the given time
2065 Thread.sleep(heartbeatInterval);
2066 // get the list of PDPs (may have changed since last time)
2068 synchronized(papEngine) {
2070 for (OnapPDPGroup g : papEngine.getOnapPDPGroups()) {
2071 for (OnapPDP p : g.getOnapPdps()) {
2075 } catch (PAPException e) {
2076 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", "Heartbeat unable to read PDPs from PAPEngine");
2079 // Check for shutdown
2080 if (this.isRunning() == false) {
2081 LOGGER.info("isRunning is false, getting out of loop.");
2084 // try to get the summary status from each PDP
2085 boolean changeSeen = false;
2086 for (OnapPDP pdp : pdps) {
2087 // Check for shutdown
2088 if (this.isRunning() == false) {
2089 LOGGER.info("isRunning is false, getting out of loop.");
2092 // the id of the PDP is its url (though we add a query parameter)
2093 URL pdpURL = idToURLMap.get(pdp.getId());
2094 if (pdpURL == null) {
2095 // haven't seen this PDP before
2096 String fullURLString = null;
2099 if(CheckPDP.validateID(pdp.getId())){
2100 fullURLString = pdp.getId() + "?type=hb";
2101 pdpURL = new URL(fullURLString);
2102 idToURLMap.put(pdp.getId(), pdpURL);
2104 } catch (MalformedURLException e) {
2105 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPapServlet", " PDP id '" + fullURLString + "' is not a valid URL");
2109 // Do a GET with type HeartBeat
2110 String newStatus = "";
2111 HttpURLConnection connection = null;
2113 // Open up the connection
2115 connection = (HttpURLConnection)pdpURL.openConnection();
2116 // Setup our method and headers
2117 connection.setRequestMethod("GET");
2118 connection.setConnectTimeout(heartbeatTimeout);
2120 String encoding = CheckPDP.getEncoding(pdp.getId());
2121 if(encoding !=null){
2122 connection.setRequestProperty("Authorization", "Basic " + encoding);
2125 connection.connect();
2126 if (connection.getResponseCode() == 204) {
2127 newStatus = connection.getHeaderField(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB);
2128 if (LOGGER.isDebugEnabled()) {
2129 LOGGER.debug("Heartbeat '" + pdp.getId() + "' status='" + newStatus + "'");
2132 // anything else is an unexpected result
2133 newStatus = PDPStatus.Status.UNKNOWN.toString();
2134 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " Heartbeat connect response code " + connection.getResponseCode() + ": " + pdp.getId());
2137 } catch (UnknownHostException e) {
2138 newStatus = PDPStatus.Status.NO_SUCH_HOST.toString();
2139 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Heartbeat '" + pdp.getId() + "' NO_SUCH_HOST");
2140 } catch (SocketTimeoutException e) {
2141 newStatus = PDPStatus.Status.CANNOT_CONNECT.toString();
2142 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Heartbeat '" + pdp.getId() + "' connection timeout");
2143 } catch (ConnectException e) {
2144 newStatus = PDPStatus.Status.CANNOT_CONNECT.toString();
2145 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Heartbeat '" + pdp.getId() + "' cannot connect");
2146 } catch (Exception e) {
2147 newStatus = PDPStatus.Status.UNKNOWN.toString();
2148 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", "Heartbeat '" + pdp.getId() + "' connect exception");
2150 // cleanup the connection
2151 if(connection != null)
2152 connection.disconnect();
2154 if ( ! pdp.getStatus().getStatus().toString().equals(newStatus)) {
2155 if (LOGGER.isDebugEnabled()) {
2156 LOGGER.debug("previous status='" + pdp.getStatus().getStatus()+"' new Status='" + newStatus + "'");
2159 setPDPSummaryStatus(pdp, newStatus);
2160 } catch (PAPException e) {
2161 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", "Unable to set state for PDP '" + pdp.getId());
2166 // Check for shutdown
2167 if (this.isRunning() == false) {
2168 LOGGER.info("isRunning is false, getting out of loop.");
2171 // if any of the PDPs changed state, tell the ACs to update
2176 } catch (InterruptedException e) {
2177 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " Heartbeat interrupted. Shutting down");
2179 Thread.currentThread().interrupt();
2185 * HELPER to change Group status when PDP status is changed
2186 * (Must NOT be called from a method that is synchronized on the papEngine or it may deadlock)
2188 private void setPDPSummaryStatus(OnapPDP pdp, PDPStatus.Status newStatus) throws PAPException {
2189 setPDPSummaryStatus(pdp, newStatus.toString());
2192 private void setPDPSummaryStatus(OnapPDP pdp, String newStatus) throws PAPException {
2193 synchronized(papEngine) {
2194 StdPDPStatus status = new StdPDPStatus();
2195 status.setStatus(PDPStatus.Status.valueOf(newStatus));
2196 ((StdPDP)pdp).setStatus(status);
2197 // now adjust the group
2198 StdPDPGroup group = (StdPDPGroup)papEngine.getPDPGroup((OnapPDP) pdp);
2199 // if the PDP was just deleted it may transiently exist but not be in a group
2200 if (group != null) {
2201 group.resetStatus();
2207 * Callback methods telling this servlet to notify PDPs of changes made by the PAP StdEngine
2208 * in the PDP group directories
2211 public void changed() {
2212 // all PDPs in all groups need to be updated/sync'd
2213 Set<OnapPDPGroup> groups;
2215 groups = papEngine.getOnapPDPGroups();
2216 } catch (PAPException e) {
2217 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " getPDPGroups failed");
2218 throw new RuntimeException(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get Groups: " + e);
2220 for (OnapPDPGroup group : groups) {
2221 groupChanged(group);
2226 public void groupChanged(OnapPDPGroup group) {
2227 // all PDPs within one group need to be updated/sync'd
2228 for (OnapPDP pdp : group.getOnapPdps()) {
2234 public void pdpChanged(OnapPDP pdp) {
2235 // kick off a thread to do an event notification for each PDP.
2236 // This needs to be on a separate thread so that PDPs that do not respond (down, non-existent, etc)
2237 // do not block the PSP response to the AC, which would freeze the GUI until all PDPs sequentially respond or time-out.
2238 Thread t = new Thread(new UpdatePDPThread(pdp));
2239 if(CheckPDP.validateID(pdp.getId())){
2244 private class UpdatePDPThread implements Runnable {
2245 private OnapPDP pdp;
2246 private String requestId;
2248 public UpdatePDPThread(OnapPDP pdp) {
2253 // send the current configuration to one PDP
2254 HttpURLConnection connection = null;
2255 // get a new logging context for the thread
2256 ONAPLoggingContext loggingContext = new ONAPLoggingContext(baseLoggingContext);
2258 loggingContext.setServiceName("PAP:PDP.putConfig");
2259 // If a requestId was provided, use it, otherwise generate one; post to loggingContext to be used later when calling PDP
2260 if ((requestId == null) || (requestId == "")) {
2261 UUID requestID = UUID.randomUUID();
2262 loggingContext.setRequestID(requestID.toString());
2263 PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (UpdatePDPThread) so we generated one: " + loggingContext.getRequestID());
2265 loggingContext.setRequestID(requestId);
2266 PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (UpdatePDPThread): " + loggingContext.getRequestID());
2268 loggingContext.transactionStarted();
2269 // the Id of the PDP is its URL
2270 if (LOGGER.isDebugEnabled()) {
2271 LOGGER.debug("creating url for id '" + pdp.getId() + "'");
2273 //TODO - currently always send both policies and pips. Do we care enough to add code to allow sending just one or the other?
2274 //TODO (need to change "cache=", implying getting some input saying which to change)
2275 URL url = new URL(pdp.getId() + "?cache=all");
2276 // Open up the connection
2277 connection = (HttpURLConnection)url.openConnection();
2278 // Setup our method and headers
2279 connection.setRequestMethod("PUT");
2281 String encoding = CheckPDP.getEncoding(pdp.getId());
2282 if(encoding !=null){
2283 connection.setRequestProperty("Authorization", "Basic " + encoding);
2285 connection.setRequestProperty("Content-Type", "text/x-java-properties");
2286 connection.setRequestProperty("X-ECOMP-RequestID", loggingContext.getRequestID());
2287 connection.setInstanceFollowRedirects(true);
2288 connection.setDoOutput(true);
2289 try (OutputStream os = connection.getOutputStream()) {
2290 OnapPDPGroup group = papEngine.getPDPGroup((OnapPDP) pdp);
2291 // if the PDP was just deleted, there is no group, but we want to send an update anyway
2292 if (group == null) {
2293 // create blank properties files
2294 Properties policyProperties = new Properties();
2295 policyProperties.put(XACMLProperties.PROP_ROOTPOLICIES, "");
2296 policyProperties.put(XACMLProperties.PROP_REFERENCEDPOLICIES, "");
2297 policyProperties.store(os, "");
2298 Properties pipProps = new Properties();
2299 pipProps.setProperty(XACMLProperties.PROP_PIP_ENGINES, "");
2300 pipProps.store(os, "");
2302 // send properties from the current group
2303 group.getPolicyProperties().store(os, "");
2304 Properties policyLocations = new Properties();
2305 for (PDPPolicy policy : group.getPolicies()) {
2306 policyLocations.put(policy.getId() + ".url", XACMLPapServlet.papURL + "?id=" + policy.getId());
2308 policyLocations.store(os, "");
2309 group.getPipConfigProperties().store(os, "");
2311 } catch (Exception e) {
2312 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Failed to send property file to " + pdp.getId());
2313 // Since this is a server-side error, it probably does not reflect a problem on the client,
2314 // so do not change the PDP status.
2318 connection.connect();
2319 if (connection.getResponseCode() == 204) {
2320 LOGGER.info("Success. We are configured correctly.");
2321 loggingContext.transactionEnded();
2322 auditLogger.info("Success. PDP is configured correctly.");
2323 PolicyLogger.audit("Transaction Success. PDP is configured correctly.");
2324 setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE);
2325 } else if (connection.getResponseCode() == 200) {
2326 LOGGER.info("Success. PDP needs to update its configuration.");
2327 loggingContext.transactionEnded();
2328 auditLogger.info("Success. PDP needs to update its configuration.");
2329 PolicyLogger.audit("Transaction Success. PDP is configured correctly.");
2330 setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH);
2332 LOGGER.warn("Failed: " + connection.getResponseCode() + " message: " + connection.getResponseMessage());
2333 loggingContext.transactionEnded();
2334 auditLogger.warn("Failed: " + connection.getResponseCode() + " message: " + connection.getResponseMessage());
2335 PolicyLogger.audit("Transaction Failed: " + connection.getResponseCode() + " message: " + connection.getResponseMessage());
2336 setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN);
2338 } catch (Exception e) {
2340 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Unable to sync config with PDP '" + pdp.getId() + "'");
2341 loggingContext.transactionEnded();
2342 PolicyLogger.audit("Transaction Failed: Unable to sync config with PDP '" + pdp.getId() + "': " + e);
2344 setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN);
2345 } catch (PAPException e1) {
2347 PolicyLogger.audit("Transaction Failed: Unable to set status of PDP " + pdp.getId() + " to UNKNOWN: " + e);
2348 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Unable to set status of PDP '" + pdp.getId() + "' to UNKNOWN");
2351 // cleanup the connection
2352 if(connection != null){
2353 connection.disconnect();
2355 // tell the AC to update it's status info
2362 * RESTful Interface from PAP to ACs notifying them of changes
2364 private void notifyAC() {
2365 // kick off a thread to do one event notification for all registered ACs
2366 // This needs to be on a separate thread so that ACs can make calls back to PAP to get the updated Group data
2367 // as part of processing this message on their end.
2368 Thread t = new Thread(new NotifyACThread());
2372 private class NotifyACThread implements Runnable {
2374 List<String> disconnectedACs = new ArrayList<>();
2375 // There should be no Concurrent exception here because the list is a CopyOnWriteArrayList.
2376 // The "for each" loop uses the collection's iterator under the covers, so it should be correct.
2377 for (String acURL : adminConsoleURLStringList) {
2378 HttpURLConnection connection = null;
2380 acURL += "?PAPNotification=true";
2381 //TODO - Currently we just tell AC that "Something changed" without being specific. Do we want to tell it which group/pdp changed?
2382 //TODO - If so, put correct parameters into the Query string here
2383 acURL += "&objectType=all" + "&action=update";
2384 if (LOGGER.isDebugEnabled()) {
2385 LOGGER.debug("creating url for id '" + acURL + "'");
2387 //TODO - currently always send both policies and pips. Do we care enough to add code to allow sending just one or the other?
2388 //TODO (need to change "cache=", implying getting some input saying which to change)
2389 URL url = new URL(acURL );
2390 // Open up the connection
2391 connection = (HttpURLConnection)url.openConnection();
2392 // Setup our method and headers
2393 connection.setRequestMethod("PUT");
2394 connection.setRequestProperty("Content-Type", "text/x-java-properties");
2395 // Adding this in. It seems the HttpUrlConnection class does NOT
2396 // properly forward our headers for POST re-direction. It does so
2397 // for a GET re-direction.
2398 // So we need to handle this ourselves.
2399 //TODO - is this needed for a PUT? seems better to leave in for now?
2400 connection.setInstanceFollowRedirects(false);
2401 // Do not include any data in the PUT because this is just a
2402 // notification to the AC.
2403 // The AC will use GETs back to the PAP to get what it needs
2404 // to fill in the screens.
2406 connection.connect();
2407 if (connection.getResponseCode() == 204) {
2408 LOGGER.info("Success. We updated correctly.");
2410 LOGGER.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed: " + connection.getResponseCode() + " message: " + connection.getResponseMessage());
2413 } catch (Exception e) {
2414 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Unable to sync config AC '" + acURL + "'");
2415 disconnectedACs.add(acURL);
2417 // cleanup the connection
2418 if(connection != null)
2419 connection.disconnect();
2422 // remove any ACs that are no longer connected
2423 if (disconnectedACs.size() > 0) {
2424 adminConsoleURLStringList.removeAll(disconnectedACs);
2429 private void testService(ONAPLoggingContext loggingContext, HttpServletResponse response) throws IOException{
2430 LOGGER.info("Test request received");
2432 im.evaluateSanity();
2433 //If we make it this far, all is well
2434 String message = "GET:/pap/test called and PAP " + papResourceName + " is OK";
2435 LOGGER.info(message);
2436 loggingContext.transactionEnded();
2437 PolicyLogger.audit("Transaction Failed - See Error.log");
2438 response.setStatus(HttpServletResponse.SC_OK);
2440 }catch (ForwardProgressException | AdministrativeStateException | StandbyStatusException e){
2442 if (e instanceof ForwardProgressException) {
2443 submsg = " is not making forward progress.";
2444 } else if (e instanceof AdministrativeStateException) {
2445 submsg = " Administrative State is LOCKED.";
2447 submsg = " Standby Status is NOT PROVIDING SERVICE.";
2450 String message = "GET:/pap/test called and PAP " + papResourceName + submsg
2451 + " Exception Message: " + e.getMessage();
2452 LOGGER.info(message, e);
2453 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
2454 loggingContext.transactionEnded();
2455 PolicyLogger.audit("Transaction Failed - See Error.log");
2456 setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
2458 }catch (Exception e) {
2459 //A subsystem is not making progress, is locked, standby or is not responding
2460 String eMsg = e.getMessage();
2462 eMsg = "No Exception Message";
2464 String message = "GET:/pap/test called and PAP " + papResourceName + " has had a subsystem failure."
2465 + " Exception Message: " + eMsg;
2466 LOGGER.info(message);
2467 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
2468 loggingContext.transactionEnded();
2469 PolicyLogger.audit("Transaction Failed - See Error.log");
2470 //Get the specific list of subsystems that failed
2471 String ssFailureList = null;
2472 for(String failedSS : papDependencyGroupsFlatArray){
2473 if(eMsg.contains(failedSS)){
2474 if(ssFailureList == null){
2475 ssFailureList = failedSS;
2477 ssFailureList = ssFailureList.concat(","+failedSS);
2481 if(ssFailureList == null){
2482 ssFailureList = "UnknownSubSystem";
2484 response.addHeader("X-ONAP-SubsystemFailure", ssFailureList);
2485 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
2491 * Authorizing the PEP Requests.
2493 private boolean authorizeRequest(HttpServletRequest request) {
2494 String clientCredentials = request.getHeader(ENVIRONMENT_HEADER);
2495 // Check if the Client is Authorized.
2496 if(clientCredentials!=null && clientCredentials.equalsIgnoreCase(environment)){
2503 private static void loadWebapps() throws PAPException{
2504 if(actionHome == null || configHome == null){
2505 Path webappsPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS));
2507 if (webappsPath == null) {
2508 PolicyLogger.error("Invalid Webapps Path Location property : " + XACMLRestProperties.PROP_PAP_WEBAPPS);
2509 throw new PAPException("Invalid Webapps Path Location property : " + XACMLRestProperties.PROP_PAP_WEBAPPS);
2511 Path webappsPathConfig = Paths.get(webappsPath.toString()+File.separator+"Config");
2512 Path webappsPathAction = Paths.get(webappsPath.toString()+File.separator+"Action");
2513 if (Files.notExists(webappsPathConfig)) {
2515 Files.createDirectories(webappsPathConfig);
2516 } catch (IOException e) {
2517 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Failed to create config directory: "
2518 + webappsPathConfig.toAbsolutePath().toString());
2521 if (Files.notExists(webappsPathAction)) {
2523 Files.createDirectories(webappsPathAction);
2524 } catch (IOException e) {
2525 LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to create config directory: "
2526 + webappsPathAction.toAbsolutePath().toString(), e);
2529 actionHome = webappsPathAction.toString();
2530 configHome = webappsPathConfig.toString();
2534 public static String getConfigHome(){
2537 } catch (PAPException e) {
2544 private static void setConfigHome(){
2545 configHome = getConfigHome();
2548 public static String getActionHome(){
2551 } catch (PAPException e) {
2558 private static void setActionHome(){
2559 actionHome = getActionHome();
2562 public static EntityManagerFactory getEmf() {
2566 public IntegrityAudit getIa() {
2570 public static String getPDPFile(){
2571 return XACMLPapServlet.pdpFile;
2574 public static String getPersistenceUnit(){
2575 return PERSISTENCE_UNIT;
2578 public static PAPPolicyEngine getPAPEngine(){
2582 public static PolicyDBDaoTransaction getDbDaoTransaction(){
2583 return policyDBDao.getNewTransaction();
2585 public static String getPapDbDriver() {
2589 public static void setPapDbDriver(String papDbDriver) {
2590 XACMLPapServlet.papDbDriver = papDbDriver;
2593 public static String getPapDbUrl() {
2597 public static void setPapDbUrl(String papDbUrl) {
2598 XACMLPapServlet.papDbUrl = papDbUrl;
2601 public static String getPapDbUser() {
2605 public static void setPapDbUser(String papDbUser) {
2606 XACMLPapServlet.papDbUser = papDbUser;
2609 public static String getPapDbPassword() {
2610 return papDbPassword;
2613 public static void setPapDbPassword(String papDbPassword) {
2614 XACMLPapServlet.papDbPassword = papDbPassword;
2617 public static String getMsOnapName() {
2621 public static void setMsOnapName(String msOnapName) {
2622 XACMLPapServlet.msOnapName = msOnapName;
2625 public static String getMsPolicyName() {
2626 return msPolicyName;
2629 public static void setMsPolicyName(String msPolicyName) {
2630 XACMLPapServlet.msPolicyName = msPolicyName;