2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.pdp.xacml.application.common;
23 import com.att.research.xacml.std.IdentifierImpl;
24 import com.att.research.xacml.std.StdStatusCode;
25 import com.att.research.xacml.std.StdVersion;
26 import com.att.research.xacml.std.dom.DOMStructureException;
27 import com.att.research.xacml.util.FactoryException;
28 import com.att.research.xacml.util.XACMLProperties;
29 import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm;
30 import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory;
31 import com.att.research.xacmlatt.pdp.policy.Policy;
32 import com.att.research.xacmlatt.pdp.policy.PolicyDef;
33 import com.att.research.xacmlatt.pdp.policy.PolicyFinder;
34 import com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory;
35 import com.att.research.xacmlatt.pdp.policy.PolicySet;
36 import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
37 import com.att.research.xacmlatt.pdp.policy.Target;
38 import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef;
39 import com.att.research.xacmlatt.pdp.std.StdPolicyFinder;
40 import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
41 import com.google.common.base.Splitter;
42 import com.google.common.base.Strings;
44 import java.util.ArrayList;
45 import java.util.Collections;
46 import java.util.List;
47 import java.util.Properties;
48 import java.util.UUID;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
53 * Implements ONAP specific ability to find Policies for XACML PDP engine.
55 * @author pameladragosh
58 public class OnapPolicyFinderFactory extends PolicyFinderFactory {
60 public static final String PROP_FILE = ".file";
61 public static final String PROP_URL = ".url";
63 private static Logger logger = LoggerFactory.getLogger(OnapPolicyFinderFactory.class);
64 private List<PolicyDef> rootPolicies;
65 private List<PolicyDef> referencedPolicies;
66 private boolean needsInit = true;
68 private Properties properties;
71 * Empty private constructor. We do not want to create
72 * an instance of this without giving Properties object.
74 * @throws OnapPolicyFinderFactoryException Exception will be thrown
76 public OnapPolicyFinderFactory() throws OnapPolicyFinderFactoryException {
77 throw new OnapPolicyFinderFactoryException("Please use the constructor with Properties object.");
81 * Constructor with properties passed. This will be preferred.
83 * @param properties Properties object
85 public OnapPolicyFinderFactory(Properties properties) {
87 logger.info("Constructed using properties {}", properties);
89 // Save our properties
91 this.properties = properties;
93 // Here we differ from the StdPolicyFinderFactory in that we initialize right away.
94 // We do not wait for a policy request to happen to look for and load policies.
100 * Loads the <code>PolicyDef</code> for the given <code>String</code> identifier by looking first
101 * for a ".file" property associated with the ID and using that to load from a <code>File</code> and
102 * looking for a ".url" property associated with the ID and using that to load from a <code>URL</code>.
104 * @param policyId the <code>String</code> identifier for the policy
105 * @return a <code>PolicyDef</code> loaded from the given identifier
107 protected PolicyDef loadPolicyDef(String policyId) {
108 String propLocation = this.properties.getProperty(policyId + PROP_FILE);
109 if (propLocation != null) {
111 // Try to load it from the file
113 PolicyDef policy = this.loadPolicyFileDef(propLocation);
114 if (policy != null) {
119 logger.error("No known location for Policy {}", policyId);
123 protected PolicyDef loadPolicyFileDef(String propLocation) {
124 var fileLocation = new File(propLocation);
125 if (!fileLocation.exists()) {
126 logger.error("Policy file {} does not exist.", fileLocation.getAbsolutePath());
129 if (!fileLocation.canRead()) {
130 logger.error("Policy file {} cannot be read.", fileLocation.getAbsolutePath());
134 logger.info("Loading policy file {}", fileLocation);
135 var policyDef = DOMPolicyDef.load(fileLocation);
136 if (policyDef != null) {
139 return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "DOM Could not load policy");
140 } catch (DOMStructureException ex) {
141 logger.error("Error loading policy file {}", fileLocation.getAbsolutePath(), ex);
142 return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
147 * Finds the identifiers for all of the policies referenced by the given property name in the
148 * <code>XACMLProperties</code> and loads them using the requested loading method.
150 * @param propertyName the <code>String</code> name of the property containing the list of policy identifiers
151 * @return a <code>List</code> of <code>PolicyDef</code>s loaded from the given property name
153 protected List<PolicyDef> getPolicyDefs(String propertyName) {
154 String policyIds = this.properties.getProperty(propertyName);
155 if (Strings.isNullOrEmpty(policyIds)) {
156 return Collections.emptyList();
159 Iterable<String> policyIdArray = Splitter.on(',').trimResults().omitEmptyStrings().split(policyIds);
160 if (policyIdArray == null) {
161 return Collections.emptyList();
164 List<PolicyDef> listPolicyDefs = new ArrayList<>();
165 for (String policyId : policyIdArray) {
166 var policyDef = this.loadPolicyDef(policyId);
167 if (policyDef != null) {
168 listPolicyDefs.add(policyDef);
171 return listPolicyDefs;
174 protected synchronized void init() {
175 if (! this.needsInit) {
176 logger.info("Does not need initialization");
179 logger.info("Initializing OnapPolicyFinderFactory Properties ");
182 // Check for property that combines root policies into one policyset
184 String combiningAlgorithm = properties.getProperty(
185 ATTPDPProperties.PROP_POLICYFINDERFACTORY_COMBINEROOTPOLICIES);
186 if (combiningAlgorithm != null) {
188 logger.info("Combining root policies with {}", combiningAlgorithm);
190 // Find the combining algorithm
192 CombiningAlgorithm<PolicySetChild> algorithm = CombiningAlgorithmFactory.newInstance()
193 .getPolicyCombiningAlgorithm(new IdentifierImpl(combiningAlgorithm));
195 // Create our root policy
197 var root = new PolicySet();
198 root.setIdentifier(new IdentifierImpl(UUID.randomUUID().toString()));
199 root.setVersion(StdVersion.newInstance("1.0"));
200 root.setTarget(new Target());
204 root.setPolicyCombiningAlgorithm(algorithm);
206 // Load all our root policies
208 for (PolicyDef policy : this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES)) {
209 root.addChild(policy);
212 // Set this policy as the root
214 this.rootPolicies = new ArrayList<>();
215 this.rootPolicies.add(root);
216 } catch (Exception e) {
217 logger.error("Failed to load Combining Algorithm Factory", e);
220 logger.info("Loading root policies");
221 this.rootPolicies = this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES);
223 this.referencedPolicies = this.getPolicyDefs(XACMLProperties.PROP_REFERENCEDPOLICIES);
224 logger.info("Root Policies: {}", this.rootPolicies.size());
225 logger.info("Referenced Policies: {}", this.referencedPolicies.size());
227 // Make sure we set that we don't need initialization
229 this.needsInit = false;
233 public PolicyFinder getPolicyFinder() throws FactoryException {
235 // Force using any properties that were passed upon construction
237 return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, this.properties);
241 public PolicyFinder getPolicyFinder(Properties properties) throws FactoryException {
242 return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, properties);