/*****************************************************************************
*
* Copyright (C) Zenoss, Inc. 2011, all rights reserved.
*
* This content is made available according to terms specified in
* License.zenoss under the directory where your Zenoss product is installed.
*
****************************************************************************/
package org.zenoss.zep.dao.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcOperations;
import org.zenoss.protobufs.zep.Zep;
import org.zenoss.utils.dao.RangePartitioner;
import org.zenoss.zep.ZepException;
import org.zenoss.zep.annotations.TransactionalReadOnly;
import org.zenoss.zep.annotations.TransactionalRollbackAllExceptions;
import org.zenoss.zep.dao.EventTimeDao;
import org.zenoss.zep.dao.impl.compat.DatabaseCompatibility;
import org.zenoss.zep.dao.impl.compat.TypeConverter;
import org.zenoss.zep.dao.impl.SimpleJdbcTemplateProxy;
import java.lang.reflect.Proxy;
import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static org.zenoss.zep.dao.impl.EventConstants.*;
/**
* NOTE: This table may be backed by MyISAM storage so normal transaction
* handling won't work here. Ignore the @Transactional* annotations on
* the methods as they are ignored.
*/
public class EventTimeDaoImpl implements EventTimeDao {
@SuppressWarnings("unused")
private static final Logger logger = LoggerFactory.getLogger(EventTimeDaoImpl.class);
private final SimpleJdbcOperations template;
private final PartitionTableConfig partitionTableConfig;
private final DatabaseCompatibility databaseCompatibility;
private final RangePartitioner partitioner;
private final TypeConverter<String> uuidConverter;
public EventTimeDaoImpl(DataSource dataSource, PartitionConfig partitionConfig,
DatabaseCompatibility databaseCompatibility) {
this.template = (SimpleJdbcOperations) Proxy.newProxyInstance(SimpleJdbcOperations.class.getClassLoader(),
new Class<?>[] {SimpleJdbcOperations.class}, new SimpleJdbcTemplateProxy(dataSource));
this.partitionTableConfig = partitionConfig.getConfig(TABLE_EVENT_TIME);
this.databaseCompatibility = databaseCompatibility;
this.partitioner = databaseCompatibility.getRangePartitioner(dataSource,
TABLE_EVENT_TIME, COLUMN_PROCESSED,
partitionTableConfig.getPartitionDuration(),
partitionTableConfig.getPartitionUnit());
this.uuidConverter = databaseCompatibility.getUUIDConverter();
}
@Override
@TransactionalRollbackAllExceptions
public void purge(int duration, TimeUnit unit) throws ZepException {
this.partitioner.pruneAndCreatePartitions(duration,
unit,
this.partitionTableConfig.getInitialPastPartitions(),
this.partitionTableConfig.getFuturePartitions());
}
@Override
@TransactionalRollbackAllExceptions
public void initializePartitions() throws ZepException {
this.partitioner.createPartitions(
this.partitionTableConfig.getInitialPastPartitions(),
this.partitionTableConfig.getFuturePartitions());
}
@Override
public long getPartitionIntervalInMs() {
return this.partitionTableConfig.getPartitionUnit().toMillis(
this.partitionTableConfig.getPartitionDuration());
}
@Override
@TransactionalReadOnly
public List<Zep.EventTime> findProcessedSince(Date startDate, int limit) {
long timestamp = startDate.getTime();
final Map<String, Object> params = Collections.singletonMap("since",
databaseCompatibility.getTimestampConverter().toDatabaseType(timestamp));
String sql = "SELECT * from %s where %s >= :since order by %s asc limit %s";
sql = String.format(sql, TABLE_EVENT_TIME, COLUMN_PROCESSED, COLUMN_PROCESSED, limit);
return template.query(sql, new EventTimeRowMapper(), params);
}
@Override
@TransactionalRollbackAllExceptions
public void save(Zep.EventTime eventTime) {
Map<String, Object> fields = new LinkedHashMap<String, Object>();
TypeConverter<Long> timestampConverter = databaseCompatibility.getTimestampConverter();
fields.put(COLUMN_PROCESSED, timestampConverter.toDatabaseType(eventTime.getProcessedTime()));
fields.put(COLUMN_CREATED, timestampConverter.toDatabaseType(eventTime.getCreatedTime()));
fields.put(COLUMN_FIRST_SEEN, timestampConverter.toDatabaseType(eventTime.getFirstSeenTime()));
fields.put(COLUMN_SUMMARY_UUID, uuidConverter.toDatabaseType(eventTime.getSummaryUuid()));
String insert = DaoUtils.createNamedInsert(TABLE_EVENT_TIME, fields.keySet());
template.update(insert, fields);
}
private class EventTimeRowMapper implements RowMapper<Zep.EventTime> {
@Override
public Zep.EventTime mapRow(ResultSet rs, int rowNum) throws SQLException {
Zep.EventTime.Builder builder = Zep.EventTime.newBuilder();
TypeConverter<Long> timestampConverter = databaseCompatibility.getTimestampConverter();
builder.setCreatedTime(timestampConverter.fromDatabaseType(rs, COLUMN_CREATED));
builder.setProcessedTime(timestampConverter.fromDatabaseType(rs, COLUMN_PROCESSED));
builder.setFirstSeenTime(timestampConverter.fromDatabaseType(rs, COLUMN_FIRST_SEEN));
String summaryUuid = uuidConverter.fromDatabaseType(rs, COLUMN_SUMMARY_UUID);
builder.setSummaryUuid(summaryUuid);
return builder.build();
}
}
}