-1 to this commit, since it breaks the build. I'm reverting it now, after confirming that the build works after the revert.
On Fri, Mar 08, 2013 at 06:53:43PM +0000, mc...@apache.org wrote: > Updated Branches: > refs/heads/master ae3eeca8d -> 5e4c2c8a9 > > > CLOUDSTACK-874 Ability to delete Events and Alerts > > Signed-off-by: Min Chen <min.c...@citrix.com> > > > Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo > Commit: > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/5e4c2c8a > Tree: > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/5e4c2c8a > Diff: > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/5e4c2c8a > > Branch: refs/heads/master > Commit: 5e4c2c8a9eb339fb467aea15582a79cd2feef4bf > Parents: ae3eeca > Author: Sanjay Tripathi <sanjay.tripa...@citrix.com> > Authored: Fri Mar 8 10:52:40 2013 -0800 > Committer: Min Chen <min.c...@citrix.com> > Committed: Fri Mar 8 10:52:40 2013 -0800 > > ---------------------------------------------------------------------- > api/src/com/cloud/alert/Alert.java | 1 + > api/src/com/cloud/event/Event.java | 1 + > api/src/com/cloud/server/ManagementService.java | 38 +++- > .../org/apache/cloudstack/api/ApiConstants.java | 1 + > client/tomcatconf/commands.properties.in | 4 + > core/src/com/cloud/alert/AlertVO.java | 38 ++-- > core/src/com/cloud/event/EventVO.java | 167 ++++++++------- > core/src/com/cloud/event/dao/EventDao.java | 5 + > core/src/com/cloud/event/dao/EventDaoImpl.java | 71 +++++-- > server/src/com/cloud/alert/dao/AlertDao.java | 7 + > server/src/com/cloud/alert/dao/AlertDaoImpl.java | 85 ++++++++ > server/src/com/cloud/api/ApiDispatcher.java | 6 +- > .../src/com/cloud/api/query/QueryManagerImpl.java | 3 + > server/src/com/cloud/api/query/vo/EventJoinVO.java | 9 + > server/src/com/cloud/configuration/Config.java | 5 +- > .../src/com/cloud/server/ManagementServerImpl.java | 109 +++++++++- > setup/db/db/schema-410to420.sql | 45 ++++ > 17 files changed, 475 insertions(+), 120 deletions(-) > ---------------------------------------------------------------------- > > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/api/src/com/cloud/alert/Alert.java > ---------------------------------------------------------------------- > diff --git a/api/src/com/cloud/alert/Alert.java > b/api/src/com/cloud/alert/Alert.java > index 050f97f..31768cf 100644 > --- a/api/src/com/cloud/alert/Alert.java > +++ b/api/src/com/cloud/alert/Alert.java > @@ -30,4 +30,5 @@ public interface Alert extends Identity, InternalIdentity { > Date getCreatedDate(); > Date getLastSent(); > Date getResolved(); > + boolean getArchived(); > } > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/api/src/com/cloud/event/Event.java > ---------------------------------------------------------------------- > diff --git a/api/src/com/cloud/event/Event.java > b/api/src/com/cloud/event/Event.java > index 1a61636..b8def4c 100644 > --- a/api/src/com/cloud/event/Event.java > +++ b/api/src/com/cloud/event/Event.java > @@ -40,4 +40,5 @@ public interface Event extends ControlledEntity, Identity, > InternalIdentity { > String getLevel(); > long getStartId(); > String getParameters(); > + boolean getArchived(); > } > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/api/src/com/cloud/server/ManagementService.java > ---------------------------------------------------------------------- > diff --git a/api/src/com/cloud/server/ManagementService.java > b/api/src/com/cloud/server/ManagementService.java > index 1736da3..1e6ca8d 100755 > --- a/api/src/com/cloud/server/ManagementService.java > +++ b/api/src/com/cloud/server/ManagementService.java > @@ -29,6 +29,8 @@ import > org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd; > import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; > import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd; > import org.apache.cloudstack.api.command.admin.pod.ListPodsByCmd; > +import org.apache.cloudstack.api.command.admin.resource.ArchiveAlertsCmd; > +import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd; > import org.apache.cloudstack.api.command.admin.resource.ListAlertsCmd; > import org.apache.cloudstack.api.command.admin.resource.ListCapacityCmd; > import > org.apache.cloudstack.api.command.admin.resource.UploadCustomCertificateCmd; > @@ -40,12 +42,12 @@ import > org.apache.cloudstack.api.command.admin.systemvm.UpgradeSystemVMCmd; > import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd; > import > org.apache.cloudstack.api.command.user.address.ListPublicIpAddressesCmd; > import org.apache.cloudstack.api.command.user.config.ListCapabilitiesCmd; > +import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd; > +import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd; > import org.apache.cloudstack.api.command.user.guest.ListGuestOsCategoriesCmd; > import org.apache.cloudstack.api.command.user.guest.ListGuestOsCmd; > import org.apache.cloudstack.api.command.user.iso.ListIsosCmd; > import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd; > -import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd; > -import > org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd; > import org.apache.cloudstack.api.command.user.ssh.CreateSSHKeyPairCmd; > import org.apache.cloudstack.api.command.user.ssh.DeleteSSHKeyPairCmd; > import org.apache.cloudstack.api.command.user.ssh.ListSSHKeyPairsCmd; > @@ -55,12 +57,10 @@ import > org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd; > import org.apache.cloudstack.api.command.user.vm.GetVMPasswordCmd; > import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd; > import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd; > -import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; > > import com.cloud.alert.Alert; > import com.cloud.capacity.Capacity; > import com.cloud.configuration.Configuration; > -import com.cloud.dc.DataCenter; > import com.cloud.dc.Pod; > import com.cloud.dc.Vlan; > import com.cloud.domain.Domain; > @@ -72,8 +72,6 @@ import com.cloud.host.Host; > import com.cloud.hypervisor.Hypervisor.HypervisorType; > import com.cloud.hypervisor.HypervisorCapabilities; > import com.cloud.network.IpAddress; > -import com.cloud.offering.DiskOffering; > -import com.cloud.offering.ServiceOffering; > import com.cloud.org.Cluster; > import com.cloud.storage.GuestOS; > import com.cloud.storage.GuestOsCategory; > @@ -195,6 +193,34 @@ public interface ManagementService { > Pair<List<? extends Alert>, Integer> searchForAlerts(ListAlertsCmd cmd); > > /** > + * Archive alerts > + * @param cmd > + * @return True on success. False otherwise. > + */ > + boolean archiveAlerts(ArchiveAlertsCmd cmd); > + > + /** > + * Delete alerts > + * @param cmd > + * @return True on success. False otherwise. > + */ > + boolean deleteAlerts(DeleteAlertsCmd cmd); > + > + /** > + * Archive events > + * @param cmd > + * @return True on success. False otherwise. > + */ > + boolean archiveEvents(ArchiveEventsCmd cmd); > + > + /** > + * Delete events > + * @param cmd > + * @return True on success. False otherwise. > + */ > + boolean deleteEvents(DeleteEventsCmd cmd); > + > + /** > * list all the capacity rows in capacity operations table > * > * @param cmd > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/api/src/org/apache/cloudstack/api/ApiConstants.java > ---------------------------------------------------------------------- > diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java > b/api/src/org/apache/cloudstack/api/ApiConstants.java > index 1b544fd..b40b26c 100755 > --- a/api/src/org/apache/cloudstack/api/ApiConstants.java > +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java > @@ -459,6 +459,7 @@ public class ApiConstants { > public static final String UCS_BLADE_DN = "bladedn"; > public static final String UCS_BLADE_ID = "bladeid"; > public static final String VM_GUEST_IP = "vmguestip"; > + public static final String OLDER_THAN = "olderthan"; > > public enum HostDetails { > all, capacity, events, stats, min; > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/client/tomcatconf/commands.properties.in > ---------------------------------------------------------------------- > diff --git a/client/tomcatconf/commands.properties.in > b/client/tomcatconf/commands.properties.in > index dd0c3f8..5018236 100644 > --- a/client/tomcatconf/commands.properties.in > +++ b/client/tomcatconf/commands.properties.in > @@ -218,9 +218,13 @@ listZones=15 > #### events commands > listEvents=15 > listEventTypes=15 > +archiveEvents=15 > +deleteEvents=15 > > #### alerts commands > listAlerts=3 > +archiveAlerts=1 > +deleteAlerts=1 > > #### system capacity commands > listCapacity=3 > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/core/src/com/cloud/alert/AlertVO.java > ---------------------------------------------------------------------- > diff --git a/core/src/com/cloud/alert/AlertVO.java > b/core/src/com/cloud/alert/AlertVO.java > index f6089d6..3f014aa 100755 > --- a/core/src/com/cloud/alert/AlertVO.java > +++ b/core/src/com/cloud/alert/AlertVO.java > @@ -28,9 +28,7 @@ import javax.persistence.Table; > import javax.persistence.Temporal; > import javax.persistence.TemporalType; > > -import org.apache.cloudstack.api.Identity; > import com.cloud.utils.db.GenericDao; > -import org.apache.cloudstack.api.InternalIdentity; > > @Entity > @Table(name="alert") > @@ -68,16 +66,19 @@ public class AlertVO implements Alert { > @Temporal(TemporalType.TIMESTAMP) > @Column(name="resolved", updatable=true, nullable=true) > private Date resolved; > - > + > @Column(name="uuid") > private String uuid; > > + @Column(name="archived") > + private boolean archived; > + > public AlertVO() { > - this.uuid = UUID.randomUUID().toString(); > + this.uuid = UUID.randomUUID().toString(); > } > public AlertVO(Long id) { > this.id = id; > - this.uuid = UUID.randomUUID().toString(); > + this.uuid = UUID.randomUUID().toString(); > } > > @Override > @@ -103,12 +104,12 @@ public class AlertVO implements Alert { > } > > public Long getClusterId() { > - return clusterId; > - } > - public void setClusterId(Long clusterId) { > - this.clusterId = clusterId; > - } > - @Override > + return clusterId; > + } > + public void setClusterId(Long clusterId) { > + this.clusterId = clusterId; > + } > + @Override > public Long getPodId() { > return podId; > } > @@ -164,10 +165,19 @@ public class AlertVO implements Alert { > > @Override > public String getUuid() { > - return this.uuid; > + return this.uuid; > } > - > + > public void setUuid(String uuid) { > - this.uuid = uuid; > + this.uuid = uuid; > + } > + > + @Override > + public boolean getArchived() { > + return archived; > + } > + > + public void setArchived(Boolean archived) { > + this.archived = archived; > } > } > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/core/src/com/cloud/event/EventVO.java > ---------------------------------------------------------------------- > diff --git a/core/src/com/cloud/event/EventVO.java > b/core/src/com/cloud/event/EventVO.java > index ac46f24..2c30ead 100644 > --- a/core/src/com/cloud/event/EventVO.java > +++ b/core/src/com/cloud/event/EventVO.java > @@ -29,74 +29,75 @@ import javax.persistence.Id; > import javax.persistence.Table; > import javax.persistence.Transient; > > -import org.apache.cloudstack.api.Identity; > import com.cloud.utils.db.GenericDao; > -import org.apache.cloudstack.api.InternalIdentity; > > @Entity > @Table(name="event") > public class EventVO implements Event { > - @Id > + @Id > @GeneratedValue(strategy=GenerationType.IDENTITY) > @Column(name="id") > - private long id = -1; > + private long id = -1; > > - @Column(name="type") > - private String type; > - > - @Enumerated(value=EnumType.STRING) > - @Column(name="state") > + @Column(name="type") > + private String type; > + > + @Enumerated(value=EnumType.STRING) > + @Column(name="state") > private State state = State.Completed; > > - @Column(name="description", length=1024) > - private String description; > + @Column(name="description", length=1024) > + private String description; > > - @Column(name=GenericDao.CREATED_COLUMN) > - private Date createDate; > + @Column(name=GenericDao.CREATED_COLUMN) > + private Date createDate; > > @Column(name="user_id") > private long userId; > > - @Column(name="account_id") > - private long accountId; > + @Column(name="account_id") > + private long accountId; > > @Column(name="domain_id") > private long domainId; > > - @Column(name="level") > - private String level = LEVEL_INFO; > - > - @Column(name="start_id") > + @Column(name="level") > + private String level = LEVEL_INFO; > + > + @Column(name="start_id") > private long startId; > > - @Column(name="parameters", length=1024) > - private String parameters; > - > - @Column(name="uuid") > - private String uuid; > - > - @Transient > - private int totalSize; > - > - public static final String LEVEL_INFO = "INFO"; > - public static final String LEVEL_WARN = "WARN"; > - public static final String LEVEL_ERROR = "ERROR"; > - > - public EventVO() { > - this.uuid = UUID.randomUUID().toString(); > - } > - > - public long getId() { > - return id; > - } > - @Override > + @Column(name="parameters", length=1024) > + private String parameters; > + > + @Column(name="uuid") > + private String uuid; > + > + @Column(name="archived") > + private boolean archived; > + > + @Transient > + private int totalSize; > + > + public static final String LEVEL_INFO = "INFO"; > + public static final String LEVEL_WARN = "WARN"; > + public static final String LEVEL_ERROR = "ERROR"; > + > + public EventVO() { > + this.uuid = UUID.randomUUID().toString(); > + } > + > + public long getId() { > + return id; > + } > + @Override > public String getType() { > - return type; > - } > - public void setType(String type) { > - this.type = type; > - } > - @Override > + return type; > + } > + public void setType(String type) { > + this.type = type; > + } > + @Override > public State getState() { > return state; > } > @@ -105,27 +106,27 @@ public class EventVO implements Event { > this.state = state; > } > > - @Override > + @Override > public String getDescription() { > - return description; > - } > - public void setDescription(String description) { > - this.description = description; > - } > - @Override > + return description; > + } > + public void setDescription(String description) { > + this.description = description; > + } > + @Override > public Date getCreateDate() { > - return createDate; > - } > - public void setCreatedDate(Date createdDate) { > - createDate = createdDate; > - } > - @Override > + return createDate; > + } > + public void setCreatedDate(Date createdDate) { > + createDate = createdDate; > + } > + @Override > public long getUserId() { > - return userId; > - } > - public void setUserId(long userId) { > - this.userId = userId; > - } > + return userId; > + } > + public void setUserId(long userId) { > + this.userId = userId; > + } > @Override > public long getAccountId() { > return accountId; > @@ -165,21 +166,29 @@ public class EventVO implements Event { > this.startId = startId; > } > > - @Override > + @Override > public String getParameters() { > - return parameters; > - } > - public void setParameters(String parameters) { > - this.parameters = parameters; > - } > - > - @Override > - public String getUuid() { > - return this.uuid; > - } > - > - public void setUuid(String uuid) { > - this.uuid = uuid; > - } > + return parameters; > + } > + public void setParameters(String parameters) { > + this.parameters = parameters; > + } > + > + @Override > + public String getUuid() { > + return this.uuid; > + } > + > + public void setUuid(String uuid) { > + this.uuid = uuid; > + } > > + @Override > + public boolean getArchived() { > + return archived; > + } > + > + public void setArchived(Boolean archived) { > + this.archived = archived; > + } > } > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/core/src/com/cloud/event/dao/EventDao.java > ---------------------------------------------------------------------- > diff --git a/core/src/com/cloud/event/dao/EventDao.java > b/core/src/com/cloud/event/dao/EventDao.java > index bfcb818..da5f47a 100644 > --- a/core/src/com/cloud/event/dao/EventDao.java > +++ b/core/src/com/cloud/event/dao/EventDao.java > @@ -30,4 +30,9 @@ public interface EventDao extends GenericDao<EventVO, Long> > { > public List<EventVO> listOlderEvents(Date oldTime); > > EventVO findCompletedEvent(long startId); > + > + public List<EventVO> listToArchiveOrDeleteEvents(List<Long> ids, String > type, Date olderThan, Long accountId); > + > + public void archiveEvents(List<EventVO> events); > + > } > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/core/src/com/cloud/event/dao/EventDaoImpl.java > ---------------------------------------------------------------------- > diff --git a/core/src/com/cloud/event/dao/EventDaoImpl.java > b/core/src/com/cloud/event/dao/EventDaoImpl.java > index 44fbb03..6ba59c5 100644 > --- a/core/src/com/cloud/event/dao/EventDaoImpl.java > +++ b/core/src/com/cloud/event/dao/EventDaoImpl.java > @@ -30,24 +30,34 @@ 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; > +import com.cloud.utils.db.SearchCriteria.Op; > > @Component > @Local(value={EventDao.class}) > public class EventDaoImpl extends GenericDaoBase<EventVO, Long> implements > EventDao { > - public static final Logger s_logger = > Logger.getLogger(EventDaoImpl.class.getName()); > - protected final SearchBuilder<EventVO> CompletedEventSearch; > - > - public EventDaoImpl () { > - CompletedEventSearch = createSearchBuilder(); > - > CompletedEventSearch.and("state",CompletedEventSearch.entity().getState(),SearchCriteria.Op.EQ); > - CompletedEventSearch.and("startId", > CompletedEventSearch.entity().getStartId(), SearchCriteria.Op.EQ); > - CompletedEventSearch.done(); > - } > + public static final Logger s_logger = > Logger.getLogger(EventDaoImpl.class.getName()); > + protected final SearchBuilder<EventVO> CompletedEventSearch; > + protected final SearchBuilder<EventVO> ToArchiveOrDeleteEventSearch; > > - @Override > - public List<EventVO> searchAllEvents(SearchCriteria<EventVO> sc, Filter > filter) { > - return listIncludingRemovedBy(sc, filter); > - } > + public EventDaoImpl () { > + CompletedEventSearch = createSearchBuilder(); > + > CompletedEventSearch.and("state",CompletedEventSearch.entity().getState(),SearchCriteria.Op.EQ); > + CompletedEventSearch.and("startId", > CompletedEventSearch.entity().getStartId(), SearchCriteria.Op.EQ); > + CompletedEventSearch.done(); > + > + ToArchiveOrDeleteEventSearch = createSearchBuilder(); > + ToArchiveOrDeleteEventSearch.and("id", > ToArchiveOrDeleteEventSearch.entity().getId(), Op.IN); > + ToArchiveOrDeleteEventSearch.and("type", > ToArchiveOrDeleteEventSearch.entity().getType(), Op.EQ); > + ToArchiveOrDeleteEventSearch.and("accountId", > ToArchiveOrDeleteEventSearch.entity().getAccountId(), Op.EQ); > + ToArchiveOrDeleteEventSearch.and("createDateL", > ToArchiveOrDeleteEventSearch.entity().getCreateDate(), Op.LT); > + ToArchiveOrDeleteEventSearch.done(); > + } > + > + @Override > + public List<EventVO> searchAllEvents(SearchCriteria<EventVO> sc, Filter > filter) { > + return listIncludingRemovedBy(sc, filter); > + } > > @Override > public List<EventVO> listOlderEvents(Date oldTime) { > @@ -55,9 +65,8 @@ public class EventDaoImpl extends GenericDaoBase<EventVO, > Long> implements Event > SearchCriteria<EventVO> sc = createSearchCriteria(); > sc.addAnd("createDate", SearchCriteria.Op.LT, oldTime); > return listIncludingRemovedBy(sc, null); > - > } > - > + > @Override > public EventVO findCompletedEvent(long startId) { > SearchCriteria<EventVO> sc = CompletedEventSearch.create(); > @@ -65,4 +74,36 @@ public class EventDaoImpl extends GenericDaoBase<EventVO, > Long> implements Event > sc.setParameters("startId", startId); > return findOneIncludingRemovedBy(sc); > } > + > + @Override > + public List<EventVO> listToArchiveOrDeleteEvents(List<Long> ids, String > type, Date olderThan, Long accountId) { > + SearchCriteria<EventVO> sc = ToArchiveOrDeleteEventSearch.create(); > + if (ids != null) { > + sc.setParameters("id", ids.toArray(new Object[ids.size()])); > + } > + if (type != null) { > + sc.setParameters("type", type); > + } > + if (olderThan != null) { > + sc.setParameters("createDateL", olderThan); > + } > + if (accountId != null) { > + sc.setParameters("accountId", accountId); > + } > + return search(sc, null); > + } > + > + @Override > + public void archiveEvents(List<EventVO> events) { > + > + Transaction txn = Transaction.currentTxn(); > + txn.start(); > + for (EventVO event : events) { > + event = lockRow(event.getId(), true); > + event.setArchived(true); > + update(event.getId(), event); > + txn.commit(); > + } > + txn.close(); > + } > } > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/server/src/com/cloud/alert/dao/AlertDao.java > ---------------------------------------------------------------------- > diff --git a/server/src/com/cloud/alert/dao/AlertDao.java > b/server/src/com/cloud/alert/dao/AlertDao.java > index eb1faa5..fda814d 100755 > --- a/server/src/com/cloud/alert/dao/AlertDao.java > +++ b/server/src/com/cloud/alert/dao/AlertDao.java > @@ -16,6 +16,9 @@ > // under the License. > package com.cloud.alert.dao; > > +import java.util.Date; > +import java.util.List; > + > import com.cloud.alert.AlertVO; > import com.cloud.utils.db.GenericDao; > > @@ -23,4 +26,8 @@ public interface AlertDao extends GenericDao<AlertVO, Long> > { > AlertVO getLastAlert(short type, long dataCenterId, Long podId, Long > clusterId); > // This is for backward compatibility > AlertVO getLastAlert(short type, long dataCenterId, Long podId); > + > + public boolean deleteAlert(List<Long> Ids, String type, Date olderThan, > Long zoneId); > + public boolean archiveAlert(List<Long> Ids, String type, Date olderThan, > Long zoneId); > + public List<AlertVO> listOlderAlerts(Date oldTime); > } > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/server/src/com/cloud/alert/dao/AlertDaoImpl.java > ---------------------------------------------------------------------- > diff --git a/server/src/com/cloud/alert/dao/AlertDaoImpl.java > b/server/src/com/cloud/alert/dao/AlertDaoImpl.java > index 2f3be88..4b9bc6a 100755 > --- a/server/src/com/cloud/alert/dao/AlertDaoImpl.java > +++ b/server/src/com/cloud/alert/dao/AlertDaoImpl.java > @@ -16,6 +16,7 @@ > // under the License. > package com.cloud.alert.dao; > > +import java.util.Date; > import java.util.List; > > import javax.ejb.Local; > @@ -25,11 +26,26 @@ import org.springframework.stereotype.Component; > import com.cloud.alert.AlertVO; > 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.SearchCriteria.Op; > +import com.cloud.utils.db.Transaction; > > @Component > @Local(value = { AlertDao.class }) > public class AlertDaoImpl extends GenericDaoBase<AlertVO, Long> implements > AlertDao { > + > + protected final SearchBuilder<AlertVO> AlertSearchByIdsAndType; > + > + public AlertDaoImpl() { > + AlertSearchByIdsAndType = createSearchBuilder(); > + AlertSearchByIdsAndType.and("id", > AlertSearchByIdsAndType.entity().getId(), Op.IN); > + AlertSearchByIdsAndType.and("type", > AlertSearchByIdsAndType.entity().getType(), Op.EQ); > + AlertSearchByIdsAndType.and("createdDateL", > AlertSearchByIdsAndType.entity().getCreatedDate(), Op.LT); > + AlertSearchByIdsAndType.and("data_center_id", > AlertSearchByIdsAndType.entity().getDataCenterId(), Op.EQ); > + AlertSearchByIdsAndType.done(); > + } > + > @Override > public AlertVO getLastAlert(short type, long dataCenterId, Long podId, > Long clusterId) { > Filter searchFilter = new Filter(AlertVO.class, "createdDate", > Boolean.FALSE, Long.valueOf(0), Long.valueOf(1)); > @@ -68,4 +84,73 @@ public class AlertDaoImpl extends GenericDaoBase<AlertVO, > Long> implements Alert > } > return null; > } > + > + @Override > + public boolean archiveAlert(List<Long> Ids, String type, Date olderThan, > Long zoneId) { > + SearchCriteria<AlertVO> sc = AlertSearchByIdsAndType.create(); > + > + if (Ids != null) { > + sc.setParameters("id", Ids.toArray(new Object[Ids.size()])); > + } > + if(type != null) { > + sc.setParameters("type", type); > + } > + if(zoneId != null) { > + sc.setParameters("data_center_id", zoneId); > + } > + if(olderThan != null) { > + sc.setParameters("createdDateL", olderThan); > + } > + boolean result = true;; > + List<AlertVO> alerts = listBy(sc); > + if (Ids != null && alerts.size() < Ids.size()) { > + result = false; > + return result; > + } > + Transaction txn = Transaction.currentTxn(); > + txn.start(); > + for (AlertVO alert : alerts) { > + alert = lockRow(alert.getId(), true); > + alert.setArchived(true); > + update(alert.getId(), alert); > + txn.commit(); > + } > + txn.close(); > + return result; > + } > + > + @Override > + public boolean deleteAlert(List<Long> ids, String type, Date olderThan, > Long zoneId) { > + SearchCriteria<AlertVO> sc = AlertSearchByIdsAndType.create(); > + > + if (ids != null) { > + sc.setParameters("id", ids.toArray(new Object[ids.size()])); > + } > + if(type != null) { > + sc.setParameters("type", type); > + } > + if(zoneId != null) { > + sc.setParameters("data_center_id", zoneId); > + } > + if(olderThan != null) { > + sc.setParameters("createdDateL", olderThan); > + } > + boolean result = true; > + List<AlertVO> alerts = listBy(sc); > + if (ids != null && alerts.size() < ids.size()) { > + result = false; > + return result; > + } > + remove(sc); > + return result; > + } > + > + @Override > + public List<AlertVO> listOlderAlerts(Date oldTime) { > + if (oldTime == null) return null; > + SearchCriteria<AlertVO> sc = createSearchCriteria(); > + sc.addAnd("createDate", SearchCriteria.Op.LT, oldTime); > + return listIncludingRemovedBy(sc, null); > + } > + > } > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/server/src/com/cloud/api/ApiDispatcher.java > ---------------------------------------------------------------------- > diff --git a/server/src/com/cloud/api/ApiDispatcher.java > b/server/src/com/cloud/api/ApiDispatcher.java > index 764b3ae..f7a3236 100755 > --- a/server/src/com/cloud/api/ApiDispatcher.java > +++ b/server/src/com/cloud/api/ApiDispatcher.java > @@ -50,6 +50,8 @@ import org.apache.cloudstack.api.InternalIdentity; > import org.apache.cloudstack.api.Parameter; > import org.apache.cloudstack.api.ServerApiException; > import org.apache.cloudstack.api.Validate; > +import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd; > +import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd; > import org.apache.cloudstack.api.command.user.event.ListEventsCmd; > import org.apache.log4j.Logger; > import org.springframework.stereotype.Component; > @@ -391,7 +393,7 @@ public class ApiDispatcher { > // This piece of code is for maintaining backward > compatibility > // and support both the date formats(Bug 9724) > // Do the date messaging for ListEventsCmd only > - if (cmdObj instanceof ListEventsCmd) { > + if (cmdObj instanceof ListEventsCmd || cmdObj instanceof > DeleteEventsCmd || cmdObj instanceof ArchiveEventsCmd) { > boolean isObjInNewDateFormat = > isObjInNewDateFormat(paramObj.toString()); > if (isObjInNewDateFormat) { > DateFormat newFormat = BaseCmd.NEW_INPUT_FORMAT; > @@ -406,6 +408,8 @@ public class ApiDispatcher { > date = messageDate(date, 0, 0, 0); > } else if (field.getName().equals("endDate")) { > date = messageDate(date, 23, 59, 59); > + } else if (field.getName().equals("olderThan")) { > + date = messageDate(date, 0, 0, 0); > } > field.set(cmdObj, date); > } > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/server/src/com/cloud/api/query/QueryManagerImpl.java > ---------------------------------------------------------------------- > diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java > b/server/src/com/cloud/api/query/QueryManagerImpl.java > index 8d8663a..35fe2f3 100644 > --- a/server/src/com/cloud/api/query/QueryManagerImpl.java > +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java > @@ -397,6 +397,7 @@ public class QueryManagerImpl extends ManagerBase > implements QueryService { > sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ); > sb.and("startId", sb.entity().getStartId(), SearchCriteria.Op.EQ); > sb.and("createDate", sb.entity().getCreateDate(), > SearchCriteria.Op.BETWEEN); > + sb.and("archived", sb.entity().getArchived(), SearchCriteria.Op.EQ); > > SearchCriteria<EventJoinVO> sc = sb.create(); > // building ACL condition > @@ -430,6 +431,8 @@ public class QueryManagerImpl extends ManagerBase > implements QueryService { > sc.setParameters("createDateL", endDate); > } > > + sc.setParameters("archived", false); > + > Pair<List<EventJoinVO>, Integer> eventPair = null; > // event_view will not have duplicate rows for each event, so > searchAndCount should be good enough. > if ((entryTime != null) && (duration != null)) { > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/server/src/com/cloud/api/query/vo/EventJoinVO.java > ---------------------------------------------------------------------- > diff --git a/server/src/com/cloud/api/query/vo/EventJoinVO.java > b/server/src/com/cloud/api/query/vo/EventJoinVO.java > index f29a942..12d7e5a 100644 > --- a/server/src/com/cloud/api/query/vo/EventJoinVO.java > +++ b/server/src/com/cloud/api/query/vo/EventJoinVO.java > @@ -104,6 +104,8 @@ public class EventJoinVO extends BaseViewVO implements > ControlledViewEntity { > @Column(name="project_name") > private String projectName; > > + @Column(name="archived") > + private boolean archived; > > > public EventJoinVO() { > @@ -313,5 +315,12 @@ public class EventJoinVO extends BaseViewVO implements > ControlledViewEntity { > this.parameters = parameters; > } > > + public boolean getArchived() { > + return archived; > + } > + > + public void setArchived(Boolean archived) { > + this.archived = archived; > + } > > } > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/server/src/com/cloud/configuration/Config.java > ---------------------------------------------------------------------- > diff --git a/server/src/com/cloud/configuration/Config.java > b/server/src/com/cloud/configuration/Config.java > index 418f97d..64465a2 100755 > --- a/server/src/com/cloud/configuration/Config.java > +++ b/server/src/com/cloud/configuration/Config.java > @@ -204,9 +204,10 @@ public enum Config { > SecStorageSessionMax("Advanced", AgentManager.class, Integer.class, > "secstorage.session.max", "50", "The max number of command execution sessions > that a SSVM can handle", null), > SecStorageCmdExecutionTimeMax("Advanced", AgentManager.class, > Integer.class, "secstorage.cmd.execution.time.max", "30", "The max command > execution time in minute", null), > SecStorageProxy("Advanced", AgentManager.class, String.class, > "secstorage.proxy", null, "http proxy used by ssvm, in > http://username:password@proxyserver:port format", null), > + AlertPurgeInterval("Advanced", ManagementServer.class, Integer.class, > "alert.purge.interval", "86400", "The interval (in seconds) to wait before > running the alert purge thread", null), > + AlertPurgeDelay("Advanced", ManagementServer.class, Integer.class, > "alert.purge.delay", "0", "Alerts older than specified number days will be > purged. Set this value to 0 to never delete alerts", null), > > - > - DirectAttachNetworkEnabled("Advanced", ManagementServer.class, > Boolean.class, "direct.attach.network.externalIpAllocator.enabled", "false", > "Direct-attach VMs using external DHCP server", "true,false"), > + DirectAttachNetworkEnabled("Advanced", ManagementServer.class, > Boolean.class, "direct.attach.network.externalIpAllocator.enabled", "false", > "Direct-attach VMs using external DHCP server", "true,false"), > DirectAttachNetworkExternalAPIURL("Advanced", ManagementServer.class, > String.class, "direct.attach.network.externalIpAllocator.url", null, > "Direct-attach VMs using external DHCP server (API url)", null), > CheckPodCIDRs("Advanced", ManagementServer.class, String.class, > "check.pod.cidrs", "true", "If true, different pods must belong to different > CIDR subnets.", "true,false"), > NetworkGcWait("Advanced", ManagementServer.class, Integer.class, > "network.gc.wait", "600", "Time (in seconds) to wait before shutting down a > network that's not in used", null), > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/server/src/com/cloud/server/ManagementServerImpl.java > ---------------------------------------------------------------------- > diff --git a/server/src/com/cloud/server/ManagementServerImpl.java > b/server/src/com/cloud/server/ManagementServerImpl.java > index 11400de..d70c45f 100755 > --- a/server/src/com/cloud/server/ManagementServerImpl.java > +++ b/server/src/com/cloud/server/ManagementServerImpl.java > @@ -47,6 +47,7 @@ import javax.management.MalformedObjectNameException; > import javax.management.NotCompliantMBeanException; > import javax.naming.ConfigurationException; > > +import org.apache.cloudstack.acl.ControlledEntity; > import org.apache.cloudstack.acl.SecurityChecker.AccessType; > import org.apache.cloudstack.api.ApiConstants; > > @@ -125,6 +126,7 @@ import com.cloud.alert.AlertManager; > import com.cloud.alert.AlertVO; > import com.cloud.alert.dao.AlertDao; > import com.cloud.api.ApiDBUtils; > +import com.cloud.api.query.vo.EventJoinVO; > import com.cloud.async.AsyncJobExecutor; > import com.cloud.async.AsyncJobManager; > import com.cloud.async.AsyncJobResult; > @@ -188,6 +190,7 @@ import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; > import com.cloud.info.ConsoleProxyInfo; > import com.cloud.keystore.KeystoreManager; > import com.cloud.network.IpAddress; > +import com.cloud.network.as.ConditionVO; > import com.cloud.network.dao.IPAddressDao; > import com.cloud.network.dao.IPAddressVO; > import com.cloud.network.dao.LoadBalancerDao; > @@ -262,6 +265,7 @@ import com.cloud.utils.db.GenericDaoBase; > import com.cloud.utils.db.GlobalLock; > import com.cloud.utils.db.JoinBuilder; > import com.cloud.utils.db.JoinBuilder.JoinType; > +import com.cloud.utils.db.SearchCriteria.Op; > import com.cloud.utils.db.SearchBuilder; > import com.cloud.utils.db.SearchCriteria; > import com.cloud.utils.db.Transaction; > @@ -295,7 +299,7 @@ public class ManagementServerImpl extends ManagerBase > implements ManagementServe > public static final Logger s_logger = > Logger.getLogger(ManagementServerImpl.class.getName()); > > @Inject > - private AccountManager _accountMgr; > + public AccountManager _accountMgr; > @Inject > private AgentManager _agentMgr; > @Inject > @@ -311,7 +315,7 @@ public class ManagementServerImpl extends ManagerBase > implements ManagementServe > @Inject > private SecondaryStorageVmDao _secStorageVmDao; > @Inject > - private EventDao _eventDao; > + public EventDao _eventDao; > @Inject > private DataCenterDao _dcDao; > @Inject > @@ -347,7 +351,7 @@ public class ManagementServerImpl extends ManagerBase > implements ManagementServe > @Inject > private AccountDao _accountDao; > @Inject > - private AlertDao _alertDao; > + public AlertDao _alertDao; > @Inject > private CapacityDao _capacityDao; > @Inject > @@ -371,6 +375,7 @@ public class ManagementServerImpl extends ManagerBase > implements ManagementServe > @Inject > private AsyncJobManager _asyncMgr; > private int _purgeDelay; > + private int _alertPurgeDelay; > @Inject > private InstanceGroupDao _vmGroupDao; > @Inject > @@ -417,6 +422,7 @@ public class ManagementServerImpl extends ManagerBase > implements ManagementServe > EventUtils _forceEventUtilsRef; > */ > private final ScheduledExecutorService _eventExecutor = > Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker")); > + private final ScheduledExecutorService _alertExecutor = > Executors.newScheduledThreadPool(1, new NamedThreadFactory("AlertChecker")); > private KeystoreManager _ksMgr; > > private Map<String, String> _configs; > @@ -446,6 +452,15 @@ public class ManagementServerImpl extends ManagerBase > implements ManagementServe > _eventExecutor.scheduleAtFixedRate(new EventPurgeTask(), > cleanup, cleanup, TimeUnit.SECONDS); > } > > + //Alerts purge configurations > + int alertPurgeInterval = > NumbersUtil.parseInt(_configDao.getValue(Config.AlertPurgeInterval.key()), > + 60 * 60 * 24); // 1 day. > + _alertPurgeDelay = > NumbersUtil.parseInt(_configDao.getValue(Config.AlertPurgeDelay.key()), 0); > + if (_alertPurgeDelay != 0) { > + _alertExecutor.scheduleAtFixedRate(new AlertPurgeTask(), > alertPurgeInterval, alertPurgeInterval, > + TimeUnit.SECONDS); > + } > + > String[] availableIds = TimeZone.getAvailableIDs(); > _availableIdsMap = new HashMap<String, Boolean>(availableIds.length); > for (String id : availableIds) { > @@ -538,6 +553,42 @@ public class ManagementServerImpl extends ManagerBase > implements ManagementServe > return _eventDao.search(sc, null); > } > > + @Override > + public boolean archiveEvents(ArchiveEventsCmd cmd) { > + List<Long> ids = cmd.getIds(); > + boolean result =true; > + > + List<EventVO> events = _eventDao.listToArchiveOrDeleteEvents(ids, > cmd.getType(), cmd.getOlderThan(), cmd.getEntityOwnerId()); > + ControlledEntity[] sameOwnerEvents = events.toArray(new > ControlledEntity[events.size()]); > + _accountMgr.checkAccess(UserContext.current().getCaller(), null, > true, sameOwnerEvents); > + > + if (ids != null && events.size() < ids.size()) { > + result = false; > + return result; > + } > + _eventDao.archiveEvents(events); > + return result; > + } > + > + @Override > + public boolean deleteEvents(DeleteEventsCmd cmd) { > + List<Long> ids = cmd.getIds(); > + boolean result =true; > + > + List<EventVO> events = _eventDao.listToArchiveOrDeleteEvents(ids, > cmd.getType(), cmd.getOlderThan(), cmd.getEntityOwnerId()); > + ControlledEntity[] sameOwnerEvents = events.toArray(new > ControlledEntity[events.size()]); > + _accountMgr.checkAccess(UserContext.current().getCaller(), null, > true, sameOwnerEvents); > + > + if (ids != null && events.size() < ids.size()) { > + result = false; > + return result; > + } > + for (EventVO event : events) { > + _eventDao.remove(event.getId()); > + } > + return result; > + } > + > private Date massageDate(Date date, int hourOfDay, int minute, int > second) { > Calendar cal = Calendar.getInstance(); > cal.setTime(date); > @@ -1663,11 +1714,26 @@ public class ManagementServerImpl extends ManagerBase > implements ManagementServe > sc.addAnd("type", SearchCriteria.Op.EQ, type); > } > > + sc.addAnd("archived", SearchCriteria.Op.EQ, false); > Pair<List<AlertVO>, Integer> result = _alertDao.searchAndCount(sc, > searchFilter); > return new Pair<List<? extends Alert>, Integer>(result.first(), > result.second()); > } > > @Override > + public boolean archiveAlerts(ArchiveAlertsCmd cmd) { > + Long zoneId = > _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), > null); > + boolean result = _alertDao.archiveAlert(cmd.getIds(), cmd.getType(), > cmd.getOlderThan(), zoneId); > + return result; > + } > + > + @Override > + public boolean deleteAlerts(DeleteAlertsCmd cmd) { > + Long zoneId = > _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), > null); > + boolean result = _alertDao.deleteAlert(cmd.getIds(), cmd.getType(), > cmd.getOlderThan(), zoneId); > + return result; > + } > + > + @Override > public List<CapacityVO> listTopConsumedResources(ListCapacityCmd cmd) { > > Integer capacityType = cmd.getType(); > @@ -2168,6 +2234,10 @@ public class ManagementServerImpl extends ManagerBase > implements ManagementServe > cmdList.add(AddIpToVmNicCmd.class); > cmdList.add(RemoveIpFromVmNicCmd.class); > cmdList.add(ListNicsCmd.class); > + cmdList.add(ArchiveAlertsCmd.class); > + cmdList.add(DeleteAlertsCmd.class); > + cmdList.add(ArchiveEventsCmd.class); > + cmdList.add(DeleteEventsCmd.class); > return cmdList; > } > > @@ -2205,6 +2275,39 @@ public class ManagementServerImpl extends ManagerBase > implements ManagementServe > } > } > > + protected class AlertPurgeTask implements Runnable { > + @Override > + public void run() { > + try { > + GlobalLock lock = GlobalLock.getInternLock("AlertPurge"); > + if (lock == null) { > + s_logger.debug("Couldn't get the global lock"); > + return; > + } > + if (!lock.lock(30)) { > + s_logger.debug("Couldn't lock the db"); > + return; > + } > + try { > + final Calendar purgeCal = Calendar.getInstance(); > + purgeCal.add(Calendar.DAY_OF_YEAR, - _alertPurgeDelay); > + Date purgeTime = purgeCal.getTime(); > + s_logger.debug("Deleting alerts older than: " + > purgeTime.toString()); > + List<AlertVO> oldAlerts = > _alertDao.listOlderAlerts(purgeTime); > + s_logger.debug("Found " + oldAlerts.size() + " events to > be purged"); > + for (AlertVO alert : oldAlerts) { > + _alertDao.expunge(alert.getId()); > + } > + } catch (Exception e) { > + s_logger.error("Exception ", e); > + } finally { > + lock.unlock(); > + } > + } catch (Exception e) { > + s_logger.error("Exception ", e); > + } > + } > + } > > @Override > public Pair<List<StoragePoolVO>, Integer> searchForStoragePools(Criteria > c) { > > http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5e4c2c8a/setup/db/db/schema-410to420.sql > ---------------------------------------------------------------------- > diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql > index f3112a1..ca15bda 100644 > --- a/setup/db/db/schema-410to420.sql > +++ b/setup/db/db/schema-410to420.sql > @@ -140,3 +140,48 @@ CREATE TABLE nic_secondary_ips ( > > ALTER TABLE `cloud`.`nics` ADD COLUMN secondary_ip SMALLINT DEFAULT '0' > COMMENT 'secondary ips configured for the nic'; > ALTER TABLE `cloud`.`user_ip_address` ADD COLUMN dnat_vmip VARCHAR(40); > + > +ALTER TABLE `cloud`.`alert` ADD COLUMN `archived` tinyint(1) unsigned NOT > NULL DEFAULT 0; > +ALTER TABLE `cloud`.`event` ADD COLUMN `archived` tinyint(1) unsigned NOT > NULL DEFAULT 0; > +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', > 'management-server', 'alert.purge.interval', '86400', 'The interval (in > seconds) to wait before running the alert purge thread'); > +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', > 'management-server', 'alert.purge.delay', '0', 'Alerts older than specified > number days will be purged. Set this value to 0 to never delete alerts'); > + > +DROP VIEW IF EXISTS `cloud`.`event_view`; > +CREATE VIEW `cloud`.`event_view` AS > + select > + event.id, > + event.uuid, > + event.type, > + event.state, > + event.description, > + event.created, > + event.level, > + event.parameters, > + event.start_id, > + eve.uuid start_uuid, > + event.user_id, > + event.archived, > + user.username user_name, > + account.id account_id, > + account.uuid account_uuid, > + account.account_name account_name, > + account.type account_type, > + domain.id domain_id, > + domain.uuid domain_uuid, > + domain.name domain_name, > + domain.path domain_path, > + projects.id project_id, > + projects.uuid project_uuid, > + projects.name project_name > + from > + `cloud`.`event` > + inner join > + `cloud`.`account` ON event.account_id = account.id > + inner join > + `cloud`.`domain` ON event.domain_id = domain.id > + inner join > + `cloud`.`user` ON event.user_id = user.id > + left join > + `cloud`.`projects` ON projects.project_account_id = event.account_id > + left join > + `cloud`.`event` eve ON event.start_id = eve.id; > >