Format ONAP-XACML and add JUnit
[policy/engine.git] / ONAP-XACML / src / main / java / org / onap / policy / xacml / std / pap / StdPDPPolicy.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-XACML
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * Modified Copyright (C) 2018 Samsung Electronics Co., Ltd.
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.xacml.std.pap;
23
24 import com.att.research.xacml.api.pap.PAPException;
25 import com.att.research.xacml.api.pap.PDPPolicy;
26 import com.fasterxml.jackson.annotation.JsonIgnore;
27 import com.google.common.base.Splitter;
28 import com.google.common.collect.Lists;
29
30 import java.io.FileNotFoundException;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.io.Serializable;
34 import java.net.URI;
35 import java.net.URL;
36 import java.util.ArrayList;
37 import java.util.Properties;
38
39 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
40 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
41
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
44 import org.onap.policy.common.logging.eelf.PolicyLogger;
45 import org.onap.policy.xacml.util.XACMLPolicyScanner;
46
47 public class StdPDPPolicy implements PDPPolicy, Serializable {
48     private static final long serialVersionUID = 1L;
49     private static Log logger = LogFactory.getLog(StdPDPPolicy.class);
50
51     private String id = null;
52
53     private String name = null;
54
55     private String policyId = null;
56
57     private String description = null;
58
59     private int[] version = null;
60
61     private boolean isRoot = false;
62
63     private boolean isValid = false;
64
65     private URI location = null;
66
67     public StdPDPPolicy() {
68         //
69         // Methods needed for JSON Deserialization
70         //
71     }
72
73     public StdPDPPolicy(String id, boolean isRoot) {
74         this.id = id;
75         this.isRoot = isRoot;
76     }
77
78     public StdPDPPolicy(String id, boolean isRoot, String name) {
79         this(id, isRoot);
80         this.name = name;
81     }
82
83     /**
84      * StdPDPPolicy.
85      *
86      * @param id String
87      * @param isRoot boolean
88      * @param name String
89      * @param location URI
90      * @throws IOException IOException
91      */
92     public StdPDPPolicy(String id, boolean isRoot, String name, URI location) throws IOException {
93         this(id, isRoot);
94         this.name = name;
95         this.location = location;
96
97         //
98         // Read the policy data
99         //
100         String theID = this.readPolicyData();
101
102         if (this.id == null) {
103             logger.debug("id is null so we are calling readPolicyData() to get the policyID");
104             this.id = theID;
105         }
106
107         logger.debug("The final outcome of the constructor returned the following:  id = " + id + ", location = "
108                 + location + ", name = " + name);
109
110     }
111
112     /**
113      * StdPDPPolicy constructor.
114      *
115      * @param stdPDPPolicyParams StdPDPPolicyParams
116      * @throws IOException IOException
117      */
118     public StdPDPPolicy(StdPDPPolicyParams stdPDPPolicyParams) throws IOException {
119         this(stdPDPPolicyParams.getId(), stdPDPPolicyParams.isRoot());
120         this.name = stdPDPPolicyParams.getName();
121         this.location = stdPDPPolicyParams.getLocation();
122         this.policyId = stdPDPPolicyParams.getPolicyId();
123         this.description = stdPDPPolicyParams.getDescription();
124         this.version = versionStringToArray(stdPDPPolicyParams.getVersion());
125         this.isValid = stdPDPPolicyParams.isValid();
126
127         logger.debug("The final outcome of the constructor returned the following:  id = " + stdPDPPolicyParams.getId()
128                 + ", location = " + stdPDPPolicyParams.getLocation() + ", name = " + stdPDPPolicyParams.getName()
129                 + ", policyId = " + stdPDPPolicyParams.getPolicyId() + ", description = "
130                 + stdPDPPolicyParams.getDescription() + ", Version = " + stdPDPPolicyParams.getVersion());
131
132     }
133
134     /**
135      * StdPDPPolicy.
136      *
137      * @param id String
138      * @param isRoot boolean
139      * @param name String
140      * @param location URI
141      * @param isFromAPI boolean
142      * @throws IOException IOException
143      */
144     public StdPDPPolicy(String id, boolean isRoot, String name, URI location, boolean isFromAPI) throws IOException {
145         this(id, isRoot);
146         this.name = name;
147         this.location = location;
148         this.isValid = isFromAPI;
149
150         logger.debug("The final outcome of the constructor returned the following:  id = " + id + ", location = "
151                 + location + ", name = " + name);
152
153     }
154
155     /**
156      * StdPDPPolicy.
157      *
158      * @param id String
159      * @param isRoot boolean
160      * @param location URI
161      * @param properties boolean
162      * @throws IOException IOException
163      */
164     public StdPDPPolicy(String id, boolean isRoot, URI location, Properties properties) throws IOException {
165         this(id, isRoot);
166         this.location = location;
167         //
168         // Read the policy data
169         //
170         this.readPolicyData();
171         //
172         // See if there's a name
173         //
174         for (Object key : properties.keySet()) {
175             if (key.toString().equals(id + ".name")) {
176                 this.name = properties.getProperty(key.toString());
177                 break;
178             }
179         }
180     }
181
182     private String readPolicyData() throws IOException {
183         //
184         // Extract XACML policy information
185         //
186         URL url = this.location.toURL();
187         Object rootElement = XACMLPolicyScanner.readPolicy(url.openStream());
188         if (rootElement == null || (!(rootElement instanceof PolicySetType) && !(rootElement instanceof PolicyType))) {
189             logger.warn("No root policy element in URI: " + this.location.toString() + " : " + rootElement);
190             this.isValid = false;
191         } else {
192             this.version = versionStringToArray(XACMLPolicyScanner.getVersion(rootElement));
193             if (rootElement instanceof PolicySetType) {
194                 this.policyId = ((PolicySetType) rootElement).getPolicySetId();
195                 this.description = ((PolicySetType) rootElement).getDescription();
196                 this.isValid = true;
197                 this.version = versionStringToArray(((PolicySetType) rootElement).getVersion());
198             } else if (rootElement instanceof PolicyType) {
199                 this.policyId = ((PolicyType) rootElement).getPolicyId();
200                 this.description = ((PolicyType) rootElement).getDescription();
201                 this.version = versionStringToArray(((PolicyType) rootElement).getVersion());
202                 this.isValid = true;
203             } else {
204                 PolicyLogger.error("Unknown root element: " + rootElement.getClass().getCanonicalName());
205             }
206         }
207         if (this.policyId != null) {
208             ArrayList<String> foo = Lists.newArrayList(Splitter.on(':').split(this.policyId));
209             if (!foo.isEmpty()) {
210                 return foo.get(foo.size() - 1);
211             }
212         }
213         return null;
214     }
215
216     @Override
217     public String getId() {
218         return id;
219     }
220
221     public void setId(String id) {
222         this.id = id;
223     }
224
225     @Override
226     public String getName() {
227         return this.name;
228     }
229
230     public void setName(String name) {
231         this.name = name;
232     }
233
234     @Override
235     public String getPolicyId() {
236         return this.policyId;
237     }
238
239     @Override
240     public String getDescription() {
241         return this.description;
242     }
243
244     @Override
245     public String getVersion() {
246         return versionArrayToString(this.version);
247     }
248
249     @Override
250     @JsonIgnore
251     public int[] getVersionInts() {
252         return version;
253     }
254
255     @Override
256     public boolean isRoot() {
257         return this.isRoot;
258     }
259
260     @Override
261     public boolean isValid() {
262         return this.isValid;
263     }
264
265     @Override
266     @JsonIgnore
267     public InputStream getStream() throws PAPException, IOException {
268         try {
269             if (this.location != null) {
270                 URL url = this.location.toURL();
271                 return url.openStream();
272             }
273             return null;
274         } catch (FileNotFoundException e) {
275             throw new PAPException(e);
276         }
277     }
278
279     @Override
280     public URI getLocation() throws PAPException {
281         return this.location;
282     }
283
284     @Override
285     public int hashCode() {
286         final int prime = 31;
287         int result = 1;
288         result = prime * result + ((id == null) ? 0 : id.hashCode());
289         result = prime * result + ((policyId == null) ? 0 : policyId.hashCode());
290         result = prime * result;
291         if (version != null) {
292             for (int i = 0; i < version.length; i++) {
293                 result += version[i];
294             }
295         }
296         return result;
297     }
298
299     @Override
300     public boolean equals(Object obj) {
301         if (this == obj) {
302             return true;
303         }
304         if (obj == null) {
305             return false;
306         }
307         if (getClass() != obj.getClass()) {
308             return false;
309         }
310         StdPDPPolicy other = (StdPDPPolicy) obj;
311         if (id == null) {
312             if (other.id != null) {
313                 return false;
314             }
315         } else if (!id.equals(other.id)) {
316             return false;
317         }
318         if (policyId == null) {
319             if (other.policyId != null) {
320                 return false;
321             }
322         } else if (!policyId.equals(other.policyId)) {
323             return false;
324         }
325         if (version != other.version) {
326             return false;
327         }
328         return true;
329     }
330
331     @Override
332     public String toString() {
333         return "StdPDPPolicy [id=" + id + ", name=" + name + ", policyId=" + policyId + ", description=" + description
334                 + ", version=" + this.getVersion() + ", isRoot=" + isRoot + ", isValid=" + isValid + ", location="
335                 + location + "]";
336     }
337
338     /**
339      * Given a version string consisting of integers with dots between them, convert it into an array of ints.
340      *
341      * @param version String
342      * @return int array
343      */
344     public static int[] versionStringToArray(String version) {
345         if (version == null || version.length() == 0) {
346             return new int[0];
347         }
348         String[] stringArray = version.split("\\.");
349         int[] resultArray = new int[stringArray.length];
350         for (int i = 0; i < stringArray.length; i++) {
351             resultArray[i] = Integer.parseInt(stringArray[i]);
352         }
353         return resultArray;
354     }
355
356     /**
357      * Given an array representing a version, create the corresponding dot-separated string.
358      *
359      * @param array int array
360      * @return String
361      */
362     public static String versionArrayToString(int[] array) {
363         if (array == null || array.length == 0) {
364             return "";
365         }
366         String versionString = "";
367         if (array.length > 0) {
368             versionString = "" + Integer.toString(array[0]);
369             for (int i = 1; i < array.length; i++) {
370                 versionString += "." + Integer.toString(array[i]);
371             }
372         }
373         return versionString;
374     }
375
376     public void setPolicyId(String policyId) {
377         this.policyId = policyId;
378     }
379
380     public void setDescription(String description) {
381         this.description = description;
382     }
383
384     public void setVersion(String version) {
385         this.version = versionStringToArray(version);
386     }
387
388     public void setRoot(boolean isRoot) {
389         this.isRoot = isRoot;
390     }
391
392     public void setValid(boolean isValid) {
393         this.isValid = isValid;
394     }
395
396     public void setLocation(URI location) {
397         this.location = location;
398     }
399
400 }