package com.dianping.pigeon.remoting.invoker.process.filter;
import com.dianping.pigeon.config.ConfigChangeListener;
import com.dianping.pigeon.config.ConfigManager;
import com.dianping.pigeon.config.ConfigManagerLoader;
import com.dianping.pigeon.monitor.Monitor;
import com.dianping.pigeon.monitor.MonitorLoader;
import com.dianping.pigeon.monitor.MonitorTransaction;
import com.dianping.pigeon.remoting.common.monitor.trace.InvokerMonitorData;
import com.dianping.pigeon.remoting.common.monitor.trace.ApplicationKey;
import com.dianping.pigeon.remoting.common.monitor.trace.MethodKey;
import com.dianping.pigeon.remoting.common.monitor.trace.OtherKey;
import com.dianping.pigeon.remoting.common.monitor.trace.SourceKey;
import com.dianping.pigeon.remoting.common.domain.CallMethod;
import com.dianping.pigeon.remoting.common.domain.InvocationResponse;
import com.dianping.pigeon.remoting.common.domain.MessageType;
import com.dianping.pigeon.remoting.common.monitor.trace.MonitorDataFactory;
import com.dianping.pigeon.remoting.common.process.ServiceInvocationHandler;
import com.dianping.pigeon.remoting.common.util.Constants;
import com.dianping.pigeon.remoting.invoker.config.InvokerConfig;
import com.dianping.pigeon.remoting.invoker.domain.InvokerContext;
import org.apache.commons.lang.StringUtils;
/**
* @author qi.yin
* 2016/11/14 下午11:59.
*/
public class TraceFilter extends InvocationInvokeFilter {
private static final String appName = ConfigManagerLoader.getConfigManager().getAppName();
private final Monitor monitor = MonitorLoader.getMonitor();
private static final ConfigManager configManager = ConfigManagerLoader.getConfigManager();
private volatile boolean isTrace = true;
public TraceFilter() {
isTrace = configManager.getBooleanValue(Constants.KEY_INVOKER_TRACE_ENABLE, Constants.DEFAULT_INVOKER_TRACE_ENABLE);
configManager.registerConfigChangeListener(new InnerConfigChangeListener());
}
@Override
public InvocationResponse invoke(ServiceInvocationHandler handler, InvokerContext invocationContext) throws Throwable {
if (!isTrace) {
return handler.handle(invocationContext);
}
InvokerConfig config = invocationContext.getInvokerConfig();
// MonitorTransaction transaction = monitor.getCurrentCallTransaction();
// String rootMessage = StringUtils.EMPTY;
//
// if (transaction != null) {
// rootMessage = transaction.getParentRootMessage();
// }
// SourceKey srcKey = null;
// if (StringUtils.isNotBlank(rootMessage)) {
// srcKey = new OtherKey(rootMessage);
// } else {
// srcKey = new ApplicationKey(appName);
// }
SourceKey srcKey = new ApplicationKey(appName);
InvokerMonitorData monitorData = MonitorDataFactory.newInvokerMonitorData(srcKey,
new MethodKey(config.getUrl(), invocationContext.getMethodName()));
invocationContext.setMonitorData(monitorData);
monitorData.start();
byte code = config.getCallMethod(invocationContext.getMethodName());
monitorData.setCallMethod(code);
monitorData.setSerialize(config.getSerialize());
monitorData.setTimeout(config.getTimeout(invocationContext.getMethodName()));
monitorData.add();
InvocationResponse response = null;
try {
response = handler.handle(invocationContext);
} finally {
if (response == null) {
monitorData.setIsSuccess(false);
monitorData.complete();
} else {
if (CallMethod.isSync(code)) {
if (MessageType.isServiceException((byte) response.getMessageType()) ||
MessageType.isException((byte) response.getMessageType())) {
monitorData.setIsSuccess(false);
} else {
monitorData.setIsSuccess(true);
}
monitorData.complete();
} else if (CallMethod.isOneway(code)) {
monitorData.setIsSuccess(true);
monitorData.complete();
}
}
}
return response;
}
private class InnerConfigChangeListener implements ConfigChangeListener {
@Override
public void onKeyUpdated(String key, String value) {
if (key.endsWith(Constants.KEY_INVOKER_TRACE_ENABLE)) {
try {
isTrace = Boolean.valueOf(value);
} catch (RuntimeException e) {
}
}
}
@Override
public void onKeyAdded(String key, String value) {
// TODO Auto-generated method stub
}
@Override
public void onKeyRemoved(String key) {
// TODO Auto-generated method stub
}
}
}