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