Re-format source code
[policy/engine.git] / PolicyEngineUtils / src / main / java / org / onap / policy / utils / PolicyUtils.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * PolicyEngineUtils
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.utils;
22
23 import com.fasterxml.jackson.core.JsonProcessingException;
24 import com.fasterxml.jackson.databind.ObjectMapper;
25 import com.google.common.base.CharMatcher;
26 import com.google.gson.JsonParser;
27 import com.google.gson.JsonSyntaxException;
28
29 import java.io.IOException;
30 import java.io.StringReader;
31 import java.io.UnsupportedEncodingException;
32 import java.util.Arrays;
33 import java.util.Base64;
34 import java.util.List;
35 import java.util.Scanner;
36 import java.util.StringTokenizer;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
39
40 import javax.xml.XMLConstants;
41 import javax.xml.parsers.SAXParser;
42 import javax.xml.parsers.SAXParserFactory;
43
44 import org.drools.core.io.impl.ReaderResource;
45 import org.drools.verifier.Verifier;
46 import org.drools.verifier.VerifierError;
47 import org.drools.verifier.builder.VerifierBuilderFactory;
48 import org.kie.api.io.ResourceType;
49 import org.onap.policy.common.logging.flexlogger.FlexLogger;
50 import org.onap.policy.common.logging.flexlogger.Logger;
51 import org.xml.sax.InputSource;
52 import org.xml.sax.XMLReader;
53
54 public class PolicyUtils {
55     private static final Logger LOGGER = FlexLogger.getLogger(PolicyUtils.class);
56     public static final String CATCH_EXCEPTION = "PE500: An exception was caught.";
57     public static final String EMAIL_PATTERN =
58             "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@" + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
59     private static final String PACKAGE_ERROR = "mismatched input '{' expecting one of the following tokens: '[package";
60     public static final String SUCCESS = "success";
61
62     private PolicyUtils() {
63         // Private Constructor
64     }
65
66     /**
67      * Converts an Object to JSON String.
68      *
69      * @param object Object
70      * @return String format of Object JSON.
71      * @throws JsonProcessingException JsonProcessingException
72      */
73     public static String objectToJsonString(Object object) throws JsonProcessingException {
74         return new ObjectMapper().writeValueAsString(object);
75     }
76
77     /**
78      * Converts JSON string into Object.
79      *
80      * @param jsonString Input JSON String
81      * @param className equivalent Class of the given JSON string
82      * @return T instance of the class given.
83      * @throws IOException IOException
84      */
85     public static <T> T jsonStringToObject(String jsonString, Class<T> className) throws IOException {
86         ObjectMapper mapper = new ObjectMapper();
87         return mapper.readValue(jsonString, className);
88     }
89
90     /**
91      * Decode a base64 string.
92      *
93      * @param encodedString String to encode
94      * @return String
95      * @throws UnsupportedEncodingException UnsupportedEncodingException
96      */
97     public static String decode(String encodedString) throws UnsupportedEncodingException {
98         if (encodedString != null && !encodedString.isEmpty()) {
99             return new String(Base64.getDecoder().decode(encodedString), "UTF-8");
100         } else {
101             return null;
102         }
103     }
104
105     /**
106      * Decodes Basic Authentication.
107      *
108      * @param encodedValue value to encode
109      * @return list of String
110      * @throws UnsupportedEncodingException UnsupportedEncodingException
111      */
112     public static String[] decodeBasicEncoding(String encodedValue) throws UnsupportedEncodingException {
113         if (encodedValue != null && encodedValue.contains("Basic ")) {
114             String encodedUserPassword = encodedValue.replaceFirst("Basic" + " ", "");
115             String usernameAndPassword;
116             byte[] decodedBytes = Base64.getDecoder().decode(encodedUserPassword);
117             usernameAndPassword = new String(decodedBytes, "UTF-8");
118             StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, ":");
119             String username = tokenizer.nextToken();
120             String password = tokenizer.nextToken();
121             return new String[] {username, password};
122         } else {
123             return new String[] {};
124         }
125     }
126
127     /**
128      * Validate a field if contains space or unacceptable policy input and return "success" if good.
129      *
130      * @param field String
131      * @return String
132      */
133     public static String policySpecialCharValidator(String field) {
134         String error;
135         if ("".equals(field) || field.contains(" ") || !field.matches("^[a-zA-Z0-9_]*$")) {
136             error = "The Value in Required Field will allow only"
137                     + " '{0-9}, {a-z}, {A-Z}, _' following set of Combinations";
138             return error;
139         }
140         return SUCCESS;
141     }
142
143     /**
144      * Validate a field (accepts space) if it contains unacceptable policy input and return "success" if good.
145      *
146      * @param field Input field String
147      * @return
148      */
149     public static String policySpecialCharWithSpaceValidator(String field) {
150         String error;
151         if ("".equals(field) || !field.matches("^[a-zA-Z0-9_ ]*$")) {
152             error = "The Value in Required Field will allow only "
153                     + "'{0-9}, {a-z}, {A-Z}, _' following set of Combinations";
154             return error;
155         }
156         return SUCCESS;
157     }
158
159     /**
160      * Validate a field (accepts Dash) if it contains unacceptable policy input and return "success" if good.
161      *
162      * @param field String
163      * @return String
164      */
165     public static String policySpecialCharWithDashValidator(String field) {
166         String error;
167         if ("".equals(field) || !field.matches("^[a-zA-Z0-9_-]*$")) {
168             error = "The Value in Required Field will allow only "
169                     + "'{0-9}, {a-z}, {A-Z}, _, -' following set of Combinations";
170             return error;
171         }
172         return SUCCESS;
173     }
174
175     /**
176      * Validate the XACML description tag and return "success" if good.
177      *
178      * @param field String
179      * @return String
180      */
181     public static String descriptionValidator(String field) {
182         String error;
183         if (field.contains("@CreatedBy:") || field.contains("@ModifiedBy:")) {
184             error = "The value in the description shouldn't contain @CreatedBy: or @ModifiedBy:";
185             return error;
186         } else {
187             error = SUCCESS;
188         }
189         return error;
190     }
191
192     /**
193      * Validate if string contains non ASCII characters.
194      *
195      * @param value String
196      * @return true if contains non ASCII characters
197      */
198     public static boolean containsNonAsciiEmptyChars(String value) {
199         return (value == null || value.contains(" ") || "".equals(value.trim())
200                 || !CharMatcher.ascii().matchesAllOf(value)) ? true : false;
201     }
202
203     /**
204      * Validate if given string is an integer.
205      *
206      * @param number String representing a number
207      * @return true if integer
208      */
209     public static Boolean isInteger(String number) {
210         if (number == null) {
211             return false;
212         }
213         for (char c : number.toCharArray()) {
214             if (!Character.isDigit(c)) {
215                 return false;
216             }
217         }
218         return true;
219     }
220
221     /**
222      * Validate Email Address and return "success" if good.
223      *
224      * @param emailAddressValue String email address
225      * @return SUCCESS String if valid
226      */
227     public static String validateEmailAddress(String emailAddressValue) {
228         String error = SUCCESS;
229         List<String> emailList = Arrays.asList(emailAddressValue.split(","));
230         for (int i = 0; i < emailList.size(); i++) {
231             Pattern pattern = Pattern.compile(EMAIL_PATTERN);
232             Matcher matcher = pattern.matcher(emailList.get(i).trim());
233             if (!matcher.matches()) {
234                 error = "Please check the Following Email Address is not Valid ....   " + emailList.get(i);
235                 return error;
236             } else {
237                 error = SUCCESS;
238             }
239         }
240         return error;
241     }
242
243     /**
244      * Validates BRMS rule as per Policy Platform and return string contains "[ERR" if there are any errors.
245      *
246      * @param rule BRMS Rule
247      * @return String error message
248      */
249     public static String brmsRawValidate(String rule) {
250         Verifier verifier = VerifierBuilderFactory.newVerifierBuilder().newVerifier();
251         verifier.addResourcesToVerify(new ReaderResource(new StringReader(rule)), ResourceType.DRL);
252         // Check if there are any Errors in Verification.
253         if (!verifier.getErrors().isEmpty()) {
254             boolean ignore = false;
255             StringBuilder message = new StringBuilder("Not a Valid DRL rule");
256             for (VerifierError error : verifier.getErrors()) {
257                 // Ignore annotations Error Messages
258                 if (!error.getMessage().contains("'@'") && !error.getMessage().contains(PACKAGE_ERROR)) {
259                     ignore = true;
260                     message.append("\n" + error.getMessage());
261                 }
262             }
263             // Ignore new package names with '{'
264             // More checks for message to check if its a package error.
265             if (ignore && !message.toString().contains("Parser returned a null Package")) {
266                 message.append("[ERR 107]");
267             }
268             return message.toString();
269         }
270         return "";
271     }
272
273     /**
274      * Validates if the given string is proper JSON format.
275      *
276      * @param data JSON data
277      * @return true if it is JSON
278      */
279     public static boolean isJSONValid(String data) {
280         try {
281             JsonParser parser = new JsonParser();
282             parser.parse(data);
283         } catch (JsonSyntaxException e) {
284             LOGGER.error("Exception Occurred While Validating" + e);
285             return false;
286         }
287         return true;
288     }
289
290     /**
291      * Validates if the given string is proper XML format.
292      *
293      * @param data XML data
294      * @return true if it is XML
295      */
296     public static boolean isXMLValid(String data) {
297         if (data == null || data.isEmpty()) {
298             return false;
299         }
300         SAXParserFactory factory = SAXParserFactory.newInstance();
301         factory.setValidating(false);
302         factory.setNamespaceAware(true);
303
304         try {
305             factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
306             SAXParser parser = factory.newSAXParser();
307             XMLReader reader = parser.getXMLReader();
308             reader.setErrorHandler(new XMLErrorHandler());
309             reader.parse(new InputSource(new StringReader(data)));
310         } catch (Exception e) {
311             LOGGER.error("Exception Occured While Validating" + e);
312             return false;
313         }
314         return true;
315     }
316
317     /**
318      * Validates if given string is valid Properties format.
319      *
320      * @param prop String of properties
321      * @return is valid property format
322      */
323     public static boolean isPropValid(String prop) {
324         Scanner scanner = new Scanner(prop);
325         while (scanner.hasNextLine()) {
326             String line = scanner.nextLine();
327             line = line.replaceAll("\\s+", "");
328             if (! line.startsWith("#")) {
329                 if (line.contains("=")) {
330                     String[] parts = line.split("=");
331                     if (parts.length < 2) {
332                         scanner.close();
333                         return false;
334                     }
335                 } else if (!line.trim().isEmpty()) {
336                     scanner.close();
337                     return false;
338                 }
339             }
340         }
341         scanner.close();
342         return true;
343     }
344
345     /**
346      * Given a version string consisting of integers with dots between them, convert it into an array of integers.
347      *
348      * @param version String representing the version
349      * @return array of int
350      * @throws NumberFormatException NumberFormatException
351      */
352     public static int[] versionStringToArray(String version) {
353         if (version == null || version.length() == 0) {
354             return new int[0];
355         }
356         String[] stringArray = version.split("\\.");
357         int[] resultArray = new int[stringArray.length];
358         for (int i = 0; i < stringArray.length; i++) {
359             resultArray[i] = Integer.parseInt(stringArray[i].trim());
360         }
361         return resultArray;
362     }
363 }