package org.openstack.atlas.service.domain.usage.repository; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openstack.atlas.service.domain.usage.entities.LoadBalancerHostUsage; import org.openstack.atlas.util.common.StringUtils; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.persistence.TemporalType; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Collection; import java.util.List; @Repository @Transactional(value = "usage") public class HostUsageRefactorRepository { final Log LOG = LogFactory.getLog(HostUsageRefactorRepository.class); @PersistenceContext(unitName = "loadbalancingUsage") private EntityManager entityManager; public void create(LoadBalancerHostUsage usageRecord) { entityManager.persist(usageRecord); } public void batchCreate(Collection<LoadBalancerHostUsage> usageRecords) { LOG.info(String.format("batchCreate() called with %d records", usageRecords.size())); if (usageRecords.size() > 0) { String query = generateBatchInsertQuery(usageRecords); entityManager.createNativeQuery(query).executeUpdate(); } } private String generateBatchInsertQuery(Collection<LoadBalancerHostUsage> usages) { final StringBuilder sb = new StringBuilder(); sb.append("INSERT INTO lb_host_usage (account_id, loadbalancer_id, host_id, bandwidth_out," + "bandwidth_in, bandwidth_out_ssl, bandwidth_in_ssl, concurrent_connections," + "concurrent_connections_ssl, tags_bitmask, num_vips, poll_time, event_type) VALUES"); sb.append(generateFormattedValuesForList(usages)); return sb.toString(); } private String generateFormattedValuesForList(Collection<LoadBalancerHostUsage> usages) { String queryString = ""; for (LoadBalancerHostUsage usage : usages) { queryString += generateFormattedValues(usage); queryString += "),"; } if (queryString.endsWith(",")) { queryString = queryString.substring(0, queryString.lastIndexOf(',')); } return queryString; } /** * The order of the following appended values is deliberate. Do no modify its order * without modifying the order in the method generateBatchInsertQuery */ private String generateFormattedValues(LoadBalancerHostUsage usage) { StringBuilder sb = new StringBuilder(); sb.append("("); sb.append(usage.getAccountId()).append(","); sb.append(usage.getLoadbalancerId()).append(","); sb.append(usage.getHostId()).append(","); sb.append(usage.getOutgoingTransfer()).append(","); sb.append(usage.getIncomingTransfer()).append(","); sb.append(usage.getOutgoingTransferSsl()).append(","); sb.append(usage.getIncomingTransferSsl()).append(","); sb.append(usage.getConcurrentConnections()).append(","); sb.append(usage.getConcurrentConnectionsSsl()).append(","); sb.append(usage.getTagsBitmask()).append(","); sb.append(usage.getNumVips()).append(","); DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String startTime = formatter.format(usage.getPollTime().getTime()); sb.append("'").append(startTime).append("',"); if (usage.getEventType() == null) { sb.append(usage.getEventType()); } else { sb.append("'").append(usage.getEventType()).append("'"); } return sb.toString(); } public void getByLbId(int lbId) { // entityManager.persist(usageEventRecord); } public LoadBalancerHostUsage getMostRecentUsageRecordForLbIdAndHostId(int lbId, int hostId) { Query query = entityManager.createQuery("SELECT h FROM LoadBalancerHostUsage h WHERE h.loadbalancerId = :lbId AND h.hostId = :hostId ORDER BY h.pollTime DESC LIMIT 1") .setParameter("lbId", lbId) .setParameter("hostId", hostId); List usages = query.getResultList(); if (!usages.isEmpty()) return (LoadBalancerHostUsage) usages.get(0); return null; } public void deleteOldHostUsage(Calendar deleteTimeMarker, Collection<Integer> lbsToExclude, Long maxId) { Query query; if (lbsToExclude == null || lbsToExclude.isEmpty()) { query = entityManager.createQuery("DELETE LoadBalancerHostUsage u WHERE u.pollTime < :deleteTimeMarker AND u.id <= :maxId"); } else { String lbIds = StringUtils.joinString(lbsToExclude, ","); query = entityManager.createQuery("DELETE LoadBalancerHostUsage u WHERE u.pollTime < :deleteTimeMarker AND loadbalancer_id not in (:lbIds) AND u.id <= :maxId"); query.setParameter("lbIds", lbIds); } query.setParameter("deleteTimeMarker", deleteTimeMarker, TemporalType.TIMESTAMP); query.setParameter("maxId", maxId); int numRowsDeleted = query.executeUpdate(); LOG.info(String.format("Deleted %d rows with endTime before %s from 'lb_host_usage' table.", numRowsDeleted, deleteTimeMarker.getTime())); } public List<LoadBalancerHostUsage> getAllLoadBalancerHostUsageRecords(boolean ascending) { String order = "ASC"; if (!ascending) { order = "DESC"; } String queryStr = "from LoadBalancerHostUsage h ORDER BY h.pollTime " + order; List<LoadBalancerHostUsage> hosts; hosts = entityManager.createQuery(queryStr).getResultList(); return hosts; } public List<LoadBalancerHostUsage> getRecordsAfterTimeInclusive(Calendar timeMarker, boolean ascending) { String order = "ASC"; if (!ascending) { order = "DESC"; } String queryStr = "from LoadBalancerHostUsage h WHERE poll_time >= :timeMarker ORDER BY h.pollTime " + order; Query query = entityManager.createQuery(queryStr).setParameter("timeMarker", timeMarker, TemporalType.TIMESTAMP); List<LoadBalancerHostUsage> hosts = query.getResultList(); return hosts; } public List<LoadBalancerHostUsage> getRecordsBeforeTimeInclusive(Calendar timeMarker, boolean ascending) { String order = "ASC"; if (!ascending) { order = "DESC"; } String queryStr = "from LoadBalancerHostUsage h WHERE poll_time <= :timeMarker ORDER BY h.pollTime " + order; Query query = entityManager.createQuery(queryStr).setParameter("timeMarker", timeMarker, TemporalType.TIMESTAMP); List<LoadBalancerHostUsage> hosts = query.getResultList(); return hosts; } }