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