package com.produban.openbus.topologies;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;
import org.elasticsearch.client.Client;
import storm.trident.operation.BaseFunction;
import storm.trident.operation.TridentCollector;
import storm.trident.operation.TridentOperationContext;
import storm.trident.tuple.TridentTuple;
import backtype.storm.tuple.Values;
public class PostfixLocationParser extends BaseFunction {
private static final long serialVersionUID = 1L;
private static Logger LOG = Logger.getLogger(PostfixLocationParser.class);
public static final char SEPARADOR = '\001';
public static Pattern pattern = Pattern.compile("(?<EVENTTIMESTAMP>(.{15}))(\\s)(\\S+)(\\s)postfix/(smtpd\\[(?<SMTPDID>(\\d+))\\]|cleanup\\[(?<CLEANUPID>(\\d+))\\]|qmgr\\[(?<QMGRID>(\\d+))\\]|smtp\\[(?<SMTPID>(\\d+))\\]|error\\[(?<ERRORID>(\\d+))\\]):((\\s+)(?<MSGID>(\\S+)):)?(\\s+)(client=(?<CLIENTE>(\\S+))\\[(?<CLIENTEIP>(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+))\\]|(?<ACCION>(connect(\\s)from(\\s)|disconnect(\\s)from(\\s)))(?<SERVER>(\\S+))\\[(?<SERVERIP>(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+))\\]|message-id=<(?<MESSAGEID>(\\S+))>|from=<(?<FROM>([^>]*)?)>,(\\s)size=(?<SIZE>(\\d+)),(\\s)nrcpt=(?<NRCPT>(\\d+))(\\s)(?<NRCPTDEC>((\\S+)(\\s)?)*)$|to=<(?<TO>(\\S+))>,(\\s)relay=(?<TOSERVERNAME>(\\S+)?)\\[(?<TOSERVERIP>(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+))\\]:(?<TOSERVERPORT>(\\d+))(,(\\s)conn_use=(\\d*))?,(\\s)delay=(?<DELAY>(\\d+)[.,]?(\\d*)),(\\s+)delays=((\\d+)[.,]?(\\d*))/((\\d+)[.,]?(\\d*))/((\\d+)[.,]?(\\d*))/((\\d+)[.,]?(\\d*)),(\\s)dsn=(?<DSN>(\\S+)),(\\s)status=(?<STATUS>(\\S+))(\\s)(?<STATUSDESC>\\((.*)\\)$))");
public static Pattern subpattern = Pattern.compile("((\\s)queued(\\s)as(\\s)(?<AMAVISID>(\\S+))\\))");
private String origen;
private String elasticSearchHost;
private String elasticSearchCluster;
private int elasticSearchPort;
private Boolean useCache;
private Client client;
private LocationStore ubicacion;
public PostfixLocationParser(String EShost, int ESPort, String clusterName, Boolean useCache) {
this.elasticSearchHost = EShost;
this.elasticSearchPort = ESPort;
this.elasticSearchCluster = clusterName;
this.useCache = useCache;
}
@Override
public void prepare(@SuppressWarnings("rawtypes") Map conf, TridentOperationContext context) {
ubicacion = new LocationStore(this.elasticSearchHost, this.elasticSearchPort, this.elasticSearchCluster, this.useCache);
super.prepare(conf, context);
}
@Override
public void cleanup() {
client.close();
}
@Override
public void execute(TridentTuple tupla, TridentCollector colector) {
Matcher matcherSubPat;
String amavisId = null;
String ip;
Localizacion location;
List<Object> objetos = tupla.getValues();
Matcher matcher = pattern.matcher("");
if (objetos.get(0) instanceof String) {
matcher = pattern.matcher(tupla.getString(0));
}
else if (objetos.get(0) instanceof byte[]) {
matcher = pattern.matcher(new String((byte[]) tupla.toArray()[0]));
}
if (matcher.find()) {
ip = matcher.group("CLIENTEIP");
location = ubicacion.getLocationRangos(ip);
if (matcher.group("STATUSDESC") != null) {
matcherSubPat = subpattern.matcher(matcher.group("STATUSDESC"));
if (matcherSubPat.find()) {
amavisId = matcherSubPat.group("AMAVISID");
}
}
colector.emit(new Values(fechaFormato(matcher.group("EVENTTIMESTAMP")), matcher.group("SMTPDID"), matcher.group("MSGID"), matcher.group("CLEANUPID"),
matcher.group("QMGRID"), matcher.group("SMTPID"), matcher.group("ERRORID"), matcher.group("CLIENTE"), matcher.group("CLIENTEIP"),
matcher.group("ACCION"), matcher.group("SERVER"), matcher.group("SERVERIP"), matcher.group("MESSAGEID"), matcher.group("FROM"),
matcher.group("SIZE"), matcher.group("NRCPT"), matcher.group("TO"), matcher.group("TOSERVERNAME"), matcher.group("TOSERVERIP"),
matcher.group("TOSERVERPORT"), matcher.group("DELAY"), matcher.group("DSN"), matcher.group("STATUS"), matcher.group("STATUSDESC"),
amavisId, location.getCoordsString(), location.getCity(), location.getPostalCode(),location.getAreaCode(), location.getMetroCode(),
location.getRegion(), location.getCountry()
));
//LOG.info(location.getCoordsString()+location.getCity()+location.getPostalCode()+location.getAreaCode()+location.getMetroCode()+location.getRegion()+location.getCountry());
}
}
public String fechaFormato(String entrada) {
String salida = entrada;
if (entrada != null && entrada.length() == 15) {
Calendar c = Calendar.getInstance();
String mesString = entrada.substring(0, 3);
String mes = "00";
if (mesString.toLowerCase().equals("jan"))
mes = "01";
else if (mesString.toLowerCase().equals("feb"))
mes = "02";
else if (mesString.toLowerCase().equals("mar"))
mes = "03";
else if (mesString.toLowerCase().equals("apr"))
mes = "04";
else if (mesString.toLowerCase().equals("may"))
mes = "05";
else if (mesString.toLowerCase().equals("jun"))
mes = "06";
else if (mesString.toLowerCase().equals("jul"))
mes = "07";
else if (mesString.toLowerCase().equals("aug"))
mes = "08";
else if (mesString.toLowerCase().equals("sep"))
mes = "09";
else if (mesString.toLowerCase().equals("oct"))
mes = "10";
else if (mesString.toLowerCase().equals("nov"))
mes = "11";
else if (mesString.toLowerCase().equals("dec"))
mes = "12";
String dia = entrada.substring(4, 6);
int anho = c.get(Calendar.YEAR);
if (mes.equals("12")) { // diciembre es el mes 0 del año siguiente
anho--;
}
char decena = entrada.charAt(4);
if (decena == ' ')
dia = "0" + entrada.charAt(5);
salida = anho + "-" + mes + "-" + dia + " " + entrada.substring(7, 9) + ":" + entrada.substring(10, 12) + ":" + entrada.substring(13, 15);
}
return salida;
}
}