1 /*******************************************************************************
2 * ============LICENSE_START==================================================
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
11 * * http://www.apache.org/licenses/LICENSE-2.0
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====================================================
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 ******************************************************************************/
25 package org.onap.dmaap.datarouter.node;
27 import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
28 import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN;
29 import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS;
30 import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
32 import com.att.eelf.configuration.EELFLogger;
33 import com.att.eelf.configuration.EELFManager;
35 import java.io.FileInputStream;
36 import java.io.IOException;
37 import java.net.InetAddress;
38 import java.security.KeyStore;
39 import java.security.KeyStoreException;
40 import java.security.MessageDigest;
41 import java.security.NoSuchAlgorithmException;
42 import java.security.cert.CertificateException;
43 import java.security.cert.X509Certificate;
44 import java.text.SimpleDateFormat;
45 import java.util.Date;
46 import java.util.Enumeration;
47 import java.util.TimeZone;
48 import java.util.UUID;
49 import java.util.zip.GZIPInputStream;
50 import javax.naming.InvalidNameException;
51 import javax.naming.ldap.LdapName;
52 import javax.naming.ldap.Rdn;
53 import javax.servlet.http.HttpServletRequest;
54 import javax.servlet.http.HttpServletResponse;
55 import org.apache.commons.codec.binary.Base64;
56 import org.apache.commons.lang3.StringUtils;
57 import org.onap.dmaap.datarouter.node.eelf.EelfMsgs;
61 * Utility functions for the data router node.
63 public class NodeUtils {
65 private static EELFLogger eelfLogger = EELFManager.getInstance()
66 .getLogger(NodeUtils.class);
72 * Base64 encode a byte array.
74 * @param raw The bytes to be encoded
75 * @return The encoded string
77 public static String base64Encode(byte[] raw) {
78 return (Base64.encodeBase64String(raw));
82 * Given a user and password, generate the credentials.
84 * @param user User name
85 * @param password User password
86 * @return Authorization header value
88 public static String getAuthHdr(String user, String password) {
89 if (user == null || password == null) {
92 return ("Basic " + base64Encode((user + ":" + password).getBytes()));
96 * Given a node name, generate the credentials.
98 * @param node Node name
100 public static String getNodeAuthHdr(String node, String key) {
102 MessageDigest md = MessageDigest.getInstance("SHA");
103 md.update(key.getBytes());
104 md.update(node.getBytes());
105 md.update(key.getBytes());
106 return (getAuthHdr(node, base64Encode(md.digest())));
107 } catch (Exception exception) {
109 .error("Exception in generating Credentials for given node name:= " + exception.toString(),
116 * Given a keystore file and its password, return the value of the CN of the first private key entry with a
119 * @param kstype The type of keystore
120 * @param ksfile The file name of the keystore
121 * @param kspass The password of the keystore
122 * @return CN of the certificate subject or null
124 public static String getCanonicalName(String kstype, String ksfile, String kspass) {
127 ks = KeyStore.getInstance(kstype);
128 if (loadKeyStore(ksfile, kspass, ks)) {
131 } catch (Exception e) {
132 setIpAndFqdnForEelf("getCanonicalName");
133 eelfLogger.error(EelfMsgs.MESSAGE_KEYSTORE_LOAD_ERROR, e, ksfile);
136 return (getCanonicalName(ks));
140 * Given a keystore, return the value of the CN of the first private key entry with a certificate.
142 * @param ks The KeyStore
143 * @return CN of the certificate subject or null
145 public static String getCanonicalName(KeyStore ks) {
147 Enumeration<String> aliases = ks.aliases();
148 while (aliases.hasMoreElements()) {
149 String name = getNameFromSubject(ks, aliases);
154 } catch (Exception e) {
155 eelfLogger.error("NODE0402 Error extracting my name from my keystore file " + e.toString(), e);
161 * Given a string representation of an IP address, get the corresponding byte array.
163 * @param ip The IP address as a string
164 * @return The IP address as a byte array or null if the address is invalid
166 public static byte[] getInetAddress(String ip) {
168 return (InetAddress.getByName(ip).getAddress());
169 } catch (Exception exception) {
171 .error("Exception in generating byte array for given IP address := " + exception.toString(),
178 * Given a uri with parameters, split out the feed ID and file ID.
180 public static String[] getFeedAndFileID(String uriandparams) {
181 int end = uriandparams.length();
182 int index = uriandparams.indexOf('#');
183 if (index != -1 && index < end) {
186 index = uriandparams.indexOf('?');
187 if (index != -1 && index < end) {
190 end = uriandparams.lastIndexOf('/', end);
194 index = uriandparams.lastIndexOf('/', end - 1);
198 return (new String[]{uriandparams.substring(index + 1, end), uriandparams.substring(end + 1)});
202 * Escape fields that might contain vertical bar, backslash, or newline by replacing them with backslash p,
203 * backslash e and backslash n.
205 public static String loge(String string) {
206 if (string == null) {
209 return (string.replaceAll("\\\\", "\\\\e").replaceAll("\\|", "\\\\p").replaceAll("\n", "\\\\n"));
213 * Undo what loge does.
215 public static String unloge(String string) {
216 if (string == null) {
219 return (string.replaceAll("\\\\p", "\\|").replaceAll("\\\\n", "\n").replaceAll("\\\\e", "\\\\"));
223 * Format a logging timestamp as yyyy-mm-ddThh:mm:ss.mmmZ
225 public static String logts(long when) {
226 return (logts(new Date(when)));
230 * Format a logging timestamp as yyyy-mm-ddThh:mm:ss.mmmZ
232 public static synchronized String logts(Date when) {
233 SimpleDateFormat logDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
234 logDate.setTimeZone(TimeZone.getTimeZone("GMT"));
235 return (logDate.format(when));
238 /** Method prints method name, server FQDN and IP Address of the machine in EELF logs.
240 * @param method Prints method name in EELF log.
242 public static void setIpAndFqdnForEelf(String method) {
244 MDC.put(MDC_SERVICE_NAME, method);
246 MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
247 MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
248 } catch (Exception exception) {
250 .error("Exception in generating byte array for given IP address := " + exception.toString(),
256 /** Method sets RequestIs and InvocationId for se in EELF logs.
258 * @param req Request used to get RequestId and InvocationId.
260 public static void setRequestIdAndInvocationId(HttpServletRequest req) {
261 String reqId = req.getHeader("X-ONAP-RequestID");
262 if (StringUtils.isBlank(reqId)) {
263 reqId = UUID.randomUUID().toString();
265 MDC.put(MDC_KEY_REQUEST_ID, reqId);
266 String invId = req.getHeader("X-InvocationID");
267 if (StringUtils.isBlank(invId)) {
268 invId = UUID.randomUUID().toString();
270 MDC.put("InvocationId", invId);
274 * Sends error as response with error code input.
276 public static void sendResponseError(HttpServletResponse response, int errorCode, EELFLogger intlogger) {
278 response.sendError(errorCode);
279 } catch (IOException ioe) {
280 intlogger.error("IOException", ioe);
285 * Method to check to see if file is of type gzip.
287 * @param file The name of the file to be checked
288 * @return True if the file is of type gzip
290 public static boolean isFiletypeGzip(File file) {
291 try (FileInputStream fileInputStream = new FileInputStream(file);
292 GZIPInputStream gzip = new GZIPInputStream(fileInputStream)) {
295 } catch (IOException e) {
296 eelfLogger.error("NODE0403 " + file.toString() + " Not in gzip(gz) format: " + e.toString() + e);
302 private static boolean loadKeyStore(String ksfile, String kspass, KeyStore ks)
303 throws NoSuchAlgorithmException, CertificateException {
304 try (FileInputStream fileInputStream = new FileInputStream(ksfile)) {
305 ks.load(fileInputStream, kspass.toCharArray());
306 } catch (IOException ioException) {
307 eelfLogger.error("IOException occurred while opening FileInputStream: " + ioException.getMessage(),
315 private static String getNameFromSubject(KeyStore ks, Enumeration<String> aliases) throws KeyStoreException {
316 String alias = aliases.nextElement();
317 if (ks.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)) {
318 X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
320 String subject = cert.getSubjectX500Principal().getName();
322 LdapName ln = new LdapName(subject);
323 for (Rdn rdn : ln.getRdns()) {
324 if (rdn.getType().equalsIgnoreCase("CN")) {
325 return rdn.getValue().toString();
328 } catch (InvalidNameException e) {
329 eelfLogger.error("No valid CN not found for dr-node cert", e);