package com.intrbiz.bergamot.io;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.List;
import java.util.Set;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.intrbiz.bergamot.model.message.agent.check.CheckAgent;
import com.intrbiz.bergamot.model.message.agent.check.CheckCPU;
import com.intrbiz.bergamot.model.message.agent.check.CheckDisk;
import com.intrbiz.bergamot.model.message.agent.check.CheckDiskIO;
import com.intrbiz.bergamot.model.message.agent.check.CheckMem;
import com.intrbiz.bergamot.model.message.agent.check.CheckNetCon;
import com.intrbiz.bergamot.model.message.agent.check.CheckNetIO;
import com.intrbiz.bergamot.model.message.agent.check.CheckNetIf;
import com.intrbiz.bergamot.model.message.agent.check.CheckOS;
import com.intrbiz.bergamot.model.message.agent.check.CheckProcess;
import com.intrbiz.bergamot.model.message.agent.check.CheckUptime;
import com.intrbiz.bergamot.model.message.agent.check.CheckWho;
import com.intrbiz.bergamot.model.message.agent.check.ExecCheck;
import com.intrbiz.bergamot.model.message.agent.error.GeneralError;
import com.intrbiz.bergamot.model.message.agent.hello.AgentHello;
import com.intrbiz.bergamot.model.message.agent.ping.AgentPing;
import com.intrbiz.bergamot.model.message.agent.ping.AgentPong;
import com.intrbiz.bergamot.model.message.agent.registration.AgentRegistrationComplete;
import com.intrbiz.bergamot.model.message.agent.registration.AgentRegistrationFailed;
import com.intrbiz.bergamot.model.message.agent.registration.AgentRegistrationRequest;
import com.intrbiz.bergamot.model.message.agent.registration.AgentRegistrationRequired;
import com.intrbiz.bergamot.model.message.agent.stat.AgentStat;
import com.intrbiz.bergamot.model.message.agent.stat.CPUStat;
import com.intrbiz.bergamot.model.message.agent.stat.DiskIOStat;
import com.intrbiz.bergamot.model.message.agent.stat.DiskStat;
import com.intrbiz.bergamot.model.message.agent.stat.ExecStat;
import com.intrbiz.bergamot.model.message.agent.stat.MemStat;
import com.intrbiz.bergamot.model.message.agent.stat.NetConStat;
import com.intrbiz.bergamot.model.message.agent.stat.NetIOStat;
import com.intrbiz.bergamot.model.message.agent.stat.NetIfStat;
import com.intrbiz.bergamot.model.message.agent.stat.OSStat;
import com.intrbiz.bergamot.model.message.agent.stat.ProcessStat;
import com.intrbiz.bergamot.model.message.agent.stat.UptimeStat;
import com.intrbiz.bergamot.model.message.agent.stat.WhoStat;
import com.intrbiz.bergamot.model.message.agent.stat.cpu.CPUInfo;
import com.intrbiz.bergamot.model.message.agent.stat.cpu.CPUTime;
import com.intrbiz.bergamot.model.message.agent.stat.cpu.CPUUsage;
import com.intrbiz.bergamot.model.message.agent.stat.disk.DiskInfo;
import com.intrbiz.bergamot.model.message.agent.stat.diskio.DiskIOInfo;
import com.intrbiz.bergamot.model.message.agent.stat.diskio.DiskIORateInfo;
import com.intrbiz.bergamot.model.message.agent.stat.netcon.NetConInfo;
import com.intrbiz.bergamot.model.message.agent.stat.netif.NetIfInfo;
import com.intrbiz.bergamot.model.message.agent.stat.netif.NetRouteInfo;
import com.intrbiz.bergamot.model.message.agent.stat.netio.NetIOInfo;
import com.intrbiz.bergamot.model.message.agent.stat.netio.NetIORateInfo;
import com.intrbiz.bergamot.model.message.agent.stat.process.ProcessInfo;
import com.intrbiz.bergamot.model.message.agent.stat.who.WhoInfo;
import com.intrbiz.bergamot.model.message.agent.util.Parameter;
import com.intrbiz.gerald.polyakov.io.PolyakovTranscoder;
/**
* Encode and decode messages
*/
public class BergamotAgentTranscoder
{
public static final Class<?>[] CLASSES = {
// error
GeneralError.class,
// hello
AgentHello.class,
// ping
AgentPing.class,
AgentPong.class,
// util
Parameter.class,
// cpu
CheckCPU.class,
CPUInfo.class,
CPUTime.class,
CPUUsage.class,
CPUStat.class,
// mem
CheckMem.class,
MemStat.class,
// disk
CheckDisk.class,
DiskInfo.class,
DiskStat.class,
// os
CheckOS.class,
OSStat.class,
// uptime
CheckUptime.class,
UptimeStat.class,
// netif
CheckNetIf.class,
NetIfInfo.class,
NetRouteInfo.class,
NetIfStat.class,
// exec
ExecCheck.class,
ExecStat.class,
// process
ProcessInfo.class,
CheckProcess.class,
ProcessStat.class,
// who
WhoInfo.class,
CheckWho.class,
WhoStat.class,
// net con
NetConInfo.class,
CheckNetCon.class,
NetConStat.class,
// agent
CheckAgent.class,
AgentStat.class,
// net io
CheckNetIO.class,
NetIOStat.class,
NetIOInfo.class,
NetIORateInfo.class,
// disk io
CheckDiskIO.class,
DiskIOStat.class,
DiskIOInfo.class,
DiskIORateInfo.class,
// registration
AgentRegistrationRequired.class,
AgentRegistrationRequest.class,
AgentRegistrationComplete.class,
AgentRegistrationFailed.class
};
private static final BergamotAgentTranscoder US = new BergamotAgentTranscoder();
public static BergamotAgentTranscoder getDefaultInstance()
{
return US;
}
private final ObjectMapper factory = new ObjectMapper();
private final boolean sealed;
public BergamotAgentTranscoder(boolean sealed)
{
super();
this.factory.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
this.factory.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
this.factory.configure(SerializationFeature.INDENT_OUTPUT, true);
this.factory.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
this.sealed = sealed;
this.factory.registerSubtypes(BergamotAgentTranscoder.CLASSES);
// include the metric reading models from Polyakov
this.addEventType(PolyakovTranscoder.CLASSES);
}
public BergamotAgentTranscoder()
{
this(false);
}
public boolean isSealed()
{
return this.sealed;
}
public void addEventType(Class<?>... classes)
{
if (! this.sealed)
{
this.factory.registerSubtypes(classes);
}
}
public void encode(Object event, OutputStream to)
{
try
{
JsonGenerator g = this.factory.getFactory().createGenerator(to);
try
{
this.factory.writeValue(g, event);
}
finally
{
g.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to encode event", e);
}
}
public void encode(Object event, Writer to)
{
try
{
JsonGenerator g = this.factory.getFactory().createGenerator(to);
try
{
this.factory.writeValue(g, event);
}
finally
{
g.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to encode event", e);
}
}
public byte[] encodeAsBytes(Object event)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
this.encode(event, baos);
return baos.toByteArray();
}
public String encodeAsString(Object event)
{
StringWriter sw = new StringWriter();
this.encode(event, sw);
return sw.toString();
}
public void encode(Object event, File file)
{
file.getParentFile().mkdirs();
try
{
FileWriter fw = new FileWriter(file);
try
{
this.encode(event, fw);
}
finally
{
fw.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to write file", e);
}
}
public <T> T decode(InputStream from, JavaType type)
{
try
{
JsonParser p = this.factory.getFactory().createParser(from);
try
{
return this.factory.readValue(p, type);
}
finally
{
p.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to decode event", e);
}
}
public <T> T decode(InputStream from, Class<T> type)
{
try
{
JsonParser p = this.factory.getFactory().createParser(from);
try
{
return this.factory.readValue(p, type);
}
finally
{
p.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to decode event", e);
}
}
public <T> List<T> decodeList(InputStream from, Class<T> elementType)
{
try
{
JsonParser p = this.factory.getFactory().createParser(from);
try
{
return this.factory.readValue(p, this.factory.getTypeFactory().constructCollectionType(List.class, elementType));
}
finally
{
p.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to decode event", e);
}
}
public <T> Set<T> decodeSet(InputStream from, Class<T> elementType)
{
try
{
JsonParser p = this.factory.getFactory().createParser(from);
try
{
return this.factory.readValue(p, this.factory.getTypeFactory().constructCollectionType(Set.class, elementType));
}
finally
{
p.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to decode event", e);
}
}
public <T> T decode(Reader from, Class<T> type)
{
try
{
JsonParser p = this.factory.getFactory().createParser(from);
try
{
return (T) this.factory.readValue(p, type);
}
finally
{
p.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to decode event", e);
}
}
public <T> T decode(Reader from, JavaType type)
{
try
{
JsonParser p = this.factory.getFactory().createParser(from);
try
{
return this.factory.readValue(p, type);
}
finally
{
p.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to decode event", e);
}
}
public <T> List<T> decodeList(Reader from, Class<T> elementType)
{
try
{
JsonParser p = this.factory.getFactory().createParser(from);
try
{
return this.factory.readValue(p, this.factory.getTypeFactory().constructCollectionType(List.class, elementType));
}
finally
{
p.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to decode event", e);
}
}
public <T> Set<T> decodeSet(Reader from, Class<T> elementType)
{
try
{
JsonParser p = this.factory.getFactory().createParser(from);
try
{
return this.factory.readValue(p, this.factory.getTypeFactory().constructCollectionType(Set.class, elementType));
}
finally
{
p.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to decode event", e);
}
}
public <T> T decodeFromString(String event, Class<T> type)
{
return this.decode(new StringReader(event), type);
}
public <T> T decodeFromString(String event, JavaType type)
{
return this.decode(new StringReader(event), type);
}
public <T> List<T> decodeListFromString(String event, Class<T> elementType)
{
return this.decodeList(new StringReader(event), elementType);
}
public <T> Set<T> decodeSetFromString(String event, Class<T> elementType)
{
return this.decodeSet(new StringReader(event), elementType);
}
public <T> T decodeFromBytes(byte[] event, Class<T> type)
{
return this.decode(new ByteArrayInputStream(event), type);
}
public <T> T decodeFromBytes(byte[] event, JavaType type)
{
return this.decode(new ByteArrayInputStream(event), type);
}
public <T> List<T> decodeListFromBytes(byte[] event, Class<T> elementType)
{
return this.decodeList(new ByteArrayInputStream(event), elementType);
}
public <T> Set<T> decodeSetFromBytes(byte[] event, Class<T> elementType)
{
return this.decodeSet(new ByteArrayInputStream(event), elementType);
}
public <T> T decode(File event, Class<T> type)
{
try
{
FileReader fr = new FileReader(event);
try
{
return this.decode(fr, type);
}
finally
{
fr.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to read file", e);
}
}
public <T> T decode(File event, JavaType type)
{
try
{
FileReader fr = new FileReader(event);
try
{
return this.decode(fr, type);
}
finally
{
fr.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to read file", e);
}
}
public <T> List<T> decodeList(File event, Class<T> elementType)
{
try
{
FileReader fr = new FileReader(event);
try
{
return this.decodeList(fr, elementType);
}
finally
{
fr.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to read file", e);
}
}
public <T> Set<T> decodeSet(File event, Class<T> elementType)
{
try
{
FileReader fr = new FileReader(event);
try
{
return this.decodeSet(fr, elementType);
}
finally
{
fr.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Failed to read file", e);
}
}
}