/*****************************************************************************
*
* Copyright (C) Zenoss, Inc. 2010, 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.zep.UUIDGenerator;
import org.zenoss.zep.ZepException;
import org.zenoss.zep.annotations.TransactionalReadOnly;
import org.zenoss.zep.annotations.TransactionalRollbackAllExceptions;
import org.zenoss.zep.dao.EventSignalSpool;
import org.zenoss.zep.dao.EventSignalSpoolDao;
import org.zenoss.zep.dao.impl.compat.DatabaseCompatibility;
import org.zenoss.zep.dao.impl.compat.NestedTransactionService;
import org.zenoss.zep.dao.impl.compat.TypeConverter;
import org.zenoss.zep.dao.impl.compat.TypeConverterUtils;
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.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class EventSignalSpoolDaoImpl implements EventSignalSpoolDao {
public static final String COLUMN_UUID = "uuid";
public static final String COLUMN_EVENT_TRIGGER_SUBSCRIPTION_UUID = "event_trigger_subscription_uuid";
public static final String COLUMN_EVENT_SUMMARY_UUID = "event_summary_uuid";
public static final String COLUMN_FLUSH_TIME = "flush_time";
public static final String COLUMN_CREATED = "created";
public static final String COLUMN_EVENT_COUNT = "event_count";
public static final String COLUMN_SENT_SIGNAL = "sent_signal";
private class EventSignalSpoolMapper implements RowMapper<EventSignalSpool> {
@Override
public EventSignalSpool mapRow(ResultSet rs, int rowNum)
throws SQLException {
TypeConverter<Long> timestampConverter = databaseCompatibility.getTimestampConverter();
EventSignalSpool spool = new EventSignalSpool();
spool.setUuid(uuidConverter.fromDatabaseType(rs, COLUMN_UUID));
spool.setCreated(timestampConverter.fromDatabaseType(rs, COLUMN_CREATED));
spool.setEventCount(rs.getInt(COLUMN_EVENT_COUNT));
spool.setEventSummaryUuid(uuidConverter.fromDatabaseType(rs, COLUMN_EVENT_SUMMARY_UUID));
spool.setSubscriptionUuid(uuidConverter.fromDatabaseType(rs, COLUMN_EVENT_TRIGGER_SUBSCRIPTION_UUID));
spool.setFlushTime(rs.getLong(COLUMN_FLUSH_TIME));
spool.setSentSignal(rs.getBoolean(COLUMN_SENT_SIGNAL));
return spool;
}
}
@SuppressWarnings("unused")
private static Logger logger = LoggerFactory.getLogger(EventSignalSpoolDaoImpl.class);
private final SimpleJdbcOperations template;
private UUIDGenerator uuidGenerator;
private DatabaseCompatibility databaseCompatibility;
private TypeConverter<String> uuidConverter;
private NestedTransactionService nestedTransactionService;
public EventSignalSpoolDaoImpl(DataSource dataSource) {
this.template = (SimpleJdbcOperations) Proxy.newProxyInstance(SimpleJdbcOperations.class.getClassLoader(),
new Class<?>[] {SimpleJdbcOperations.class}, new SimpleJdbcTemplateProxy(dataSource));
}
public void setUuidGenerator(UUIDGenerator uuidGenerator) {
this.uuidGenerator = uuidGenerator;
}
public void setDatabaseCompatibility(DatabaseCompatibility databaseCompatibility) {
this.databaseCompatibility = databaseCompatibility;
this.uuidConverter = databaseCompatibility.getUUIDConverter();
}
public void setNestedTransactionService(NestedTransactionService nestedTransactionService) {
this.nestedTransactionService = nestedTransactionService;
}
private Map<String, Object> spoolToFields(EventSignalSpool spool) {
final Map<String, Object> fields = new LinkedHashMap<String, Object>();
TypeConverter<Long> timestampConverter = databaseCompatibility.getTimestampConverter();
fields.put(COLUMN_CREATED, timestampConverter.toDatabaseType(spool.getCreated()));
fields.put(COLUMN_EVENT_SUMMARY_UUID, uuidConverter.toDatabaseType(spool.getEventSummaryUuid()));
fields.put(COLUMN_EVENT_TRIGGER_SUBSCRIPTION_UUID, uuidConverter.toDatabaseType(spool.getSubscriptionUuid()));
fields.put(COLUMN_FLUSH_TIME, spool.getFlushTime());
fields.put(COLUMN_EVENT_COUNT, spool.getEventCount());
fields.put(COLUMN_SENT_SIGNAL, spool.isSentSignal());
return fields;
}
@Override
@TransactionalRollbackAllExceptions
public String create(EventSignalSpool spool) throws ZepException {
final Map<String, Object> fields = spoolToFields(spool);
String uuid = spool.getUuid();
if (uuid == null) {
uuid = uuidGenerator.generate().toString();
}
fields.put(COLUMN_UUID, uuidConverter.toDatabaseType(uuid));
final StringBuilder names = new StringBuilder();
final StringBuilder values = new StringBuilder();
for (String key : fields.keySet()) {
if (names.length() > 0) {
names.append(',');
values.append(',');
}
names.append(key);
values.append(':').append(key);
}
final String insertSql = String.format("INSERT INTO event_trigger_signal_spool (%s) VALUES(%s)", names,
values);
final String updateSql = "UPDATE event_trigger_signal_spool SET event_count = event_count + 1" +
" WHERE uuid=:uuid";
DaoUtils.insertOrUpdate(nestedTransactionService, template, insertSql, updateSql, fields);
spool.setUuid(uuid);
return uuid;
}
@Override
@TransactionalRollbackAllExceptions
public int delete(String uuid) throws ZepException {
return delete(Collections.singletonList(uuid));
}
@Override
@TransactionalRollbackAllExceptions
public int delete(List<String> uuids) throws ZepException {
final Map<String,List<Object>> fields = Collections.singletonMap("_uuids",
TypeConverterUtils.batchToDatabaseType(uuidConverter, uuids));
final String sql = "DELETE FROM event_trigger_signal_spool WHERE uuid IN (:_uuids)";
return this.template.update(sql, fields);
}
@Override
@TransactionalRollbackAllExceptions
public int delete(String triggerUuid, String summaryUuid) throws ZepException {
Map<String,Object> fields = new HashMap<String, Object>(2);
fields.put(COLUMN_EVENT_SUMMARY_UUID, uuidConverter.toDatabaseType(summaryUuid));
fields.put(EventTriggerSubscriptionDaoImpl.COLUMN_EVENT_TRIGGER_UUID,
uuidConverter.toDatabaseType(triggerUuid));
final String sql = "DELETE FROM event_trigger_signal_spool WHERE event_summary_uuid=:event_summary_uuid " +
"AND event_trigger_subscription_uuid IN " +
"(SELECT uuid FROM event_trigger_subscription WHERE event_trigger_uuid=:event_trigger_uuid)";
return this.template.update(sql, fields);
}
@Override
@TransactionalRollbackAllExceptions
public int deleteByEventSummaryUuid(String eventSummaryUuid) throws ZepException {
return deleteByEventSummaryUuids(Collections.singletonList(eventSummaryUuid));
}
@Override
public int deleteByEventSummaryUuids(Collection<String> eventSummaryUuids) throws ZepException {
if (eventSummaryUuids.isEmpty()) {
return 0;
}
final Map<String,List<Object>> fields = Collections.singletonMap("_uuids",
TypeConverterUtils.batchToDatabaseType(uuidConverter, eventSummaryUuids));
final String sql = "DELETE FROM event_trigger_signal_spool WHERE event_summary_uuid IN (:_uuids)";
return this.template.update(sql, fields);
}
@Override
@TransactionalRollbackAllExceptions
public int deleteByTriggerUuid(String triggerUuid) throws ZepException {
final Map<String, Object> fields = Collections.singletonMap(
EventTriggerSubscriptionDaoImpl.COLUMN_EVENT_TRIGGER_UUID, uuidConverter.toDatabaseType(triggerUuid));
final String sql = "DELETE FROM event_trigger_signal_spool WHERE event_trigger_subscription_uuid IN " +
"(SELECT uuid FROM event_trigger_subscription WHERE event_trigger_uuid=:event_trigger_uuid)";
return this.template.update(sql, fields);
}
@Override
@TransactionalReadOnly
public EventSignalSpool findByUuid(String uuid) throws ZepException {
Map<String,Object> fields = Collections.singletonMap(COLUMN_UUID, uuidConverter.toDatabaseType(uuid));
final String sql = "SELECT * FROM event_trigger_signal_spool WHERE uuid=:uuid";
List<EventSignalSpool> spools = this.template.query(sql, new EventSignalSpoolMapper(), fields);
EventSignalSpool spool = null;
if (!spools.isEmpty()) {
spool = spools.get(0);
}
return spool;
}
@Override
@TransactionalRollbackAllExceptions
public int update(EventSignalSpool spool) throws ZepException {
Map<String, Object> fields = new HashMap<String, Object>();
fields.put(COLUMN_UUID, uuidConverter.toDatabaseType(spool.getUuid()));
fields.put(COLUMN_FLUSH_TIME, spool.getFlushTime());
fields.put(COLUMN_EVENT_COUNT, spool.getEventCount());
fields.put(COLUMN_SENT_SIGNAL, spool.isSentSignal());
final String sql = "UPDATE event_trigger_signal_spool SET flush_time=:flush_time,event_count=:event_count,"
+ "sent_signal=:sent_signal WHERE uuid=:uuid";
return this.template.update(sql, fields);
}
@Override
@TransactionalReadOnly
public EventSignalSpool findBySubscriptionAndEventSummaryUuids(
String subscriptionUuid, String summaryUuid) throws ZepException {
final Map<String,Object> fields = new HashMap<String,Object>();
fields.put(COLUMN_EVENT_TRIGGER_SUBSCRIPTION_UUID, uuidConverter.toDatabaseType(subscriptionUuid));
fields.put(COLUMN_EVENT_SUMMARY_UUID, uuidConverter.toDatabaseType(summaryUuid));
final String sql = "SELECT * FROM event_trigger_signal_spool WHERE " +
"event_trigger_subscription_uuid=:event_trigger_subscription_uuid AND " +
"event_summary_uuid=:event_summary_uuid";
final List<EventSignalSpool> spools = this.template.query(sql,
new EventSignalSpoolMapper(), fields);
return (!spools.isEmpty()) ? spools.get(0) : null;
}
@Override
@TransactionalReadOnly
public List<EventSignalSpool> findAllDue() throws ZepException {
Map<String,Long> fields = Collections.singletonMap(COLUMN_FLUSH_TIME,System.currentTimeMillis());
final String sql = "SELECT * FROM event_trigger_signal_spool WHERE flush_time <= :flush_time";
return this.template.query(sql, new EventSignalSpoolMapper(), fields);
}
@Override
@TransactionalReadOnly
public List<EventSignalSpool> findAllByEventSummaryUuid(String eventSummaryUuid) throws ZepException {
return findAllByEventSummaryUuids(Collections.singletonList(eventSummaryUuid));
}
@Override
public List<EventSignalSpool> findAllByEventSummaryUuids(Collection<String> eventSummaryUuids) throws ZepException {
if (eventSummaryUuids.isEmpty()) {
return Collections.emptyList();
}
final String sql = "SELECT * FROM event_trigger_signal_spool WHERE event_summary_uuid IN (:_uuids)";
final Map<String,List<Object>> fields = Collections.singletonMap("_uuids",
TypeConverterUtils.batchToDatabaseType(uuidConverter, eventSummaryUuids));
return this.template.query(sql, new EventSignalSpoolMapper(), fields);
}
@Override
@TransactionalReadOnly
public long getNextFlushTime() throws ZepException {
final String sql = "SELECT MIN(flush_time) FROM event_trigger_signal_spool";
return this.template.queryForLong(sql);
}
}