b6a502071effbc02290f7c471e2c0a164b360d88
[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     /**
134      * convert timestamp with ending placeholder in filter to elasticsearch filter e.g. 2017* => gte:
135      * 2017-01-01T00:00:00Z, lt:2018-01-01T00:00:00Z
136      *
137      * 201* => 2010-01... 2020 .. 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         } catch (Exception e) {
152
153         }
154         if (dt == null) {
155             return null;
156         }
157         //        property.substring(0,idx)+REPLACE.substring(idx+1);
158         Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
159         c.setTime(dt);
160         int tmpvalue;
161         switch (idx) {
162             case 1: // (2*)
163                 c.set(Calendar.YEAR, c.get(Calendar.YEAR) + 1000);
164                 upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
165                 break;
166             case 2: // (20*)
167                 c.set(Calendar.YEAR, c.get(Calendar.YEAR) + 100);
168                 upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
169                 break;
170             case 3: // (200*)
171                 c.set(Calendar.YEAR, c.get(Calendar.YEAR) + 10);
172                 upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
173                 break;
174             case 4: // (2000*)
175             case 5: // (2000-*)
176                 c.set(Calendar.YEAR, c.get(Calendar.YEAR) + 1);
177                 upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
178                 break;
179             case 6: //switch 10 months (2000-0* or 2000-1*)
180                 tmpvalue = c.get(Calendar.MONTH);
181                 if (tmpvalue < 9) {
182                     c.set(Calendar.MONTH, 9);
183                 } else {
184                     c.set(Calendar.YEAR, c.get(Calendar.YEAR) + 1);
185                     c.set(Calendar.MONTH, 0);
186                 }
187                 upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
188
189                 break;
190             case 7: //switch one month (2018-01* or 2018-01-*)
191             case 8:
192                 c.add(Calendar.MONTH, 1);
193                 upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
194                 break;
195             case 9: // (2018-01-0*)
196                 tmpvalue = c.get(Calendar.DAY_OF_MONTH);
197                 if (tmpvalue == 1) {
198                     c.set(Calendar.DAY_OF_MONTH, 10);
199                 } else if (tmpvalue == 10) {
200                     c.set(Calendar.DAY_OF_MONTH, 20);
201                 } else if (tmpvalue == 20) {
202                     if (c.getActualMaximum(Calendar.DAY_OF_MONTH) < 30) {
203                         c.set(Calendar.DAY_OF_MONTH, 1);
204                         c.add(Calendar.MONTH, 1);
205                     } else {
206                         c.set(Calendar.DAY_OF_MONTH, 30);
207                     }
208                 } else if (tmpvalue == 30) {
209                     c.set(Calendar.DAY_OF_MONTH, 1);
210                     c.add(Calendar.MONTH, 1);
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                 } else {
227                     c.add(Calendar.HOUR_OF_DAY, 10);
228                 }
229                 upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
230                 break;
231             case 13: // (2018-01-01T11*)
232             case 14: // (2018-01-01T11-*)
233                 c.add(Calendar.HOUR_OF_DAY, 1);
234                 upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
235                 break;
236             case 15: // (2018-01-01T11-3*)
237                 c.add(Calendar.MINUTE, 10);
238                 upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
239                 break;
240             case 16: // (2018-01-01T11-32*)
241             case 17: // (2018-01-01T11-32-*)
242                 c.add(Calendar.MINUTE, 1);
243                 upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
244                 break;
245             case 18: // (2018-01-01T11-32-1*)
246                 c.add(Calendar.SECOND, 10);
247                 upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
248                 break;
249             case 19: // (2018-01-01T11-32-11*)
250             case 20: // (2018-01-01T11-32-11.*)
251                 c.add(Calendar.SECOND, 1);
252                 upperEnd = converter.getTimeStampAsNetconfString(c.getTime());
253                 break;
254
255             default:
256                 break;
257         }
258
259         if (upperEnd == null) {
260             return null;
261         }
262         return QueryBuilders.rangeQuery(property).gte(lowerEnd).lt(upperEnd);
263
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             } else {
277                 //    v=v.toLowerCase();
278             }
279             if (DbFilter.hasSearchParams(v)) {
280                 if (p != null && timestampValueNames.contains(p.toLowerCase())) {
281                     query = fromTimestampSearchFilter(p, v);
282                     if (query != null) {
283                         return query;
284                     }
285                 }
286                 return QueryBuilders.regex(p, DbFilter.createDatabaseRegex(v));
287
288
289             } else if (DbFilter.isComparisonValid(v)) {
290                 RangeQueryBuilder q = DbFilter.getRangeQuery((prefix != null ? prefix : "") + p, v);
291                 if (q != null) {
292                     return q;
293                 } else {
294                     return QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v);
295                 }
296             } else {
297                 return QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v);
298             }
299         } else {
300             BoolQueryBuilder query = new BoolQueryBuilder();
301             QueryBuilder tmpQuery;
302             for (Filter fi : filters) {
303                 String p = fi.getProperty();
304                 String v = fi.getFiltervalue();
305                 if ("id".equals(p)) {
306                     p = "_id";
307                 } else {
308                     //    v=v.toLowerCase();
309                 }
310                 if (DbFilter.hasSearchParams(v)) {
311                     if (p != null && timestampValueNames.contains(p.toLowerCase())) {
312                         tmpQuery = fromTimestampSearchFilter(p, v);
313                         if (tmpQuery != null) {
314                             query.must(tmpQuery);
315                         } else {
316                             query.must(QueryBuilders.regex((prefix != null ? prefix : "") + p,
317                                     DbFilter.createDatabaseRegex(v)));
318                         }
319                     } else {
320                         query.must(QueryBuilders.regex((prefix != null ? prefix : "") + p,
321                                 DbFilter.createDatabaseRegex(v)));
322                     }
323                 } else if (DbFilter.isComparisonValid(v)) {
324                     RangeQueryBuilder q = DbFilter.getRangeQuery((prefix != null ? prefix : "") + p, v);
325                     if (q != null) {
326                         query.must(q);
327                     } else {
328                         query.must(QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v));
329                     }
330                 } else {
331                     query.must(QueryBuilders.matchQuery((prefix != null ? prefix : "") + p, v));
332                 }
333             }
334             LOG.trace("Query result. {}", query.toJSON());
335             return query;
336         }
337     }
338
339 }