Remove diffutils dependency
[aai/traversal.git] / aai-traversal / src / main / java / org / onap / aai / interceptors / AAILogJAXRSInInterceptor.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
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 package org.onap.aai.interceptors;
23
24 import java.io.InputStream;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.UUID;
30 import java.util.regex.Matcher;
31 import java.util.regex.Pattern;
32
33 import javax.ws.rs.core.MediaType;
34
35 import org.apache.commons.io.IOUtils;
36 import org.apache.cxf.helpers.CastUtils;
37 import org.apache.cxf.interceptor.LoggingMessage;
38 import org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor;
39 import org.apache.cxf.message.Message;
40 import org.onap.aai.exceptions.AAIException;
41 import org.onap.aai.logging.ErrorLogHelper;
42 import org.onap.aai.rest.util.EchoResponse;
43 import org.onap.aai.util.AAIConfig;
44 import org.onap.aai.util.AAIConstants;
45 import org.onap.aai.util.FormatDate;
46 import org.onap.aai.util.HbaseSaltPrefixer;
47
48 import com.att.eelf.configuration.EELFLogger;
49 import com.att.eelf.configuration.EELFManager;
50 import org.slf4j.MDC;
51
52 public class AAILogJAXRSInInterceptor extends JAXRSInInterceptor {
53
54         protected final String COMPONENT = "aairest";
55         protected final String CAMEL_REQUEST ="CamelHttpUrl";
56         private static final Pattern uuidPattern = Pattern.compile("^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$");
57         private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(AAILogJAXRSInInterceptor.class);
58         
59         /**
60          * {@inheritDoc}
61          */
62         public void handleMessage(Message message) {
63
64                 boolean go = false;
65                 String uri = null;
66                 String query = null;
67                 try {
68                 
69                         uri = (String)message.get(CAMEL_REQUEST);
70                         if (uri != null) { 
71                                 query = (String)message.get(Message.QUERY_STRING);
72                         }
73                         
74                         if (AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_INTERCEPTOR).equalsIgnoreCase("true") &&
75                                         AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_ENABLED).equalsIgnoreCase("true")) {
76                                 go = true;
77                                 message.getExchange().put("AAI_LOGGING_HBASE_ENABLED", 1);
78                                 if (AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_LOGREQUEST).equalsIgnoreCase("true") ) {
79                                         message.getExchange().put("AAI_LOGGING_HBASE_LOGREQUEST", 1);
80                                 }
81                                 if (AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_LOGRESPONSE).equalsIgnoreCase("true") ) {
82                                         message.getExchange().put("AAI_LOGGING_HBASE_LOGRESPONSE", 1);
83                                 }
84                         }
85                         if (AAIConfig.get(AAIConstants.AAI_LOGGING_TRACE_ENABLED).equalsIgnoreCase("true") ) {
86                                 go = true;
87                                 message.getExchange().put("AAI_LOGGING_TRACE_ENABLED", 1);
88                                 if (AAIConfig.get(AAIConstants.AAI_LOGGING_TRACE_LOGREQUEST).equalsIgnoreCase("true") ) {
89                                         message.getExchange().put("AAI_LOGGING_TRACE_LOGREQUEST", 1);
90                                 }
91                                 if (AAIConfig.get(AAIConstants.AAI_LOGGING_TRACE_LOGRESPONSE).equalsIgnoreCase("true") ) {
92                                         message.getExchange().put("AAI_LOGGING_TRACE_LOGRESPONSE", 1);
93                                 }
94                         }
95                 } catch (AAIException e1) {
96                         ErrorLogHelper.logException(e1);
97                 }
98                 
99                 if ((uri != null) && (uri.contains(EchoResponse.echoPath))) {
100                         // if it's a health check, we don't want to log ANYTHING if it's a lightweight one
101                         if (query == null) {
102                                 if (message.getExchange().containsKey("AAI_LOGGING_HBASE_ENABLED")) {
103                                         message.getExchange().remove("AAI_LOGGING_HBASE_ENABLED");
104                                 }
105                                 if (message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) { 
106                                         message.getExchange().remove("AAI_LOGGING_TRACE_ENABLED");
107                                 }
108                                 go = false;
109                         }
110                 }
111                 else if ((uri != null) && (uri.contains("/translog/"))) {
112                         // if it's a translog query, we don't want to log the responses
113                         if (message.getExchange().containsKey("AAI_LOGGING_HBASE_LOGRESPONSE")) {
114                                 message.getExchange().remove("AAI_LOGGING_HBASE_LOGRESPONSE");
115                         }
116                         if (message.getExchange().containsKey("AAI_LOGGING_TRACE_LOGRESPONSE")) {
117                                 message.getExchange().remove("AAI_LOGGING_TRACE_LOGRESPONSE");
118                         }
119                 }
120                 
121                 if (go == false) { // there's nothing to do 
122                         return;
123                 }
124
125                 // DONE: get a TXID based on hostname, time (YYYYMMDDHHMMSSMILLIS,  and LoggingMessage.nextId(); 20150326145301-1
126                 String now = genDate();
127
128                 message.getExchange().put("AAI_RQST_TM", now);
129
130                 String id = (String)message.getExchange().get(LoggingMessage.ID_KEY);
131
132                 String fullId = null;
133                 try {
134                         if (id == null) {
135                                 id = LoggingMessage.nextId();
136                         }
137                         fullId = AAIConfig.get(AAIConstants.AAI_NODENAME) + "-" + now + "-" + id;
138                         fullId = HbaseSaltPrefixer.getInstance().prependSalt(fullId);
139                         message.getExchange().put(LoggingMessage.ID_KEY, fullId);
140                 } catch (AAIException e1) {
141                         LOGGER.debug("config problem", e1);
142                 }
143                 
144                 if (fullId == null) { 
145                         fullId = now + "-" + id;
146                         fullId = HbaseSaltPrefixer.getInstance().prependSalt(fullId);
147                 }
148                 message.put(LoggingMessage.ID_KEY, fullId);
149                 final LoggingMessage buffer = new LoggingMessage("Message", fullId);
150
151                 Integer responseCode = (Integer)message.get(Message.RESPONSE_CODE);
152                 if (responseCode != null) {
153                         buffer.getResponseCode().append(responseCode);
154                 }
155
156                 String encoding = (String)message.get(Message.ENCODING);
157
158                 if (encoding != null) {
159                         buffer.getEncoding().append(encoding);
160                 }
161                 String httpMethod = (String)message.get(Message.HTTP_REQUEST_METHOD);
162                 if (httpMethod != null) {
163                         buffer.getHttpMethod().append(httpMethod);
164                 }
165
166                 String ct = (String)message.get(Message.CONTENT_TYPE);
167                 if (ct != null) {
168                         if ("*/*".equals(ct)) {
169                                 message.put(Message.CONTENT_TYPE, MediaType.APPLICATION_JSON);
170                                 ct = MediaType.APPLICATION_JSON;
171                         }
172                         buffer.getContentType().append(ct);
173
174                 }
175                 Object headers = message.get(Message.PROTOCOL_HEADERS);
176                 if (headers != null) {
177                         buffer.getHeader().append(headers);
178                         
179                         Map<String, List<String>> headersList = CastUtils.cast((Map<?, ?>)message.get(Message.PROTOCOL_HEADERS));
180                         String transId = "";
181                         List<String> xt = headersList.get("X-TransactionId");
182                         String newTransId = transId;
183                         boolean missingTransId = false;
184                         boolean replacedTransId = false;
185                         String logMsg = null;
186                         if (xt != null) {
187                                 for (String transIdValue : xt) {
188                                         transId = transIdValue;
189                                 }       
190                                 Matcher matcher = uuidPattern.matcher(transId);
191                                 if (!matcher.find()) {
192                                         replacedTransId = true;
193                                         // check if there's a colon, and check the first group?
194                                         if (transId.contains(":")) {
195                                                 String[] uuidParts = transId.split(":");
196                                                 Matcher matcher2 = uuidPattern.matcher(uuidParts[0]);
197                                                 if (matcher2.find()) { 
198                                                         newTransId = uuidParts[0];
199                                                 } else {
200                                                         // punt, we tried to find it, it has a colon but no UUID-1
201                                                         newTransId = UUID.randomUUID().toString();
202                                                 }
203                                         } else {
204                                                 newTransId = UUID.randomUUID().toString();
205                                         }
206                                 }
207                         } else { 
208                                 newTransId = UUID.randomUUID().toString();
209                                 missingTransId = true;
210                         }
211                                                 
212                         if (missingTransId || replacedTransId) {
213                                 List<String> txList = new ArrayList<String>();
214                                 txList.add(newTransId);
215                                 headersList.put("X-TransactionId", txList);
216                                 if (missingTransId) { 
217                                         logMsg = "Missing requestID. Assigned " + newTransId;
218                                 } else if (replacedTransId) { 
219                                         logMsg = "Replaced invalid requestID of " + transId + " Assigned " + newTransId;
220                                 }
221                                 MDC.put("RequestId",newTransId);
222                         }
223                         else {
224                                 MDC.put("RequestId",transId);
225                         }
226
227
228                         List<String> fromAppIdList = headersList.get("X-FromAppId");
229                         if (fromAppIdList != null) {
230                                 String fromAppId = null;
231                                 for (String fromAppIdValue : fromAppIdList) {
232                                         fromAppId = fromAppIdValue;
233                                 }
234                                 MDC.put("PartnerName",fromAppId);
235                         }
236
237                         List<String> contentType = headersList.get("Content-Type");
238                         if (contentType == null) {
239                                 ct = (String)message.get(Message.CONTENT_TYPE);
240                                 headersList.put(Message.CONTENT_TYPE, Collections.singletonList(ct));
241                         }
242                         
243                         LOGGER.auditEvent("REST " + httpMethod + " " + ((query != null)? uri+"?"+query : uri) + " HbaseTxId=" + fullId);
244                         LOGGER.info(logMsg);
245                 }
246
247
248                 if (uri != null) {
249                         buffer.getAddress().append(uri);
250                         if (query != null) {
251                                 buffer.getAddress().append("?").append(query);
252                         }
253                 }
254
255                 InputStream is = message.getContent(InputStream.class);
256                 if (is != null) {
257                         try {
258                                 String currentPayload = IOUtils.toString(is, "UTF-8");
259                                 IOUtils.closeQuietly(is);
260                                 buffer.getPayload().append(currentPayload);
261                                 is = IOUtils.toInputStream(currentPayload, "UTF-8");
262                                 message.setContent(InputStream.class, is);
263                                 IOUtils.closeQuietly(is);
264                         } catch (Exception e) { 
265                                 // It's ok to not have request input content
266                                 // throw new Fault(e); 
267                         }
268                 }
269
270                 // this will be saved in the message exchange, and can be pulled out later...
271                 message.getExchange().put(fullId + "_REQUEST", buffer.toString());
272         }
273
274         /**
275          * Gen date.
276          *
277          * @param aaiLogger the aai logger
278          * @param logline the logline
279          * @return the string
280          */
281         protected String genDate() {
282                 FormatDate fd = new FormatDate("YYMMdd-HH:mm:ss:SSS");
283                 return fd.getDateTime();
284         }
285
286 }