d2ab80346c61a8649859db59791f198d47415def
[dmaap/datarouter.git] / datarouter-node / src / main / java / org / onap / dmaap / datarouter / node / NodeUtils.java
1 /*******************************************************************************
2  * ============LICENSE_START==================================================
3  * * org.onap.dmaap
4  * * ===========================================================================
5  * * Copyright © 2017 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  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  * *
22  ******************************************************************************/
23
24
25 package org.onap.dmaap.datarouter.node;
26
27 import com.att.eelf.configuration.EELFLogger;
28 import com.att.eelf.configuration.EELFManager;
29
30 import java.io.File;
31 import java.io.FileInputStream;
32 import java.io.IOException;
33 import java.net.InetAddress;
34 import java.security.KeyStore;
35 import java.security.MessageDigest;
36 import java.security.cert.X509Certificate;
37 import java.text.SimpleDateFormat;
38 import java.util.Date;
39 import java.util.Enumeration;
40 import java.util.TimeZone;
41 import java.util.UUID;
42 import java.util.zip.GZIPInputStream;
43 import javax.servlet.http.HttpServletRequest;
44 import javax.servlet.http.HttpServletResponse;
45 import org.apache.commons.codec.binary.Base64;
46 import org.apache.commons.lang3.StringUtils;
47 import org.apache.log4j.Logger;
48 import org.onap.dmaap.datarouter.node.eelf.EelfMsgs;
49 import org.slf4j.MDC;
50
51 import static com.att.eelf.configuration.Configuration.*;
52
53 /**
54  * Utility functions for the data router node
55  */
56 public class NodeUtils {
57
58     private static EELFLogger eelfLogger = EELFManager.getInstance()
59             .getLogger(NodeUtils.class);
60     private static Logger nodeUtilsLogger = Logger.getLogger("org.onap.dmaap.datarouter.node.NodeUtils");
61
62     private NodeUtils() {
63     }
64
65     /**
66      * Base64 encode a byte array
67      *
68      * @param  raw The bytes to be encoded
69      * @return The encoded string
70      */
71     public static String base64Encode(byte[] raw) {
72         return (Base64.encodeBase64String(raw));
73     }
74
75     /**
76      * Given a user and password, generate the credentials
77      *
78      * @param user User name
79      * @param password User password
80      * @return Authorization header value
81      */
82     public static String getAuthHdr(String user, String password) {
83         if (user == null || password == null) {
84             return (null);
85         }
86         return ("Basic " + base64Encode((user + ":" + password).getBytes()));
87     }
88
89     /**
90      * Given a node name, generate the credentials
91      *
92      * @param node Node name
93      */
94     public static String getNodeAuthHdr(String node, String key) {
95         try {
96             MessageDigest md = MessageDigest.getInstance("SHA");
97             md.update(key.getBytes());
98             md.update(node.getBytes());
99             md.update(key.getBytes());
100             return (getAuthHdr(node, base64Encode(md.digest())));
101         } catch (Exception exception) {
102             nodeUtilsLogger
103                     .error("Exception in generating Credentials for given node name:= " + exception.toString(),
104                             exception);
105             return (null);
106         }
107     }
108
109     /**
110      * Given a keystore file and its password, return the value of the CN of the first private key entry with a
111      * certificate.
112      *
113      * @param kstype The type of keystore
114      * @param ksfile The file name of the keystore
115      * @param kspass The password of the keystore
116      * @return CN of the certificate subject or null
117      */
118     public static String getCanonicalName(String kstype, String ksfile, String kspass) {
119         KeyStore ks;
120         try {
121             ks = KeyStore.getInstance(kstype);
122             try (FileInputStream fileInputStream = new FileInputStream(ksfile)) {
123                 ks.load(fileInputStream, kspass.toCharArray());
124             } catch (IOException ioException) {
125                 nodeUtilsLogger.error("IOException occurred while opening FileInputStream: " + ioException.getMessage(),
126                         ioException);
127                 return (null);
128             }
129         } catch (Exception e) {
130             setIpAndFqdnForEelf("getCanonicalName");
131             eelfLogger.error(EelfMsgs.MESSAGE_KEYSTORE_LOAD_ERROR, ksfile, e.toString());
132             nodeUtilsLogger.error("NODE0401 Error loading my keystore file + " + ksfile + " " + e.toString(), e);
133             return (null);
134         }
135         return (getCanonicalName(ks));
136     }
137
138     /**
139      * Given a keystore, return the value of the CN of the first private key entry with a certificate.
140      *
141      * @param ks The KeyStore
142      * @return CN of the certificate subject or null
143      */
144     public static String getCanonicalName(KeyStore ks) {
145         try {
146             Enumeration<String> aliases = ks.aliases();
147             while (aliases.hasMoreElements()) {
148                 String s = aliases.nextElement();
149                 if (ks.entryInstanceOf(s, KeyStore.PrivateKeyEntry.class)) {
150                     X509Certificate c = (X509Certificate) ks.getCertificate(s);
151                     if (c != null) {
152                         String subject = c.getSubjectX500Principal().getName();
153                         String[] parts = subject.split(",");
154                         if (parts.length < 1) {
155                             return (null);
156                         }
157                         subject = parts[5].trim();
158                         if (!subject.startsWith("CN=")) {
159                             return (null);
160
161                         }
162                         return (subject.substring(3));
163                     }
164                 }
165             }
166         } catch (Exception e) {
167             nodeUtilsLogger.error("NODE0402 Error extracting my name from my keystore file " + e.toString(), e);
168         }
169         return (null);
170     }
171
172     /**
173      * Given a string representation of an IP address, get the corresponding byte array
174      *
175      * @param ip The IP address as a string
176      * @return The IP address as a byte array or null if the address is invalid
177      */
178     public static byte[] getInetAddress(String ip) {
179         try {
180             return (InetAddress.getByName(ip).getAddress());
181         } catch (Exception exception) {
182             nodeUtilsLogger
183                     .error("Exception in generating byte array for given IP address := " + exception.toString(),
184                             exception);
185         }
186         return (null);
187     }
188
189     /**
190      * Given a uri with parameters, split out the feed ID and file ID
191      */
192     public static String[] getFeedAndFileID(String uriandparams) {
193         int end = uriandparams.length();
194         int i = uriandparams.indexOf('#');
195         if (i != -1 && i < end) {
196             end = i;
197         }
198         i = uriandparams.indexOf('?');
199         if (i != -1 && i < end) {
200             end = i;
201         }
202         end = uriandparams.lastIndexOf('/', end);
203         if (end < 2) {
204             return (null);
205         }
206         i = uriandparams.lastIndexOf('/', end - 1);
207         if (i == -1) {
208             return (null);
209         }
210         return (new String[]{uriandparams.substring(i + 1, end), uriandparams.substring(end + 1)});
211     }
212
213     /**
214      * Escape fields that might contain vertical bar, backslash, or newline by replacing them with backslash p,
215      * backslash e and backslash n.
216      */
217     public static String loge(String s) {
218         if (s == null) {
219             return (s);
220         }
221         return (s.replaceAll("\\\\", "\\\\e").replaceAll("\\|", "\\\\p").replaceAll("\n", "\\\\n"));
222     }
223
224     /**
225      * Undo what loge does.
226      */
227     public static String unloge(String s) {
228         if (s == null) {
229             return (s);
230         }
231         return (s.replaceAll("\\\\p", "\\|").replaceAll("\\\\n", "\n").replaceAll("\\\\e", "\\\\"));
232     }
233
234     /**
235      * Format a logging timestamp as yyyy-mm-ddThh:mm:ss.mmmZ
236      */
237     public static String logts(long when) {
238         return (logts(new Date(when)));
239     }
240
241     /**
242      * Format a logging timestamp as yyyy-mm-ddThh:mm:ss.mmmZ
243      */
244     public static synchronized String logts(Date when) {
245         SimpleDateFormat logDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
246         logDate.setTimeZone(TimeZone.getTimeZone("GMT"));
247         return (logDate.format(when));
248     }
249
250     /* Method prints method name, server FQDN and IP Address of the machine in EELF logs
251      * @Method - setIpAndFqdnForEelf - Rally:US664892
252      * @Params - method, prints method name in EELF log.
253      */
254     public static void setIpAndFqdnForEelf(String method) {
255         MDC.clear();
256         MDC.put(MDC_SERVICE_NAME, method);
257         try {
258             MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
259             MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
260         } catch (Exception exception) {
261             nodeUtilsLogger
262                     .error("Exception in generating byte array for given IP address := " + exception.toString(),
263                             exception);
264         }
265
266     }
267
268     /* Method sets RequestIs and InvocationId for se in EELF logs
269      * @Method - setIpAndFqdnForEelf
270      * @Params - Req, Request used to get RequestId and InvocationId
271      */
272     public static void setRequestIdAndInvocationId(HttpServletRequest req) {
273         String reqId = req.getHeader("X-ONAP-RequestID");
274         if (StringUtils.isBlank(reqId)) {
275             reqId = UUID.randomUUID().toString();
276         }
277         MDC.put(MDC_KEY_REQUEST_ID, reqId);
278         String invId = req.getHeader("X-InvocationID");
279         if (StringUtils.isBlank(invId)) {
280             invId = UUID.randomUUID().toString();
281         }
282         MDC.put("InvocationId", invId);
283     }
284
285     public static void sendResponseError(HttpServletResponse response, int errorCode, Logger intlogger) {
286         try {
287             response.sendError(errorCode);
288         } catch (IOException ioe) {
289             intlogger.error("IOException" + ioe.getMessage());
290         }
291     }
292
293     /**
294      * Method to check to see if file is of type gzip
295      *
296      * @param   file The name of the file to be checked
297      * @return  True if the file is of type gzip
298      */
299     public static boolean isFiletypeGzip(File file){
300         try(FileInputStream fileInputStream = new FileInputStream(file);
301             GZIPInputStream gzip = new GZIPInputStream(fileInputStream)) {
302
303             return true;
304         }catch (IOException e){
305             nodeUtilsLogger.error("NODE0403 " + file.toString() + " Not in gzip(gz) format: " + e.toString() + e);
306             return false;
307         }
308     }
309
310
311 }