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(); + } + } + +}