Consolidate PolicyRestAdapter setup
[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     private static final String PACKAGE_ERROR = "mismatched input '{' expecting one of the following tokens: '[package";
57
58     public static final String CATCH_EXCEPTION = "PE500: An exception was caught.";
59     public static final String EMAIL_PATTERN =
60             "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@" + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
61     public static final String SUCCESS = "success";
62     public static final String CHARACTER_ENCODING = "UTF-8";
63     public static final String APPLICATION_JSON = "application/json";
64
65     private PolicyUtils() {
66         // Private Constructor
67     }
68
69     /**
70      * Converts an Object to JSON String.
71      *
72      * @param object Object
73      * @return String format of Object JSON.
74      * @throws JsonProcessingException JsonProcessingException
75      */
76     public static String objectToJsonString(Object object) throws JsonProcessingException {
77         return new ObjectMapper().writeValueAsString(object);
78     }
79
80     /**
81      * Converts JSON string into Object.
82      *
83      * @param jsonString Input JSON String
84      * @param className equivalent Class of the given JSON string
85      * @return T instance of the class given.
86      * @throws IOException IOException
87      */
88     public static <T> T jsonStringToObject(String jsonString, Class<T> className) throws IOException {
89         ObjectMapper mapper = new ObjectMapper();
90         return mapper.readValue(jsonString, className);
91     }
92
93     /**
94      * Decode a base64 string.
95      *
96      * @param encodedString String to encode
97      * @return String
98      * @throws UnsupportedEncodingException UnsupportedEncodingException
99      */
100     public static String decode(String encodedString) throws UnsupportedEncodingException {
101         if (encodedString != null && !encodedString.isEmpty()) {
102             return new String(Base64.getDecoder().decode(encodedString), "UTF-8");
103         } else {
104             return null;
105         }
106     }
107
108     /**
109      * Decodes Basic Authentication.
110      *
111      * @param encodedValue value to encode
112      * @return list of String
113      * @throws UnsupportedEncodingException UnsupportedEncodingException
114      */
115     public static String[] decodeBasicEncoding(String encodedValue) throws UnsupportedEncodingException {
116         if (encodedValue != null && encodedValue.contains("Basic ")) {
117             String encodedUserPassword = encodedValue.replaceFirst("Basic" + " ", "");
118             String usernameAndPassword;
119             byte[] decodedBytes = Base64.getDecoder().decode(encodedUserPassword);
120             usernameAndPassword = new String(decodedBytes, "UTF-8");
121             StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, ":");
122             String username = tokenizer.nextToken();
123             String password = tokenizer.nextToken();
124             return new String[] {username, password};
125         } else {
126             return new String[] {};
127         }
128     }
129
130     /**
131      * Validate a field if contains space or unacceptable policy input and return "success" if good.
132      *
133      * @param field String
134      * @return String
135      */
136     public static String policySpecialCharValidator(String field) {
137         String error;
138         if ("".equals(field) || field.contains(" ") || !field.matches("^[a-zA-Z0-9_]*$")) {
139             error = "The Value in Required Field will allow only"
140                     + " '{0-9}, {a-z}, {A-Z}, _' following set of Combinations";
141             return error;
142         }
143         return SUCCESS;
144     }
145
146     /**
147      * Validate a field (accepts space) if it contains unacceptable policy input and return "success" if good.
148      *
149      * @param field Input field String
150      * @return
151      */
152     public static String policySpecialCharWithSpaceValidator(String field) {
153         String error;
154         if ("".equals(field) || !field.matches("^[a-zA-Z0-9_ ]*$")) {
155             error = "The Value in Required Field will allow only "
156                     + "'{0-9}, {a-z}, {A-Z}, _' following set of Combinations";
157             return error;
158         }
159         return SUCCESS;
160     }
161
162     /**
163      * Validate a field (accepts Dash) if it contains unacceptable policy input and return "success" if good.
164      *
165      * @param field String
166      * @return String
167      */
168     public static String policySpecialCharWithDashValidator(String field) {
169         String error;
170         if ("".equals(field) || !field.matches("^[a-zA-Z0-9_-]*$")) {
171             error = "The Value in Required Field will allow only "
172                     + "'{0-9}, {a-z}, {A-Z}, _, -' following set of Combinations";
173             return error;
174         }
175         return SUCCESS;
176     }
177
178     /**
179      * Validate the XACML description tag and return "success" if good.
180      *
181      * @param field String
182      * @return String
183      */
184     public static String descriptionValidator(String field) {
185         String error;
186         if (field.contains("@CreatedBy:") || field.contains("@ModifiedBy:")) {
187             error = "The value in the description shouldn't contain @CreatedBy: or @ModifiedBy:";
188             return error;
189         } else {
190             error = SUCCESS;
191         }
192         return error;
193     }
194
195     /**
196      * Validate if string contains non ASCII characters.
197      *
198      * @param value String
199      * @return true if contains non ASCII characters
200      */
201     public static boolean containsNonAsciiEmptyChars(String value) {
202         return (value == null || value.contains(" ") || "".equals(value.trim())
203                 || !CharMatcher.ascii().matchesAllOf(value)) ? true : false;
204     }
205
206     /**
207      * Validate if given string is an integer.
208      *
209      * @param number String representing a number
210      * @return true if integer
211      */
212     public static Boolean isInteger(String number) {
213         if (number == null) {
214             return false;
215         }
216         for (char c : number.toCharArray()) {
217             if (!Character.isDigit(c)) {
218                 return false;
219             }
220         }
221         return true;
222     }
223
224     /**
225      * Validate Email Address and return "success" if good.
226      *
227      * @param emailAddressValue String email address
228      * @return SUCCESS String if valid
229      */
230     public static String validateEmailAddress(String emailAddressValue) {
231         String error = SUCCESS;
232         List<String> emailList = Arrays.asList(emailAddressValue.split(","));
233         for (int i = 0; i < emailList.size(); i++) {
234             Pattern pattern = Pattern.compile(EMAIL_PATTERN);
235             Matcher matcher = pattern.matcher(emailList.get(i).trim());
236             if (!matcher.matches()) {
237                 error = "Please check the Following Email Address is not Valid ....   " + emailList.get(i);
238                 return error;
239             } else {
240                 error = SUCCESS;
241             }
242         }
243         return error;
244     }
245
246     /**
247      * Validates BRMS rule as per Policy Platform and return string contains "[ERR" if there are any errors.
248      *
249      * @param rule BRMS Rule
250      * @return String error message
251      */
252     public static String brmsRawValidate(String rule) {
253         Verifier verifier = VerifierBuilderFactory.newVerifierBuilder().newVerifier();
254         verifier.addResourcesToVerify(new ReaderResource(new StringReader(rule)), ResourceType.DRL);
255         // Check if there are any Errors in Verification.
256         if (!verifier.getErrors().isEmpty()) {
257             boolean ignore = false;
258             StringBuilder message = new StringBuilder("Not a Valid DRL rule");
259             for (VerifierError error : verifier.getErrors()) {
260                 // Ignore annotations Error Messages
261                 if (!error.getMessage().contains("'@'") && !error.getMessage().contains(PACKAGE_ERROR)) {
262                     ignore = true;
263                     message.append("\n" + error.getMessage());
264                 }
265             }
266             // Ignore new package names with '{'
267             // More checks for message to check if its a package error.
268             if (ignore && !message.toString().contains("Parser returned a null Package")) {
269                 message.append("[ERR 107]");
270             }
271             return message.toString();
272         }
273         return "";
274     }
275
276     /**
277      * Validates if the given string is proper JSON format.
278      *
279      * @param data JSON data
280      * @return true if it is JSON
281      */
282     public static boolean isJSONValid(String data) {
283         try {
284             JsonParser parser = new JsonParser();
285             parser.parse(data);
286         } catch (JsonSyntaxException e) {
287             LOGGER.error("Exception Occurred While Validating" + e);
288             return false;
289         }
290         return true;
291     }
292
293     /**
294      * Validates if the given string is proper XML format.
295      *
296      * @param data XML data
297      * @return true if it is XML
298      */
299     public static boolean isXMLValid(String data) {
300         if (data == null || data.isEmpty()) {
301             return false;
302         }
303         SAXParserFactory factory = SAXParserFactory.newInstance();
304         factory.setValidating(false);
305         factory.setNamespaceAware(true);
306
307         try {
308             factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
309             SAXParser parser = factory.newSAXParser();
310             XMLReader reader = parser.getXMLReader();
311             reader.setErrorHandler(new XMLErrorHandler());
312             reader.parse(new InputSource(new StringReader(data)));
313         } catch (Exception e) {
314             LOGGER.error("Exception Occured While Validating" + e);
315             return false;
316         }
317         return true;
318     }
319
320     /**
321      * Validates if given string is valid Properties format.
322      *
323      * @param prop String of properties
324      * @return is valid property format
325      */
326     public static boolean isPropValid(String prop) {
327         Scanner scanner = new Scanner(prop);
328         while (scanner.hasNextLine()) {
329             String line = scanner.nextLine();
330             line = line.replaceAll("\\s+", "");
331             if (! line.startsWith("#")) {
332                 if (line.contains("=")) {
333                     String[] parts = line.split("=");
334                     if (parts.length < 2) {
335                         scanner.close();
336                         return false;
337                     }
338                 } else if (!line.trim().isEmpty()) {
339                     scanner.close();
340                     return false;
341                 }
342             }
343         }
344         scanner.close();
345         return true;
346     }
347
348     /**
349      * Given a version string consisting of integers with dots between them, convert it into an array of integers.
350      *
351      * @param version String representing the version
352      * @return array of int
353      * @throws NumberFormatException NumberFormatException
354      */
355     public static int[] versionStringToArray(String version) {
356         if (version == null || version.length() == 0) {
357             return new int[0];
358         }
359         String[] stringArray = version.split("\\.");
360         int[] resultArray = new int[stringArray.length];
361         for (int i = 0; i < stringArray.length; i++) {
362             resultArray[i] = Integer.parseInt(stringArray[i].trim());
363         }
364         return resultArray;
365     }
366 }