package com.produban.openbus.topologies;
import java.util.Calendar;
import java.util.List;
import org.apache.storm.hdfs.trident.rotation.FileRotationPolicy;
import storm.trident.tuple.TridentTuple;
public class TimeStampRotationPolicy implements FileRotationPolicy {
/**
*
*/
private static final long serialVersionUID = 1L;
public static enum Units {
KB((long)Math.pow(2, 10)),
MB((long)Math.pow(2, 20)),
GB((long)Math.pow(2, 30)),
TB((long)Math.pow(2, 40));
private long byteCount;
private Units(long byteCount){
this.byteCount = byteCount;
}
public long getByteCount(){
return byteCount;
}
}
private long maxBytes;
private long lastOffset = 0;
private long currentBytesWritten = 0;
//milisegundos que tiene cada unidad
public static final long
HOUR=3600000,
MINUTE=60000,
SECOND=1000,
DAY=86400000;
private Calendar limiteTimeStamp=null;
private Calendar ultimoRegistro=Calendar.getInstance();
private long unidad;
private long periodo;
private long diferenciaMillisPermitida;
public TimeStampRotationPolicy setTimePeriod(int periodo,long unidad){
this.unidad=unidad;
this.periodo=periodo;
this.diferenciaMillisPermitida=this.unidad*this.periodo;
resetTimePeriod();
return this;
}
public TimeStampRotationPolicy setSizeMax(float count, Units units){
this.maxBytes = (long)(count * units.getByteCount());
return this;
}
public boolean markTimePeriod(TridentTuple tupla) {
// TODO Auto-generated method stub
boolean result=false;
long diferencia;
List objetos =tupla.getValues();
if (objetos.get(0) instanceof String){
ultimoRegistro=getCalendarTimestamp(tupla.getString(0));
}else if(objetos.get(0) instanceof byte[]){
ultimoRegistro=getCalendarTimestamp(new String((byte[]) tupla.toArray()[0]));
}
//ultimoRegistro=getCalendarTimestamp(tupla.getString(0));
if (limiteTimeStamp==null){
//inicializamos
result=true;
}else{
//comprobar si pasamos del periodo en la unidad
diferencia=Math.abs(limiteTimeStamp.getTimeInMillis()-ultimoRegistro.getTimeInMillis());
result=diferencia>=diferenciaMillisPermitida;
}
return result;
}
public void resetTimePeriod() {
//truncamos a la unidad seleccionada
if (unidad>=SECOND){
ultimoRegistro.set(Calendar.MILLISECOND,0);
}
if (unidad>=MINUTE){
ultimoRegistro.set(Calendar.SECOND,0);
}
if (unidad>=HOUR){
ultimoRegistro.set(Calendar.MINUTE,0);
}
if(unidad>=DAY){
ultimoRegistro.set(Calendar.HOUR, 0);
}
limiteTimeStamp=ultimoRegistro;
}
@Override
public boolean mark(TridentTuple tuple, long offset) {
long diff = offset - this.lastOffset;
this.currentBytesWritten += diff;
this.lastOffset = offset;
return this.currentBytesWritten >= this.maxBytes;
}
@Override
public void reset() {
this.currentBytesWritten = 0;
this.lastOffset = 0;
}
public String getBaseTimestamp(){
String result="";
int anho,mes,dia,hora,minuto,segundo;
String s_mes,s_dia,s_hora,s_minuto,s_segundo;
if (limiteTimeStamp==null){
ultimoRegistro=Calendar.getInstance();
resetTimePeriod();
}
anho=limiteTimeStamp.get(Calendar.YEAR);
mes=limiteTimeStamp.get(Calendar.MONTH);
dia=limiteTimeStamp.get(Calendar.DAY_OF_MONTH);
hora=limiteTimeStamp.get(Calendar.HOUR_OF_DAY);
minuto=limiteTimeStamp.get(Calendar.MINUTE);
segundo=limiteTimeStamp.get(Calendar.SECOND);
if (mes==0){
mes=12;
anho--;
}
s_mes=String.valueOf(mes);
s_dia=String.valueOf(dia);
s_hora=String.valueOf(hora);
s_minuto=String.valueOf(minuto);
s_segundo=String.valueOf(segundo);
if (mes<10) s_mes="0"+s_mes;
if (dia<10) s_dia="0"+s_dia;
if (hora<10) s_hora="0"+s_hora;
if (minuto<10) s_minuto="0"+s_minuto;
if (segundo<10) s_segundo="0"+s_segundo;
result=anho+s_mes+s_dia+"_"+s_hora+s_minuto+s_segundo;
return result;
}
private Calendar getCalendarTimestamp(String timestamp){
Calendar resultado=Calendar.getInstance();
resultado.set(Integer.parseInt(timestamp.substring(0,4)), Integer.parseInt(timestamp.substring(5,7)),Integer.parseInt(timestamp.substring(8,10)),
Integer.parseInt(timestamp.substring(11,13)), Integer.parseInt(timestamp.substring(14,16)), Integer.parseInt(timestamp.substring(17,19)));
return resultado;
}
}