a83dfd9750e9acf1402c97a0bec59dd76b8dcb44
[ccsdk/features.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property.
6  * All rights reserved.
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.ccsdk.features.sdnr.wt.dataprovider.data;
23
24 import java.util.Arrays;
25 import java.util.Calendar;
26 import java.util.Date;
27 import java.util.List;
28 import java.util.TimeZone;
29
30 import org.eclipse.jdt.annotation.Nullable;
31 import org.onap.ccsdk.features.sdnr.wt.common.database.data.DbFilter;
32 import org.onap.ccsdk.features.sdnr.wt.common.database.queries.BoolQueryBuilder;
33 import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder;
34 import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilders;
35 import org.onap.ccsdk.features.sdnr.wt.common.database.queries.RangeQueryBuilder;
36 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp;
37 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.EntityInput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.SortOrder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Filter;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev190801.entity.input.Sortorder;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 public class QueryByFilter {
46
47      private static final Logger LOG = LoggerFactory.getLogger(DataObjectAcessorPm.class);
48          private static final List<String> timestampValueNames = Arrays.asList("timestamp","start","end");
49
50      private QueryByFilter() {
51          //Hide
52      }
53
54     static long getPage(EntityInput input) {
55         return getPage(input, 1);
56     }
57
58     @SuppressWarnings("null")
59     private static long getPage(EntityInput input, long defaultValue) {
60         return input.getPagination() != null ? input.getPagination().getPage().longValue() : defaultValue;
61     }
62
63     static long getPageSize(EntityInput input) {
64         return getPageSize(input, 1);
65     }
66
67     @SuppressWarnings("null")
68     private static long getPageSize(EntityInput input, long defaultValue) {
69         return input.getPagination() != null ? input.getPagination().getSize().longValue() : defaultValue;
70     }
71
72
73     public static QueryBuilder setSortOrder(QueryBuilder query, @Nullable List<Sortorder> sortorder) {
74         return setSortOrder(query, sortorder, "");
75     }
76
77     private static QueryBuilder setSortOrder(QueryBuilder query, @Nullable List<Sortorder> sortorder, String prefix) {
78         if (sortorder != null && sortorder.size() > 0) {
79             for (Sortorder so : sortorder) {
80                 query.sort((prefix != null ? prefix : "") + so.getProperty(),
81                         so.getSortorder() == SortOrder.Ascending
82                                 ? org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder.ASCENDING
83                                 : org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder.DESCENDING);
84             }
85         }
86         return query;
87
88     }
89
90
91      public static Sortorder getSortOrder(@Nullable List<Sortorder> list, String prop) {
92         if (list == null) {
93             return null;
94         }
95         for (Sortorder o : list) {
96             if (prop.equals(o.getProperty())) {
97                 return o;
98             }
99         }
100         return null;
101     }
102
103      public static Filter getFilter(@Nullable List<Filter> list, String prop) {
104         if (list == null) {
105             return null;
106         }
107         for (Filter f : list) {
108             if (prop.equals(f.getProperty())) {
109                 return f;
110             }
111         }
112         return null;
113     }
114
115      public static QueryBuilder fromFilter(@Nullable List<Filter> filters) {
116         return fromFilter(filters, "");
117     }
118
119      private static String fillTimeStamp(String value) {
120         int idx=value.lastIndexOf("*");
121         final String REPLACE="0000-00-00T00:00:00.0Z";
122         String s = value.substring(0,idx)+REPLACE.substring(idx);
123         if(Integer.parseInt(s.substring(5,7))==0) {
124             s=s.substring(0,5)+"01-"+s.substring(8);
125         }
126         if(Integer.parseInt(s.substring(8,10))==0) {
127             s=s.substring(0,8)+"01"+s.substring(10);
128         }
129
130         return s;
131      }
132      /**
133       * convert timestamp with ending placeholder in filter to elasticsearch filter
134       * e.g. 2017* => gte: 2017-01-01T00:00:00Z, lt:2018-01-01T00:00:00Z
135       *
136       * 201*   => 2010-01... 2020 ..
137       * 2018-* => 2018-01... <=> 2019-01
138       *
139       */
140     private static @Nullable QueryBuilder fromTimestampSearchFilter(String property,String value) {
141         if(!value.endsWith("*")) {
142             return null;
143         }
144         int idx=value.lastIndexOf("*");
145         String lowerEnd = fillTimeStamp(value);
146         String upperEnd =null;
147         NetconfTimeStamp converter = NetconfTimeStampImpl.getConverter();
148         Date dt = null;
149         try{
150             dt=converter.getDateFromNetconf(lowerEnd);
151         }
152         catch(Exception e) {
153
154         }
155         if(dt==null) {
156             return null;
157         }
158 //        property.substring(0,idx)+REPLACE.substring(idx+1);
159         Calendar c  = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
160         c.setTime(dt);
161         int tmpvalue;
162         switch(idx) {
163         case 1:  // (2*)
164             c.set(Calendar.YEAR,c.get(Calendar.YEAR)+1000);
165             upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
166             break;
167         case 2:  // (20*)
168             c.set(Calendar.YEAR,c.get(Calendar.YEAR)+100);
169             upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
170             break;
171         case 3:  // (200*)
172             c.set(Calendar.YEAR,c.get(Calendar.YEAR)+10);
173             upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
174             break;
175         case 4:  // (2000*)
176         case 5:  // (2000-*)
177             c.set(Calendar.YEAR,c.get(Calendar.YEAR)+1);
178             upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
179             break;
180         case 6: //switch 10 months (2000-0* or 2000-1*)
181             tmpvalue = c.get(Calendar.MONTH);
182                 if(tmpvalue<9) {
183                     c.set(Calendar.MONTH,9);
184                 }
185                 else {
186                     c.set(Calendar.YEAR,c.get(Calendar.YEAR)+1);
187                     c.set(Calendar.MONTH,0);
188                 }
189                 upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
190
191             break;
192         case 7: //switch one month (2018-01* or 2018-01-*)
193         case 8:
194             c.add(Calendar.MONTH, 1);
195             upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
196             break;
197         case 9: // (2018-01-0*)
198             tmpvalue = c.get(Calendar.DAY_OF_MONTH);
199             if(tmpvalue==1) {
200                 c.set(Calendar.DAY_OF_MONTH, 10);
201             }else if(tmpvalue==10) {
202                 c.set(Calendar.DAY_OF_MONTH, 20);
203             }else if(tmpvalue==20) {
204                 if(c.getActualMaximum(Calendar.DAY_OF_MONTH)<30) {
205                     c.set(Calendar.DAY_OF_MONTH,1);
206                     c.add(Calendar.MONTH,1);
207                 }
208                 else {
209                     c.set(Calendar.DAY_OF_MONTH,30);
210                 }
211             }else if(tmpvalue==30) {
212                 c.set(Calendar.DAY_OF_MONTH,1);
213                 c.add(Calendar.MONTH,1);
214             }
215             else {
216                 break;
217             }
218             upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
219             break;
220         case 10: // (2018-01-01*)
221         case 11: // (2018-01-01T*)
222             c.add(Calendar.DAY_OF_MONTH,1);
223             upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
224             break;
225         case 12: // (2018-01-01T1*)
226             tmpvalue = c.get(Calendar.HOUR_OF_DAY);
227             if(tmpvalue==20) {
228                 c.set(Calendar.HOUR_OF_DAY,0);
229                 c.add(Calendar.DAY_OF_MONTH,1);
230             }
231             else {
232                 c.add(Calendar.HOUR_OF_DAY,10);
233             }
234             upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
235             break;
236         case 13: // (2018-01-01T11*)
237         case 14: // (2018-01-01T11-*)
238             c.add(Calendar.HOUR_OF_DAY,1);
239             upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
240             break;
241         case 15: // (2018-01-01T11-3*)
242             c.add(Calendar.MINUTE,10);
243             upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
244             break;
245         case 16: // (2018-01-01T11-32*)
246         case 17: // (2018-01-01T11-32-*)
247             c.add(Calendar.MINUTE,1);
248             upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
249             break;
250         case 18: // (2018-01-01T11-32-1*)
251             c.add(Calendar.SECOND,10);
252             upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
253             break;
254         case 19: // (2018-01-01T11-32-11*)
255         case 20: // (2018-01-01T11-32-11.*)
256             c.add(Calendar.SECOND,1);
257             upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
258             break;
259
260             default:
261                 break;
262         }
263
264         if(upperEnd==null) {
265             return null;
266         }
267         return QueryBuilders.rangeQuery(property).gte(lowerEnd).lt(upperEnd);
268
269     }
270     private static QueryBuilder fromFilter(@Nullable List<Filter> filters, String prefix) {
271         if (filters == null || filters.size() == 0) {
272             return QueryBuilders.matchAllQuery();
273
274         } else if (filters.size() == 1) {
275             QueryBuilder query;
276             String p = filters.get(0).getProperty();
277             String v= filters.get(0).getFiltervalue();
278             if ("id".equals(p)) {
279                 p = "_id";
280             }
281             else {
282             //    v=v.toLowerCase();
283             }
284             if (DbFilter.hasSearchParams(v)) {
285                 if(p!=null && timestampValueNames.contains(p.toLowerCase())) {
286                     query = fromTimestampSearchFilter(p,v);
287                     if(query!=null) {
288                         return query;
289                     }
290                 }
291                 return QueryBuilders.regex(p, DbFilter.createDatabaseRegex(v));
292
293
294             } else if (DbFilter.isComparisonValid(v)) {
295                 RangeQueryBuilder q = DbFilter.getRangeQuery((prefix != null ? prefix : "") + p, v);
296                 if (q != null) {
297                     return q;
298                 }
299                 else {
300                     return QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v);
301                 }
302             }
303             else {
304                 return QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v);
305             }
306         }
307         else {
308             BoolQueryBuilder query = new BoolQueryBuilder();
309             QueryBuilder tmpQuery;
310             for (Filter fi : filters) {
311                 String p = fi.getProperty();
312                 String v=fi.getFiltervalue();
313                 if ("id".equals(p)) {
314                     p = "_id";
315                 }
316                 else {
317                 //    v=v.toLowerCase();
318                 }
319                 if(DbFilter.hasSearchParams(v)) {
320                     if(p!=null && timestampValueNames.contains(p.toLowerCase())) {
321                         tmpQuery=fromTimestampSearchFilter(p,v);
322                         if(tmpQuery!=null) {
323                             query.must(tmpQuery);
324                         }else {
325                             query.must(QueryBuilders.regex((prefix != null ? prefix : "") + p,DbFilter.createDatabaseRegex(v)));
326                         }
327                     }else {
328                         query.must(QueryBuilders.regex((prefix != null ? prefix : "") + p,DbFilter.createDatabaseRegex(v)));
329                     }
330                 }
331                 else if (DbFilter.isComparisonValid(v)) {
332                     RangeQueryBuilder q = DbFilter.getRangeQuery((prefix != null ? prefix : "") + p,v);
333                     if(q!=null) {
334                         query.must(q);
335                     }
336                     else {
337                         query.must(QueryBuilders.matchQuery((prefix != null ? prefix : "") + p,v));
338                     }
339                 }
340                 else {
341                     query.must(QueryBuilders.matchQuery((prefix != null ? prefix : "") + p,v));
342                 }
343             }
344             LOG.trace("Query result. {}", query.toJSON());
345             return query;
346         }
347     }
348
349 }