09ceeac7e23407012258c194183f29a93577f540
[dcaegen2/collectors/ves.git] / src / main / java / org / onap / dcae / commonFunction / ConfigProcessors.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * PROJECT
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                                              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.dcae.commonFunction;
23
24 import org.json.JSONArray;
25 import org.json.JSONObject;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 import java.text.DecimalFormat;
30
31 public class ConfigProcessors {
32
33     private static final Logger log = LoggerFactory.getLogger(ConfigProcessors.class);
34     private static final String FIELD = "field";
35     private static final String OLD_FIELD = "oldField";
36     private static final String FILTER = "filter";
37     private static final String VALUE = "value";
38     private static final String REGEX = "\\[\\]";
39     private static final String OBJECT_NOT_FOUND = "ObjectNotFound";
40     private static final String FILTER_NOT_MET = "Filter not met";
41     private static final String MAP_TYPE = "mapType";
42     private static final String COMP_FALSE = "==false";
43
44     private final JSONObject event;
45
46     public ConfigProcessors(JSONObject eventJson) {
47         event = eventJson;
48     }
49
50     public void getValue(JSONObject jsonObject) {
51
52         final String field = jsonObject.getString(FIELD);
53         final JSONObject filter = jsonObject.optJSONObject(FILTER);
54
55         if (filter == null || isFilterMet(filter)) {
56             getEventObjectVal(field);
57         } else
58             log.info(FILTER_NOT_MET);
59     }
60
61
62     public void setValue(JSONObject jsonObject) {
63         final String field = jsonObject.getString(FIELD);
64         final String value = jsonObject.getString(VALUE);
65         final JSONObject filter = jsonObject.optJSONObject(FILTER);
66         if (filter == null || isFilterMet(filter)) {
67             setEventObjectVal(field, value);
68         } else
69             log.info(FILTER_NOT_MET);
70     }
71
72
73     private String evaluate(String str) {
74         String value = str;
75         if (str.startsWith("$")) {
76             value = (String) getEventObjectVal(str.substring(1));
77
78         }
79         return value;
80     }
81
82
83     public void suppressEvent(JSONObject jsonObject) {
84         final JSONObject filter = jsonObject.optJSONObject(FILTER);
85
86         if (filter == null || isFilterMet(filter)) {
87             setEventObjectVal("suppressEvent", "true");
88         } else
89             log.info(FILTER_NOT_MET);
90     }
91
92
93     public void addAttribute(JSONObject jsonObject) {
94
95         final String field = jsonObject.getString(FIELD);
96         final String value = evaluate(jsonObject.getString(VALUE));
97         final JSONObject filter = jsonObject.optJSONObject(FILTER);
98         final String fieldType = jsonObject.optString("fieldType", "string").toLowerCase();
99
100         if (filter == null || isFilterMet(filter)) {
101             setEventObjectVal(field, value, fieldType);
102         } else
103             log.info(FILTER_NOT_MET);
104     }
105
106
107     public void updateAttribute(JSONObject jsonObject) {
108
109         final String field = jsonObject.getString(FIELD);
110         final String value = evaluate(jsonObject.getString(VALUE));
111         final JSONObject filter = jsonObject.optJSONObject(FILTER);
112         if (filter == null || isFilterMet(filter)) {
113             setEventObjectVal(field, value);
114         } else
115             log.info(FILTER_NOT_MET);
116     }
117
118
119     public void removeAttribute(JSONObject jsonObject) {
120
121         final String field = jsonObject.getString(FIELD);
122         final JSONObject filter = jsonObject.optJSONObject(FILTER);
123
124         if (filter == null || isFilterMet(filter)) {
125             removeEventKey(field);
126         } else
127             log.info(FILTER_NOT_MET);
128     }
129
130
131     private void renameArrayInArray(JSONObject jsonObject) // map
132     {
133         log.info("renameArrayInArray");
134         final String field = jsonObject.getString(FIELD);
135         final String oldField = jsonObject.getString(OLD_FIELD);
136         final JSONObject filter = jsonObject.optJSONObject(FILTER);
137
138         if (filter == null || isFilterMet(filter)) {
139
140             final String[] fsplit = field.split(REGEX, field.length());
141             final String[] oldfsplit = oldField.split(REGEX, oldField.length());
142
143             final String oldValue = getEventObjectVal(oldfsplit[0]).toString();
144             if (!oldValue.equals(OBJECT_NOT_FOUND)) {
145                 final String oldArrayName = oldfsplit[1].substring(1);
146                 final String newArrayName = fsplit[1].substring(1);
147                 final String value = oldValue.replaceAll(oldArrayName, newArrayName);
148
149                 log.info("oldValue ==" + oldValue);
150                 log.info("value ==" + value);
151                 JSONArray ja = new JSONArray(value);
152                 removeEventKey(oldfsplit[0]);
153                 setEventObjectVal(fsplit[0], ja);
154             }
155         } else
156             log.info(FILTER_NOT_MET);
157     }
158
159     private void renameObject(JSONObject jsonObject) // map
160     {
161         log.info("renameArrayInArray");
162         final String field = jsonObject.getString(FIELD);
163         final String oldField = jsonObject.getString(OLD_FIELD);
164         final JSONObject filter = jsonObject.optJSONObject(FILTER);
165
166         if (filter == null || isFilterMet(filter)) {
167
168             final JSONObject oldValue = (JSONObject) getEventObjectVal(oldField);
169             if (!oldValue.toString().equals(OBJECT_NOT_FOUND)) {
170                 setEventObjectVal(field, oldValue);
171                 removeEventKey(oldField);
172             }
173         } else
174             log.info(FILTER_NOT_MET);
175     }
176     
177     public void map(JSONObject jsonObject) {
178
179         final String field = jsonObject.getString(FIELD);
180         final String mapType = jsonObject.optString(MAP_TYPE, "");
181         if (field.contains("[]")) {
182             if (field.matches(".*\\[\\]\\..*\\[\\]"))
183                 renameArrayInArray(jsonObject);
184             else
185                 mapToJArray(jsonObject);
186         }
187         else if (mapType.equals("hashmapToNameValueArray"))
188                 mapHashmapToNameValueArray(jsonObject);
189         else if (mapType.equals("nameValueArrayToHashmap"))
190                 mapNameValueArrayToHashmap(jsonObject);
191         else if (mapType.equals("renameObject"))
192                 renameObject(jsonObject);
193                 
194         else
195         mapAttribute(jsonObject);
196     }
197
198     private String performOperation(String operation, String value) {
199         log.info("performOperation");
200         if ("convertMBtoKB".equals(operation)) {
201             float kbValue = Float.parseFloat(value) * 1024;
202             value = String.valueOf(kbValue);
203         }
204         return value;
205     }
206
207
208     public void mapAttribute(JSONObject jsonObject) {
209
210         final String field = jsonObject.getString(FIELD);
211         final String oldField = jsonObject.getString(OLD_FIELD);
212         final JSONObject filter = jsonObject.optJSONObject(FILTER);
213         final String operation = jsonObject.optString("operation");
214         String value;
215         if (filter == null || isFilterMet(filter)) {
216
217             value = getEventObjectVal(oldField).toString();
218             if (!value.equals(OBJECT_NOT_FOUND)) {
219                 if (operation != null && !operation.isEmpty())
220                     value = performOperation(operation, value);
221
222                 setEventObjectVal(field, value);
223
224                 removeEventKey(oldField);
225             }
226         } else
227             log.info(FILTER_NOT_MET);
228     }
229
230
231     private void mapToJArray(JSONObject jsonObject) {
232         log.info("mapToJArray");
233         String field = jsonObject.getString(FIELD);
234         String oldField = jsonObject.getString(OLD_FIELD);
235         final JSONObject filter = jsonObject.optJSONObject(FILTER);
236         final JSONObject attrMap = jsonObject.optJSONObject("attrMap");
237         oldField = oldField.replaceAll(REGEX, "");
238         field = field.replaceAll(REGEX, "");
239
240         if (filter == null || isFilterMet(filter)) {
241
242             String value = getEventObjectVal(oldField).toString();
243             if (!value.equals(OBJECT_NOT_FOUND)) {
244                 log.info("old value ==" + value);
245                 // update old value based on attrMap
246                 if (attrMap != null) {
247                     // loop thru attrMap and update attribute name to new name
248                     for (String key : attrMap.keySet()) {
249                         value = value.replaceAll(key, attrMap.getString(key));
250                     }
251                 }
252
253                 log.info("new value ==" + value);
254                 char c = value.charAt(0);
255                 if (c != '[') {
256                     // oldfield is JsonObject
257                     JSONObject valueJO = new JSONObject(value);
258                     // if the array already exists
259                     String existingValue = getEventObjectVal(field).toString();
260                     if (!existingValue.equals(OBJECT_NOT_FOUND)) {
261                         JSONArray ja = new JSONArray(existingValue);
262                         JSONObject jo = ja.optJSONObject(0);
263                         if (jo != null) {
264                             for (String key : valueJO.keySet()) {
265                                 jo.put(key, valueJO.get(key));
266
267                             }
268                             ja.put(0, jo);
269
270                             setEventObjectVal(field, ja);
271                         }
272                     } else // if new array
273                         setEventObjectVal(field + "[0]", new JSONObject(value), "JArray");
274                 } else // oldfield is jsonArray
275                     setEventObjectVal(field, new JSONArray(value));
276
277                 removeEventKey(oldField);
278             }
279         } else
280             log.info(FILTER_NOT_MET);
281     }
282     
283     // this method is to support the mapping 5.x to VES7.x format for additionalInformation field
284     private void mapNameValueArrayToHashmap(JSONObject jsonObject) {
285         log.info("mapNameValueArrayToHashmap");
286         String field = jsonObject.getString(FIELD);
287         String oldField = jsonObject.getString(FIELD);
288         final JSONObject filter = jsonObject.optJSONObject(FILTER);
289
290         if (filter == null || isFilterMet(filter)) {
291                 JSONObject newHashMap = new JSONObject(); // this will hold the newly mapped hashmap elements
292             JSONArray arrayValue = (JSONArray) getEventObjectVal(oldField); // old Array structure value
293             JSONObject tempJObj = null;
294             String tempName = "";
295             String tempValue = "";
296             if (!arrayValue.toString().equals(OBJECT_NOT_FOUND)) {
297                 log.info("old value ==" + arrayValue.toString());
298                 // Loop thru the JSONArray, get the name:value pair and write to new JSONObject as hashmap elements
299                 for (int i = 0; i < arrayValue.length(); i++) {
300
301                         tempJObj = arrayValue.getJSONObject(i);
302                     if (tempJObj != null) {
303                         tempName = tempJObj.get("name").toString();
304                         tempValue = tempJObj.get(VALUE).toString();
305                         newHashMap.put(tempName, tempValue);
306                     }
307                 }
308                 // remove the old Array structure
309                 removeEventKey(oldField);
310                 //Add the new Hashmap 
311                 setEventObjectVal(field, newHashMap);
312             }
313         } else
314             log.info(FILTER_NOT_MET);
315     }
316     
317  // this method is to support the mapping 7.x to VES5.x format for additionalInformation field
318     private void mapHashmapToNameValueArray(JSONObject jsonObject) {
319         log.info("mapHashmapToNameValueArray");
320         System.out.println("mapHashmapToNameValueArray");
321         String field = jsonObject.getString(FIELD);
322         String oldField = jsonObject.getString(FIELD);
323         final JSONObject filter = jsonObject.optJSONObject(FILTER);
324
325         if (filter == null || isFilterMet(filter)) {
326                 JSONArray newArray = new JSONArray(); // this will hold the new name:value JSONObject
327                 JSONObject nameValJObj;
328                 System.out.println("object ==" + getEventObjectVal(oldField).toString());
329                 if (!getEventObjectVal(oldField).toString().equals(OBJECT_NOT_FOUND)) {
330                         
331                     JSONObject hashMap = (JSONObject) getEventObjectVal(oldField); // old hashmap structure value
332                     if (hashMap != null) {
333                         log.info("old value ==" + hashMap.toString());
334                         // Loop thru the hashMap JSONObject, get the hashmap elements add them as name:value JsonObject into the newArray
335                         for (String key : hashMap.keySet()) {
336                                 nameValJObj = new JSONObject(); //create new object so not to overwrite in memory for Array insertion
337                                 nameValJObj.put("name", key);
338                                 nameValJObj.put("value", hashMap.get(key));
339                                 newArray.put(nameValJObj);
340                         }
341                         // remove the old hashMap structure
342                         removeEventKey(oldField);
343                         //Add the newArray containing the name:value Object
344                         setEventObjectVal(field, newArray);
345                     }
346                 }
347         } else
348             log.info(FILTER_NOT_MET);
349     }
350
351     /**
352      * example - { "functionName": "concatenateValue", "args":{ "filter":
353      * {"event.commonEventHeader.event":"heartbeat"},
354      * FIELD:"event.commonEventHeader.eventName", "concatenate":
355      * ["event.commonEventHeader.domain","event.commonEventHeader.eventType","event.commonEventHeader.alarmCondition"],
356      * "delimiter":"_" } }
357      **/
358     public void concatenateValue(JSONObject jsonObject) {
359
360         final String field = jsonObject.getString(FIELD);
361         final String delimiter = jsonObject.getString("delimiter");
362         final JSONArray values = jsonObject.getJSONArray("concatenate");
363         final JSONObject filter = jsonObject.optJSONObject(FILTER);
364         if (filter == null || isFilterMet(filter)) {
365             StringBuilder value = new StringBuilder();
366             for (int i = 0; i < values.length(); i++) {
367
368                 String tempVal = evaluate(values.getString(i));
369                 if (!tempVal.equals(OBJECT_NOT_FOUND)) {
370                     if (i == 0)
371                         value.append(tempVal);
372                     else
373                         value.append(delimiter).append(tempVal);
374                 }
375             }
376
377             setEventObjectVal(field, value.toString());
378         } else
379             log.info(FILTER_NOT_MET);
380     }
381
382     public void subtractValue(JSONObject jsonObject) {
383
384         final String field = jsonObject.getString(FIELD);
385         final JSONArray values = jsonObject.getJSONArray("subtract");
386         final JSONObject filter = jsonObject.optJSONObject(FILTER);
387         if (filter == null || isFilterMet(filter)) {
388             float value = 0;
389             for (int i = 0; i < values.length(); i++) {
390                 log.info(values.getString(i));
391                 String tempVal = evaluate(values.getString(i));
392                 log.info("tempVal==" + tempVal);
393                 if (!tempVal.equals(OBJECT_NOT_FOUND)) {
394                     if (i == 0)
395                         value = value + Float.valueOf(tempVal);
396                     else
397                         value = value - Float.valueOf(tempVal);
398                 }
399             }
400             log.info("value ==" + value);
401             setEventObjectVal(field, value, "number");
402         } else
403             log.info(FILTER_NOT_MET);
404     }
405
406
407     private void removeEventKey(String field) {
408         String[] keySet = field.split("\\.", field.length());
409         JSONObject keySeries = event;
410         for (int i = 0; i < (keySet.length - 1); i++) {
411
412             keySeries = keySeries.getJSONObject(keySet[i]);
413         }
414
415         keySeries.remove(keySet[keySet.length - 1]);
416     }
417
418
419     private boolean checkFilter(JSONObject jo, String key, String logicKey) {
420         String filterValue = jo.getString(key);
421         if (filterValue.contains(":")) {
422             String[] splitVal = filterValue.split(":");
423             if ("matches".equals(splitVal[0])) {
424                 if ("not".equals(logicKey)) {
425                     if (getEventObjectVal(key).toString().matches(splitVal[1])) {
426                         log.info(filterValue + "==" + key + "==" + getEventObjectVal(key) + COMP_FALSE);
427                         return false;
428                     }
429                 } else {
430                     if (!(getEventObjectVal(key).toString().matches(splitVal[1]))) {
431                         log.info(filterValue + "==" + key + "==" + getEventObjectVal(key) + COMP_FALSE);
432                         return false;
433                     }
434                 }
435
436             }
437             if ("contains".equals(splitVal[0])) {
438                 if ("not".equals(logicKey)) {
439                     if (getEventObjectVal(key).toString().contains(splitVal[1])) {
440                         log.info(filterValue + "==" + key + "==" + getEventObjectVal(key) + COMP_FALSE);
441                         return false;
442                     }
443                 } else {
444                     if (!(getEventObjectVal(key).toString().contains(splitVal[1]))) {
445                         log.info(filterValue + "==" + key + "==" + getEventObjectVal(key) + COMP_FALSE);
446                         return false;
447                     }
448                 }
449
450             }
451         } else {
452             if ("not".equals(logicKey)) {
453                 if (getEventObjectVal(key).toString().equals(filterValue)) {
454                     log.info(filterValue + "==" + key + "==" + getEventObjectVal(key) + COMP_FALSE);
455                     return false;
456                 }
457             } else {
458                 if (!(getEventObjectVal(key).toString().equals(filterValue))) {
459                     log.info(filterValue + "==" + key + "==" + getEventObjectVal(key) + COMP_FALSE);
460                     return false;
461                 }
462             }
463         }
464         return true;
465     }
466
467
468     public boolean isFilterMet(JSONObject jo) {
469         for (String key : jo.keySet()) {
470             if ("not".equals(key)) {
471                 JSONObject njo = jo.getJSONObject(key);
472                 for (String njoKey : njo.keySet()) {
473                     if (!checkFilter(njo, njoKey, key))
474                         return false;
475                 }
476             } else {
477                 if (!checkFilter(jo, key, key))
478                     return false;
479             }
480         }
481         return true;
482     }
483
484     /**
485      * returns a string or JSONObject or JSONArray
486      **/
487     public Object getEventObjectVal(String keySeriesStr) {
488         keySeriesStr = keySeriesStr.replaceAll("\\[", ".");
489         keySeriesStr = keySeriesStr.replaceAll("\\]", ".");
490         if (keySeriesStr.contains("..")) {
491             keySeriesStr = keySeriesStr.replaceAll("\\.\\.", ".");
492         }
493
494         if (keySeriesStr.lastIndexOf(".") == keySeriesStr.length() - 1)
495             keySeriesStr = keySeriesStr.substring(0, keySeriesStr.length() - 1);
496         String[] keySet = keySeriesStr.split("\\.", keySeriesStr.length());
497         Object keySeriesObj = event;
498         for (String aKeySet : keySet) {
499             if (keySeriesObj != null) {
500                 if (keySeriesObj instanceof String) {
501
502                     log.info("STRING==" + keySeriesObj);
503                 } else if (keySeriesObj instanceof JSONArray) {
504                     keySeriesObj = ((JSONArray) keySeriesObj).optJSONObject(Integer.parseInt(aKeySet));
505
506                 } else if (keySeriesObj instanceof JSONObject) {
507                     keySeriesObj = ((JSONObject) keySeriesObj).opt(aKeySet);
508
509                 } else {
510                     log.info("unknown object==" + keySeriesObj);
511                 }
512             }
513         }
514
515         if (keySeriesObj == null)
516             return OBJECT_NOT_FOUND;
517         return keySeriesObj;
518     }
519
520     public void setEventObjectVal(String keySeriesStr, Object value) {
521         setEventObjectVal(keySeriesStr, value, "string");
522     }
523
524     /**
525      * returns a string or JSONObject or JSONArray
526      **/
527     public void setEventObjectVal(String keySeriesStr, Object value, String fieldType) {
528         keySeriesStr = keySeriesStr.replaceAll("\\[", ".");
529         keySeriesStr = keySeriesStr.replaceAll("\\]", ".");
530         if (keySeriesStr.contains("..")) {
531             keySeriesStr = keySeriesStr.replaceAll("\\.\\.", ".");
532         }
533         log.info("fieldType==" + fieldType);
534
535         if (keySeriesStr.lastIndexOf(".") == keySeriesStr.length() - 1)
536             keySeriesStr = keySeriesStr.substring(0, keySeriesStr.length() - 1);
537         String[] keySet = keySeriesStr.split("\\.", keySeriesStr.length());
538         Object keySeriesObj = event;
539         for (int i = 0; i < (keySet.length - 1); i++) {
540
541             if (keySeriesObj instanceof JSONArray) {
542
543                 if (((JSONArray) keySeriesObj).optJSONObject(Integer.parseInt(keySet[i])) == null) // if
544                 // the
545                 // object
546                 // is
547                 // not
548                 // there
549                 // then
550                 // add
551                 // it
552                 {
553                     log.info("Object is null, must add it");
554                     if (keySet[i + 1].matches("[0-9]*")) // if index then array
555                         ((JSONArray) keySeriesObj).put(Integer.parseInt(keySet[i]), new JSONArray());
556                     else
557                         ((JSONArray) keySeriesObj).put(Integer.parseInt(keySet[i]), new JSONObject());
558                 }
559                 keySeriesObj = ((JSONArray) keySeriesObj).optJSONObject(Integer.parseInt(keySet[i]));
560
561             } else if (keySeriesObj instanceof JSONObject) {
562                 if (((JSONObject) keySeriesObj).opt(keySet[i]) == null) // if
563                 // the
564                 // object
565                 // is
566                 // not
567                 // there
568                 // then
569                 // add
570                 // it
571                 {
572                     if (keySet[i + 1].matches("[0-9]*")) // if index then array
573                         ((JSONObject) keySeriesObj).put(keySet[i], new JSONArray());
574                     else
575                         ((JSONObject) keySeriesObj).put(keySet[i], new JSONObject());
576                     log.info("Object is null, must add it");
577                 }
578                 keySeriesObj = ((JSONObject) keySeriesObj).opt(keySet[i]);
579             } else {
580                 log.info("unknown object==" + keySeriesObj);
581             }
582         }
583         if ("number".equals(fieldType)) {
584             DecimalFormat df = new DecimalFormat("#.0");
585             if (value instanceof String)
586                 ((JSONObject) keySeriesObj).put(keySet[keySet.length - 1],
587                         Float.valueOf(df.format(Float.valueOf((String) value))));
588             else
589                 ((JSONObject) keySeriesObj).put(keySet[keySet.length - 1], Float.valueOf(df.format(value)));
590         } else if ("integer".equals(fieldType) && value instanceof String)
591             ((JSONObject) keySeriesObj).put(keySet[keySet.length - 1], Integer.valueOf((String) value));
592         else if ("JArray".equals(fieldType))
593             ((JSONArray) keySeriesObj).put(value);
594         else
595             ((JSONObject) keySeriesObj).put(keySet[keySet.length - 1], value);
596
597     }
598 }