package org.addsimplicity.anicetus.flume;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.addsimplicity.anicetus.entity.GlobalInfo;
import org.addsimplicity.anicetus.entity.GlobalInfoFields;
import org.addsimplicity.anicetus.entity.TelemetryContainer;
import org.addsimplicity.anicetus.io.DeliveryAdapter;
import org.addsimplicity.anicetus.io.ExceptionHandler;
import org.addsimplicity.anicetus.io.SystemErrorExceptionHandler;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import com.cloudera.flume.handlers.thrift.Priority;
import com.cloudera.flume.handlers.thrift.ThriftFlumeEvent;
import com.cloudera.flume.handlers.thrift.ThriftFlumeEventServer;
public class FlumeDeliveryAdapter implements DeliveryAdapter, DisposableBean, InitializingBean {
private static final Set<String> s_blockKeys = new HashSet<String>();
static {
s_blockKeys.add(GlobalInfoFields.ReportingNode.name());
s_blockKeys.add(GlobalInfoFields.Message.name());
s_blockKeys.add(GlobalInfoFields.TimeStamp.name());
}
private static Charset FLUME_CHARSET = Charset.forName("UTF-8");
private ExceptionHandler m_exceptionHandler = new SystemErrorExceptionHandler();
private TTransport m_transport;
private ThriftFlumeEventServer.Client m_eventClient;
private String m_flumeHost;
private int m_flumePort;
@Override
public void afterPropertiesSet() throws Exception {
m_transport = new TSocket(m_flumeHost, m_flumePort);
TProtocol proto = new TBinaryProtocol(m_transport);
m_eventClient = new ThriftFlumeEventServer.Client(proto);
m_transport.open();
}
@Override
public void destroy() throws Exception {
m_transport.close();
}
public ExceptionHandler getExceptionHandler() {
return m_exceptionHandler;
}
public String getFlumeHost() {
return m_flumeHost;
}
public int getFlumePort() {
return m_flumePort;
}
@Override
public void sendTelemetry(GlobalInfo telemetry) {
String smsg = telemetry.getMessage();
if (smsg == null) {
smsg = "(null)";
}
byte [] msg = smsg.getBytes(FLUME_CHARSET);
ByteBuffer body = ByteBuffer.wrap(msg);
Map<String, ByteBuffer> fields = new HashMap<String, ByteBuffer>();
fields.put(
"TelemetryType",
ByteBuffer.wrap(telemetry.getClass().getName()
.getBytes(FLUME_CHARSET)));
for (Map.Entry<String, Object> entry : telemetry.entrySet()) {
String key = entry.getKey();
if (s_blockKeys.contains(key)) {
continue;
}
Class<?> type = entry.getValue().getClass();
if (!type.isArray()) {
fields.put(
key,
ByteBuffer.wrap(entry.getValue().toString()
.getBytes(FLUME_CHARSET)));
} else {
fields.put(key, ByteBuffer.wrap(toStringArray((Object[]) entry
.getValue())));
}
}
ThriftFlumeEvent evt = new ThriftFlumeEvent(telemetry.getTimeStamp(),
Priority.INFO, body, 0, telemetry.getReportingNode(), fields);
try {
m_eventClient.append(evt);
} catch (TException e) {
m_exceptionHandler.exceptionCaught(e);
}
if (telemetry instanceof TelemetryContainer) {
for (GlobalInfo t : ((TelemetryContainer)telemetry).getChildren()) {
sendTelemetry(t);
}
}
}
@Override
public void setExceptionHandler(ExceptionHandler handler) {
m_exceptionHandler = handler;
}
public void setFlumeHost(String flumeHost) {
m_flumeHost = flumeHost;
}
public void setFlumePort(int flumePort) {
m_flumePort = flumePort;
}
private byte[] toStringArray(Object values[]) {
StringBuilder sb = new StringBuilder();
for (Object v : values) {
if (sb.length() > 0) {
sb.append(",");
}
sb.append(v.toString());
}
return sb.toString().getBytes(FLUME_CHARSET);
}
}