[Policy-17] Removed the sql scripts from sdk app
[policy/engine.git] / ECOMP-PDP-REST / src / main / java / org / openecomp / policy / pdp / rest / PapUrlResolver.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ECOMP-PDP-REST
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.openecomp.policy.pdp.rest;
22
23 import java.net.URI;
24 import java.text.DateFormat;
25 import java.text.ParseException;
26 import java.text.SimpleDateFormat;
27 import java.util.Arrays;
28 import java.util.Date;
29 import java.util.NoSuchElementException;
30 import java.util.Properties;
31
32 import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
33 import org.openecomp.policy.common.logging.flexlogger.Logger;
34 import org.openecomp.policy.rest.XACMLRestProperties;
35
36 import com.att.research.xacml.util.XACMLProperties;
37
38 public class PapUrlResolver {
39         private static final Logger LOGGER = FlexLogger.getLogger(PapUrlResolver.class);
40         //how long to keep a pap failed before making it un-failed, in milli-seconds
41         private static final long FAIL_TIMEOUT = 18000000;
42         
43         //thread locks
44         public static final Object propertyLock = new Object();
45         
46         //keeping this here for backward compatibility
47         public static String extractIdFromUrl(String url){
48                 return extractQuery(url);
49         }
50         public static String extractQuery(String url){
51                 try{
52                         return URI.create(url).getQuery();
53                 } catch(Exception e){
54                         LOGGER.error("Exception occured while extracting query. So, empty string is returned"+e);
55                         return "";
56                 }
57         }
58         public static String modifyUrl(String idUrl, String serverUrl){
59                 URI one = URI.create(idUrl);
60                 String host = one.getPath()+one.getQuery();
61                 URI two = URI.create(serverUrl);
62                 two.resolve(host);
63                 return two.toString();
64         }
65
66         //get an instance of a new PapUrlResolver, using XACMLProperties to get the url lists
67         public static PapUrlResolver getInstance(){
68                 return new PapUrlResolver(null,null,null,true);
69         }
70         
71         //get an instance of a new PapUrlResolver, using the provides strings for the url lists
72         public static PapUrlResolver getInstance(String urlList, String failedList, String succeededList){
73                 return new PapUrlResolver(urlList, failedList, succeededList,false);
74         }
75
76         //keeps track of our current location in the list of urls, allows for iterating
77         private int pointer;
78         
79         //should the XACML property lists be updated after anything changes or should we wait for the update
80         //method to be called.
81         private boolean autoUpdateProperties;
82         
83         //this list keeps the sorted, priority of PAP URLs
84         private PapUrlNode[] sortedUrlNodes;
85         //this list keeps the original list of nodes so that they can be entered into the property list correctly
86         private PapUrlNode[] originalUrlNodes;
87         
88         //private constructor to make an instance of a PapUrlResolver, called by static method getInstance.
89         //If the list property strings are not defined, we get the values from XACMLProperties.
90         //The instance acts as an iterator, with hasNext and next methods, but does not implement Iterable,
91         //because it is used for a difference purpose.
92         private PapUrlResolver(String urlList, String failedList, String succeededList, boolean autoUpdateProperties){  
93                 this.autoUpdateProperties = autoUpdateProperties;
94                 String papUrlLists = urlList;
95                 String papUrlFailedList = failedList;
96                 String papUrlSuccessList = succeededList;
97                 if(papUrlLists == null){
98                         papUrlLists = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URLS);
99                         if(papUrlLists == null){
100                                 papUrlLists = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
101                         }
102                         papUrlFailedList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS);
103                         papUrlSuccessList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS);
104                 }
105                 
106                 String[] urls = papUrlLists.split(",");
107                 if(urls.length == 0){           
108                         //log error
109                 }
110                 String[] failed = emptyOrSplit(papUrlFailedList,urls.length);
111                 String[] succeeded = emptyOrSplit(papUrlSuccessList,urls.length);
112                 
113                 sortedUrlNodes = new PapUrlNode[urls.length];
114                 for(int i=0;i<urls.length;i++){
115                 
116                         String userId = null;
117                         String pass = null;
118                         userId = XACMLProperties.getProperty(urls[i]+"."+XACMLRestProperties.PROP_PAP_USERID);                                  
119                         pass = XACMLProperties.getProperty(urls[i]+"."+XACMLRestProperties.PROP_PAP_PASS);
120                         if(userId == null || pass == null){
121                                 userId = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID);
122                                 pass = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS);
123                         }
124                         if(userId == null || pass == null){
125                                 userId = "";
126                                 pass = "";
127                         }
128                         PapUrlNode newNode = new PapUrlNode(urls[i],userId,pass);
129                         newNode.setFailedTime(failed[i]);
130                         newNode.setSucceededTime(succeeded[i]);
131                         if(sortedUrlNodes[i] == null){
132                                 sortedUrlNodes[i] = newNode;
133                         }
134                 }
135                 originalUrlNodes = sortedUrlNodes.clone();
136                 sort(sortedUrlNodes);
137                 pointer = 0;
138         }
139         
140         
141         //either split a list by commas, or fill an array to the expected length, if the property list is not long enough
142         private String[] emptyOrSplit(String list,int expectedLength){
143                 String[] ret;
144                 if(list == null){
145                         ret = new String[expectedLength];
146                         for(int i=0;i<expectedLength;i++){
147                                 ret[i] = "-1";
148                         }
149                 } else {
150                         ret = list.split(",");
151                         if(ret.length != expectedLength){
152                                 ret = emptyOrSplit(null,expectedLength);
153                         }
154                 }
155                 return ret;
156         }
157         
158         private void sort(PapUrlNode[] array){
159                 
160                 //O(n^2) double-loop most likely the best in this case, since number of records will be VERY small
161                 for(int i=0;i<array.length;i++){
162                         for(int j=i;j<array.length;j++){
163                                 if(array[j].compareTo(array[i])<0){
164                                         PapUrlNode temp = array[i];
165                                         array[i] = array[j];
166                                         array[j] = temp;
167                                 }
168                         }
169                 }
170         }
171         
172         //returns whether this PapUrlResolver object has more PAP urls that can be tried
173         public boolean hasMoreUrls(){
174                 return pointer < sortedUrlNodes.length;
175         }
176         
177         //sets the current PAP url as being failed
178         //this will set the failed time to now and remove any succeeded time
179         public void failed(){
180                 LOGGER.error("PAP Server FAILED: "+sortedUrlNodes[pointer].getUrl());
181
182                 sortedUrlNodes[pointer].setFailedTime(new Date());
183                 sortedUrlNodes[pointer].setSucceededTime(null);
184                 propertiesUpdated();
185         }
186         
187         //sets the current PAP url as being working
188         //this will set the succeeded time to now and remove any failed time
189         //Also, this will cause hasMoreUrls to return false, since a working one has been found
190         
191         public void succeeded(){
192                 registered();
193                 pointer = sortedUrlNodes.length;
194         }
195         public void registered(){
196                 sortedUrlNodes[pointer].setFailedTime(null);
197                 sortedUrlNodes[pointer].setSucceededTime(new Date());
198                 LOGGER.info("PAP server SUCCEEDED "+sortedUrlNodes[pointer].getUrl());
199                 propertiesUpdated();
200         }
201         
202         //returns a properties object with the properties that pertain to PAP urls
203         public Properties getProperties(){
204                 String failedPropertyString = "";
205                 String succeededPropertyString = "";
206                 String urlPropertyString = "";
207                 for(int i=0;i<originalUrlNodes.length;i++){
208                         failedPropertyString = failedPropertyString.concat(",").concat(originalUrlNodes[i].getFailedTime());
209                         succeededPropertyString = succeededPropertyString.concat(",").concat(originalUrlNodes[i].getSucceededTime());
210                         urlPropertyString = urlPropertyString.concat(",").concat(originalUrlNodes[i].getUrl());
211                 }
212                 Properties prop = new Properties();
213                 failedPropertyString = failedPropertyString.substring(1);
214                 succeededPropertyString = succeededPropertyString.substring(1);
215                 urlPropertyString = urlPropertyString.substring(1);
216                 prop.setProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS,failedPropertyString);
217                 prop.setProperty(XACMLRestProperties.PROP_PAP_URLS,urlPropertyString);
218                 prop.setProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS,succeededPropertyString);
219                 return prop;
220         }
221         
222         //saves the updates urls to the correct properties
223         private void propertiesUpdated(){
224                 if(!autoUpdateProperties){
225                         return;
226                 }
227                 Properties prop = getProperties();
228
229                 LOGGER.debug("Failed PAP Url List: "+prop.getProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS));
230                 LOGGER.debug("Succeeded PAP Url List: "+prop.getProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS));
231                 XACMLProperties.setProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS,prop.getProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS));
232                 XACMLProperties.setProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS,prop.getProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS));
233         }
234         
235         //iterates to the next available PAP url, according to the priority order
236         public void getNext(){
237                 pointer++;
238         }
239         
240         //returns the url of the current PAP server that we are iterating over
241         //will append the provided policy id to the url
242         public String getUrl(String query){
243                 if(sortedUrlNodes[pointer]== null){
244                         throw new NoSuchElementException();
245                 } else {
246                         return sortedUrlNodes[pointer].getUrl().concat("?").concat(query);
247                 }
248         }
249         
250         //returns the url of the current PAP server that we are iterating over
251         //Just returns the url, with no id appended to it
252         public String getUrl(){
253                 if(sortedUrlNodes[pointer]== null){
254                         throw new NoSuchElementException();
255                 } else {        
256                         
257                         return sortedUrlNodes[pointer].getUrl();
258                 }
259         }
260         public String getUserId(){
261                 if(sortedUrlNodes[pointer]== null){
262                         throw new NoSuchElementException();
263                 } else {        
264                         
265                         return sortedUrlNodes[pointer].getUserId();
266                 }
267         }
268         public String getPass(){
269                 if(sortedUrlNodes[pointer]== null){
270                         throw new NoSuchElementException();
271                 } else {        
272                         
273                         return sortedUrlNodes[pointer].getPass();
274                 }
275         }
276
277         
278         //This is the class to hold the details of a single PAP URL
279         //including: the url itself, the last time it failed, and the last time it succeeded
280         //It also includes the custom comparer which can compare based on failed and succeeded times, and takes into account
281         //the timeout on failures.
282         private class PapUrlNode implements Comparable<PapUrlNode> {
283                 private String papUrl;
284                 private Date failedTime;
285                 private Date succeededTime;
286                 private String userId;
287                 private String pass;
288                 
289                 public PapUrlNode(String url,String userId,String pass){
290                         this.papUrl = url;
291                         failedTime = null;
292                         this.succeededTime = null;
293                         this.userId = userId;
294                         this.pass = pass;
295                         
296                 }
297                 public String getUserId(){
298                         return this.userId;
299                 }
300                 public String getPass(){
301                         return this.pass;
302                 }
303                 
304                 public void setFailedTime(Object time){
305                         Date failedTimeAsDate = setHandler(time);
306                         if(failedTimeAsDate == null){
307                                 this.failedTime = null;
308                         } else {
309                                 long timeDifference = new Date().getTime() - failedTimeAsDate.getTime();
310                                 if(timeDifference < FAIL_TIMEOUT){
311                                         this.failedTime = failedTimeAsDate;
312                                 } else {
313                                         this.failedTime = null;
314                                 }
315                         }
316                 }
317                 
318                 //set the time that this url succeeded at
319                 public void setSucceededTime(Object time){
320                         this.succeededTime = setHandler(time);
321                 }
322                 
323                 //parses string into a date or a null date, if the url never failed/succeeded (since -1 will be in the property)
324                 private Date setHandler(Object time){
325                         if(time instanceof String){
326                                 if("-1".equals((String)time)){
327                                         return null;
328                                 }
329                                 try {
330                                         DateFormat df = new SimpleDateFormat();
331                                         return df.parse((String)time);
332                                 } catch (ParseException e) {                                    
333                                         return null;
334                                 }
335                         }
336                         if(time instanceof Date){
337                                 return (Date)time;
338                         }
339                         return null;
340                 }
341                 
342                 
343                 public String getFailedTime(){
344                         return formatTime(this.failedTime);
345                 }
346                 
347                 public String getSucceededTime(){
348                         return formatTime(this.succeededTime);
349                 }
350                 
351                 //formats a Date into a string or a -1 if there is not date (-1 is used in properties for no date)
352                 private String formatTime(Date d){
353                         if(d == null){
354                                 return "-1";
355                         }
356                         DateFormat df = new SimpleDateFormat();
357                         return df.format(d);
358                 }
359                 
360                 public String getUrl(){
361                         return papUrl;
362                 }
363                 
364                 @Override
365                 public int compareTo(PapUrlNode other){
366                         if(this.failedTime == null && other.failedTime != null){
367                                 return -1;
368                         }
369                         if(this.failedTime != null && other.failedTime == null){
370                                 return 1;
371                         }
372                         if(this.failedTime != null){
373                                 return this.failedTime.compareTo(other.failedTime);
374                         }
375                         return 0;
376                 }
377         }
378 }