diff --git a/core/src/com/cloud/event/UsageEvent.java b/core/src/com/cloud/event/UsageEvent.java
new file mode 100644
index 00000000000..c90840afce2
--- /dev/null
+++ b/core/src/com/cloud/event/UsageEvent.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.cloud.event;
+
+import java.util.Date;
+
+public interface UsageEvent {
+ long getId();
+ String getType();
+
+ Date getCreateDate();
+ long getAccountId();
+ Long getSize();
+ Long getTemplateId();
+ Long getOfferingId();
+ long getResourceId();
+ long getZoneId();
+}
diff --git a/core/src/com/cloud/event/UsageEventVO.java b/core/src/com/cloud/event/UsageEventVO.java
new file mode 100644
index 00000000000..4390978b8bf
--- /dev/null
+++ b/core/src/com/cloud/event/UsageEventVO.java
@@ -0,0 +1,169 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.cloud.event;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.PrimaryKeyJoinColumn;
+import javax.persistence.SecondaryTable;
+import javax.persistence.Table;
+
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name="usage_event")
+@SecondaryTable(name="account",
+ pkJoinColumns={@PrimaryKeyJoinColumn(name="account_id", referencedColumnName="id")})
+public class UsageEventVO implements UsageEvent {
+ @Id
+ @GeneratedValue(strategy=GenerationType.IDENTITY)
+ @Column(name="id")
+ private long id = -1;
+
+ @Column(name="type")
+ private String type;
+
+ @Column(name=GenericDao.CREATED_COLUMN)
+ private Date createDate;
+
+ @Column(name="account_id")
+ private long accountId;
+
+ @Column(name="zone_id")
+ private long zoneId;
+
+ @Column(name="resource_id")
+ private long resourceId;
+
+ @Column(name="resource_name")
+ private String resourceName;
+
+ @Column(name="offering_id")
+ private Long offeringId;
+
+ @Column(name="template_id")
+ private Long templateId;
+
+ @Column(name="size")
+ private Long size;
+
+
+ public UsageEventVO() {
+ }
+
+ public UsageEventVO(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, Long size) {
+ this.type = usageType;
+ this.accountId = accountId;
+ this.zoneId = zoneId;
+ this.resourceId = resourceId;
+ this.resourceName = resourceName;
+ this.offeringId = offeringId;
+ this.templateId = templateId;
+ this.size = size;
+ }
+
+ public UsageEventVO(String usageType, long accountId, long zoneId, long resourceId, String resourceName) {
+ this.type = usageType;
+ this.accountId = accountId;
+ this.zoneId = zoneId;
+ this.resourceId = resourceId;
+ this.resourceName = resourceName;
+ }
+
+ public long getId() {
+ return id;
+ }
+ @Override
+ public String getType() {
+ return type;
+ }
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ @Override
+ public Date getCreateDate() {
+ return createDate;
+ }
+ public void setCreatedDate(Date createdDate) {
+ createDate = createdDate;
+ }
+
+ @Override
+ public long getAccountId() {
+ return accountId;
+ }
+ public void setAccountId(long accountId) {
+ this.accountId = accountId;
+ }
+
+ public void setZoneId(long zoneId) {
+ this.zoneId = zoneId;
+ }
+ @Override
+ public long getZoneId() {
+ return zoneId;
+ }
+
+ public void setResourceId(long resourceId) {
+ this.resourceId = resourceId;
+ }
+ @Override
+ public long getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceName(String resourceName) {
+ this.resourceName = resourceName;
+ }
+
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ public void setOfferingId(long offeringId) {
+ this.offeringId = offeringId;
+ }
+ @Override
+ public Long getOfferingId() {
+ return offeringId;
+ }
+
+ public void setTemplateId(long templateId) {
+ this.templateId = templateId;
+ }
+ @Override
+ public Long getTemplateId() {
+ return templateId;
+ }
+
+ public void setSize(long size) {
+ this.size = size;
+ }
+ @Override
+ public Long getSize() {
+ return size;
+ }
+
+}
diff --git a/core/src/com/cloud/event/dao/UsageEventDao.java b/core/src/com/cloud/event/dao/UsageEventDao.java
new file mode 100644
index 00000000000..271856b2f5d
--- /dev/null
+++ b/core/src/com/cloud/event/dao/UsageEventDao.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.cloud.event.dao;
+
+import java.util.Date;
+import java.util.List;
+
+import com.cloud.event.UsageEventVO;
+import com.cloud.exception.UsageServerException;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.db.SearchCriteria;
+
+public interface UsageEventDao extends GenericDao {
+
+ public List searchAllUsageEvents(SearchCriteria sc, Filter filter);
+
+ public List listLatestEvents(Date recentEventDate, Date endDate);
+
+ public List listAllEvents(Date endDate);
+
+ public List getLatestEventDate();
+
+ List getRecentEvents(Date endDate) throws UsageServerException;
+
+}
\ No newline at end of file
diff --git a/core/src/com/cloud/event/dao/UsageEventDaoImpl.java b/core/src/com/cloud/event/dao/UsageEventDaoImpl.java
new file mode 100644
index 00000000000..170892dd95e
--- /dev/null
+++ b/core/src/com/cloud/event/dao/UsageEventDaoImpl.java
@@ -0,0 +1,163 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.cloud.event.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+
+import javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.event.UsageEventVO;
+import com.cloud.exception.UsageServerException;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+
+@Local(value={UsageEventDao.class})
+public class UsageEventDaoImpl extends GenericDaoBase implements UsageEventDao {
+ public static final Logger s_logger = Logger.getLogger(UsageEventDaoImpl.class.getName());
+
+ private final SearchBuilder latestEventsSearch;
+ private final SearchBuilder allEventsSearch;
+ private static final String GET_LATEST_EVENT_DATE = "SELECT created FROM usage_event ORDER BY created DESC LIMIT 1";
+ private static final String COPY_EVENTS = "INSERT INTO cloud_usage.usage_event SELECT id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size FROM cloud.usage_event vmevt WHERE vmevt.created > ? and vmevt.created <= ? ";
+ private static final String COPY_ALL_EVENTS = "INSERT INTO cloud_usage.usage_event SELECT id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size FROM cloud.usage_event where created <= ? ";
+
+
+ public UsageEventDaoImpl () {
+ latestEventsSearch = createSearchBuilder();
+ latestEventsSearch.and("recentEventDate", latestEventsSearch.entity().getCreateDate(), SearchCriteria.Op.GT);
+ latestEventsSearch.and("enddate", latestEventsSearch.entity().getCreateDate(), SearchCriteria.Op.LTEQ);
+ latestEventsSearch.done();
+
+ allEventsSearch = createSearchBuilder();
+ allEventsSearch.and("enddate", allEventsSearch.entity().getCreateDate(), SearchCriteria.Op.LTEQ);
+ allEventsSearch.done();
+
+ }
+
+ @Override
+ public List listLatestEvents(Date recentEventDate, Date endDate) {
+ Filter filter = new Filter(UsageEventVO.class, "createDate", Boolean.TRUE, null, null);
+ SearchCriteria sc = latestEventsSearch.create();
+ sc.setParameters("recentEventDate", recentEventDate);
+ sc.setParameters("enddate", endDate);
+ return listBy(sc, filter);
+ }
+
+ @Override
+ public List listAllEvents(Date endDate) {
+ Filter filter = new Filter(UsageEventVO.class, "createDate", Boolean.TRUE, null, null);
+ SearchCriteria sc = latestEventsSearch.create();
+ sc.setParameters("enddate", endDate);
+ return listBy(sc, filter);
+ }
+
+ @Override
+ public List getLatestEventDate() {
+ Filter filter = new Filter(UsageEventVO.class, "createDate", Boolean.FALSE, null, 1L);
+ return listAll(filter);
+ }
+
+ @Override
+ public List searchAllUsageEvents(SearchCriteria sc, Filter filter) {
+ return listIncludingRemovedBy(sc, filter);
+ }
+
+
+ public synchronized List getRecentEvents(Date endDate) throws UsageServerException {
+ Transaction txn = Transaction.open(Transaction.USAGE_DB);
+ Date recentEventDate = getMostRecentEventDate();
+ String sql = COPY_EVENTS;
+ if (recentEventDate == null) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("no recent event date, copying all events");
+ }
+ sql = COPY_ALL_EVENTS;
+ }
+
+ PreparedStatement pstmt = null;
+ try {
+ txn.start();
+ pstmt = txn.prepareAutoCloseStatement(sql);
+ int i = 1;
+ if (recentEventDate != null) {
+ pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), recentEventDate));
+ }
+ pstmt.setString(i, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
+ pstmt.executeUpdate();
+ txn.commit();
+ return findRecentEvents(recentEventDate, endDate);
+ } catch (Exception ex) {
+ txn.rollback();
+ s_logger.error("error copying events from cloud db to usage db", ex);
+ throw new UsageServerException(ex.getMessage());
+ } finally {
+ txn.close();
+ }
+ }
+
+ private Date getMostRecentEventDate() throws UsageServerException {
+ Transaction txn = Transaction.open(Transaction.USAGE_DB);
+ PreparedStatement pstmt = null;
+ String sql = GET_LATEST_EVENT_DATE;
+ try {
+ pstmt = txn.prepareAutoCloseStatement(sql);
+ ResultSet rs = pstmt.executeQuery();
+ if (rs.next()) {
+ String mostRecentTimestampStr = rs.getString(1);
+ if (mostRecentTimestampStr != null) {
+ return DateUtil.parseDateString(s_gmtTimeZone, mostRecentTimestampStr);
+ }
+ }
+ } catch (Exception ex) {
+ s_logger.error("error getting most recent event date", ex);
+ throw new UsageServerException(ex.getMessage());
+ } finally {
+ txn.close();
+ }
+ return null;
+ }
+
+ private List findRecentEvents(Date recentEventDate, Date endDate) throws UsageServerException {
+ Transaction txn = Transaction.open(Transaction.USAGE_DB);
+ try {
+ int i = 1;
+ if (recentEventDate == null) {
+ return listAllEvents(endDate);
+ } else {
+ return listLatestEvents(recentEventDate, endDate);
+ }
+ } catch (Exception ex) {
+ s_logger.error("error getting most recent event date", ex);
+ throw new UsageServerException(ex.getMessage());
+ } finally {
+ txn.close();
+ }
+ }
+
+}