Remove diffutils dependency
[aai/traversal.git] / aai-traversal / src / main / java / org / onap / aai / interceptors / AAILogJAXRSOutInterceptor.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.OutputStream;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29
30 import org.apache.cxf.helpers.CastUtils;
31 import org.apache.cxf.interceptor.LoggingMessage;
32 import org.apache.cxf.io.CacheAndWriteOutputStream;
33 import org.apache.cxf.io.CachedOutputStream;
34 import org.apache.cxf.io.CachedOutputStreamCallback;
35 import org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor;
36 import org.apache.cxf.message.Message;
37 import org.onap.aai.exceptions.AAIException;
38 import org.onap.aai.logging.ErrorLogHelper;
39 import org.onap.aai.util.AAIConfig;
40 import org.onap.aai.util.AAIConstants;
41 import org.onap.aai.util.FormatDate;
42
43 import com.att.eelf.configuration.EELFLogger;
44 import com.att.eelf.configuration.EELFManager;
45
46 // right after the request is complete, there may be content
47 public class AAILogJAXRSOutInterceptor extends JAXRSOutInterceptor {
48
49         private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(AAILogJAXRSOutInterceptor.class);
50         
51         protected final String COMPONENT = "aairest";
52         protected final String CAMEL_REQUEST = "CamelHttpUrl";
53
54         /**
55          * {@inheritDoc}
56          */
57         public void handleMessage(Message message) {
58
59                 String fullId = (String) message.getExchange().get(LoggingMessage.ID_KEY);
60
61                 Map<String, List<String>> headers = CastUtils.cast((Map<?, ?>) message.get(Message.PROTOCOL_HEADERS));
62                 if (headers == null) {
63                         headers = new HashMap<String, List<String>>();
64                 }
65
66                 headers.put("X-AAI-TXID", Collections.singletonList(fullId));
67                 message.put(Message.PROTOCOL_HEADERS, headers);
68
69                 Message outMessage = message.getExchange().getOutMessage();
70                 final OutputStream os = outMessage.getContent(OutputStream.class);
71                 if (os == null) {
72                         return;
73                 }
74
75                 // we only want to register the callback if there is good reason for it.
76                 if (message.getExchange().containsKey("AAI_LOGGING_HBASE_ENABLED") || message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) {
77
78                         final CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(os);
79                         message.setContent(OutputStream.class, newOut);
80                         newOut.registerCallback(new LoggingCallback(message, os));
81                 }
82
83         }
84
85         class LoggingCallback implements CachedOutputStreamCallback {
86
87                 private final Message message;
88                 private final OutputStream origStream;
89
90                 public LoggingCallback(final Message msg, final OutputStream os) {
91                         this.message = msg;
92                         this.origStream = os;
93                 }
94
95                 public void onFlush(CachedOutputStream cos) {
96
97                 }
98
99                 public void onClose(CachedOutputStream cos) {
100
101                         String getValue = "";
102                         String postValue = "";
103                         String logValue = "";
104
105                         try {
106                                 logValue = AAIConfig.get("aai.transaction.logging");
107                                 getValue = AAIConfig.get("aai.transaction.logging.get");
108                                 postValue = AAIConfig.get("aai.transaction.logging.post");
109                         } catch (AAIException e) {
110                                 // TODO Auto-generated catch block
111                                 e.printStackTrace();
112                         }
113
114                         if (!message.getExchange().containsKey("AAI_LOGGING_HBASE_ENABLED") && !message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) {
115                                 return;
116                         }
117
118                         String fullId = (String) message.getExchange().get(LoggingMessage.ID_KEY);
119
120                         Message inMessage = message.getExchange().getInMessage();
121                         String transId = null;
122                         String fromAppId = null;
123
124                         Map<String, List<String>> headersList = CastUtils.cast((Map<?, ?>) inMessage.get(Message.PROTOCOL_HEADERS));
125                         if (headersList != null) {
126                                 List<String> xt = headersList.get("X-TransactionId");
127                                 if (xt != null) {
128                                         for (String transIdValue : xt) {
129                                                 transId = transIdValue;
130                                         }
131                                 }
132                                 List<String> fa = headersList.get("X-FromAppId");
133                                 if (fa != null) {
134                                         for (String fromAppIdValue : fa) {
135
136                                                 fromAppId = fromAppIdValue;
137                                         }
138                                 }
139                         }
140
141                         String httpMethod = (String) inMessage.get(Message.HTTP_REQUEST_METHOD);
142
143                         String uri = (String) inMessage.get(CAMEL_REQUEST);
144                         String fullUri = uri;
145                         if (uri != null) {
146                                 String query = (String) message.get(Message.QUERY_STRING);
147                                 if (query != null) {
148                                         fullUri = uri + "?" + query;
149                                 }
150                         }
151
152                         String request = (String) message.getExchange().get(fullId + "_REQUEST");
153
154                         Message outMessage = message.getExchange().getOutMessage();
155
156                         final LoggingMessage buffer = new LoggingMessage("OUTMessage", fullId);
157
158                         // should we check this, and make sure it's not an error?
159                         Integer responseCode = (Integer) outMessage.get(Message.RESPONSE_CODE);
160                         if (responseCode == null) {
161                                 responseCode = 200; // this should never happen, but just in
162                                                                         // case we don't get one
163                         }
164                         buffer.getResponseCode().append(responseCode);
165
166                         String encoding = (String) outMessage.get(Message.ENCODING);
167
168                         if (encoding != null) {
169                                 buffer.getEncoding().append(encoding);
170                         }
171
172                         String ct = (String) outMessage.get(Message.CONTENT_TYPE);
173                         if (ct != null) {
174                                 buffer.getContentType().append(ct);
175                         }
176
177                         Object headers = outMessage.get(Message.PROTOCOL_HEADERS);
178                         if (headers != null) {
179                                 buffer.getHeader().append(headers);
180                         }
181
182                         Boolean ss = false;
183                         if (responseCode >= 200 && responseCode <= 299) {
184                                 ss = true;
185                         }
186                         String response = buffer.toString();
187
188                         // this should have been set by the in interceptor
189                         String rqstTm = (String) message.getExchange().get("AAI_RQST_TM");
190
191                         // just in case it wasn't, we'll put this here. not great, but it'll
192                         // have a val.
193                         if (rqstTm == null) {
194                                 rqstTm = genDate();
195                         }
196
197
198                         String respTm = genDate();
199
200                         try {
201                                 String actualRequest = request;
202                                 StringBuilder builder = new StringBuilder();
203                                 cos.writeCacheTo(builder, 100000);
204                                 // here comes my xml:
205                                 String payload = builder.toString();
206
207                                 String actualResponse = response;
208                                 if (payload == null) {
209
210                                 } else {
211                                         actualResponse = response + payload;
212                                 }
213
214                                 // we only log to AAI log if it's eanbled in the config props
215                                 // file
216                                 if (message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) {
217
218                                         if (message.getExchange().containsKey("AAI_LOGGING_TRACE_LOGREQUEST")) {
219
220                                                 // strip newlines from request
221                                                 String traceRequest = actualRequest;
222                                                 traceRequest = traceRequest.replace("\n", " ");
223                                                 traceRequest = traceRequest.replace("\r", "");
224                                                 traceRequest = traceRequest.replace("\t", "");
225                                                 LOGGER.debug(traceRequest);
226                                         }
227                                         if (message.getExchange().containsKey("AAI_LOGGING_TRACE_LOGRESPONSE")) {
228                                                 // strip newlines from response
229                                                 String traceResponse = actualResponse;
230                                                 traceResponse = traceResponse.replace("\n", " ");
231                                                 traceResponse = traceResponse.replace("\r", "");
232                                                 traceResponse = traceResponse.replace("\t", "");
233
234                                                 LOGGER.debug(traceResponse);
235                                         }
236                                 }
237
238                                 // we only log to HBASE if it's enabled in the config props file
239                                 // TODO: pretty print XML/JSON. we might need to get the payload
240                                 // and envelope seperately
241                                 if (message.getExchange().containsKey("AAI_LOGGING_HBASE_ENABLED")) {
242                                         if (!message.getExchange().containsKey("AAI_LOGGING_HBASE_LOGREQUEST")) {
243                                                 actualRequest = "loggingDisabled";
244                                         }
245                                         if (!message.getExchange().containsKey("AAI_LOGGING_HBASE_LOGRESPONSE")) {
246                                                 actualResponse = "loggingDisabled";
247                                         }
248
249                                         LOGGER.debug("action={}, urlin={}, HbTransId={}", httpMethod, fullUri, fullId);
250
251                                         if (logValue.equals("false")) {
252                                         } else if (getValue.equals("false") && httpMethod.equals("GET")) {
253                                         } else if (postValue.equals("false") && httpMethod.equals("POST")) {
254                                         } else {
255                                                 putTransaction(transId, responseCode.toString(), rqstTm, respTm, fromAppId + ":" + transId, fullUri, httpMethod, request, response, actualResponse);
256
257                                         }
258                                 }
259                         } catch (Exception ex) {
260                                 // ignore
261                         }
262
263                         message.setContent(OutputStream.class, origStream);
264                         
265                         LOGGER.auditEvent("HTTP Response Code: {}", responseCode.toString());
266                 }
267
268         }
269
270         protected String genDate() {
271                 FormatDate fd = new FormatDate("YYMMdd-HH:mm:ss:SSS");
272                 return fd.getDateTime();
273         }
274
275         public String putTransaction(String tid, String status, String rqstTm, String respTm, String srcId, String rsrcId, String rsrcType, String rqstBuf, String respBuf, String actualResponse) {
276                 String tm = null;
277
278                 if (tid == null || "".equals(tid)) {
279                         tm = this.genDate();
280                         tid = tm + "-";
281                 }
282
283                 String htid = tid;
284
285                 if (rqstTm == null || "".equals(rqstTm)) {
286                         rqstTm = tm;
287                 }
288
289                 if (respTm == null || "".equals(respTm)) {
290                         respTm = tm;
291                 }
292
293                 try {
294                         LOGGER.debug(" transactionId:" + tid + " status: " + status + " rqstDate: " + rqstTm + " respDate: " + respTm + " sourceId: " + srcId + " resourceId: "
295                                         + rsrcId + " resourceType: " + rsrcType + " payload rqstBuf: " + rqstBuf + " payload respBuf: " + respBuf + " Payload Error Messages: " + actualResponse);
296                         return htid;
297                 } catch (Exception e) {
298                         ErrorLogHelper.logError("AAI_4000", "Exception updating HBase:");
299                         return htid;
300                 }
301
302         }
303 }