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;
}
}