/*******************************************************************************
* Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*******************************************************************************/
package org.ebayopensource.turmeric.runtime.sif.impl.pipeline;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.List;
import java.util.logging.Level;
import org.ebayopensource.turmeric.runtime.binding.objectnode.ObjectNode;
import org.ebayopensource.turmeric.runtime.binding.utils.ObjectNodeUtils;
import org.ebayopensource.turmeric.runtime.common.exceptions.ServiceException;
import org.ebayopensource.turmeric.runtime.common.handler.HandlerPreconditions;
import org.ebayopensource.turmeric.runtime.common.impl.pipeline.BaseLoggingHandler;
import org.ebayopensource.turmeric.runtime.common.pipeline.LoggingHandlerStage;
import org.ebayopensource.turmeric.runtime.common.pipeline.Message;
import org.ebayopensource.turmeric.runtime.common.pipeline.MessageContext;
import org.ebayopensource.turmeric.runtime.common.service.ServiceId;
import org.ebayopensource.turmeric.runtime.sif.impl.internal.config.ClientServiceConfigBeanManager;
import org.ebayopensource.turmeric.runtime.sif.pipeline.ClientMessageContext;
import org.ebayopensource.turmeric.runtime.sif.service.ClientServiceId;
import org.ebayopensource.turmeric.common.v1.types.CommonErrorData;
import org.ebayopensource.turmeric.common.v1.types.ErrorMessage;
/**
* @author ichernyshev
*/
public class ClientLoggingHandler extends BaseLoggingHandler {
@Override
public void init(InitContext ctx)
throws ServiceException
{
HandlerPreconditions.checkClientSide(ctx, this.getClass()); // Client Side Only
super.init(ctx);
}
@Override
protected ClientLoggingHandlerUtils getHandlerUtils() {
return new ClientLoggingHandlerUtils();
}
@Override
public void logProcessingStage(MessageContext ctx, LoggingHandlerStage stage)
throws ServiceException
{
long startTime = System.nanoTime();
try {
super.logProcessingStage(ctx, stage);
if (stage == LoggingHandlerStage.RESPONSE_COMPLETE) {
Level appErrorLogLevel = getAppErrorLogLevel();
if (getLogger().isLoggable(appErrorLogLevel)) {
Message responseMsg = ctx.getResponseMessage();
if (responseMsg.isErrorMessage()) {
Object errorResponse = null;
if (ctx.isOutboundRawMode()) {
// We are not guaranteed to have TypeMappings and therefore might not be able
// to deserialize the message. so the safe thing to do is log the raw message.
ByteBuffer bb = responseMsg.getByteBuffer();
if (bb != null)
try {
errorResponse = new String(bb.array(), Charset.defaultCharset().name());
} catch (UnsupportedEncodingException e) {
// e.printStackTrace();
// FIXME: exception to be handled
}
} else {
errorResponse = responseMsg.getErrorResponse();
}
logErrorResponse(ctx, errorResponse, appErrorLogLevel);
}
}
}
}
finally {
long duration = System.nanoTime() - startTime;
logMetrics(ctx, stage, duration);
}
}
@Override
protected void addCallInfo(MessageContext ctx, LoggingHandlerStage stage, String separator, StringBuilder sb) throws ServiceException {
if (sb.length() != 0) {
sb.append(separator);
}
sb.append(stage);
if (stage.equals(LoggingHandlerStage.RESPONSE_STARTED) || stage.equals(LoggingHandlerStage.RESPONSE_COMPLETE)) {
String guid = ctx.getRequestGuid();
if (guid != null) {
sb.append(separator);
sb.append("GUID=");
sb.append(guid);
}
}
}
protected void logErrorResponse(MessageContext ctx, Object errorResponse, Level logLevel) {
if (!getLogger().isLoggable(logLevel)) {
return;
}
StringBuilder sb = new StringBuilder();
Throwable thrown = null;
if (errorResponse instanceof ErrorMessage) {
List<CommonErrorData> errors = ((ErrorMessage)errorResponse).getError();
if (!errors.isEmpty()) {
CommonErrorData error = errors.get(0);
String domain = error.getDomain();
sb.append("Error Response '");
if (domain != null) {
sb.append(domain);
sb.append('.');
}
sb.append(error.getErrorId());
sb.append("' with message '");
sb.append(error.getMessage());
sb.append('\'');
} else {
sb.append("Empty Error Response");
}
} else {
if (errorResponse != null) {
sb.append("Error Response ");
String customText = getHandlerUtils().getCustomResponseText((ClientMessageContext)ctx, errorResponse);
if (customText == null) {
if (errorResponse instanceof ObjectNode) {
try {
ObjectNode objNode = (ObjectNode) errorResponse;
StringWriter sw = new StringWriter();
ObjectNodeUtils.writeAsXML(objNode, sw, true, "UTF-8");
sb.append(sw.toString());
} catch (Throwable thr) {
sb.append("Could not compose error response: " + thr
+ ((thr.getMessage() == null) ? "" : ": " + thr.getMessage()));
thrown = thr;
}
} else {
// JAXB toString is not good at all, but we have nothing else
customText = errorResponse.toString();
sb.append(customText);
}
}
} else {
sb.append("Null Error Response");
}
}
String prefix = getErrorPrefixText(ctx);
getLogger().log(logLevel, prefix + sb.toString(), thrown);
}
@Override
protected String getRequestPayloadLog(MessageContext ctx)
{
ServiceId id = ctx.getServiceId();
String adminName = id.getAdminName();
String clientName = ((ClientServiceId)id).getClientName();
String envName = ((ClientServiceId)id).getEnvName();
return ClientServiceConfigBeanManager.
getPayloadLogInstance(adminName, clientName,envName).getRequestPayloadLog();
}
@Override
protected String getResponsePayloadLog(MessageContext ctx)
{
ServiceId id = ctx.getServiceId();
String adminName = id.getAdminName();
String clientName = ((ClientServiceId)id).getClientName();
String envName = ((ClientServiceId)id).getEnvName();
return ClientServiceConfigBeanManager.
getPayloadLogInstance(adminName, clientName,envName).getResponsePayloadLog();
}
}