Fix knock on tabs/SONAR/Checkstyle issues
[policy/engine.git] / ONAP-PDP-REST / src / main / java / org / onap / policy / pdp / rest / XACMLPdpLoader.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-PDP-REST
4  * ================================================================================
5  * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2019 Nordix Foundation.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.pdp.rest;
23
24 import com.att.research.xacml.api.pap.PAPException;
25 import com.att.research.xacml.api.pap.PDPStatus;
26 import com.att.research.xacml.api.pap.PDPStatus.Status;
27 import com.att.research.xacml.api.pdp.PDPEngine;
28 import com.att.research.xacml.api.pdp.PDPEngineFactory;
29 import com.att.research.xacml.api.pip.PIPEngine;
30 import com.att.research.xacml.api.pip.PIPException;
31 import com.att.research.xacml.api.pip.PIPFinder;
32 import com.att.research.xacml.api.pip.PIPFinderFactory;
33 import com.att.research.xacml.util.FactoryException;
34 import com.att.research.xacml.util.XACMLProperties;
35 import com.att.research.xacmlatt.pdp.policy.PolicyDef;
36 import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef;
37 import com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory;
38 import com.google.common.base.Splitter;
39
40 import java.io.FileOutputStream;
41 import java.io.IOException;
42 import java.io.InputStream;
43 import java.io.OutputStream;
44 import java.net.MalformedURLException;
45 import java.net.URI;
46 import java.net.URL;
47 import java.net.URLConnection;
48 import java.nio.charset.StandardCharsets;
49 import java.nio.file.Files;
50 import java.nio.file.Path;
51 import java.nio.file.Paths;
52 import java.util.Base64;
53 import java.util.ConcurrentModificationException;
54 import java.util.HashMap;
55 import java.util.Properties;
56 import java.util.Set;
57
58 import org.apache.commons.io.IOUtils;
59 import org.onap.policy.common.logging.flexlogger.FlexLogger;
60 import org.onap.policy.common.logging.flexlogger.Logger;
61 import org.onap.policy.pdp.rest.notifications.NotificationController;
62 import org.onap.policy.rest.XacmlRest;
63 import org.onap.policy.rest.XacmlRestProperties;
64 import org.onap.policy.xacml.api.XACMLErrorConstants;
65 import org.onap.policy.xacml.std.pap.StdPDPPIPConfig;
66 import org.onap.policy.xacml.std.pap.StdPDPPolicy;
67 import org.onap.policy.xacml.std.pap.StdPDPStatus;
68
69 /**
70  * Does the work for loading policy and PIP configurations sent from the PAP servlet.
71  */
72 public class XACMLPdpLoader {
73     private static final Logger LOGGER = FlexLogger.getLogger(XACMLPdpLoader.class);
74
75     // Repeated string constants.
76     private static final String DOES_NOT_EXIST = " does NOT exist.";
77     private static final String CORRUPTED_POLICY_FILE_DELETING = "Corrupted policy file, deleting: ";
78     private static final String DOT_FILE = ".file";
79
80     private static NotificationController notificationController = new NotificationController();
81     private static final Long notifyDelay = (long) XACMLPdpServlet.getNotificationDelay();
82
83     public static synchronized PDPEngine loadEngine(StdPDPStatus status, Properties policyProperties,
84             Properties pipProperties) {
85         LOGGER.info("loadEngine: " + policyProperties + " " + pipProperties);
86         //
87         // First load our policies
88         //
89         try {
90             //
91             // Were we given some properties?
92             //
93             if (policyProperties == null) {
94                 //
95                 // On init we have no incoming configuration, so just
96                 // Load our current saved configuration
97                 //
98                 policyProperties = new Properties();
99                 try (InputStream is = Files.newInputStream(getPDPPolicyCache())) {
100                     policyProperties.load(is);
101                 }
102             }
103
104             //
105             // Get our policy cache up-to-date
106             //
107             // Side effects of this include:
108             // - downloading of policies from remote locations, and
109             // - creating new "<PolicyId>.file" properties for files existing
110             // local
111             //
112             LOGGER.info("XACMLPdpLoader: cache the policies.");
113             XACMLPdpLoader.cachePolicies(policyProperties);
114             //
115             // Validate the policies
116             //
117             LOGGER.info("XACMLPdpLoader: validating the policies.");
118             XACMLPdpLoader.validatePolicies(policyProperties, status);
119             if (LOGGER.isDebugEnabled()) {
120                 LOGGER.debug("Status: " + status);
121             }
122         } catch (ConcurrentModificationException e) {
123             LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e.getMessage() + e);
124         } catch (Exception e) {
125             String error = "Failed to load Policy Cache properties file: " + e.getMessage();
126             LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + error, e);
127             status.addLoadError(error);
128             status.setStatus(PDPStatus.Status.LOAD_ERRORS);
129         }
130         //
131         // Load our PIP configuration
132         //
133         try {
134             //
135             // Were we given some properties to use?
136             //
137             if (pipProperties == null) {
138                 //
139                 // Load our current saved configuration
140                 //
141                 pipProperties = new Properties();
142                 try (InputStream is = Files.newInputStream(getPIPConfig())) {
143                     pipProperties.load(is);
144                 }
145             }
146             //
147             // Validate our PIP configurations
148             //
149             XACMLPdpLoader.validatePipConfiguration(pipProperties, status);
150             if (LOGGER.isDebugEnabled()) {
151                 LOGGER.debug("Status: " + status);
152             }
153         } catch (Exception e) {
154             String error = "Failed to load/validate Pip Config properties file: " + e.getMessage();
155             LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + error, e);
156             status.addLoadError(XACMLErrorConstants.ERROR_PROCESS_FLOW + error);
157             status.setStatus(PDPStatus.Status.LOAD_ERRORS);
158         }
159         //
160         // Were they validated?
161         //
162         if (status.getStatus() == Status.LOAD_ERRORS) {
163             LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "there were load errors");
164             return null;
165         }
166         //
167         // Reset our official properties the PDP factory
168         // uses to configure the PDP engine.
169         //
170         XacmlRest.loadXacmlProperties(policyProperties, pipProperties);
171         //
172         // Dump ALL our properties that we are trying to load
173         //
174         try {
175             LOGGER.info(XACMLProperties.getProperties().toString());
176         } catch (IOException e) {
177             LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to get XACML Properties", e);
178         }
179         //
180         // Now load the PDP engine
181         //
182         PDPEngineFactory factory = null;
183         PDPEngine engine = null;
184         try {
185             factory = PDPEngineFactory.newInstance();
186             engine = factory.newEngine();
187             LOGGER.info("Loaded new PDP engine.");
188             status.setStatus(Status.UP_TO_DATE);
189         } catch (FactoryException e) {
190             String error = "Failed to create new PDP Engine";
191             LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + error, e);
192             status.addLoadError(error);
193         }
194         return engine;
195     }
196
197     private static HashMap<String, PolicyDef> policyContainer = null;
198
199     /**
200      * Thread for sending notifications.
201      */
202     public static synchronized void sendNotification() {
203         Thread notify = new Thread() {
204             @Override
205             public void run() {
206                 try {
207                     Thread.sleep(notifyDelay);
208                     NotificationController.sendNotification();
209                 } catch (Exception e) {
210                     LOGGER.error(XACMLErrorConstants.ERROR_UNKNOWN + e);
211                 }
212             }
213         };
214         notify.start();
215     }
216
217     /**
218      * Method to validate policies.
219      *
220      * @param properties The properties of the policies
221      * @param status the PDP status
222      * @throws PAPException on validation errors
223      */
224     public static synchronized void validatePolicies(Properties properties, StdPDPStatus status) throws PAPException {
225         Set<String> rootPolicies = XACMLProperties.getRootPolicyIDs(properties);
226         policyContainer = new HashMap<>();
227
228         LOGGER.info("XACMLPdpLoader: load rootPolicies");
229         for (String id : rootPolicies) {
230             loadPolicy(properties, status, id, true);
231         }
232         // remember which policies were root policies
233         status.addAllLoadedRootPolicies(status.getLoadedPolicies());
234         LOGGER.info("XACMLPdpLoader: load referencedPolicies");
235         Set<String> refPolicies = XACMLProperties.getReferencedPolicyIDs(properties);
236         for (String id : refPolicies) {
237             loadPolicy(properties, status, id, false);
238         }
239         LOGGER.info("Loaded " + status.getLoadedPolicies().size() + " policies, failed to load "
240                 + status.getFailedPolicies().size() + " policies, " + status.getLoadedRootPolicies().size()
241                 + " root policies");
242         notificationController.check(status, policyContainer);
243         if (status.getLoadedRootPolicies().isEmpty()) {
244             LOGGER.warn(
245                     XACMLErrorConstants.ERROR_PROCESS_FLOW + "NO ROOT POLICIES LOADED!!!  Cannot serve PEP Requests.");
246             status.addLoadWarning("NO ROOT POLICIES LOADED!!!  Cannot serve PEP Requests.");
247         }
248         policyContainer.clear();
249     }
250
251     /**
252      * Load a policy.
253      *
254      * @param properties the policy properties
255      * @param status the PDP status
256      * @param id the policy ID
257      * @param isRoot indicates if operation being done as root
258      * @throws PAPException on loading errors
259      */
260     public static synchronized void loadPolicy(Properties properties, StdPDPStatus status, String id, boolean isRoot)
261             throws PAPException {
262         PolicyDef policy = null;
263         String location = null;
264         URI locationUri = null;
265         boolean isFile = false;
266         boolean rougeFile = false;
267         try {
268             location = properties.getProperty(id + DOT_FILE);
269             if (location != null) {
270                 isFile = true;
271                 locationUri = Paths.get(location).toUri();
272                 try (InputStream is = Files.newInputStream(Paths.get(location))) {
273                     policy = DOMPolicyDef.load(is);
274                 } catch (Exception e) {
275                     // This Happens if a any issue with the error policyFile. Lets remove it.
276                     try {
277                         LOGGER.error(CORRUPTED_POLICY_FILE_DELETING + location + e);
278                         Files.delete(Paths.get(location));
279                         properties.remove(id + DOT_FILE);
280                         rougeFile = true;
281                     } catch (IOException e1) {
282                         LOGGER.error(e1);
283                     }
284                 }
285             }
286             if (location == null || rougeFile) {
287                 if (rougeFile) {
288                     rougeFile = false;
289                 }
290                 location = properties.getProperty(id + ".url");
291                 if (location != null) {
292                     //
293                     // Construct the URL
294                     //
295                     int errorCount = 0;
296                     boolean error = false;
297                     do {
298                         error = false;
299                         PapUrlResolver papUrls = PapUrlResolver.getInstance();
300                         while (papUrls.hasMoreUrls()) {
301                             String papID = papUrls.getUserId();
302                             String papPass = papUrls.getPass();
303                             Base64.Encoder encoder = Base64.getEncoder();
304                             locationUri = URI.create(papUrls.getUrl(PapUrlResolver.extractIdFromUrl(location)));
305                             URL url = locationUri.toURL();
306                             URLConnection urlConnection = null;
307                             try {
308                                 urlConnection = url.openConnection();
309                             } catch (IOException e) {
310                                 LOGGER.error("Exception Occured while opening connection" + e);
311                                 papUrls.failed();
312                                 papUrls.getNext();
313                                 break;
314                             }
315                             String encoding =
316                                     encoder.encodeToString((papID + ":" + papPass).getBytes(StandardCharsets.UTF_8));
317                             urlConnection.setRequestProperty(XacmlRestProperties.PROP_PDP_HTTP_HEADER_ID,
318                                     XACMLProperties.getProperty(XacmlRestProperties.PROP_PDP_ID));
319                             urlConnection.setRequestProperty("Authorization", "Basic " + encoding);
320                             //
321                             // Now construct the output file name
322                             //
323                             Path outFile = Paths.get(getPDPConfig().toAbsolutePath().toString(), id);
324                             //
325                             // Copy it to disk
326                             //
327                             try (FileOutputStream fos = new FileOutputStream(outFile.toFile())) {
328                                 IOUtils.copy(urlConnection.getInputStream(), fos);
329                             } catch (IOException e) {
330                                 LOGGER.error("Exception Occured while Copying  input stream" + e);
331                                 papUrls.failed();
332                                 papUrls.getNext();
333                                 break;
334                             }
335                             //
336                             // Now try to load
337                             //
338                             isFile = true;
339                             try (InputStream fis = Files.newInputStream(outFile)) {
340                                 policy = DOMPolicyDef.load(fis);
341                             } catch (Exception e) {
342                                 try {
343                                     LOGGER.error(CORRUPTED_POLICY_FILE_DELETING + location + e);
344                                     Files.delete(outFile);
345                                     error = true;
346                                     errorCount++;
347                                     break;
348                                 } catch (IOException e1) {
349                                     LOGGER.error(e1);
350                                 }
351                             }
352                             //
353                             // Save it
354                             //
355                             properties.setProperty(id + DOT_FILE, outFile.toAbsolutePath().toString());
356                             error = false;
357                             break;
358                         }
359                     }
360                     while (error && errorCount > 2);
361                 }
362             }
363             if (policy != null) {
364                 status.addLoadedPolicy(new StdPDPPolicy(id, isRoot, locationUri, properties));
365                 LOGGER.info(
366                         "Loaded policy: " + policy.getIdentifier() + " version: " + policy.getVersion().stringValue());
367                 // Sending the policy objects to the Notification Controller.
368                 policyContainer.put(id, policy);
369             } else {
370                 String error = "Failed to load policy " + location;
371                 LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + error);
372                 status.setStatus(PDPStatus.Status.LOAD_ERRORS);
373                 status.addLoadError(error);
374                 status.addFailedPolicy(new StdPDPPolicy(id, isRoot));
375             }
376         } catch (Exception e) {
377             LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to load policy '" + id + "' from location '"
378                     + location + "'", e);
379             status.setStatus(PDPStatus.Status.LOAD_ERRORS);
380             status.addFailedPolicy(new StdPDPPolicy(id, isRoot));
381             //
382             // Is it a file?
383             //
384             if (isFile) {
385                 //
386                 // Let's remove it
387                 //
388                 try {
389                     LOGGER.error(
390                             XACMLErrorConstants.ERROR_PROCESS_FLOW + CORRUPTED_POLICY_FILE_DELETING + location);
391                     Files.delete(Paths.get(location));
392
393                 } catch (IOException e1) {
394                     LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e1);
395                 }
396             }
397         }
398     }
399
400     /**
401      * Validate PIP configuration.
402      *
403      * @param properties the properties to validate
404      * @param status the PDP status
405      * @throws PAPException on validation exceptions
406      */
407     public static synchronized void validatePipConfiguration(Properties properties, StdPDPStatus status)
408             throws PAPException {
409         try {
410             PIPFinderFactory factory = PIPFinderFactory.newInstance(properties);
411             if (factory == null) {
412                 throw new FactoryException("Could not create PIP Finder Factory: "
413                         + properties.getProperty(XACMLProperties.PROP_PIPFINDERFACTORY));
414             }
415             PIPFinder finder = factory.getFinder(properties);
416             //
417             // Check for this, although it should always return something
418             //
419             if (finder == null) {
420                 LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "pip finder factory returned a null engine.");
421                 throw new PIPException("Could not create PIP Finder");
422             } else {
423                 LOGGER.info("Loaded PIP finder");
424             }
425             for (PIPEngine engine : finder.getPIPEngines()) {
426                 LOGGER.info("Configured PIP Engine: " + engine.getName());
427                 StdPDPPIPConfig config = new StdPDPPIPConfig();
428                 config.setName(engine.getName());
429                 status.addLoadedPipConfig(config);
430             }
431         } catch (FactoryException | PIPException e) {
432             LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "validate PIP configuration failed: "
433                     + e.getLocalizedMessage());
434             status.addLoadError(e.getLocalizedMessage());
435             status.setStatus(Status.LOAD_ERRORS);
436             throw new PAPException(e);
437         }
438     }
439
440     /**
441      * Iterates the policies defined in the props object to ensure they are loaded locally. Policies are searched for in
442      * the following order: - see if the current properties has a "&lt;PolicyID&gt;.file" entry and that file exists in
443      * the local directory - if not, see if the file exists in the local directory; if so create a ".file" property for
444      * it. - if not, get the "&lt;PolicyID&gt;.url" property and try to GET the policy from that location (and set the
445      * ".file" property)
446      *
447      * <p>If the ".file" property is created, then true is returned to tell the caller that the props object changed.
448      *
449      * @param props the properties to cache
450      * @return true/false if anything was changed in the props object
451      * @throws PAPException on cacheing exceptions
452      */
453     public static synchronized boolean cachePolicies(Properties props) throws PAPException {
454         boolean changed = false;
455         String[] lists = new String[2];
456         lists[0] = props.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
457         lists[1] = props.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
458         for (String list : lists) {
459             //
460             // Check for a null or empty parameter
461             //
462             if (list == null || list.length() == 0) {
463                 continue;
464             }
465             Iterable<String> policies = Splitter.on(',').trimResults().omitEmptyStrings().split(list);
466             for (String policy : policies) {
467                 boolean policyExists = false;
468
469                 // First look for ".file" property and verify the file exists
470                 String propLocation = props.getProperty(policy + StdPolicyFinderFactory.PROP_FILE);
471                 if (propLocation != null) {
472                     //
473                     // Does it exist?
474                     //
475                     policyExists = Paths.get(propLocation).toFile().exists();
476                     if (!policyExists) {
477                         LOGGER.warn(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Policy file " + policy + " expected at "
478                                 + propLocation + DOES_NOT_EXIST);
479                     }
480                 }
481
482                 // If ".file" property does not exist, try looking for the local
483                 // file anyway
484                 // (it might exist without having a ".file" property set for it)
485                 if (!policyExists) {
486                     //
487                     // Now construct the output file name
488                     //
489                     Path outFile = Paths.get(getPDPConfig().toAbsolutePath().toString(), policy);
490                     //
491                     // Double check to see if we pulled it at some point
492                     //
493                     policyExists = outFile.toFile().exists();
494                     if (policyExists) {
495                         //
496                         // Set the property so the PDP engine doesn't have
497                         // to pull it from the URL but rather the FILE.
498                         //
499                         LOGGER.info("Policy does exist: " + outFile.toAbsolutePath().toString());
500                         props.setProperty(policy + StdPolicyFinderFactory.PROP_FILE,
501                                 outFile.toAbsolutePath().toString());
502                         //
503                         // Indicate that there were changes made to the
504                         // properties
505                         //
506                         changed = true;
507                     } else {
508
509                         // File does not exist locally, so we need to get it
510                         // from the location given in the ".url" property (which
511                         // MUST exist)
512
513                         //
514                         // There better be a URL to retrieve it
515                         //
516                         propLocation = props.getProperty(policy + StdPolicyFinderFactory.PROP_URL);
517                         if (propLocation != null) {
518                             //
519                             // Get it
520                             //
521                             PapUrlResolver papUrls = PapUrlResolver.getInstance();
522                             while (papUrls.hasMoreUrls()) {
523                                 String papID = papUrls.getUserId();
524                                 String papPass = papUrls.getPass();
525                                 Base64.Encoder encoder = Base64.getEncoder();
526                                 String encoding = encoder
527                                         .encodeToString((papID + ":" + papPass).getBytes(StandardCharsets.UTF_8));
528                                 URL url = null;
529                                 try {
530                                     //
531                                     // Create the URL
532                                     //
533                                     url = new URL(papUrls.getUrl(PapUrlResolver.extractIdFromUrl(propLocation)));
534                                     LOGGER.info("Pulling " + url.toString());
535                                     //
536                                     // Open the connection
537                                     //
538                                     URLConnection urlConnection = url.openConnection();
539                                     urlConnection.setRequestProperty(XacmlRestProperties.PROP_PDP_HTTP_HEADER_ID,
540                                             XACMLProperties.getProperty(XacmlRestProperties.PROP_PDP_ID));
541                                     urlConnection.setRequestProperty("Authorization", "Basic " + encoding);
542                                     //
543                                     // Copy it to disk
544                                     //
545                                     try (InputStream is = urlConnection.getInputStream();
546                                             OutputStream os = new FileOutputStream(outFile.toFile())) {
547                                         IOUtils.copy(is, os);
548                                     }
549                                     //
550                                     // Now save it in the properties as a .file
551                                     //
552                                     LOGGER.info("Pulled policy: " + outFile.toAbsolutePath().toString());
553                                     props.setProperty(policy + StdPolicyFinderFactory.PROP_FILE,
554                                             outFile.toAbsolutePath().toString());
555                                     papUrls.succeeded();
556                                     //
557                                     // Indicate that there were changes made to the
558                                     // properties
559                                     //
560                                     changed = true;
561                                 } catch (MalformedURLException e) {
562                                     papUrls.failed();
563                                     LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Policy '" + policy
564                                             + "' had bad URL in new configuration, URL='" + propLocation + "'");
565                                 } catch (Exception e) {
566                                     papUrls.failed();
567                                     LOGGER.error(
568                                             XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while retrieving policy "
569                                                     + policy + " from URL " + url + ", e=" + e);
570                                 }
571                                 papUrls.getNext();
572                             }
573                         } else {
574                             LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Policy " + policy
575                                     + " does NOT exist and does NOT have a URL");
576                         }
577                     }
578                 }
579             }
580         }
581         return changed;
582     }
583
584     /**
585      * Get the PDP policy cache.
586      *
587      * @return  the PDP policy cache
588      * @throws PAPException on cache get errors
589      */
590     public static synchronized Path getPDPPolicyCache() throws PAPException {
591         Path config = getPDPConfig();
592         Path policyProperties = Paths.get(config.toAbsolutePath().toString(), "xacml.policy.properties");
593         if (!policyProperties.toFile().exists()) {
594             LOGGER.warn(XACMLErrorConstants.ERROR_PROCESS_FLOW + policyProperties.toAbsolutePath().toString()
595                     + DOES_NOT_EXIST);
596             //
597             // Try to create the file
598             //
599             try {
600                 Files.createFile(policyProperties);
601             } catch (IOException e) {
602                 LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to create policy properties file: "
603                         + policyProperties.toAbsolutePath().toString() + e);
604                 throw new PAPException(
605                         "Failed to create policy properties file: " + policyProperties.toAbsolutePath().toString());
606             }
607         }
608         return policyProperties;
609     }
610
611     /**
612      * Get the PIP configuration.
613      *
614      * @return the PIP configuration
615      * @throws PAPException on get exceptions
616      */
617     public static synchronized Path getPIPConfig() throws PAPException {
618         Path config = getPDPConfig();
619         Path pipConfigProperties = Paths.get(config.toAbsolutePath().toString(), "xacml.pip.properties");
620         if (!pipConfigProperties.toFile().exists()) {
621             LOGGER.warn(XACMLErrorConstants.ERROR_PROCESS_FLOW + pipConfigProperties.toAbsolutePath().toString()
622                     + DOES_NOT_EXIST);
623             //
624             // Try to create the file
625             //
626             try {
627                 Files.createFile(pipConfigProperties);
628             } catch (IOException e) {
629                 LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to create pip properties file: "
630                         + pipConfigProperties.toAbsolutePath().toString() + e);
631                 throw new PAPException(
632                         "Failed to create pip properties file: " + pipConfigProperties.toAbsolutePath().toString());
633             }
634         }
635         return pipConfigProperties;
636     }
637
638     /**
639      * Get the PDP configuration.
640      *
641      * @return the PDP configuration
642      * @throws PAPException on get exceptions
643      */
644     public static synchronized Path getPDPConfig() throws PAPException {
645         Path config = Paths.get(XACMLProperties.getProperty(XacmlRestProperties.PROP_PDP_CONFIG));
646         if (!config.toFile().exists()) {
647             LOGGER.warn(
648                     XACMLErrorConstants.ERROR_PROCESS_FLOW + config.toAbsolutePath().toString() + DOES_NOT_EXIST);
649             //
650             // Try to create the directory
651             //
652             try {
653                 Files.createDirectories(config);
654             } catch (IOException e) {
655                 LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to create config directory: "
656                         + config.toAbsolutePath().toString(), e);
657                 throw new PAPException("Failed to create config directory: " + config.toAbsolutePath().toString());
658             }
659         }
660         return config;
661     }
662
663 }