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 package org.onap.aai.interceptors;
24 import java.io.OutputStream;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.List;
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;
43 import com.att.eelf.configuration.EELFLogger;
44 import com.att.eelf.configuration.EELFManager;
46 // right after the request is complete, there may be content
47 public class AAILogJAXRSOutInterceptor extends JAXRSOutInterceptor {
49 private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(AAILogJAXRSOutInterceptor.class);
51 protected final String COMPONENT = "aairest";
52 protected final String CAMEL_REQUEST = "CamelHttpUrl";
57 public void handleMessage(Message message) {
59 String fullId = (String) message.getExchange().get(LoggingMessage.ID_KEY);
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>>();
66 headers.put("X-AAI-TXID", Collections.singletonList(fullId));
67 message.put(Message.PROTOCOL_HEADERS, headers);
69 Message outMessage = message.getExchange().getOutMessage();
70 final OutputStream os = outMessage.getContent(OutputStream.class);
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")) {
78 final CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(os);
79 message.setContent(OutputStream.class, newOut);
80 newOut.registerCallback(new LoggingCallback(message, os));
85 class LoggingCallback implements CachedOutputStreamCallback {
87 private final Message message;
88 private final OutputStream origStream;
90 public LoggingCallback(final Message msg, final OutputStream os) {
95 public void onFlush(CachedOutputStream cos) {
99 public void onClose(CachedOutputStream cos) {
101 String getValue = "";
102 String postValue = "";
103 String logValue = "";
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
114 if (!message.getExchange().containsKey("AAI_LOGGING_HBASE_ENABLED") && !message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) {
118 String fullId = (String) message.getExchange().get(LoggingMessage.ID_KEY);
120 Message inMessage = message.getExchange().getInMessage();
121 String transId = null;
122 String fromAppId = null;
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");
128 for (String transIdValue : xt) {
129 transId = transIdValue;
132 List<String> fa = headersList.get("X-FromAppId");
134 for (String fromAppIdValue : fa) {
136 fromAppId = fromAppIdValue;
141 String httpMethod = (String) inMessage.get(Message.HTTP_REQUEST_METHOD);
143 String uri = (String) inMessage.get(CAMEL_REQUEST);
144 String fullUri = uri;
146 String query = (String) message.get(Message.QUERY_STRING);
148 fullUri = uri + "?" + query;
152 String request = (String) message.getExchange().get(fullId + "_REQUEST");
154 Message outMessage = message.getExchange().getOutMessage();
156 final LoggingMessage buffer = new LoggingMessage("OUTMessage", fullId);
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
164 buffer.getResponseCode().append(responseCode);
166 String encoding = (String) outMessage.get(Message.ENCODING);
168 if (encoding != null) {
169 buffer.getEncoding().append(encoding);
172 String ct = (String) outMessage.get(Message.CONTENT_TYPE);
174 buffer.getContentType().append(ct);
177 Object headers = outMessage.get(Message.PROTOCOL_HEADERS);
178 if (headers != null) {
179 buffer.getHeader().append(headers);
183 if (responseCode >= 200 && responseCode <= 299) {
186 String response = buffer.toString();
188 // this should have been set by the in interceptor
189 String rqstTm = (String) message.getExchange().get("AAI_RQST_TM");
191 // just in case it wasn't, we'll put this here. not great, but it'll
193 if (rqstTm == null) {
198 String respTm = genDate();
201 String actualRequest = request;
202 StringBuilder builder = new StringBuilder();
203 cos.writeCacheTo(builder, 100000);
204 // here comes my xml:
205 String payload = builder.toString();
207 String actualResponse = response;
208 if (payload == null) {
211 actualResponse = response + payload;
214 // we only log to AAI log if it's eanbled in the config props
216 if (message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) {
218 if (message.getExchange().containsKey("AAI_LOGGING_TRACE_LOGREQUEST")) {
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);
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", "");
234 LOGGER.debug(traceResponse);
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";
245 if (!message.getExchange().containsKey("AAI_LOGGING_HBASE_LOGRESPONSE")) {
246 actualResponse = "loggingDisabled";
249 LOGGER.debug("action={}, urlin={}, HbTransId={}", httpMethod, fullUri, fullId);
251 if (logValue.equals("false")) {
252 } else if (getValue.equals("false") && httpMethod.equals("GET")) {
253 } else if (postValue.equals("false") && httpMethod.equals("POST")) {
255 putTransaction(transId, responseCode.toString(), rqstTm, respTm, fromAppId + ":" + transId, fullUri, httpMethod, request, response, actualResponse);
259 } catch (Exception ex) {
263 message.setContent(OutputStream.class, origStream);
265 LOGGER.auditEvent("HTTP Response Code: {}", responseCode.toString());
270 protected String genDate() {
271 FormatDate fd = new FormatDate("YYMMdd-HH:mm:ss:SSS");
272 return fd.getDateTime();
275 public String putTransaction(String tid, String status, String rqstTm, String respTm, String srcId, String rsrcId, String rsrcType, String rqstBuf, String respBuf, String actualResponse) {
278 if (tid == null || "".equals(tid)) {
285 if (rqstTm == null || "".equals(rqstTm)) {
289 if (respTm == null || "".equals(respTm)) {
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);
297 } catch (Exception e) {
298 ErrorLogHelper.logError("AAI_4000", "Exception updating HBase:");