| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| package com.cloud.event.dao; |
| |
| import java.sql.PreparedStatement; |
| import java.sql.ResultSet; |
| import java.util.Date; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.TimeZone; |
| |
| import javax.inject.Inject; |
| |
| import org.springframework.stereotype.Component; |
| |
| import com.cloud.dc.Vlan; |
| import com.cloud.event.EventTypes; |
| import com.cloud.event.UsageEventVO; |
| import com.cloud.utils.DateUtil; |
| import com.cloud.utils.db.DB; |
| 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.TransactionLegacy; |
| import com.cloud.utils.exception.CloudRuntimeException; |
| |
| @Component |
| public class UsageEventDaoImpl extends GenericDaoBase<UsageEventVO, Long> implements UsageEventDao { |
| |
| private final SearchBuilder<UsageEventVO> latestEventsSearch; |
| private final SearchBuilder<UsageEventVO> IpeventsSearch; |
| private static final String COPY_EVENTS = |
| "INSERT INTO cloud_usage.usage_event (id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size, resource_type, virtual_size) " |
| + "SELECT id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size, resource_type, virtual_size FROM cloud.usage_event vmevt WHERE vmevt.id > ? and vmevt.id <= ? "; |
| private static final String COPY_ALL_EVENTS = |
| "INSERT INTO cloud_usage.usage_event (id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size, resource_type, virtual_size) " |
| + "SELECT id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size, resource_type, virtual_size FROM cloud.usage_event vmevt WHERE vmevt.id <= ?"; |
| private static final String COPY_EVENT_DETAILS = "INSERT INTO cloud_usage.usage_event_details (id, usage_event_id, name, value) " |
| + "SELECT id, usage_event_id, name, value FROM cloud.usage_event_details vmevtDetails WHERE vmevtDetails.usage_event_id > ? and vmevtDetails.usage_event_id <= ? "; |
| private static final String COPY_ALL_EVENT_DETAILS = "INSERT INTO cloud_usage.usage_event_details (id, usage_event_id, name, value) " |
| + "SELECT id, usage_event_id, name, value FROM cloud.usage_event_details vmevtDetails WHERE vmevtDetails.usage_event_id <= ?"; |
| private static final String MAX_EVENT = "select max(id) from cloud.usage_event where created <= ?"; |
| @Inject |
| protected UsageEventDetailsDao usageEventDetailsDao; |
| |
| public UsageEventDaoImpl() { |
| latestEventsSearch = createSearchBuilder(); |
| latestEventsSearch.and("processed", latestEventsSearch.entity().isProcessed(), SearchCriteria.Op.EQ); |
| latestEventsSearch.and("enddate", latestEventsSearch.entity().getCreateDate(), SearchCriteria.Op.LTEQ); |
| latestEventsSearch.done(); |
| |
| IpeventsSearch = createSearchBuilder(); |
| IpeventsSearch.and("startdate", IpeventsSearch.entity().getCreateDate(), SearchCriteria.Op.GTEQ); |
| IpeventsSearch.and("enddate", IpeventsSearch.entity().getCreateDate(), SearchCriteria.Op.LTEQ); |
| IpeventsSearch.and("zoneid", IpeventsSearch.entity().getZoneId(), SearchCriteria.Op.EQ); |
| IpeventsSearch.and("networktype", IpeventsSearch.entity().getResourceType(), SearchCriteria.Op.EQ); |
| IpeventsSearch.and().op("assignEvent", IpeventsSearch.entity().getType(), SearchCriteria.Op.EQ); |
| IpeventsSearch.or("releaseEvent", IpeventsSearch.entity().getType(), SearchCriteria.Op.EQ); |
| IpeventsSearch.cp(); |
| IpeventsSearch.done(); |
| } |
| |
| @Override |
| public List<UsageEventVO> listLatestEvents(Date endDate) { |
| Filter filter = new Filter(UsageEventVO.class, "createDate", Boolean.TRUE, null, null); |
| SearchCriteria<UsageEventVO> sc = latestEventsSearch.create(); |
| sc.setParameters("processed", false); |
| sc.setParameters("enddate", endDate); |
| return listBy(sc, filter); |
| } |
| |
| @Override |
| public List<UsageEventVO> getLatestEvent() { |
| Filter filter = new Filter(UsageEventVO.class, "id", Boolean.FALSE, Long.valueOf(0), Long.valueOf(1)); |
| return listAll(filter); |
| } |
| |
| @Override |
| @DB |
| public synchronized List<UsageEventVO> getRecentEvents(Date endDate) { |
| long recentEventId = getMostRecentEventId(); |
| long maxEventId = getMaxEventId(endDate); |
| TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); |
| // Copy events from cloud db to usage db |
| String sql = COPY_EVENTS; |
| if (recentEventId == 0) { |
| if (logger.isDebugEnabled()) { |
| 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 (recentEventId != 0) { |
| pstmt.setLong(i++, recentEventId); |
| } |
| pstmt.setLong(i++, maxEventId); |
| pstmt.executeUpdate(); |
| txn.commit(); |
| } catch (Exception ex) { |
| txn.rollback(); |
| logger.error("error copying events from cloud db to usage db", ex); |
| throw new CloudRuntimeException(ex.getMessage()); |
| } finally { |
| txn.close(); |
| } |
| |
| // Copy event details from cloud db to usage db |
| sql = COPY_EVENT_DETAILS; |
| if (recentEventId == 0) { |
| if (logger.isDebugEnabled()) { |
| logger.debug("no recent event date, copying all event detailss"); |
| } |
| sql = COPY_ALL_EVENT_DETAILS; |
| } |
| |
| pstmt = null; |
| try { |
| txn.start(); |
| pstmt = txn.prepareAutoCloseStatement(sql); |
| int i = 1; |
| if (recentEventId != 0) { |
| pstmt.setLong(i++, recentEventId); |
| } |
| pstmt.setLong(i++, maxEventId); |
| pstmt.executeUpdate(); |
| txn.commit(); |
| } catch (Exception ex) { |
| txn.rollback(); |
| logger.error("error copying event details from cloud db to usage db", ex); |
| throw new CloudRuntimeException(ex.getMessage()); |
| } finally { |
| txn.close(); |
| } |
| |
| return findRecentEvents(endDate); |
| } |
| |
| @DB |
| private long getMostRecentEventId() { |
| TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); |
| try { |
| List<UsageEventVO> latestEvents = getLatestEvent(); |
| |
| if (latestEvents != null && latestEvents.size() == 1) { |
| UsageEventVO latestEvent = latestEvents.get(0); |
| if (latestEvent != null) { |
| return latestEvent.getId(); |
| } |
| } |
| return 0; |
| } catch (Exception ex) { |
| logger.error("error getting most recent event id", ex); |
| throw new CloudRuntimeException(ex.getMessage()); |
| } finally { |
| txn.close(); |
| } |
| } |
| |
| private List<UsageEventVO> findRecentEvents(Date endDate) { |
| TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); |
| try { |
| return listLatestEvents(endDate); |
| } catch (Exception ex) { |
| logger.error("error getting most recent event date", ex); |
| throw new CloudRuntimeException(ex.getMessage()); |
| } finally { |
| txn.close(); |
| } |
| } |
| |
| private long getMaxEventId(Date endDate) { |
| TransactionLegacy txn = TransactionLegacy.currentTxn(); |
| PreparedStatement pstmt = null; |
| try { |
| String sql = MAX_EVENT; |
| pstmt = txn.prepareAutoCloseStatement(sql); |
| pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate)); |
| ResultSet rs = pstmt.executeQuery(); |
| if (rs.next()) { |
| return Long.valueOf(rs.getLong(1)); |
| } |
| return 0; |
| } catch (Exception ex) { |
| logger.error("error getting max event id", ex); |
| throw new CloudRuntimeException(ex.getMessage()); |
| } finally { |
| txn.close(); |
| } |
| } |
| |
| @Override |
| public List<UsageEventVO> listDirectIpEvents(Date startDate, Date endDate, long zoneId) { |
| Filter filter = new Filter(UsageEventVO.class, "createDate", Boolean.TRUE, null, null); |
| SearchCriteria<UsageEventVO> sc = IpeventsSearch.create(); |
| sc.setParameters("startdate", startDate); |
| sc.setParameters("enddate", endDate); |
| sc.setParameters("assignEvent", EventTypes.EVENT_NET_IP_ASSIGN); |
| sc.setParameters("releaseEvent", EventTypes.EVENT_NET_IP_RELEASE); |
| sc.setParameters("zoneid", zoneId); |
| sc.setParameters("networktype", Vlan.VlanType.DirectAttached.toString()); |
| return listBy(sc, filter); |
| } |
| |
| @Override |
| public void saveDetails(long eventId, Map<String, String> details) { |
| usageEventDetailsDao.persist(eventId, details); |
| } |
| |
| } |