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