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