TCA:Bug fix for JsonPath with non array values
[dcaegen2/analytics/tca.git] / dcae-analytics-common / src / main / java / org / openecomp / dcae / apod / analytics / common / service / filter / GenericJsonMessageFilter.java
1 /*\r
2  * ===============================LICENSE_START======================================\r
3  *  dcae-analytics\r
4  * ================================================================================\r
5  *    Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * ================================================================================\r
7  *  Licensed under the Apache License, Version 2.0 (the "License");\r
8  *  you may not use this file except in compliance with the License.\r
9  *   You may obtain a copy of the License at\r
10  *\r
11  *          http://www.apache.org/licenses/LICENSE-2.0\r
12  *\r
13  *  Unless required by applicable law or agreed to in writing, software\r
14  *  distributed under the License is distributed on an "AS IS" BASIS,\r
15  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  *  See the License for the specific language governing permissions and\r
17  *  limitations under the License.\r
18  *  ============================LICENSE_END===========================================\r
19  */\r
20 \r
21 package org.openecomp.dcae.apod.analytics.common.service.filter;\r
22 \r
23 import com.google.common.collect.ImmutableSet;\r
24 import com.jayway.jsonpath.DocumentContext;\r
25 import com.jayway.jsonpath.JsonPath;\r
26 import com.jayway.jsonpath.PathNotFoundException;\r
27 import org.apache.commons.lang3.StringUtils;\r
28 import org.openecomp.dcae.apod.analytics.common.service.processor.AbstractMessageProcessor;\r
29 import org.slf4j.Logger;\r
30 import org.slf4j.LoggerFactory;\r
31 \r
32 import java.util.List;\r
33 import java.util.Set;\r
34 \r
35 /**\r
36  * A Generic Json Message Filter which filter the json message based on given json Path and list of expected values\r
37  * for that json path. The {@link JsonMessageFilterProcessorContext#isMatched} flag will be changed as per table below:\r
38  * <pre>\r
39  *      Incoming message is blank or invalid Json                               =  null\r
40  *      Incoming message path is matches expected values                        = true\r
41  *      Incoming message does not match expected values or path does not exist  = false\r
42  * </pre>\r
43  * <p>\r
44  * @author Rajiv Singla . Creation Date: 2/10/2017.\r
45  */\r
46 public class GenericJsonMessageFilter extends AbstractMessageProcessor<JsonMessageFilterProcessorContext> {\r
47 \r
48     private static final Logger LOG = LoggerFactory.getLogger(GenericJsonMessageFilter.class);\r
49     private static final long serialVersionUID = 1L;\r
50 \r
51     private final String filterName;\r
52     private final String jsonPath;\r
53     private final Set<String> expectedValues;\r
54 \r
55     public GenericJsonMessageFilter(final String filterName, final String jsonPath, final Set<String> expectedValues) {\r
56         this.filterName = filterName;\r
57         this.jsonPath = jsonPath;\r
58         this.expectedValues = expectedValues;\r
59     }\r
60 \r
61     public GenericJsonMessageFilter(final String filterName, final String jsonPath, final String expectedValue) {\r
62         this(filterName, jsonPath, ImmutableSet.of(expectedValue));\r
63     }\r
64 \r
65     @Override\r
66     public String getProcessorDescription() {\r
67         return filterName;\r
68     }\r
69 \r
70     @Override\r
71     public JsonMessageFilterProcessorContext processMessage(final JsonMessageFilterProcessorContext processorContext) {\r
72 \r
73         final String jsonMessage = processorContext.getMessage().trim();\r
74 \r
75         if (StringUtils.isNotBlank(jsonMessage) && jsonMessage.startsWith("{") && jsonMessage.endsWith("}")) {\r
76 \r
77             // locate json path value\r
78             final DocumentContext documentContext = JsonPath.parse(jsonMessage);\r
79             String jsonPathValue = null;\r
80             try {\r
81                 final List jsonPathValues = documentContext.read(jsonPath);\r
82                 final Object pathValue = jsonPathValues.isEmpty() ? null :  jsonPathValues.get(0);\r
83                 jsonPathValue = pathValue instanceof Number ? pathValue.toString() : (String) pathValue;\r
84             } catch (PathNotFoundException ex) {\r
85                 LOG.info("Unable to find json Path: {}. Exception: {}, Json Message: {}", jsonPath, ex, jsonMessage);\r
86             }\r
87 \r
88             LOG.debug("Value for jsonPath: {}, jsonPathValue: {}, expected Values: {}",\r
89                     jsonPath, jsonPathValue, expectedValues);\r
90 \r
91             // if json path value is null or we json value is not present in expect values then terminate early\r
92             if (jsonPathValue == null || !expectedValues.contains(jsonPathValue)) {\r
93                 final String terminatingMessage = String.format("Filter match unsuccessful. " +\r
94                                 "JsonPath: %s, Actual JsonPathValue: %s, Excepted Json Path Values: %s",\r
95                         jsonPath, jsonPathValue, expectedValues);\r
96                 processorContext.setMatched(false);\r
97                 setTerminatingProcessingMessage(terminatingMessage, processorContext);\r
98             } else {\r
99                 final String finishProcessingMessage = String.format("Filter match successful. " +\r
100                                 "JsonPath: %s, Actual JsonPathValue: %s, Excepted Json Path Values: %s",\r
101                         jsonPath, jsonPathValue, expectedValues);\r
102                 processorContext.setMatched(true);\r
103                 setFinishedProcessingMessage(finishProcessingMessage, processorContext);\r
104             }\r
105         } else {\r
106             // if incoming message is blank of valid Json then matched flag will be null\r
107             final String terminatingMessage = "Incoming json message is blank or not json. " +\r
108                     "Json filter cannot be applied";\r
109             processorContext.setMatched(null);\r
110             setTerminatingProcessingMessage(terminatingMessage, processorContext);\r
111         }\r
112 \r
113         return processorContext;\r
114     }\r
115 }\r