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.InputStream;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.List;
29 import java.util.UUID;
30 import java.util.regex.Matcher;
31 import java.util.regex.Pattern;
33 import javax.ws.rs.core.MediaType;
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;
48 import com.att.eelf.configuration.EELFLogger;
49 import com.att.eelf.configuration.EELFManager;
52 public class AAILogJAXRSInInterceptor extends JAXRSInInterceptor {
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);
62 public void handleMessage(Message message) {
69 uri = (String)message.get(CAMEL_REQUEST);
71 query = (String)message.get(Message.QUERY_STRING);
74 if (AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_INTERCEPTOR).equalsIgnoreCase("true") &&
75 AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_ENABLED).equalsIgnoreCase("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);
81 if (AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_LOGRESPONSE).equalsIgnoreCase("true") ) {
82 message.getExchange().put("AAI_LOGGING_HBASE_LOGRESPONSE", 1);
85 if (AAIConfig.get(AAIConstants.AAI_LOGGING_TRACE_ENABLED).equalsIgnoreCase("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);
91 if (AAIConfig.get(AAIConstants.AAI_LOGGING_TRACE_LOGRESPONSE).equalsIgnoreCase("true") ) {
92 message.getExchange().put("AAI_LOGGING_TRACE_LOGRESPONSE", 1);
95 } catch (AAIException e1) {
96 ErrorLogHelper.logException(e1);
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
102 if (message.getExchange().containsKey("AAI_LOGGING_HBASE_ENABLED")) {
103 message.getExchange().remove("AAI_LOGGING_HBASE_ENABLED");
105 if (message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) {
106 message.getExchange().remove("AAI_LOGGING_TRACE_ENABLED");
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");
116 if (message.getExchange().containsKey("AAI_LOGGING_TRACE_LOGRESPONSE")) {
117 message.getExchange().remove("AAI_LOGGING_TRACE_LOGRESPONSE");
121 if (go == false) { // there's nothing to do
125 // DONE: get a TXID based on hostname, time (YYYYMMDDHHMMSSMILLIS, and LoggingMessage.nextId(); 20150326145301-1
126 String now = genDate();
128 message.getExchange().put("AAI_RQST_TM", now);
130 String id = (String)message.getExchange().get(LoggingMessage.ID_KEY);
132 String fullId = null;
135 id = LoggingMessage.nextId();
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);
144 if (fullId == null) {
145 fullId = now + "-" + id;
146 fullId = HbaseSaltPrefixer.getInstance().prependSalt(fullId);
148 message.put(LoggingMessage.ID_KEY, fullId);
149 final LoggingMessage buffer = new LoggingMessage("Message", fullId);
151 Integer responseCode = (Integer)message.get(Message.RESPONSE_CODE);
152 if (responseCode != null) {
153 buffer.getResponseCode().append(responseCode);
156 String encoding = (String)message.get(Message.ENCODING);
158 if (encoding != null) {
159 buffer.getEncoding().append(encoding);
161 String httpMethod = (String)message.get(Message.HTTP_REQUEST_METHOD);
162 if (httpMethod != null) {
163 buffer.getHttpMethod().append(httpMethod);
166 String ct = (String)message.get(Message.CONTENT_TYPE);
168 if ("*/*".equals(ct)) {
169 message.put(Message.CONTENT_TYPE, MediaType.APPLICATION_JSON);
170 ct = MediaType.APPLICATION_JSON;
172 buffer.getContentType().append(ct);
175 Object headers = message.get(Message.PROTOCOL_HEADERS);
176 if (headers != null) {
177 buffer.getHeader().append(headers);
179 Map<String, List<String>> headersList = CastUtils.cast((Map<?, ?>)message.get(Message.PROTOCOL_HEADERS));
181 List<String> xt = headersList.get("X-TransactionId");
182 String newTransId = transId;
183 boolean missingTransId = false;
184 boolean replacedTransId = false;
185 String logMsg = null;
187 for (String transIdValue : xt) {
188 transId = transIdValue;
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];
200 // punt, we tried to find it, it has a colon but no UUID-1
201 newTransId = UUID.randomUUID().toString();
204 newTransId = UUID.randomUUID().toString();
208 newTransId = UUID.randomUUID().toString();
209 missingTransId = true;
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;
221 MDC.put("RequestId",newTransId);
224 MDC.put("RequestId",transId);
228 List<String> fromAppIdList = headersList.get("X-FromAppId");
229 if (fromAppIdList != null) {
230 String fromAppId = null;
231 for (String fromAppIdValue : fromAppIdList) {
232 fromAppId = fromAppIdValue;
234 MDC.put("PartnerName",fromAppId);
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));
243 LOGGER.auditEvent("REST " + httpMethod + " " + ((query != null)? uri+"?"+query : uri) + " HbaseTxId=" + fullId);
249 buffer.getAddress().append(uri);
251 buffer.getAddress().append("?").append(query);
255 InputStream is = message.getContent(InputStream.class);
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);
270 // this will be saved in the message exchange, and can be pulled out later...
271 message.getExchange().put(fullId + "_REQUEST", buffer.toString());
277 * @param aaiLogger the aai logger
278 * @param logline the logline
281 protected String genDate() {
282 FormatDate fd = new FormatDate("YYMMdd-HH:mm:ss:SSS");
283 return fd.getDateTime();