From 65d5d4d549a67882d9637fe83f5167541bb2f5b8 Mon Sep 17 00:00:00 2001 From: David Nalley Date: Mon, 9 Apr 2012 20:07:33 -0400 Subject: [PATCH] fixing line endings in usage --- .../cloud/usage/UsageAlertManagerImpl.java | 510 +-- usage/src/com/cloud/usage/UsageManager.java | 18 +- .../src/com/cloud/usage/UsageManagerImpl.java | 3024 ++++++++--------- usage/src/com/cloud/usage/UsageServer.java | 48 +- .../usage/parser/IPAddressUsageParser.java | 320 +- .../usage/parser/LoadBalancerUsageParser.java | 286 +- .../parser/NetworkOfferingUsageParser.java | 310 +- .../usage/parser/NetworkUsageParser.java | 298 +- .../parser/PortForwardingUsageParser.java | 286 +- .../parser/SecurityGroupUsageParser.java | 296 +- .../usage/parser/StorageUsageParser.java | 378 +-- .../com/cloud/usage/parser/UsageParser.java | 38 +- .../usage/parser/VMInstanceUsageParser.java | 368 +- .../usage/parser/VPNUserUsageParser.java | 286 +- .../cloud/usage/parser/VolumeUsageParser.java | 334 +- 15 files changed, 3400 insertions(+), 3400 deletions(-) diff --git a/usage/src/com/cloud/usage/UsageAlertManagerImpl.java b/usage/src/com/cloud/usage/UsageAlertManagerImpl.java index 348211ad18c..c1c8f9a7a94 100644 --- a/usage/src/com/cloud/usage/UsageAlertManagerImpl.java +++ b/usage/src/com/cloud/usage/UsageAlertManagerImpl.java @@ -10,258 +10,258 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage; - -import java.io.UnsupportedEncodingException; -import java.util.Date; -import java.util.Map; -import java.util.Properties; - -import javax.ejb.Local; -import javax.mail.Authenticator; -import javax.mail.MessagingException; -import javax.mail.PasswordAuthentication; -import javax.mail.Session; -import javax.mail.URLName; -import javax.mail.Message.RecipientType; -import javax.mail.internet.InternetAddress; -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - -import com.cloud.alert.AlertManager; -import com.cloud.alert.AlertVO; -import com.cloud.alert.dao.AlertDao; -import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.utils.NumbersUtil; -import com.cloud.utils.component.ComponentLocator; -import com.sun.mail.smtp.SMTPMessage; -import com.sun.mail.smtp.SMTPSSLTransport; -import com.sun.mail.smtp.SMTPTransport; - -@Local(value={AlertManager.class}) -public class UsageAlertManagerImpl implements AlertManager { - private static final Logger s_logger = Logger.getLogger(UsageAlertManagerImpl.class.getName()); - - private String _name = null; - private EmailAlert _emailAlert; - private AlertDao _alertDao; - - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - _name = name; - - ComponentLocator locator = ComponentLocator.getCurrentLocator(); - ConfigurationDao configDao = locator.getDao(ConfigurationDao.class); - if (configDao == null) { - s_logger.error("Unable to get the configuration dao."); - return false; - } - - Map configs = configDao.getConfiguration("management-server", params); - - // set up the email system for alerts - String emailAddressList = configs.get("alert.email.addresses"); - String[] emailAddresses = null; - if (emailAddressList != null) { - emailAddresses = emailAddressList.split(","); - } - - String smtpHost = configs.get("alert.smtp.host"); - int smtpPort = NumbersUtil.parseInt(configs.get("alert.smtp.port"), 25); - String useAuthStr = configs.get("alert.smtp.useAuth"); - boolean useAuth = ((useAuthStr == null) ? false : Boolean.parseBoolean(useAuthStr)); - String smtpUsername = configs.get("alert.smtp.username"); - String smtpPassword = configs.get("alert.smtp.password"); - String emailSender = configs.get("alert.email.sender"); - String smtpDebugStr = configs.get("alert.smtp.debug"); - boolean smtpDebug = false; - if (smtpDebugStr != null) { - smtpDebug = Boolean.parseBoolean(smtpDebugStr); - } - - _emailAlert = new EmailAlert(emailAddresses, smtpHost, smtpPort, useAuth, smtpUsername, smtpPassword, emailSender, smtpDebug); - - _alertDao = locator.getDao(AlertDao.class); - if (_alertDao == null) { - s_logger.error("Unable to get the alert dao."); - return false; - } - - return true; - } - - @Override - public String getName() { - return _name; - } - - @Override - public boolean start() { - return true; - } - - @Override - public boolean stop() { - return true; - } - - @Override - public void clearAlert(short alertType, long dataCenterId, long podId) { - try { - if (_emailAlert != null) { - _emailAlert.clearAlert(alertType, dataCenterId, podId); - } - } catch (Exception ex) { - s_logger.error("Problem clearing email alert", ex); - } - } - - @Override - public void sendAlert(short alertType, long dataCenterId, Long podId, String subject, String body) { - // TODO: queue up these messages and send them as one set of issues once a certain number of issues is reached? If that's the case, - // shouldn't we have a type/severity as part of the API so that severe errors get sent right away? - try { - if (_emailAlert != null) { - _emailAlert.sendAlert(alertType, dataCenterId, podId, subject, body); - } - } catch (Exception ex) { - s_logger.error("Problem sending email alert", ex); - } - } - - - class EmailAlert { - private Session _smtpSession; - private InternetAddress[] _recipientList; - private final String _smtpHost; - private int _smtpPort = -1; - private boolean _smtpUseAuth = false; - private final String _smtpUsername; - private final String _smtpPassword; - private final String _emailSender; - - public EmailAlert(String[] recipientList, String smtpHost, int smtpPort, boolean smtpUseAuth, final String smtpUsername, final String smtpPassword, String emailSender, boolean smtpDebug) { - if (recipientList != null) { - _recipientList = new InternetAddress[recipientList.length]; - for (int i = 0; i < recipientList.length; i++) { - try { - _recipientList[i] = new InternetAddress(recipientList[i], recipientList[i]); - } catch (Exception ex) { - s_logger.error("Exception creating address for: " + recipientList[i], ex); - } - } - } - - _smtpHost = smtpHost; - _smtpPort = smtpPort; - _smtpUseAuth = smtpUseAuth; - _smtpUsername = smtpUsername; - _smtpPassword = smtpPassword; - _emailSender = emailSender; - - if (_smtpHost != null) { - Properties smtpProps = new Properties(); - smtpProps.put("mail.smtp.host", smtpHost); - smtpProps.put("mail.smtp.port", smtpPort); - smtpProps.put("mail.smtp.auth", ""+smtpUseAuth); - if (smtpUsername != null) { - smtpProps.put("mail.smtp.user", smtpUsername); - } - - smtpProps.put("mail.smtps.host", smtpHost); - smtpProps.put("mail.smtps.port", smtpPort); - smtpProps.put("mail.smtps.auth", ""+smtpUseAuth); - if (smtpUsername != null) { - smtpProps.put("mail.smtps.user", smtpUsername); - } - - if ((smtpUsername != null) && (smtpPassword != null)) { - _smtpSession = Session.getInstance(smtpProps, new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(smtpUsername, smtpPassword); - } - }); - } else { - _smtpSession = Session.getInstance(smtpProps); - } - _smtpSession.setDebug(smtpDebug); - } else { - _smtpSession = null; - } - } - - // TODO: make sure this handles SSL transport (useAuth is true) and regular - public void sendAlert(short alertType, long dataCenterId, Long podId, String subject, String content) throws MessagingException, UnsupportedEncodingException { - AlertVO alert = null; - - if ((alertType != AlertManager.ALERT_TYPE_HOST) && - (alertType != AlertManager.ALERT_TYPE_USERVM) && - (alertType != AlertManager.ALERT_TYPE_DOMAIN_ROUTER) && - (alertType != AlertManager.ALERT_TYPE_CONSOLE_PROXY) && - (alertType != AlertManager.ALERT_TYPE_SSVM) && - (alertType != AlertManager.ALERT_TYPE_STORAGE_MISC) && - (alertType != AlertManager.ALERT_TYPE_MANAGMENT_NODE)) { - alert = _alertDao.getLastAlert(alertType, dataCenterId, podId); - } - - if (alert == null) { - // set up a new alert - AlertVO newAlert = new AlertVO(); - newAlert.setType(alertType); - newAlert.setSubject(subject); - newAlert.setPodId(podId); - newAlert.setDataCenterId(dataCenterId); - newAlert.setSentCount(1); // initialize sent count to 1 since we are now sending an alert - newAlert.setLastSent(new Date()); - _alertDao.persist(newAlert); - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Have already sent: " + alert.getSentCount() + " emails for alert type '" + alertType + "' -- skipping send email"); - } - return; - } - - if (_smtpSession != null) { - SMTPMessage msg = new SMTPMessage(_smtpSession); - msg.setSender(new InternetAddress(_emailSender, _emailSender)); - msg.setFrom(new InternetAddress(_emailSender, _emailSender)); - for (InternetAddress address : _recipientList) { - msg.addRecipient(RecipientType.TO, address); - } - msg.setSubject(subject); - msg.setSentDate(new Date()); - msg.setContent(content, "text/plain"); - msg.saveChanges(); - - SMTPTransport smtpTrans = null; - if (_smtpUseAuth) { - smtpTrans = new SMTPSSLTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword)); - } else { - smtpTrans = new SMTPTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword)); - } - smtpTrans.connect(); - smtpTrans.sendMessage(msg, msg.getAllRecipients()); - smtpTrans.close(); - } - } - - public void clearAlert(short alertType, long dataCenterId, Long podId) { - if (alertType != -1) { - AlertVO alert = _alertDao.getLastAlert(alertType, dataCenterId, podId); - if (alert != null) { - AlertVO updatedAlert = _alertDao.createForUpdate(); - updatedAlert.setResolved(new Date()); - _alertDao.update(alert.getId(), updatedAlert); - } - } - } - } - - @Override - public void recalculateCapacity() { - // TODO Auto-generated method stub - - } -} +package com.cloud.usage; + +import java.io.UnsupportedEncodingException; +import java.util.Date; +import java.util.Map; +import java.util.Properties; + +import javax.ejb.Local; +import javax.mail.Authenticator; +import javax.mail.MessagingException; +import javax.mail.PasswordAuthentication; +import javax.mail.Session; +import javax.mail.URLName; +import javax.mail.Message.RecipientType; +import javax.mail.internet.InternetAddress; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.alert.AlertManager; +import com.cloud.alert.AlertVO; +import com.cloud.alert.dao.AlertDao; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.component.ComponentLocator; +import com.sun.mail.smtp.SMTPMessage; +import com.sun.mail.smtp.SMTPSSLTransport; +import com.sun.mail.smtp.SMTPTransport; + +@Local(value={AlertManager.class}) +public class UsageAlertManagerImpl implements AlertManager { + private static final Logger s_logger = Logger.getLogger(UsageAlertManagerImpl.class.getName()); + + private String _name = null; + private EmailAlert _emailAlert; + private AlertDao _alertDao; + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + _name = name; + + ComponentLocator locator = ComponentLocator.getCurrentLocator(); + ConfigurationDao configDao = locator.getDao(ConfigurationDao.class); + if (configDao == null) { + s_logger.error("Unable to get the configuration dao."); + return false; + } + + Map configs = configDao.getConfiguration("management-server", params); + + // set up the email system for alerts + String emailAddressList = configs.get("alert.email.addresses"); + String[] emailAddresses = null; + if (emailAddressList != null) { + emailAddresses = emailAddressList.split(","); + } + + String smtpHost = configs.get("alert.smtp.host"); + int smtpPort = NumbersUtil.parseInt(configs.get("alert.smtp.port"), 25); + String useAuthStr = configs.get("alert.smtp.useAuth"); + boolean useAuth = ((useAuthStr == null) ? false : Boolean.parseBoolean(useAuthStr)); + String smtpUsername = configs.get("alert.smtp.username"); + String smtpPassword = configs.get("alert.smtp.password"); + String emailSender = configs.get("alert.email.sender"); + String smtpDebugStr = configs.get("alert.smtp.debug"); + boolean smtpDebug = false; + if (smtpDebugStr != null) { + smtpDebug = Boolean.parseBoolean(smtpDebugStr); + } + + _emailAlert = new EmailAlert(emailAddresses, smtpHost, smtpPort, useAuth, smtpUsername, smtpPassword, emailSender, smtpDebug); + + _alertDao = locator.getDao(AlertDao.class); + if (_alertDao == null) { + s_logger.error("Unable to get the alert dao."); + return false; + } + + return true; + } + + @Override + public String getName() { + return _name; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public void clearAlert(short alertType, long dataCenterId, long podId) { + try { + if (_emailAlert != null) { + _emailAlert.clearAlert(alertType, dataCenterId, podId); + } + } catch (Exception ex) { + s_logger.error("Problem clearing email alert", ex); + } + } + + @Override + public void sendAlert(short alertType, long dataCenterId, Long podId, String subject, String body) { + // TODO: queue up these messages and send them as one set of issues once a certain number of issues is reached? If that's the case, + // shouldn't we have a type/severity as part of the API so that severe errors get sent right away? + try { + if (_emailAlert != null) { + _emailAlert.sendAlert(alertType, dataCenterId, podId, subject, body); + } + } catch (Exception ex) { + s_logger.error("Problem sending email alert", ex); + } + } + + + class EmailAlert { + private Session _smtpSession; + private InternetAddress[] _recipientList; + private final String _smtpHost; + private int _smtpPort = -1; + private boolean _smtpUseAuth = false; + private final String _smtpUsername; + private final String _smtpPassword; + private final String _emailSender; + + public EmailAlert(String[] recipientList, String smtpHost, int smtpPort, boolean smtpUseAuth, final String smtpUsername, final String smtpPassword, String emailSender, boolean smtpDebug) { + if (recipientList != null) { + _recipientList = new InternetAddress[recipientList.length]; + for (int i = 0; i < recipientList.length; i++) { + try { + _recipientList[i] = new InternetAddress(recipientList[i], recipientList[i]); + } catch (Exception ex) { + s_logger.error("Exception creating address for: " + recipientList[i], ex); + } + } + } + + _smtpHost = smtpHost; + _smtpPort = smtpPort; + _smtpUseAuth = smtpUseAuth; + _smtpUsername = smtpUsername; + _smtpPassword = smtpPassword; + _emailSender = emailSender; + + if (_smtpHost != null) { + Properties smtpProps = new Properties(); + smtpProps.put("mail.smtp.host", smtpHost); + smtpProps.put("mail.smtp.port", smtpPort); + smtpProps.put("mail.smtp.auth", ""+smtpUseAuth); + if (smtpUsername != null) { + smtpProps.put("mail.smtp.user", smtpUsername); + } + + smtpProps.put("mail.smtps.host", smtpHost); + smtpProps.put("mail.smtps.port", smtpPort); + smtpProps.put("mail.smtps.auth", ""+smtpUseAuth); + if (smtpUsername != null) { + smtpProps.put("mail.smtps.user", smtpUsername); + } + + if ((smtpUsername != null) && (smtpPassword != null)) { + _smtpSession = Session.getInstance(smtpProps, new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(smtpUsername, smtpPassword); + } + }); + } else { + _smtpSession = Session.getInstance(smtpProps); + } + _smtpSession.setDebug(smtpDebug); + } else { + _smtpSession = null; + } + } + + // TODO: make sure this handles SSL transport (useAuth is true) and regular + public void sendAlert(short alertType, long dataCenterId, Long podId, String subject, String content) throws MessagingException, UnsupportedEncodingException { + AlertVO alert = null; + + if ((alertType != AlertManager.ALERT_TYPE_HOST) && + (alertType != AlertManager.ALERT_TYPE_USERVM) && + (alertType != AlertManager.ALERT_TYPE_DOMAIN_ROUTER) && + (alertType != AlertManager.ALERT_TYPE_CONSOLE_PROXY) && + (alertType != AlertManager.ALERT_TYPE_SSVM) && + (alertType != AlertManager.ALERT_TYPE_STORAGE_MISC) && + (alertType != AlertManager.ALERT_TYPE_MANAGMENT_NODE)) { + alert = _alertDao.getLastAlert(alertType, dataCenterId, podId); + } + + if (alert == null) { + // set up a new alert + AlertVO newAlert = new AlertVO(); + newAlert.setType(alertType); + newAlert.setSubject(subject); + newAlert.setPodId(podId); + newAlert.setDataCenterId(dataCenterId); + newAlert.setSentCount(1); // initialize sent count to 1 since we are now sending an alert + newAlert.setLastSent(new Date()); + _alertDao.persist(newAlert); + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Have already sent: " + alert.getSentCount() + " emails for alert type '" + alertType + "' -- skipping send email"); + } + return; + } + + if (_smtpSession != null) { + SMTPMessage msg = new SMTPMessage(_smtpSession); + msg.setSender(new InternetAddress(_emailSender, _emailSender)); + msg.setFrom(new InternetAddress(_emailSender, _emailSender)); + for (InternetAddress address : _recipientList) { + msg.addRecipient(RecipientType.TO, address); + } + msg.setSubject(subject); + msg.setSentDate(new Date()); + msg.setContent(content, "text/plain"); + msg.saveChanges(); + + SMTPTransport smtpTrans = null; + if (_smtpUseAuth) { + smtpTrans = new SMTPSSLTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword)); + } else { + smtpTrans = new SMTPTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword)); + } + smtpTrans.connect(); + smtpTrans.sendMessage(msg, msg.getAllRecipients()); + smtpTrans.close(); + } + } + + public void clearAlert(short alertType, long dataCenterId, Long podId) { + if (alertType != -1) { + AlertVO alert = _alertDao.getLastAlert(alertType, dataCenterId, podId); + if (alert != null) { + AlertVO updatedAlert = _alertDao.createForUpdate(); + updatedAlert.setResolved(new Date()); + _alertDao.update(alert.getId(), updatedAlert); + } + } + } + } + + @Override + public void recalculateCapacity() { + // TODO Auto-generated method stub + + } +} diff --git a/usage/src/com/cloud/usage/UsageManager.java b/usage/src/com/cloud/usage/UsageManager.java index aef2d76d1d9..f45646453ed 100644 --- a/usage/src/com/cloud/usage/UsageManager.java +++ b/usage/src/com/cloud/usage/UsageManager.java @@ -10,12 +10,12 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage; - -import com.cloud.usage.UsageJobVO; -import com.cloud.utils.component.Manager; - -public interface UsageManager extends Manager { - public void scheduleParse(); - public void parse(UsageJobVO job, long startDateMillis, long endDateMillis); -} +package com.cloud.usage; + +import com.cloud.usage.UsageJobVO; +import com.cloud.utils.component.Manager; + +public interface UsageManager extends Manager { + public void scheduleParse(); + public void parse(UsageJobVO job, long startDateMillis, long endDateMillis); +} diff --git a/usage/src/com/cloud/usage/UsageManagerImpl.java b/usage/src/com/cloud/usage/UsageManagerImpl.java index 9011ee7bef0..be513d2300c 100644 --- a/usage/src/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/com/cloud/usage/UsageManagerImpl.java @@ -10,1515 +10,1515 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage; - -import java.net.InetAddress; -import java.sql.SQLException; -import java.util.Calendar; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.TimeZone; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - -import com.cloud.alert.AlertManager; -import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; -import com.cloud.event.dao.UsageEventDao; -import com.cloud.usage.dao.UsageDao; -import com.cloud.usage.dao.UsageIPAddressDao; -import com.cloud.usage.dao.UsageJobDao; -import com.cloud.usage.dao.UsageLoadBalancerPolicyDao; -import com.cloud.usage.dao.UsageNetworkDao; -import com.cloud.usage.dao.UsageNetworkOfferingDao; -import com.cloud.usage.dao.UsagePortForwardingRuleDao; -import com.cloud.usage.dao.UsageSecurityGroupDao; -import com.cloud.usage.dao.UsageStorageDao; -import com.cloud.usage.dao.UsageVMInstanceDao; -import com.cloud.usage.dao.UsageVPNUserDao; -import com.cloud.usage.dao.UsageVolumeDao; -import com.cloud.usage.parser.IPAddressUsageParser; -import com.cloud.usage.parser.LoadBalancerUsageParser; -import com.cloud.usage.parser.NetworkOfferingUsageParser; -import com.cloud.usage.parser.NetworkUsageParser; -import com.cloud.usage.parser.PortForwardingUsageParser; -import com.cloud.usage.parser.SecurityGroupUsageParser; -import com.cloud.usage.parser.StorageUsageParser; -import com.cloud.usage.parser.VMInstanceUsageParser; -import com.cloud.usage.parser.VPNUserUsageParser; -import com.cloud.usage.parser.VolumeUsageParser; -import com.cloud.user.Account; -import com.cloud.user.AccountVO; -import com.cloud.user.UserStatisticsVO; -import com.cloud.user.dao.AccountDao; -import com.cloud.user.dao.UserStatisticsDao; -import com.cloud.utils.component.ComponentLocator; -import com.cloud.utils.component.Inject; -import com.cloud.utils.concurrency.NamedThreadFactory; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.GlobalLock; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.exception.CloudRuntimeException; - -@Local(value={UsageManager.class}) -public class UsageManagerImpl implements UsageManager, Runnable { - public static final Logger s_logger = Logger.getLogger(UsageManagerImpl.class.getName()); - - protected static final String DAILY = "DAILY"; - protected static final String WEEKLY = "WEEKLY"; - protected static final String MONTHLY = "MONTHLY"; - - private static final int HOURLY_TIME = 60; - private static final int DAILY_TIME = 60 * 24; - private static final int THREE_DAYS_IN_MINUTES = 60 * 24 * 3; - private static final int USAGE_AGGREGATION_RANGE_MIN = 10; - - private final ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); - private final AccountDao m_accountDao = _locator.getDao(AccountDao.class); - private final UserStatisticsDao m_userStatsDao = _locator.getDao(UserStatisticsDao.class); - private final UsageDao m_usageDao = _locator.getDao(UsageDao.class); - private final UsageVMInstanceDao m_usageInstanceDao = _locator.getDao(UsageVMInstanceDao.class); - private final UsageIPAddressDao m_usageIPAddressDao = _locator.getDao(UsageIPAddressDao.class); - private final UsageNetworkDao m_usageNetworkDao = _locator.getDao(UsageNetworkDao.class); - private final UsageVolumeDao m_usageVolumeDao = _locator.getDao(UsageVolumeDao.class); - private final UsageStorageDao m_usageStorageDao = _locator.getDao(UsageStorageDao.class); - private final UsageLoadBalancerPolicyDao m_usageLoadBalancerPolicyDao = _locator.getDao(UsageLoadBalancerPolicyDao.class); - private final UsagePortForwardingRuleDao m_usagePortForwardingRuleDao = _locator.getDao(UsagePortForwardingRuleDao.class); - private final UsageNetworkOfferingDao m_usageNetworkOfferingDao = _locator.getDao(UsageNetworkOfferingDao.class); - private final UsageVPNUserDao m_usageVPNUserDao = _locator.getDao(UsageVPNUserDao.class); - private final UsageSecurityGroupDao m_usageSecurityGroupDao = _locator.getDao(UsageSecurityGroupDao.class); - private final UsageJobDao m_usageJobDao = _locator.getDao(UsageJobDao.class); - @Inject protected AlertManager _alertMgr; - @Inject protected UsageEventDao _usageEventDao; - - private String m_version = null; - private String m_name = null; - private final Calendar m_jobExecTime = Calendar.getInstance(); - private int m_aggregationDuration = 0; - private int m_sanityCheckInterval = 0; - String m_hostname = null; - int m_pid = 0; - TimeZone m_usageTimezone = TimeZone.getTimeZone("GMT");; - private final GlobalLock m_heartbeatLock = GlobalLock.getInternLock("usage.job.heartbeat.check"); - - private final ScheduledExecutorService m_executor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("Usage-Job")); - private final ScheduledExecutorService m_heartbeatExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("Usage-HB")); - private final ScheduledExecutorService m_sanityExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("Usage-Sanity")); - private Future m_scheduledFuture = null; - private Future m_heartbeat = null; - private Future m_sanity = null; - - protected UsageManagerImpl() { - } - - private void mergeConfigs(Map dbParams, Map xmlParams) { - for (Map.Entry param : xmlParams.entrySet()) { - dbParams.put(param.getKey(), (String)param.getValue()); - } - } - - public boolean configure(String name, Map params) throws ConfigurationException { - final String run = "usage.vmops.pid"; - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Checking to see if " + run + " exists."); - } - - final Class c = UsageServer.class; - m_version = c.getPackage().getImplementationVersion(); - if (m_version == null) { - throw new CloudRuntimeException("Unable to find the implementation version of this usage server"); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("Implementation Version is " + m_version); - } - - m_name = name; - - ComponentLocator locator = ComponentLocator.getCurrentLocator(); - ConfigurationDao configDao = locator.getDao(ConfigurationDao.class); - if (configDao == null) { - s_logger.error("Unable to get the configuration dao."); - return false; - } - - Map configs = configDao.getConfiguration(params); - - if (params != null) { - mergeConfigs(configs, params); - } - - String execTime = configs.get("usage.stats.job.exec.time"); - String aggregationRange = configs.get("usage.stats.job.aggregation.range"); - String execTimeZone = configs.get("usage.execution.timezone"); - String aggreagationTimeZone = configs.get("usage.aggregation.timezone"); - String sanityCheckInterval = configs.get("usage.sanity.check.interval"); - if(sanityCheckInterval != null){ - m_sanityCheckInterval = Integer.parseInt(sanityCheckInterval); - } - - if(aggreagationTimeZone != null && !aggreagationTimeZone.isEmpty()){ - m_usageTimezone = TimeZone.getTimeZone(aggreagationTimeZone); - } - s_logger.debug("Usage stats aggregation time zone: "+aggreagationTimeZone); - - try { - if ((execTime == null) || (aggregationRange == null)) { - s_logger.error("missing configuration values for usage job, usage.stats.job.exec.time = " + execTime + ", usage.stats.job.aggregation.range = " + aggregationRange); - throw new ConfigurationException("Missing configuration values for usage job, usage.stats.job.exec.time = " + execTime + ", usage.stats.job.aggregation.range = " + aggregationRange); - } - String[] execTimeSegments = execTime.split(":"); - if (execTimeSegments.length != 2) { - s_logger.error("Unable to parse usage.stats.job.exec.time"); - throw new ConfigurationException("Unable to parse usage.stats.job.exec.time '" + execTime + "'"); - } - int hourOfDay = Integer.parseInt(execTimeSegments[0]); - int minutes = Integer.parseInt(execTimeSegments[1]); - m_jobExecTime.setTime(new Date()); - - m_jobExecTime.set(Calendar.HOUR_OF_DAY, hourOfDay); - m_jobExecTime.set(Calendar.MINUTE, minutes); - m_jobExecTime.set(Calendar.SECOND, 0); - m_jobExecTime.set(Calendar.MILLISECOND, 0); - if(execTimeZone != null && !execTimeZone.isEmpty()){ - m_jobExecTime.setTimeZone(TimeZone.getTimeZone(execTimeZone)); - } - - // if the hour to execute the job has already passed, roll the day forward to the next day - Date execDate = m_jobExecTime.getTime(); - if (execDate.before(new Date())) { - m_jobExecTime.roll(Calendar.DAY_OF_YEAR, true); - } - - s_logger.debug("Execution Time: "+execDate.toString()); - Date currentDate = new Date(System.currentTimeMillis()); - s_logger.debug("Current Time: "+currentDate.toString()); - - m_aggregationDuration = Integer.parseInt(aggregationRange); - if (m_aggregationDuration < USAGE_AGGREGATION_RANGE_MIN) { - s_logger.warn("Usage stats job aggregation range is to small, using the minimum value of " + USAGE_AGGREGATION_RANGE_MIN); - m_aggregationDuration = USAGE_AGGREGATION_RANGE_MIN; - } - m_hostname = InetAddress.getLocalHost().getHostName() + "/" + InetAddress.getLocalHost().getHostAddress(); - } catch (NumberFormatException ex) { - throw new ConfigurationException("Unable to parse usage.stats.job.exec.time '" + execTime + "' or usage.stats.job.aggregation.range '" + aggregationRange + "', please check configuration values"); - } catch (Exception e) { - s_logger.error("Unhandled exception configuring UsageManger", e); - throw new ConfigurationException("Unhandled exception configuring UsageManager " + e.toString()); - } - m_pid = Integer.parseInt(System.getProperty("pid")); - return true; - } - - public String getName() { - return m_name; - } - - public boolean start() { - if (s_logger.isInfoEnabled()) { - s_logger.info("Starting Usage Manager"); - } - - // use the configured exec time and aggregation duration for scheduling the job - m_scheduledFuture = m_executor.scheduleAtFixedRate(this, m_jobExecTime.getTimeInMillis() - System.currentTimeMillis(), m_aggregationDuration * 60 * 1000, TimeUnit.MILLISECONDS); - - m_heartbeat = m_heartbeatExecutor.scheduleAtFixedRate(new Heartbeat(), /* start in 15 seconds...*/15*1000, /* check database every minute*/60*1000, TimeUnit.MILLISECONDS); - - if(m_sanityCheckInterval > 0){ - m_sanity = m_sanityExecutor.scheduleAtFixedRate(new SanityCheck(), 1, m_sanityCheckInterval, TimeUnit.DAYS); - } - - Transaction usageTxn = Transaction.open(Transaction.USAGE_DB); - try { - if(m_heartbeatLock.lock(3)) { // 3 second timeout - try { - UsageJobVO job = m_usageJobDao.getLastJob(); - if (job == null) { - m_usageJobDao.createNewJob(m_hostname, m_pid, UsageJobVO.JOB_TYPE_RECURRING); - } - } finally { - m_heartbeatLock.unlock(); - } - } else { - if(s_logger.isTraceEnabled()) - s_logger.trace("Heartbeat lock is in use by others, returning true as someone else will take over the job if required"); - } - } finally { - usageTxn.close(); - } - - return true; - } - - public boolean stop() { - m_heartbeat.cancel(true); - m_scheduledFuture.cancel(true); - if(m_sanity != null){ - m_sanity.cancel(true); - } - return true; - } - - public void run() { - if (s_logger.isInfoEnabled()) { - s_logger.info("starting usage job..."); - } - - // how about we update the job exec time when the job starts??? - long execTime = m_jobExecTime.getTimeInMillis(); - long now = System.currentTimeMillis() + 2000; // 2 second buffer since jobs can run a little early (though usually just by milliseconds) - - if (execTime < now) { - // if exec time is in the past, calculate the next time the job will execute...if this is a one-off job that is a result - // of scheduleParse() then don't update the next exec time... - m_jobExecTime.add(Calendar.MINUTE, m_aggregationDuration); - } - - UsageJobVO job = m_usageJobDao.isOwner(m_hostname, m_pid); - if (job != null) { - // FIXME: we really need to do a better job of not missing any events...so we should some how - // keep track of the last time usage was run, then go from there... - // For executing the job, we treat hourly and daily as special time ranges, using the previous full hour or the previous - // full day. Otherwise we just subtract off the aggregation range from the current time and use that as start date with - // current time as end date. - Calendar cal = Calendar.getInstance(m_usageTimezone); - cal.setTime(new Date()); - long startDate = 0; - long endDate = 0; - if (m_aggregationDuration == DAILY_TIME) { - cal.roll(Calendar.DAY_OF_YEAR, false); - cal.set(Calendar.HOUR_OF_DAY, 0); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - startDate = cal.getTime().getTime(); - - cal.roll(Calendar.DAY_OF_YEAR, true); - cal.add(Calendar.MILLISECOND, -1); - endDate = cal.getTime().getTime(); - } else if (m_aggregationDuration == HOURLY_TIME) { - cal.roll(Calendar.HOUR_OF_DAY, false); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - startDate = cal.getTime().getTime(); - - cal.roll(Calendar.HOUR_OF_DAY, true); - cal.add(Calendar.MILLISECOND, -1); - endDate = cal.getTime().getTime(); - } else { - endDate = cal.getTime().getTime(); // current time - cal.add(Calendar.MINUTE, -1*m_aggregationDuration); - startDate = cal.getTime().getTime(); - } - - parse(job, startDate, endDate); - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Not owner of usage job, skipping..."); - } - } - if (s_logger.isInfoEnabled()) { - s_logger.info("usage job complete"); - } - } - - public void scheduleParse() { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Scheduling Usage job..."); - } - m_executor.schedule(this, 0, TimeUnit.MILLISECONDS); - } - - public void parse(UsageJobVO job, long startDateMillis, long endDateMillis) { - // TODO: Shouldn't we also allow parsing by the type of usage? - - boolean success = false; - long timeStart = System.currentTimeMillis(); - long deleteOldStatsTimeMillis = 0L; - try { - if ((endDateMillis == 0) || (endDateMillis > timeStart)) { - endDateMillis = timeStart; - } - - long lastSuccess = m_usageJobDao.getLastJobSuccessDateMillis(); - if (lastSuccess != 0) { - startDateMillis = lastSuccess+1; // 1 millisecond after - } - - if (startDateMillis >= endDateMillis) { - if (s_logger.isInfoEnabled()) { - s_logger.info("not parsing usage records since start time mills (" + startDateMillis + ") is on or after end time millis (" + endDateMillis + ")"); - } - - Transaction jobUpdateTxn = Transaction.open(Transaction.USAGE_DB); - try { - jobUpdateTxn.start(); - // everything seemed to work...set endDate as the last success date - m_usageJobDao.updateJobSuccess(job.getId(), startDateMillis, endDateMillis, System.currentTimeMillis() - timeStart, success); - - // create a new job if this is a recurring job - if (job.getJobType() == UsageJobVO.JOB_TYPE_RECURRING) { - m_usageJobDao.createNewJob(m_hostname, m_pid, UsageJobVO.JOB_TYPE_RECURRING); - } - jobUpdateTxn.commit(); - } finally { - jobUpdateTxn.close(); - } - - return; - } - deleteOldStatsTimeMillis = startDateMillis; - - Date startDate = new Date(startDateMillis); - Date endDate = new Date(endDateMillis); - if (s_logger.isInfoEnabled()) { - s_logger.info("Parsing usage records between " + startDate + " and " + endDate); - } - - List accounts = null; - List userStats = null; - Map networkStats = null; - Transaction userTxn = Transaction.open(Transaction.CLOUD_DB); - try { - Long limit = Long.valueOf(500); - Long offset = Long.valueOf(0); - Long lastAccountId = m_usageDao.getLastAccountId(); - if (lastAccountId == null) { - lastAccountId = Long.valueOf(0); - } - - do { - Filter filter = new Filter(AccountVO.class, "id", true, offset, limit); - - accounts = m_accountDao.findActiveAccounts(lastAccountId, filter); - - if ((accounts != null) && !accounts.isEmpty()) { - // now update the accounts in the cloud_usage db - m_usageDao.updateAccounts(accounts); - } - offset = new Long(offset.longValue() + limit.longValue()); - } while ((accounts != null) && !accounts.isEmpty()); - - // reset offset - offset = Long.valueOf(0); - - do { - Filter filter = new Filter(AccountVO.class, "id", true, offset, limit); - - accounts = m_accountDao.findRecentlyDeletedAccounts(lastAccountId, startDate, filter); - - if ((accounts != null) && !accounts.isEmpty()) { - // now update the accounts in the cloud_usage db - m_usageDao.updateAccounts(accounts); - } - offset = new Long(offset.longValue() + limit.longValue()); - } while ((accounts != null) && !accounts.isEmpty()); - - // reset offset - offset = Long.valueOf(0); - - do { - Filter filter = new Filter(AccountVO.class, "id", true, offset, limit); - - accounts = m_accountDao.findNewAccounts(lastAccountId, filter); - - if ((accounts != null) && !accounts.isEmpty()) { - // now copy the accounts to cloud_usage db - m_usageDao.saveAccounts(accounts); - } - offset = new Long(offset.longValue() + limit.longValue()); - } while ((accounts != null) && !accounts.isEmpty()); - - // reset offset - offset = Long.valueOf(0); - - // get all the user stats to create usage records for the network usage - Long lastUserStatsId = m_usageDao.getLastUserStatsId(); - if (lastUserStatsId == null) { - lastUserStatsId = Long.valueOf(0); - } - - SearchCriteria sc2 = m_userStatsDao.createSearchCriteria(); - sc2.addAnd("id", SearchCriteria.Op.LTEQ, lastUserStatsId); - do { - Filter filter = new Filter(UserStatisticsVO.class, "id", true, offset, limit); - - userStats = m_userStatsDao.search(sc2, filter); - - if ((userStats != null) && !userStats.isEmpty()) { - // now copy the accounts to cloud_usage db - m_usageDao.updateUserStats(userStats); - } - offset = new Long(offset.longValue() + limit.longValue()); - } while ((userStats != null) && !userStats.isEmpty()); - - // reset offset - offset = Long.valueOf(0); - - sc2 = m_userStatsDao.createSearchCriteria(); - sc2.addAnd("id", SearchCriteria.Op.GT, lastUserStatsId); - do { - Filter filter = new Filter(UserStatisticsVO.class, "id", true, offset, limit); - - userStats = m_userStatsDao.search(sc2, filter); - - if ((userStats != null) && !userStats.isEmpty()) { - // now copy the accounts to cloud_usage db - m_usageDao.saveUserStats(userStats); - } - offset = new Long(offset.longValue() + limit.longValue()); - } while ((userStats != null) && !userStats.isEmpty()); - } finally { - userTxn.close(); - } - - // TODO: Fetch a maximum number of events and process them before moving on to the next range of events - - // - get a list of the latest events - // - insert the latest events into the usage.events table - List events = _usageEventDao.getRecentEvents(new Date(endDateMillis)); - - - Transaction usageTxn = Transaction.open(Transaction.USAGE_DB); - try { - usageTxn.start(); - - // make sure start date is before all of our un-processed events (the events are ordered oldest - // to newest, so just test against the first event) - if ((events != null) && (events.size() > 0)) { - Date oldestEventDate = events.get(0).getCreateDate(); - if (oldestEventDate.getTime() < startDateMillis) { - startDateMillis = oldestEventDate.getTime(); - startDate = new Date(startDateMillis); - } - - // - loop over the list of events and create entries in the helper tables - // - create the usage records using the parse methods below - for (UsageEventVO event : events) { - event.setProcessed(true); - _usageEventDao.update(event.getId(), event); - createHelperRecord(event); - } - } - - // TODO: Fetch a maximum number of user stats and process them before moving on to the next range of user stats - - // get user stats in order to compute network usage - networkStats = m_usageNetworkDao.getRecentNetworkStats(); - - Calendar recentlyDeletedCal = Calendar.getInstance(m_usageTimezone); - recentlyDeletedCal.setTimeInMillis(startDateMillis); - recentlyDeletedCal.add(Calendar.MINUTE, -1*THREE_DAYS_IN_MINUTES); - Date recentlyDeletedDate = recentlyDeletedCal.getTime(); - - // Keep track of user stats for an account, across all of its public IPs - Map aggregatedStats = new HashMap(); - int startIndex = 0; - do { - userStats = m_userStatsDao.listActiveAndRecentlyDeleted(recentlyDeletedDate, startIndex, 500); - - if (userStats != null) { - for (UserStatisticsVO userStat : userStats) { - if(userStat.getDeviceId() != null){ - String hostKey = userStat.getDataCenterId() + "-" + userStat.getAccountId()+"-Host-" + userStat.getDeviceId(); - UserStatisticsVO hostAggregatedStat = aggregatedStats.get(hostKey); - if (hostAggregatedStat == null) { - hostAggregatedStat = new UserStatisticsVO(userStat.getAccountId(), userStat.getDataCenterId(), userStat.getPublicIpAddress(), - userStat.getDeviceId(), userStat.getDeviceType(), userStat.getNetworkId()); - } - - hostAggregatedStat.setAggBytesSent(hostAggregatedStat.getAggBytesSent() + userStat.getAggBytesSent()); - hostAggregatedStat.setAggBytesReceived(hostAggregatedStat.getAggBytesReceived() + userStat.getAggBytesReceived()); - aggregatedStats.put(hostKey, hostAggregatedStat); - } - } - } - startIndex += 500; - } while ((userStats != null) && !userStats.isEmpty()); - - // loop over the user stats, create delta entries in the usage_network helper table - int numAcctsProcessed = 0; - for (String key : aggregatedStats.keySet()) { - UsageNetworkVO currentNetworkStats = null; - if (networkStats != null) { - currentNetworkStats = networkStats.get(key); - } - - createNetworkHelperEntry(aggregatedStats.get(key), currentNetworkStats, endDateMillis); - numAcctsProcessed++; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("created network stats helper entries for " + numAcctsProcessed + " accts"); - } - - // commit the helper records, then start a new transaction - usageTxn.commit(); - usageTxn.start(); - - boolean parsed = false; - numAcctsProcessed = 0; - - Date currentStartDate = startDate; - Date currentEndDate = endDate; - Date tempDate = endDate; - - Calendar aggregateCal = Calendar.getInstance(m_usageTimezone); - - while ((tempDate.after(startDate)) && ((tempDate.getTime() - startDate.getTime()) > 60000)){ - currentEndDate = tempDate; - aggregateCal.setTime(tempDate); - aggregateCal.add(Calendar.MINUTE, -m_aggregationDuration); - tempDate = aggregateCal.getTime(); - } - - while (!currentEndDate.after(endDate) || (currentEndDate.getTime() -endDate.getTime() < 60000)){ - Long offset = Long.valueOf(0); - Long limit = Long.valueOf(500); - - do { - Filter filter = new Filter(AccountVO.class, "id", true, offset, limit); - accounts = m_accountDao.listAll(filter); - if ((accounts != null) && !accounts.isEmpty()) { - for (AccountVO account : accounts) { - parsed = parseHelperTables(account, currentStartDate, currentEndDate); - numAcctsProcessed++; - } - } - offset = new Long(offset.longValue() + limit.longValue()); - } while ((accounts != null) && !accounts.isEmpty()); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("processed VM/Network Usage for " + numAcctsProcessed + " ACTIVE accts"); - } - numAcctsProcessed = 0; - - // reset offset - offset = Long.valueOf(0); - - do { - Filter filter = new Filter(AccountVO.class, "id", true, offset, limit); - - accounts = m_accountDao.findRecentlyDeletedAccounts(null, recentlyDeletedDate, filter); - - if ((accounts != null) && !accounts.isEmpty()) { - for (AccountVO account : accounts) { - parsed = parseHelperTables(account, currentStartDate, currentEndDate); - List publicTemplates = m_usageDao.listPublicTemplatesByAccount(account.getId()); - for(Long templateId : publicTemplates){ - //mark public templates owned by deleted accounts as deleted - List storageVOs = m_usageStorageDao.listById(account.getId(), templateId, StorageTypes.TEMPLATE); - if (storageVOs.size() > 1) { - s_logger.warn("More that one usage entry for storage: " + templateId + " assigned to account: " + account.getId() + "; marking them all as deleted..."); - } - for (UsageStorageVO storageVO : storageVOs) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("deleting template: " + storageVO.getId() + " from account: " + storageVO.getAccountId()); - } - storageVO.setDeleted(account.getRemoved()); - m_usageStorageDao.update(storageVO); - } - } - numAcctsProcessed++; - } - } - offset = new Long(offset.longValue() + limit.longValue()); - } while ((accounts != null) && !accounts.isEmpty()); - - currentStartDate = new Date(currentEndDate.getTime() + 1); - aggregateCal.setTime(currentEndDate); - aggregateCal.add(Calendar.MINUTE, m_aggregationDuration); - currentEndDate = aggregateCal.getTime(); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("processed Usage for " + numAcctsProcessed + " RECENTLY DELETED accts"); - } - - // FIXME: we don't break the above loop if something fails to parse, so it gets reset every account, - // do we want to break out of processing accounts and rollback if there are errors? - if (!parsed) { - usageTxn.rollback(); - } else { - success = true; - } - } catch (Exception ex) { - s_logger.error("Exception in usage manager", ex); - usageTxn.rollback(); - } finally { - // everything seemed to work...set endDate as the last success date - m_usageJobDao.updateJobSuccess(job.getId(), startDateMillis, endDateMillis, System.currentTimeMillis() - timeStart, success); - - // create a new job if this is a recurring job - if (job.getJobType() == UsageJobVO.JOB_TYPE_RECURRING) { - m_usageJobDao.createNewJob(m_hostname, m_pid, UsageJobVO.JOB_TYPE_RECURRING); - } - usageTxn.commit(); - usageTxn.close(); - - // switch back to CLOUD_DB - Transaction swap = Transaction.open(Transaction.CLOUD_DB); - if(!success){ - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USAGE_SERVER_RESULT, 0, new Long(0), "Usage job failed. Job id: "+job.getId(), "Usage job failed. Job id: "+job.getId()); - } else { - _alertMgr.clearAlert(AlertManager.ALERT_TYPE_USAGE_SERVER_RESULT, 0, 0); - } - swap.close(); - - } - } catch (Exception e) { - s_logger.error("Usage Manager error", e); - } - } - - private boolean parseHelperTables(AccountVO account, Date currentStartDate, Date currentEndDate){ - boolean parsed = false; - - parsed = VMInstanceUsageParser.parse(account, currentStartDate, currentEndDate); - if (s_logger.isDebugEnabled()) { - if (!parsed) { - s_logger.debug("vm usage instances successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); - } - } - - parsed = NetworkUsageParser.parse(account, currentStartDate, currentEndDate); - if (s_logger.isDebugEnabled()) { - if (!parsed) { - s_logger.debug("network usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); - } - } - - parsed = VolumeUsageParser.parse(account, currentStartDate, currentEndDate); - if (s_logger.isDebugEnabled()) { - if (!parsed) { - s_logger.debug("volume usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); - } - } - - parsed = StorageUsageParser.parse(account, currentStartDate, currentEndDate); - if (s_logger.isDebugEnabled()) { - if (!parsed) { - s_logger.debug("storage usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); - } - } - - parsed = SecurityGroupUsageParser.parse(account, currentStartDate, currentEndDate); - if (s_logger.isDebugEnabled()) { - if (!parsed) { - s_logger.debug("Security Group usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); - } - } - - parsed = LoadBalancerUsageParser.parse(account, currentStartDate, currentEndDate); - if (s_logger.isDebugEnabled()) { - if (!parsed) { - s_logger.debug("load balancer usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); - } - } - - parsed = PortForwardingUsageParser.parse(account, currentStartDate, currentEndDate); - if (s_logger.isDebugEnabled()) { - if (!parsed) { - s_logger.debug("port forwarding usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); - } - } - - parsed = NetworkOfferingUsageParser.parse(account, currentStartDate, currentEndDate); - if (s_logger.isDebugEnabled()) { - if (!parsed) { - s_logger.debug("network offering usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); - } - } - - parsed = IPAddressUsageParser.parse(account, currentStartDate, currentEndDate); - if (s_logger.isDebugEnabled()) { - if (!parsed) { - s_logger.debug("IPAddress usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); - } - } - parsed = VPNUserUsageParser.parse(account, currentStartDate, currentEndDate); - if (s_logger.isDebugEnabled()) { - if (!parsed) { - s_logger.debug("VPN user usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); - } - } - return parsed; - } - - private void createHelperRecord(UsageEventVO event) { - String eventType = event.getType(); - if (isVMEvent(eventType)) { - createVMHelperEvent(event); - } else if (isIPEvent(eventType)) { - createIPHelperEvent(event); - } else if (isVolumeEvent(eventType)) { - createVolumeHelperEvent(event); - } else if (isTemplateEvent(eventType)) { - createTemplateHelperEvent(event); - } else if (isISOEvent(eventType)) { - createISOHelperEvent(event); - } else if (isSnapshotEvent(eventType)) { - createSnapshotHelperEvent(event); - } else if (isLoadBalancerEvent(eventType)) { - createLoadBalancerHelperEvent(event); - } else if (isPortForwardingEvent(eventType)) { - createPortForwardingHelperEvent(event); - } else if (isNetworkOfferingEvent(eventType)) { - createNetworkOfferingEvent(event); - } else if (isVPNUserEvent(eventType)) { - createVPNUserEvent(event); - } else if (isSecurityGroupEvent(eventType)) { - createSecurityGroupEvent(event); - } - } - - private boolean isVMEvent(String eventType) { - if (eventType == null) return false; - return eventType.startsWith("VM."); - } - - private boolean isIPEvent(String eventType) { - if (eventType == null) return false; - return eventType.startsWith("NET.IP"); - } - - private boolean isVolumeEvent(String eventType) { - if (eventType == null) return false; - return (eventType.equals(EventTypes.EVENT_VOLUME_CREATE) || - eventType.equals(EventTypes.EVENT_VOLUME_DELETE)); - } - - private boolean isTemplateEvent(String eventType) { - if (eventType == null) return false; - return (eventType.equals(EventTypes.EVENT_TEMPLATE_CREATE) || - eventType.equals(EventTypes.EVENT_TEMPLATE_COPY) || - eventType.equals(EventTypes.EVENT_TEMPLATE_DELETE)); - } - - private boolean isISOEvent(String eventType) { - if (eventType == null) return false; - return (eventType.equals(EventTypes.EVENT_ISO_CREATE) || - eventType.equals(EventTypes.EVENT_ISO_COPY) || - eventType.equals(EventTypes.EVENT_ISO_DELETE)); - } - - private boolean isSnapshotEvent(String eventType) { - if (eventType == null) return false; - return (eventType.equals(EventTypes.EVENT_SNAPSHOT_CREATE) || - eventType.equals(EventTypes.EVENT_SNAPSHOT_DELETE)); - } - - private boolean isLoadBalancerEvent(String eventType) { - if (eventType == null) return false; - return eventType.startsWith("LB."); - } - - private boolean isPortForwardingEvent(String eventType) { - if (eventType == null) return false; - return eventType.startsWith("NET.RULE"); - } - - private boolean isNetworkOfferingEvent(String eventType) { - if (eventType == null) return false; - return (eventType.equals(EventTypes.EVENT_NETWORK_OFFERING_CREATE) || - eventType.equals(EventTypes.EVENT_NETWORK_OFFERING_DELETE) || - eventType.equals(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN) || - eventType.equals(EventTypes.EVENT_NETWORK_OFFERING_REMOVE)); - } - - private boolean isVPNUserEvent(String eventType) { - if (eventType == null) return false; - return eventType.startsWith("VPN.USER"); - } - - private boolean isSecurityGroupEvent(String eventType) { - if (eventType == null) return false; - return (eventType.equals(EventTypes.EVENT_SECURITY_GROUP_ASSIGN) || - eventType.equals(EventTypes.EVENT_SECURITY_GROUP_REMOVE)); - } - - private void createVMHelperEvent(UsageEventVO event) { - - // One record for handling VM.START and VM.STOP - // One record for handling VM.CREATE and VM.DESTROY - // VM events have the parameter "id=" - long vmId = event.getResourceId(); - Long soId = event.getOfferingId();; // service offering id - long zoneId = event.getZoneId(); - String vmName = event.getResourceName(); - - if (EventTypes.EVENT_VM_START.equals(event.getType())) { - // create a new usage_vm_instance row for this VM - try { - - SearchCriteria sc = m_usageInstanceDao.createSearchCriteria(); - sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, Long.valueOf(vmId)); - sc.addAnd("endDate", SearchCriteria.Op.NULL); - sc.addAnd("usageType", SearchCriteria.Op.EQ, UsageTypes.RUNNING_VM); - List usageInstances = m_usageInstanceDao.search(sc, null); - if (usageInstances != null) { - if (usageInstances.size() > 0) { - s_logger.error("found entries for a vm running with id: " + vmId + ", which are not stopped. Ending them all..."); - for (UsageVMInstanceVO usageInstance : usageInstances) { - usageInstance.setEndDate(event.getCreateDate()); - m_usageInstanceDao.update(usageInstance); - } - } - } - - sc = m_usageInstanceDao.createSearchCriteria(); - sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, Long.valueOf(vmId)); - sc.addAnd("endDate", SearchCriteria.Op.NULL); - sc.addAnd("usageType", SearchCriteria.Op.EQ, UsageTypes.ALLOCATED_VM); - usageInstances = m_usageInstanceDao.search(sc, null); - if (usageInstances == null || (usageInstances.size() == 0)) { - s_logger.error("Cannot find allocated vm entry for a vm running with id: " + vmId); - } - - Long templateId = event.getTemplateId(); - String hypervisorType = event.getResourceType(); - - // add this VM to the usage helper table - UsageVMInstanceVO usageInstanceNew = new UsageVMInstanceVO(UsageTypes.RUNNING_VM, zoneId, event.getAccountId(), vmId, vmName, - soId, templateId, hypervisorType, event.getCreateDate(), null); - m_usageInstanceDao.persist(usageInstanceNew); - } catch (Exception ex) { - s_logger.error("Error saving usage instance for vm: " + vmId, ex); - } - } else if (EventTypes.EVENT_VM_STOP.equals(event.getType())) { - // find the latest usage_vm_instance row, update the stop date (should be null) to the event date - // FIXME: search criteria needs to have some kind of type information so we distinguish between START/STOP and CREATE/DESTROY - SearchCriteria sc = m_usageInstanceDao.createSearchCriteria(); - sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, Long.valueOf(vmId)); - sc.addAnd("endDate", SearchCriteria.Op.NULL); - sc.addAnd("usageType", SearchCriteria.Op.EQ, UsageTypes.RUNNING_VM); - List usageInstances = m_usageInstanceDao.search(sc, null); - if (usageInstances != null) { - if (usageInstances.size() > 1) { - s_logger.warn("found multiple entries for a vm running with id: " + vmId + ", ending them all..."); - } - for (UsageVMInstanceVO usageInstance : usageInstances) { - usageInstance.setEndDate(event.getCreateDate()); - // TODO: UsageVMInstanceVO should have an ID field and we should do updates through that field since we are really - // updating one row at a time here - m_usageInstanceDao.update(usageInstance); - } - } - } else if (EventTypes.EVENT_VM_CREATE.equals(event.getType())) { - try { - Long templateId = event.getTemplateId(); - String hypervisorType = event.getResourceType(); - // add this VM to the usage helper table - UsageVMInstanceVO usageInstanceNew = new UsageVMInstanceVO(UsageTypes.ALLOCATED_VM, zoneId, event.getAccountId(), vmId, vmName, - soId, templateId, hypervisorType, event.getCreateDate(), null); - m_usageInstanceDao.persist(usageInstanceNew); - } catch (Exception ex) { - s_logger.error("Error saving usage instance for vm: " + vmId, ex); - } - } else if (EventTypes.EVENT_VM_DESTROY.equals(event.getType())) { - SearchCriteria sc = m_usageInstanceDao.createSearchCriteria(); - sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, Long.valueOf(vmId)); - sc.addAnd("endDate", SearchCriteria.Op.NULL); - sc.addAnd("usageType", SearchCriteria.Op.EQ, UsageTypes.ALLOCATED_VM); - List usageInstances = m_usageInstanceDao.search(sc, null); - if (usageInstances != null) { - if (usageInstances.size() > 1) { - s_logger.warn("found multiple entries for a vm allocated with id: " + vmId + ", detroying them all..."); - } - for (UsageVMInstanceVO usageInstance : usageInstances) { - usageInstance.setEndDate(event.getCreateDate()); - m_usageInstanceDao.update(usageInstance); - } - } - } else if (EventTypes.EVENT_VM_UPGRADE.equals(event.getType())) { - SearchCriteria sc = m_usageInstanceDao.createSearchCriteria(); - sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, Long.valueOf(vmId)); - sc.addAnd("endDate", SearchCriteria.Op.NULL); - sc.addAnd("usageType", SearchCriteria.Op.EQ, UsageTypes.ALLOCATED_VM); - List usageInstances = m_usageInstanceDao.search(sc, null); - if (usageInstances != null) { - if (usageInstances.size() > 1) { - s_logger.warn("found multiple entries for a vm allocated with id: " + vmId + ", updating end_date for all of them..."); - } - for (UsageVMInstanceVO usageInstance : usageInstances) { - usageInstance.setEndDate(event.getCreateDate()); - m_usageInstanceDao.update(usageInstance); - } - } - - Long templateId = event.getTemplateId(); - String hypervisorType = event.getResourceType(); - // add this VM to the usage helper table - UsageVMInstanceVO usageInstanceNew = new UsageVMInstanceVO(UsageTypes.ALLOCATED_VM, zoneId, event.getAccountId(), vmId, vmName, - soId, templateId, hypervisorType, event.getCreateDate(), null); - m_usageInstanceDao.persist(usageInstanceNew); - } - } - - private void createNetworkHelperEntry(UserStatisticsVO userStat, UsageNetworkVO usageNetworkStats, long timestamp) { - long currentAccountedBytesSent = 0L; - long currentAccountedBytesReceived = 0L; - if (usageNetworkStats != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("getting current accounted bytes for... accountId: " + usageNetworkStats.getAccountId() + " in zone: " + userStat.getDataCenterId() + "; abr: " + usageNetworkStats.getAggBytesReceived() + - "; abs: " + usageNetworkStats.getAggBytesSent()); - } - currentAccountedBytesSent = usageNetworkStats.getAggBytesSent(); - currentAccountedBytesReceived = usageNetworkStats.getAggBytesReceived(); - } - long bytesSent = userStat.getAggBytesSent() - currentAccountedBytesSent; - long bytesReceived = userStat.getAggBytesReceived() - currentAccountedBytesReceived; - - if (bytesSent < 0) { - s_logger.warn("Calculated negative value for bytes sent: " + bytesSent + ", user stats say: " + userStat.getAggBytesSent() + ", previous network usage was: " + currentAccountedBytesSent); - bytesSent = 0; - } - if (bytesReceived < 0) { - s_logger.warn("Calculated negative value for bytes received: " + bytesReceived + ", user stats say: " + userStat.getAggBytesReceived() + ", previous network usage was: " + currentAccountedBytesReceived); - bytesReceived = 0; - } - - long hostId = 0; - - if(userStat.getDeviceId() != null){ - hostId = userStat.getDeviceId(); - } - - UsageNetworkVO usageNetworkVO = new UsageNetworkVO(userStat.getAccountId(), userStat.getDataCenterId(), hostId, userStat.getDeviceType(), userStat.getNetworkId(), bytesSent, bytesReceived, - userStat.getAggBytesReceived(), userStat.getAggBytesSent(), timestamp); - if (s_logger.isDebugEnabled()) { - s_logger.debug("creating networkHelperEntry... accountId: " + userStat.getAccountId() + " in zone: " + userStat.getDataCenterId() + "; abr: " + userStat.getAggBytesReceived() + "; abs: " + userStat.getAggBytesSent() + - "; curABS: " + currentAccountedBytesSent + "; curABR: " + currentAccountedBytesReceived + "; ubs: " + bytesSent + "; ubr: " + bytesReceived); - } - m_usageNetworkDao.persist(usageNetworkVO); - } - - private void createIPHelperEvent(UsageEventVO event) { - - String ipAddress = event.getResourceName(); - - if (EventTypes.EVENT_NET_IP_ASSIGN.equals(event.getType())) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("assigning ip address: " + ipAddress + " to account: " + event.getAccountId()); - } - Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); - long zoneId = event.getZoneId(); - long id = event.getResourceId(); - long sourceNat = event.getSize(); - boolean isSourceNat = (sourceNat == 1) ? true : false ; - boolean isSystem = (event.getTemplateId() == null || event.getTemplateId() == 0) ? false : true ; - UsageIPAddressVO ipAddressVO = new UsageIPAddressVO(id, event.getAccountId(), acct.getDomainId(), zoneId, ipAddress, isSourceNat, isSystem, event.getCreateDate(), null); - m_usageIPAddressDao.persist(ipAddressVO); - } else if (EventTypes.EVENT_NET_IP_RELEASE.equals(event.getType())) { - SearchCriteria sc = m_usageIPAddressDao.createSearchCriteria(); - sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); - sc.addAnd("address", SearchCriteria.Op.EQ, ipAddress); - sc.addAnd("released", SearchCriteria.Op.NULL); - List ipAddressVOs = m_usageIPAddressDao.search(sc, null); - if (ipAddressVOs.size() > 1) { - s_logger.warn("More that one usage entry for ip address: " + ipAddress + " assigned to account: " + event.getAccountId() + "; marking them all as released..."); - } - for (UsageIPAddressVO ipAddressVO : ipAddressVOs) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("releasing ip address: " + ipAddressVO.getAddress() + " from account: " + ipAddressVO.getAccountId()); - } - ipAddressVO.setReleased(event.getCreateDate()); // there really shouldn't be more than one - m_usageIPAddressDao.update(ipAddressVO); - } - } - } - - private void createVolumeHelperEvent(UsageEventVO event) { - - Long doId = -1L; - long zoneId = -1L; - Long templateId = -1L; - long size = -1L; - - long volId = event.getResourceId(); - if (EventTypes.EVENT_VOLUME_CREATE.equals(event.getType())) { - doId = event.getOfferingId(); - zoneId = event.getZoneId(); - templateId = event.getTemplateId(); - size = event.getSize(); - } - - if (EventTypes.EVENT_VOLUME_CREATE.equals(event.getType())) { - SearchCriteria sc = m_usageVolumeDao.createSearchCriteria(); - sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); - sc.addAnd("id", SearchCriteria.Op.EQ, volId); - sc.addAnd("deleted", SearchCriteria.Op.NULL); - List volumesVOs = m_usageVolumeDao.search(sc, null); - if (volumesVOs.size() > 0) { - //This is a safeguard to avoid double counting of volumes. - s_logger.error("Found duplicate usage entry for volume: " + volId + " assigned to account: " + event.getAccountId() + "; marking as deleted..."); - } - for (UsageVolumeVO volumesVO : volumesVOs) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("deleting volume: " + volumesVO.getId() + " from account: " + volumesVO.getAccountId()); - } - volumesVO.setDeleted(event.getCreateDate()); - m_usageVolumeDao.update(volumesVO); - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("create volume with id : " + volId + " for account: " + event.getAccountId()); - } - Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); - UsageVolumeVO volumeVO = new UsageVolumeVO(volId, zoneId, event.getAccountId(), acct.getDomainId(), doId, templateId, size, event.getCreateDate(), null); - m_usageVolumeDao.persist(volumeVO); - } else if (EventTypes.EVENT_VOLUME_DELETE.equals(event.getType())) { - SearchCriteria sc = m_usageVolumeDao.createSearchCriteria(); - sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); - sc.addAnd("id", SearchCriteria.Op.EQ, volId); - sc.addAnd("deleted", SearchCriteria.Op.NULL); - List volumesVOs = m_usageVolumeDao.search(sc, null); - if (volumesVOs.size() > 1) { - s_logger.warn("More that one usage entry for volume: " + volId + " assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); - } - for (UsageVolumeVO volumesVO : volumesVOs) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("deleting volume: " + volumesVO.getId() + " from account: " + volumesVO.getAccountId()); - } - volumesVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one - m_usageVolumeDao.update(volumesVO); - } - } - } - - private void createTemplateHelperEvent(UsageEventVO event) { - - long templateId = -1L; - long zoneId = -1L; - long templateSize = -1L; - - templateId = event.getResourceId(); - zoneId = event.getZoneId(); - if (EventTypes.EVENT_TEMPLATE_CREATE.equals(event.getType()) || EventTypes.EVENT_TEMPLATE_COPY.equals(event.getType())) { - templateSize = event.getSize(); - if(templateSize < 1){ - s_logger.error("Incorrect size for template with Id "+templateId); - return; - } - if(zoneId == -1L){ - s_logger.error("Incorrect zoneId for template with Id "+templateId); - return; - } - } - - if (EventTypes.EVENT_TEMPLATE_CREATE.equals(event.getType()) || EventTypes.EVENT_TEMPLATE_COPY.equals(event.getType())) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("create template with id : " + templateId + " for account: " + event.getAccountId()); - } - List storageVOs = m_usageStorageDao.listByIdAndZone(event.getAccountId(), templateId, StorageTypes.TEMPLATE, zoneId); - if (storageVOs.size() > 0) { - s_logger.warn("Usage entry for Template: " + templateId + " assigned to account: " + event.getAccountId() + "already exists in zone "+zoneId); - return; - } - Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); - UsageStorageVO storageVO = new UsageStorageVO(templateId, zoneId, event.getAccountId(), acct.getDomainId(), StorageTypes.TEMPLATE, event.getTemplateId(), - templateSize, event.getCreateDate(), null); - m_usageStorageDao.persist(storageVO); - } else if (EventTypes.EVENT_TEMPLATE_DELETE.equals(event.getType())) { - List storageVOs; - if(zoneId != -1L){ - storageVOs = m_usageStorageDao.listByIdAndZone(event.getAccountId(), templateId, StorageTypes.TEMPLATE, zoneId); - } else { - storageVOs = m_usageStorageDao.listById(event.getAccountId(), templateId, StorageTypes.TEMPLATE); - } - if (storageVOs.size() > 1) { - s_logger.warn("More that one usage entry for storage: " + templateId + " assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); - } - for (UsageStorageVO storageVO : storageVOs) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("deleting template: " + storageVO.getId() + " from account: " + storageVO.getAccountId()); - } - storageVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one - m_usageStorageDao.update(storageVO); - } - } - } - - private void createISOHelperEvent(UsageEventVO event) { - long isoSize = -1L; - - long isoId = event.getResourceId(); - long zoneId = event.getZoneId(); - if (EventTypes.EVENT_ISO_CREATE.equals(event.getType()) || EventTypes.EVENT_ISO_COPY.equals(event.getType())) { - isoSize = event.getSize(); - } - - if (EventTypes.EVENT_ISO_CREATE.equals(event.getType()) || EventTypes.EVENT_ISO_COPY.equals(event.getType())) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("create iso with id : " + isoId + " for account: " + event.getAccountId()); - } - List storageVOs = m_usageStorageDao.listByIdAndZone(event.getAccountId(), isoId, StorageTypes.ISO, zoneId); - if (storageVOs.size() > 0) { - s_logger.warn("Usage entry for ISO: " + isoId + " assigned to account: " + event.getAccountId() + "already exists in zone "+zoneId); - return; - } - Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); - UsageStorageVO storageVO = new UsageStorageVO( isoId, zoneId, event.getAccountId(), acct.getDomainId(), StorageTypes.ISO, null, - isoSize, event.getCreateDate(), null); - m_usageStorageDao.persist(storageVO); - } else if (EventTypes.EVENT_ISO_DELETE.equals(event.getType())) { - List storageVOs; - if(zoneId != -1L){ - storageVOs = m_usageStorageDao.listByIdAndZone(event.getAccountId(), isoId, StorageTypes.ISO, zoneId); - } else { - storageVOs = m_usageStorageDao.listById(event.getAccountId(), isoId, StorageTypes.ISO); - } - - if (storageVOs.size() > 1) { - s_logger.warn("More that one usage entry for storage: " + isoId + " assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); - } - for (UsageStorageVO storageVO : storageVOs) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("deleting iso: " + storageVO.getId() + " from account: " + storageVO.getAccountId()); - } - storageVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one - m_usageStorageDao.update(storageVO); - } - } - } - - private void createSnapshotHelperEvent(UsageEventVO event) { - long snapSize = -1L; - long zoneId = -1L; - - long snapId = event.getResourceId(); - if (EventTypes.EVENT_SNAPSHOT_CREATE.equals(event.getType())) { - snapSize = event.getSize(); - zoneId = event.getZoneId(); - } - - if (EventTypes.EVENT_SNAPSHOT_CREATE.equals(event.getType())) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("create snapshot with id : " + snapId + " for account: " + event.getAccountId()); - } - Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); - UsageStorageVO storageVO = new UsageStorageVO( snapId, zoneId, event.getAccountId(), acct.getDomainId(), StorageTypes.SNAPSHOT, null, - snapSize, event.getCreateDate(), null); - m_usageStorageDao.persist(storageVO); - } else if (EventTypes.EVENT_SNAPSHOT_DELETE.equals(event.getType())) { - List storageVOs = m_usageStorageDao.listById(event.getAccountId(), snapId, StorageTypes.SNAPSHOT); - if (storageVOs.size() > 1) { - s_logger.warn("More that one usage entry for storage: " + snapId + " assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); - } - for (UsageStorageVO storageVO : storageVOs) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("deleting snapshot: " + storageVO.getId() + " from account: " + storageVO.getAccountId()); - } - storageVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one - m_usageStorageDao.update(storageVO); - } - } - } - - private void createLoadBalancerHelperEvent(UsageEventVO event) { - - long zoneId = -1L; - - long id = event.getResourceId(); - - if (EventTypes.EVENT_LOAD_BALANCER_CREATE.equals(event.getType())) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating load balancer : " + id + " for account: " + event.getAccountId()); - } - zoneId = event.getZoneId(); - Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); - UsageLoadBalancerPolicyVO lbVO = new UsageLoadBalancerPolicyVO(id, zoneId, event.getAccountId(), acct.getDomainId(), - event.getCreateDate(), null); - m_usageLoadBalancerPolicyDao.persist(lbVO); - } else if (EventTypes.EVENT_LOAD_BALANCER_DELETE.equals(event.getType())) { - SearchCriteria sc = m_usageLoadBalancerPolicyDao.createSearchCriteria(); - sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); - sc.addAnd("id", SearchCriteria.Op.EQ, id); - sc.addAnd("deleted", SearchCriteria.Op.NULL); - List lbVOs = m_usageLoadBalancerPolicyDao.search(sc, null); - if (lbVOs.size() > 1) { - s_logger.warn("More that one usage entry for load balancer policy: " + id + " assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); - } - for (UsageLoadBalancerPolicyVO lbVO : lbVOs) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("deleting load balancer policy: " + lbVO.getId() + " from account: " + lbVO.getAccountId()); - } - lbVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one - m_usageLoadBalancerPolicyDao.update(lbVO); - } - } - } - - private void createPortForwardingHelperEvent(UsageEventVO event) { - - long zoneId = -1L; - - long id = event.getResourceId(); - - if (EventTypes.EVENT_NET_RULE_ADD.equals(event.getType())) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating port forwarding rule : " + id + " for account: " + event.getAccountId()); - } - zoneId = event.getZoneId(); - Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); - UsagePortForwardingRuleVO pfVO = new UsagePortForwardingRuleVO(id, zoneId, event.getAccountId(), acct.getDomainId(), - event.getCreateDate(), null); - m_usagePortForwardingRuleDao.persist(pfVO); - } else if (EventTypes.EVENT_NET_RULE_DELETE.equals(event.getType())) { - SearchCriteria sc = m_usagePortForwardingRuleDao.createSearchCriteria(); - sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); - sc.addAnd("id", SearchCriteria.Op.EQ, id); - sc.addAnd("deleted", SearchCriteria.Op.NULL); - List pfVOs = m_usagePortForwardingRuleDao.search(sc, null); - if (pfVOs.size() > 1) { - s_logger.warn("More that one usage entry for port forwarding rule: " + id + " assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); - } - for (UsagePortForwardingRuleVO pfVO : pfVOs) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("deleting port forwarding rule: " + pfVO.getId() + " from account: " + pfVO.getAccountId()); - } - pfVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one - m_usagePortForwardingRuleDao.update(pfVO); - } - } - } - - private void createNetworkOfferingEvent(UsageEventVO event) { - - long zoneId = -1L; - - long vmId = event.getResourceId(); - long networkOfferingId = event.getOfferingId(); - - if (EventTypes.EVENT_NETWORK_OFFERING_CREATE.equals(event.getType()) || EventTypes.EVENT_NETWORK_OFFERING_ASSIGN.equals(event.getType())) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating networking offering: "+ networkOfferingId +" for Vm: " + vmId + " for account: " + event.getAccountId()); - } - zoneId = event.getZoneId(); - Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); - boolean isDefault = (event.getSize() == 1) ? true : false ; - UsageNetworkOfferingVO networkOffering = new UsageNetworkOfferingVO(zoneId, event.getAccountId(), acct.getDomainId(), vmId, networkOfferingId, isDefault, event.getCreateDate(), null); - m_usageNetworkOfferingDao.persist(networkOffering); - } else if (EventTypes.EVENT_NETWORK_OFFERING_DELETE.equals(event.getType()) || EventTypes.EVENT_NETWORK_OFFERING_REMOVE.equals(event.getType())) { - SearchCriteria sc = m_usageNetworkOfferingDao.createSearchCriteria(); - sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); - sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, vmId); - sc.addAnd("networkOfferingId", SearchCriteria.Op.EQ, networkOfferingId); - sc.addAnd("deleted", SearchCriteria.Op.NULL); - List noVOs = m_usageNetworkOfferingDao.search(sc, null); - if (noVOs.size() > 1) { - s_logger.warn("More that one usage entry for networking offering: "+ networkOfferingId +" for Vm: " + vmId+" assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); - } - for (UsageNetworkOfferingVO noVO : noVOs) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("deleting network offering: " + noVO.getNetworkOfferingId() + " from Vm: " + noVO.getVmInstanceId()); - } - noVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one - m_usageNetworkOfferingDao.update(noVO); - } - } - } - - private void createVPNUserEvent(UsageEventVO event) { - - long zoneId = 0L; - - long userId = event.getResourceId(); - - if (EventTypes.EVENT_VPN_USER_ADD.equals(event.getType())) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating VPN user: "+ userId + " for account: " + event.getAccountId()); - } - Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); - String userName = event.getResourceName(); - UsageVPNUserVO vpnUser = new UsageVPNUserVO(zoneId, event.getAccountId(), acct.getDomainId(), userId, userName, event.getCreateDate(), null); - m_usageVPNUserDao.persist(vpnUser); - } else if (EventTypes.EVENT_VPN_USER_REMOVE.equals(event.getType())) { - SearchCriteria sc = m_usageVPNUserDao.createSearchCriteria(); - sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); - sc.addAnd("userId", SearchCriteria.Op.EQ, userId); - sc.addAnd("deleted", SearchCriteria.Op.NULL); - List vuVOs = m_usageVPNUserDao.search(sc, null); - if (vuVOs.size() > 1) { - s_logger.warn("More that one usage entry for vpn user: "+ userId +" assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); - } - for (UsageVPNUserVO vuVO : vuVOs) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("deleting vpn user: " + vuVO.getUserId()); - } - vuVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one - m_usageVPNUserDao.update(vuVO); - } - } - } - - private void createSecurityGroupEvent(UsageEventVO event) { - - long zoneId = -1L; - - long vmId = event.getResourceId(); - long sgId = event.getOfferingId(); - - if (EventTypes.EVENT_SECURITY_GROUP_ASSIGN.equals(event.getType())) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Assigning : security group"+ sgId +" to Vm: " + vmId + " for account: " + event.getAccountId()); - } - zoneId = event.getZoneId(); - Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); - UsageSecurityGroupVO securityGroup = new UsageSecurityGroupVO(zoneId, event.getAccountId(), acct.getDomainId(), vmId, sgId,event.getCreateDate(), null); - m_usageSecurityGroupDao.persist(securityGroup); - } else if (EventTypes.EVENT_SECURITY_GROUP_REMOVE.equals(event.getType())) { - SearchCriteria sc = m_usageSecurityGroupDao.createSearchCriteria(); - sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); - sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, vmId); - sc.addAnd("securityGroupId", SearchCriteria.Op.EQ, sgId); - sc.addAnd("deleted", SearchCriteria.Op.NULL); - List sgVOs = m_usageSecurityGroupDao.search(sc, null); - if (sgVOs.size() > 1) { - s_logger.warn("More that one usage entry for security group: "+ sgId +" for Vm: " + vmId+" assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); - } - for (UsageSecurityGroupVO sgVO : sgVOs) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("deleting security group: " + sgVO.getSecurityGroupId() + " from Vm: " + sgVO.getVmInstanceId()); - } - sgVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one - m_usageSecurityGroupDao.update(sgVO); - } - } - } - - private class Heartbeat implements Runnable { - public void run() { - Transaction usageTxn = Transaction.open(Transaction.USAGE_DB); - try { - if(!m_heartbeatLock.lock(3)) { // 3 second timeout - if(s_logger.isTraceEnabled()) - s_logger.trace("Heartbeat lock is in use by others, returning true as someone else will take over the job if required"); - return; - } - - try { - // check for one-off jobs - UsageJobVO nextJob = m_usageJobDao.getNextImmediateJob(); - if (nextJob != null) { - if (m_hostname.equals(nextJob.getHost()) && (m_pid == nextJob.getPid().intValue())) { - updateJob(nextJob.getId(), null, null, null, UsageJobVO.JOB_SCHEDULED); - scheduleParse(); - } - } - - Long jobId = m_usageJobDao.checkHeartbeat(m_hostname, m_pid, m_aggregationDuration); - if (jobId != null) { - // if I'm taking over the job...see how long it's been since the last job, and if it's more than the - // aggregation range...do a one off job to catch up. However, only do this if we are more than half - // the aggregation range away from executing the next job - long now = System.currentTimeMillis(); - long timeToJob = m_jobExecTime.getTimeInMillis() - now; - long timeSinceJob = 0; - long aggregationDurationMillis = m_aggregationDuration * 60 * 1000; - long lastSuccess = m_usageJobDao.getLastJobSuccessDateMillis(); - if (lastSuccess > 0) { - timeSinceJob = now - lastSuccess; - } - - if ((timeSinceJob > 0) && (timeSinceJob > aggregationDurationMillis)) { - if (timeToJob > (aggregationDurationMillis/2)) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("it's been " + timeSinceJob + " ms since last usage job and " + timeToJob + " ms until next job, scheduling an immediate job to catch up (aggregation duration is " + m_aggregationDuration + " minutes)"); - } - scheduleParse(); - } - } - - boolean changeOwner = updateJob(jobId, m_hostname, Integer.valueOf(m_pid), new Date(), UsageJobVO.JOB_NOT_SCHEDULED); - if (changeOwner) { - deleteOneOffJobs(m_hostname, m_pid); - } - } - } finally { - m_heartbeatLock.unlock(); - } - } catch (Exception ex) { - s_logger.error("error in heartbeat", ex); - } finally { - usageTxn.close(); - } - } - - @DB - protected boolean updateJob(Long jobId, String hostname, Integer pid, Date heartbeat, int scheduled) { - boolean changeOwner = false; - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - - // take over the job, setting our hostname/pid/heartbeat time - UsageJobVO job = m_usageJobDao.lockRow(jobId, Boolean.TRUE); - if (!job.getHost().equals(hostname) || !job.getPid().equals(pid)) { - changeOwner = true; - } - - UsageJobVO jobForUpdate = m_usageJobDao.createForUpdate(); - if (hostname != null) { - jobForUpdate.setHost(hostname); - } - if (pid != null) { - jobForUpdate.setPid(pid); - } - if (heartbeat != null) { - jobForUpdate.setHeartbeat(heartbeat); - } - jobForUpdate.setScheduled(scheduled); - m_usageJobDao.update(job.getId(), jobForUpdate); - - txn.commit(); - } catch (Exception dbEx) { - txn.rollback(); - s_logger.error("error updating usage job", dbEx); - } - return changeOwner; - } - - @DB - protected void deleteOneOffJobs(String hostname, int pid) { - SearchCriteria sc = m_usageJobDao.createSearchCriteria(); - SearchCriteria ssc = m_usageJobDao.createSearchCriteria(); - ssc.addOr("host", SearchCriteria.Op.NEQ, hostname); - ssc.addOr("pid", SearchCriteria.Op.NEQ, pid); - sc.addAnd("host", SearchCriteria.Op.SC, ssc); - sc.addAnd("endMillis", SearchCriteria.Op.EQ, Long.valueOf(0)); - sc.addAnd("jobType", SearchCriteria.Op.EQ, Integer.valueOf(UsageJobVO.JOB_TYPE_SINGLE)); - sc.addAnd("scheduled", SearchCriteria.Op.EQ, Integer.valueOf(0)); - m_usageJobDao.expunge(sc); - } - } - - private class SanityCheck implements Runnable { - public void run() { - UsageSanityChecker usc = new UsageSanityChecker(); - try { - String errors = usc.runSanityCheck(); - if(errors.length() > 0){ - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USAGE_SANITY_RESULT, 0, new Long(0), "Usage Sanity Check failed", errors); - } else { - _alertMgr.clearAlert(AlertManager.ALERT_TYPE_USAGE_SANITY_RESULT, 0, 0); - } - } catch (SQLException e) { - s_logger.error("Error in sanity check", e); - } - } - } -} +package com.cloud.usage; + +import java.net.InetAddress; +import java.sql.SQLException; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.alert.AlertManager; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.event.EventTypes; +import com.cloud.event.UsageEventVO; +import com.cloud.event.dao.UsageEventDao; +import com.cloud.usage.dao.UsageDao; +import com.cloud.usage.dao.UsageIPAddressDao; +import com.cloud.usage.dao.UsageJobDao; +import com.cloud.usage.dao.UsageLoadBalancerPolicyDao; +import com.cloud.usage.dao.UsageNetworkDao; +import com.cloud.usage.dao.UsageNetworkOfferingDao; +import com.cloud.usage.dao.UsagePortForwardingRuleDao; +import com.cloud.usage.dao.UsageSecurityGroupDao; +import com.cloud.usage.dao.UsageStorageDao; +import com.cloud.usage.dao.UsageVMInstanceDao; +import com.cloud.usage.dao.UsageVPNUserDao; +import com.cloud.usage.dao.UsageVolumeDao; +import com.cloud.usage.parser.IPAddressUsageParser; +import com.cloud.usage.parser.LoadBalancerUsageParser; +import com.cloud.usage.parser.NetworkOfferingUsageParser; +import com.cloud.usage.parser.NetworkUsageParser; +import com.cloud.usage.parser.PortForwardingUsageParser; +import com.cloud.usage.parser.SecurityGroupUsageParser; +import com.cloud.usage.parser.StorageUsageParser; +import com.cloud.usage.parser.VMInstanceUsageParser; +import com.cloud.usage.parser.VPNUserUsageParser; +import com.cloud.usage.parser.VolumeUsageParser; +import com.cloud.user.Account; +import com.cloud.user.AccountVO; +import com.cloud.user.UserStatisticsVO; +import com.cloud.user.dao.AccountDao; +import com.cloud.user.dao.UserStatisticsDao; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.component.Inject; +import com.cloud.utils.concurrency.NamedThreadFactory; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.GlobalLock; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; + +@Local(value={UsageManager.class}) +public class UsageManagerImpl implements UsageManager, Runnable { + public static final Logger s_logger = Logger.getLogger(UsageManagerImpl.class.getName()); + + protected static final String DAILY = "DAILY"; + protected static final String WEEKLY = "WEEKLY"; + protected static final String MONTHLY = "MONTHLY"; + + private static final int HOURLY_TIME = 60; + private static final int DAILY_TIME = 60 * 24; + private static final int THREE_DAYS_IN_MINUTES = 60 * 24 * 3; + private static final int USAGE_AGGREGATION_RANGE_MIN = 10; + + private final ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); + private final AccountDao m_accountDao = _locator.getDao(AccountDao.class); + private final UserStatisticsDao m_userStatsDao = _locator.getDao(UserStatisticsDao.class); + private final UsageDao m_usageDao = _locator.getDao(UsageDao.class); + private final UsageVMInstanceDao m_usageInstanceDao = _locator.getDao(UsageVMInstanceDao.class); + private final UsageIPAddressDao m_usageIPAddressDao = _locator.getDao(UsageIPAddressDao.class); + private final UsageNetworkDao m_usageNetworkDao = _locator.getDao(UsageNetworkDao.class); + private final UsageVolumeDao m_usageVolumeDao = _locator.getDao(UsageVolumeDao.class); + private final UsageStorageDao m_usageStorageDao = _locator.getDao(UsageStorageDao.class); + private final UsageLoadBalancerPolicyDao m_usageLoadBalancerPolicyDao = _locator.getDao(UsageLoadBalancerPolicyDao.class); + private final UsagePortForwardingRuleDao m_usagePortForwardingRuleDao = _locator.getDao(UsagePortForwardingRuleDao.class); + private final UsageNetworkOfferingDao m_usageNetworkOfferingDao = _locator.getDao(UsageNetworkOfferingDao.class); + private final UsageVPNUserDao m_usageVPNUserDao = _locator.getDao(UsageVPNUserDao.class); + private final UsageSecurityGroupDao m_usageSecurityGroupDao = _locator.getDao(UsageSecurityGroupDao.class); + private final UsageJobDao m_usageJobDao = _locator.getDao(UsageJobDao.class); + @Inject protected AlertManager _alertMgr; + @Inject protected UsageEventDao _usageEventDao; + + private String m_version = null; + private String m_name = null; + private final Calendar m_jobExecTime = Calendar.getInstance(); + private int m_aggregationDuration = 0; + private int m_sanityCheckInterval = 0; + String m_hostname = null; + int m_pid = 0; + TimeZone m_usageTimezone = TimeZone.getTimeZone("GMT");; + private final GlobalLock m_heartbeatLock = GlobalLock.getInternLock("usage.job.heartbeat.check"); + + private final ScheduledExecutorService m_executor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("Usage-Job")); + private final ScheduledExecutorService m_heartbeatExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("Usage-HB")); + private final ScheduledExecutorService m_sanityExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("Usage-Sanity")); + private Future m_scheduledFuture = null; + private Future m_heartbeat = null; + private Future m_sanity = null; + + protected UsageManagerImpl() { + } + + private void mergeConfigs(Map dbParams, Map xmlParams) { + for (Map.Entry param : xmlParams.entrySet()) { + dbParams.put(param.getKey(), (String)param.getValue()); + } + } + + public boolean configure(String name, Map params) throws ConfigurationException { + final String run = "usage.vmops.pid"; + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Checking to see if " + run + " exists."); + } + + final Class c = UsageServer.class; + m_version = c.getPackage().getImplementationVersion(); + if (m_version == null) { + throw new CloudRuntimeException("Unable to find the implementation version of this usage server"); + } + + if (s_logger.isInfoEnabled()) { + s_logger.info("Implementation Version is " + m_version); + } + + m_name = name; + + ComponentLocator locator = ComponentLocator.getCurrentLocator(); + ConfigurationDao configDao = locator.getDao(ConfigurationDao.class); + if (configDao == null) { + s_logger.error("Unable to get the configuration dao."); + return false; + } + + Map configs = configDao.getConfiguration(params); + + if (params != null) { + mergeConfigs(configs, params); + } + + String execTime = configs.get("usage.stats.job.exec.time"); + String aggregationRange = configs.get("usage.stats.job.aggregation.range"); + String execTimeZone = configs.get("usage.execution.timezone"); + String aggreagationTimeZone = configs.get("usage.aggregation.timezone"); + String sanityCheckInterval = configs.get("usage.sanity.check.interval"); + if(sanityCheckInterval != null){ + m_sanityCheckInterval = Integer.parseInt(sanityCheckInterval); + } + + if(aggreagationTimeZone != null && !aggreagationTimeZone.isEmpty()){ + m_usageTimezone = TimeZone.getTimeZone(aggreagationTimeZone); + } + s_logger.debug("Usage stats aggregation time zone: "+aggreagationTimeZone); + + try { + if ((execTime == null) || (aggregationRange == null)) { + s_logger.error("missing configuration values for usage job, usage.stats.job.exec.time = " + execTime + ", usage.stats.job.aggregation.range = " + aggregationRange); + throw new ConfigurationException("Missing configuration values for usage job, usage.stats.job.exec.time = " + execTime + ", usage.stats.job.aggregation.range = " + aggregationRange); + } + String[] execTimeSegments = execTime.split(":"); + if (execTimeSegments.length != 2) { + s_logger.error("Unable to parse usage.stats.job.exec.time"); + throw new ConfigurationException("Unable to parse usage.stats.job.exec.time '" + execTime + "'"); + } + int hourOfDay = Integer.parseInt(execTimeSegments[0]); + int minutes = Integer.parseInt(execTimeSegments[1]); + m_jobExecTime.setTime(new Date()); + + m_jobExecTime.set(Calendar.HOUR_OF_DAY, hourOfDay); + m_jobExecTime.set(Calendar.MINUTE, minutes); + m_jobExecTime.set(Calendar.SECOND, 0); + m_jobExecTime.set(Calendar.MILLISECOND, 0); + if(execTimeZone != null && !execTimeZone.isEmpty()){ + m_jobExecTime.setTimeZone(TimeZone.getTimeZone(execTimeZone)); + } + + // if the hour to execute the job has already passed, roll the day forward to the next day + Date execDate = m_jobExecTime.getTime(); + if (execDate.before(new Date())) { + m_jobExecTime.roll(Calendar.DAY_OF_YEAR, true); + } + + s_logger.debug("Execution Time: "+execDate.toString()); + Date currentDate = new Date(System.currentTimeMillis()); + s_logger.debug("Current Time: "+currentDate.toString()); + + m_aggregationDuration = Integer.parseInt(aggregationRange); + if (m_aggregationDuration < USAGE_AGGREGATION_RANGE_MIN) { + s_logger.warn("Usage stats job aggregation range is to small, using the minimum value of " + USAGE_AGGREGATION_RANGE_MIN); + m_aggregationDuration = USAGE_AGGREGATION_RANGE_MIN; + } + m_hostname = InetAddress.getLocalHost().getHostName() + "/" + InetAddress.getLocalHost().getHostAddress(); + } catch (NumberFormatException ex) { + throw new ConfigurationException("Unable to parse usage.stats.job.exec.time '" + execTime + "' or usage.stats.job.aggregation.range '" + aggregationRange + "', please check configuration values"); + } catch (Exception e) { + s_logger.error("Unhandled exception configuring UsageManger", e); + throw new ConfigurationException("Unhandled exception configuring UsageManager " + e.toString()); + } + m_pid = Integer.parseInt(System.getProperty("pid")); + return true; + } + + public String getName() { + return m_name; + } + + public boolean start() { + if (s_logger.isInfoEnabled()) { + s_logger.info("Starting Usage Manager"); + } + + // use the configured exec time and aggregation duration for scheduling the job + m_scheduledFuture = m_executor.scheduleAtFixedRate(this, m_jobExecTime.getTimeInMillis() - System.currentTimeMillis(), m_aggregationDuration * 60 * 1000, TimeUnit.MILLISECONDS); + + m_heartbeat = m_heartbeatExecutor.scheduleAtFixedRate(new Heartbeat(), /* start in 15 seconds...*/15*1000, /* check database every minute*/60*1000, TimeUnit.MILLISECONDS); + + if(m_sanityCheckInterval > 0){ + m_sanity = m_sanityExecutor.scheduleAtFixedRate(new SanityCheck(), 1, m_sanityCheckInterval, TimeUnit.DAYS); + } + + Transaction usageTxn = Transaction.open(Transaction.USAGE_DB); + try { + if(m_heartbeatLock.lock(3)) { // 3 second timeout + try { + UsageJobVO job = m_usageJobDao.getLastJob(); + if (job == null) { + m_usageJobDao.createNewJob(m_hostname, m_pid, UsageJobVO.JOB_TYPE_RECURRING); + } + } finally { + m_heartbeatLock.unlock(); + } + } else { + if(s_logger.isTraceEnabled()) + s_logger.trace("Heartbeat lock is in use by others, returning true as someone else will take over the job if required"); + } + } finally { + usageTxn.close(); + } + + return true; + } + + public boolean stop() { + m_heartbeat.cancel(true); + m_scheduledFuture.cancel(true); + if(m_sanity != null){ + m_sanity.cancel(true); + } + return true; + } + + public void run() { + if (s_logger.isInfoEnabled()) { + s_logger.info("starting usage job..."); + } + + // how about we update the job exec time when the job starts??? + long execTime = m_jobExecTime.getTimeInMillis(); + long now = System.currentTimeMillis() + 2000; // 2 second buffer since jobs can run a little early (though usually just by milliseconds) + + if (execTime < now) { + // if exec time is in the past, calculate the next time the job will execute...if this is a one-off job that is a result + // of scheduleParse() then don't update the next exec time... + m_jobExecTime.add(Calendar.MINUTE, m_aggregationDuration); + } + + UsageJobVO job = m_usageJobDao.isOwner(m_hostname, m_pid); + if (job != null) { + // FIXME: we really need to do a better job of not missing any events...so we should some how + // keep track of the last time usage was run, then go from there... + // For executing the job, we treat hourly and daily as special time ranges, using the previous full hour or the previous + // full day. Otherwise we just subtract off the aggregation range from the current time and use that as start date with + // current time as end date. + Calendar cal = Calendar.getInstance(m_usageTimezone); + cal.setTime(new Date()); + long startDate = 0; + long endDate = 0; + if (m_aggregationDuration == DAILY_TIME) { + cal.roll(Calendar.DAY_OF_YEAR, false); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + startDate = cal.getTime().getTime(); + + cal.roll(Calendar.DAY_OF_YEAR, true); + cal.add(Calendar.MILLISECOND, -1); + endDate = cal.getTime().getTime(); + } else if (m_aggregationDuration == HOURLY_TIME) { + cal.roll(Calendar.HOUR_OF_DAY, false); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + startDate = cal.getTime().getTime(); + + cal.roll(Calendar.HOUR_OF_DAY, true); + cal.add(Calendar.MILLISECOND, -1); + endDate = cal.getTime().getTime(); + } else { + endDate = cal.getTime().getTime(); // current time + cal.add(Calendar.MINUTE, -1*m_aggregationDuration); + startDate = cal.getTime().getTime(); + } + + parse(job, startDate, endDate); + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Not owner of usage job, skipping..."); + } + } + if (s_logger.isInfoEnabled()) { + s_logger.info("usage job complete"); + } + } + + public void scheduleParse() { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Scheduling Usage job..."); + } + m_executor.schedule(this, 0, TimeUnit.MILLISECONDS); + } + + public void parse(UsageJobVO job, long startDateMillis, long endDateMillis) { + // TODO: Shouldn't we also allow parsing by the type of usage? + + boolean success = false; + long timeStart = System.currentTimeMillis(); + long deleteOldStatsTimeMillis = 0L; + try { + if ((endDateMillis == 0) || (endDateMillis > timeStart)) { + endDateMillis = timeStart; + } + + long lastSuccess = m_usageJobDao.getLastJobSuccessDateMillis(); + if (lastSuccess != 0) { + startDateMillis = lastSuccess+1; // 1 millisecond after + } + + if (startDateMillis >= endDateMillis) { + if (s_logger.isInfoEnabled()) { + s_logger.info("not parsing usage records since start time mills (" + startDateMillis + ") is on or after end time millis (" + endDateMillis + ")"); + } + + Transaction jobUpdateTxn = Transaction.open(Transaction.USAGE_DB); + try { + jobUpdateTxn.start(); + // everything seemed to work...set endDate as the last success date + m_usageJobDao.updateJobSuccess(job.getId(), startDateMillis, endDateMillis, System.currentTimeMillis() - timeStart, success); + + // create a new job if this is a recurring job + if (job.getJobType() == UsageJobVO.JOB_TYPE_RECURRING) { + m_usageJobDao.createNewJob(m_hostname, m_pid, UsageJobVO.JOB_TYPE_RECURRING); + } + jobUpdateTxn.commit(); + } finally { + jobUpdateTxn.close(); + } + + return; + } + deleteOldStatsTimeMillis = startDateMillis; + + Date startDate = new Date(startDateMillis); + Date endDate = new Date(endDateMillis); + if (s_logger.isInfoEnabled()) { + s_logger.info("Parsing usage records between " + startDate + " and " + endDate); + } + + List accounts = null; + List userStats = null; + Map networkStats = null; + Transaction userTxn = Transaction.open(Transaction.CLOUD_DB); + try { + Long limit = Long.valueOf(500); + Long offset = Long.valueOf(0); + Long lastAccountId = m_usageDao.getLastAccountId(); + if (lastAccountId == null) { + lastAccountId = Long.valueOf(0); + } + + do { + Filter filter = new Filter(AccountVO.class, "id", true, offset, limit); + + accounts = m_accountDao.findActiveAccounts(lastAccountId, filter); + + if ((accounts != null) && !accounts.isEmpty()) { + // now update the accounts in the cloud_usage db + m_usageDao.updateAccounts(accounts); + } + offset = new Long(offset.longValue() + limit.longValue()); + } while ((accounts != null) && !accounts.isEmpty()); + + // reset offset + offset = Long.valueOf(0); + + do { + Filter filter = new Filter(AccountVO.class, "id", true, offset, limit); + + accounts = m_accountDao.findRecentlyDeletedAccounts(lastAccountId, startDate, filter); + + if ((accounts != null) && !accounts.isEmpty()) { + // now update the accounts in the cloud_usage db + m_usageDao.updateAccounts(accounts); + } + offset = new Long(offset.longValue() + limit.longValue()); + } while ((accounts != null) && !accounts.isEmpty()); + + // reset offset + offset = Long.valueOf(0); + + do { + Filter filter = new Filter(AccountVO.class, "id", true, offset, limit); + + accounts = m_accountDao.findNewAccounts(lastAccountId, filter); + + if ((accounts != null) && !accounts.isEmpty()) { + // now copy the accounts to cloud_usage db + m_usageDao.saveAccounts(accounts); + } + offset = new Long(offset.longValue() + limit.longValue()); + } while ((accounts != null) && !accounts.isEmpty()); + + // reset offset + offset = Long.valueOf(0); + + // get all the user stats to create usage records for the network usage + Long lastUserStatsId = m_usageDao.getLastUserStatsId(); + if (lastUserStatsId == null) { + lastUserStatsId = Long.valueOf(0); + } + + SearchCriteria sc2 = m_userStatsDao.createSearchCriteria(); + sc2.addAnd("id", SearchCriteria.Op.LTEQ, lastUserStatsId); + do { + Filter filter = new Filter(UserStatisticsVO.class, "id", true, offset, limit); + + userStats = m_userStatsDao.search(sc2, filter); + + if ((userStats != null) && !userStats.isEmpty()) { + // now copy the accounts to cloud_usage db + m_usageDao.updateUserStats(userStats); + } + offset = new Long(offset.longValue() + limit.longValue()); + } while ((userStats != null) && !userStats.isEmpty()); + + // reset offset + offset = Long.valueOf(0); + + sc2 = m_userStatsDao.createSearchCriteria(); + sc2.addAnd("id", SearchCriteria.Op.GT, lastUserStatsId); + do { + Filter filter = new Filter(UserStatisticsVO.class, "id", true, offset, limit); + + userStats = m_userStatsDao.search(sc2, filter); + + if ((userStats != null) && !userStats.isEmpty()) { + // now copy the accounts to cloud_usage db + m_usageDao.saveUserStats(userStats); + } + offset = new Long(offset.longValue() + limit.longValue()); + } while ((userStats != null) && !userStats.isEmpty()); + } finally { + userTxn.close(); + } + + // TODO: Fetch a maximum number of events and process them before moving on to the next range of events + + // - get a list of the latest events + // - insert the latest events into the usage.events table + List events = _usageEventDao.getRecentEvents(new Date(endDateMillis)); + + + Transaction usageTxn = Transaction.open(Transaction.USAGE_DB); + try { + usageTxn.start(); + + // make sure start date is before all of our un-processed events (the events are ordered oldest + // to newest, so just test against the first event) + if ((events != null) && (events.size() > 0)) { + Date oldestEventDate = events.get(0).getCreateDate(); + if (oldestEventDate.getTime() < startDateMillis) { + startDateMillis = oldestEventDate.getTime(); + startDate = new Date(startDateMillis); + } + + // - loop over the list of events and create entries in the helper tables + // - create the usage records using the parse methods below + for (UsageEventVO event : events) { + event.setProcessed(true); + _usageEventDao.update(event.getId(), event); + createHelperRecord(event); + } + } + + // TODO: Fetch a maximum number of user stats and process them before moving on to the next range of user stats + + // get user stats in order to compute network usage + networkStats = m_usageNetworkDao.getRecentNetworkStats(); + + Calendar recentlyDeletedCal = Calendar.getInstance(m_usageTimezone); + recentlyDeletedCal.setTimeInMillis(startDateMillis); + recentlyDeletedCal.add(Calendar.MINUTE, -1*THREE_DAYS_IN_MINUTES); + Date recentlyDeletedDate = recentlyDeletedCal.getTime(); + + // Keep track of user stats for an account, across all of its public IPs + Map aggregatedStats = new HashMap(); + int startIndex = 0; + do { + userStats = m_userStatsDao.listActiveAndRecentlyDeleted(recentlyDeletedDate, startIndex, 500); + + if (userStats != null) { + for (UserStatisticsVO userStat : userStats) { + if(userStat.getDeviceId() != null){ + String hostKey = userStat.getDataCenterId() + "-" + userStat.getAccountId()+"-Host-" + userStat.getDeviceId(); + UserStatisticsVO hostAggregatedStat = aggregatedStats.get(hostKey); + if (hostAggregatedStat == null) { + hostAggregatedStat = new UserStatisticsVO(userStat.getAccountId(), userStat.getDataCenterId(), userStat.getPublicIpAddress(), + userStat.getDeviceId(), userStat.getDeviceType(), userStat.getNetworkId()); + } + + hostAggregatedStat.setAggBytesSent(hostAggregatedStat.getAggBytesSent() + userStat.getAggBytesSent()); + hostAggregatedStat.setAggBytesReceived(hostAggregatedStat.getAggBytesReceived() + userStat.getAggBytesReceived()); + aggregatedStats.put(hostKey, hostAggregatedStat); + } + } + } + startIndex += 500; + } while ((userStats != null) && !userStats.isEmpty()); + + // loop over the user stats, create delta entries in the usage_network helper table + int numAcctsProcessed = 0; + for (String key : aggregatedStats.keySet()) { + UsageNetworkVO currentNetworkStats = null; + if (networkStats != null) { + currentNetworkStats = networkStats.get(key); + } + + createNetworkHelperEntry(aggregatedStats.get(key), currentNetworkStats, endDateMillis); + numAcctsProcessed++; + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("created network stats helper entries for " + numAcctsProcessed + " accts"); + } + + // commit the helper records, then start a new transaction + usageTxn.commit(); + usageTxn.start(); + + boolean parsed = false; + numAcctsProcessed = 0; + + Date currentStartDate = startDate; + Date currentEndDate = endDate; + Date tempDate = endDate; + + Calendar aggregateCal = Calendar.getInstance(m_usageTimezone); + + while ((tempDate.after(startDate)) && ((tempDate.getTime() - startDate.getTime()) > 60000)){ + currentEndDate = tempDate; + aggregateCal.setTime(tempDate); + aggregateCal.add(Calendar.MINUTE, -m_aggregationDuration); + tempDate = aggregateCal.getTime(); + } + + while (!currentEndDate.after(endDate) || (currentEndDate.getTime() -endDate.getTime() < 60000)){ + Long offset = Long.valueOf(0); + Long limit = Long.valueOf(500); + + do { + Filter filter = new Filter(AccountVO.class, "id", true, offset, limit); + accounts = m_accountDao.listAll(filter); + if ((accounts != null) && !accounts.isEmpty()) { + for (AccountVO account : accounts) { + parsed = parseHelperTables(account, currentStartDate, currentEndDate); + numAcctsProcessed++; + } + } + offset = new Long(offset.longValue() + limit.longValue()); + } while ((accounts != null) && !accounts.isEmpty()); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("processed VM/Network Usage for " + numAcctsProcessed + " ACTIVE accts"); + } + numAcctsProcessed = 0; + + // reset offset + offset = Long.valueOf(0); + + do { + Filter filter = new Filter(AccountVO.class, "id", true, offset, limit); + + accounts = m_accountDao.findRecentlyDeletedAccounts(null, recentlyDeletedDate, filter); + + if ((accounts != null) && !accounts.isEmpty()) { + for (AccountVO account : accounts) { + parsed = parseHelperTables(account, currentStartDate, currentEndDate); + List publicTemplates = m_usageDao.listPublicTemplatesByAccount(account.getId()); + for(Long templateId : publicTemplates){ + //mark public templates owned by deleted accounts as deleted + List storageVOs = m_usageStorageDao.listById(account.getId(), templateId, StorageTypes.TEMPLATE); + if (storageVOs.size() > 1) { + s_logger.warn("More that one usage entry for storage: " + templateId + " assigned to account: " + account.getId() + "; marking them all as deleted..."); + } + for (UsageStorageVO storageVO : storageVOs) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("deleting template: " + storageVO.getId() + " from account: " + storageVO.getAccountId()); + } + storageVO.setDeleted(account.getRemoved()); + m_usageStorageDao.update(storageVO); + } + } + numAcctsProcessed++; + } + } + offset = new Long(offset.longValue() + limit.longValue()); + } while ((accounts != null) && !accounts.isEmpty()); + + currentStartDate = new Date(currentEndDate.getTime() + 1); + aggregateCal.setTime(currentEndDate); + aggregateCal.add(Calendar.MINUTE, m_aggregationDuration); + currentEndDate = aggregateCal.getTime(); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("processed Usage for " + numAcctsProcessed + " RECENTLY DELETED accts"); + } + + // FIXME: we don't break the above loop if something fails to parse, so it gets reset every account, + // do we want to break out of processing accounts and rollback if there are errors? + if (!parsed) { + usageTxn.rollback(); + } else { + success = true; + } + } catch (Exception ex) { + s_logger.error("Exception in usage manager", ex); + usageTxn.rollback(); + } finally { + // everything seemed to work...set endDate as the last success date + m_usageJobDao.updateJobSuccess(job.getId(), startDateMillis, endDateMillis, System.currentTimeMillis() - timeStart, success); + + // create a new job if this is a recurring job + if (job.getJobType() == UsageJobVO.JOB_TYPE_RECURRING) { + m_usageJobDao.createNewJob(m_hostname, m_pid, UsageJobVO.JOB_TYPE_RECURRING); + } + usageTxn.commit(); + usageTxn.close(); + + // switch back to CLOUD_DB + Transaction swap = Transaction.open(Transaction.CLOUD_DB); + if(!success){ + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USAGE_SERVER_RESULT, 0, new Long(0), "Usage job failed. Job id: "+job.getId(), "Usage job failed. Job id: "+job.getId()); + } else { + _alertMgr.clearAlert(AlertManager.ALERT_TYPE_USAGE_SERVER_RESULT, 0, 0); + } + swap.close(); + + } + } catch (Exception e) { + s_logger.error("Usage Manager error", e); + } + } + + private boolean parseHelperTables(AccountVO account, Date currentStartDate, Date currentEndDate){ + boolean parsed = false; + + parsed = VMInstanceUsageParser.parse(account, currentStartDate, currentEndDate); + if (s_logger.isDebugEnabled()) { + if (!parsed) { + s_logger.debug("vm usage instances successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); + } + } + + parsed = NetworkUsageParser.parse(account, currentStartDate, currentEndDate); + if (s_logger.isDebugEnabled()) { + if (!parsed) { + s_logger.debug("network usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); + } + } + + parsed = VolumeUsageParser.parse(account, currentStartDate, currentEndDate); + if (s_logger.isDebugEnabled()) { + if (!parsed) { + s_logger.debug("volume usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); + } + } + + parsed = StorageUsageParser.parse(account, currentStartDate, currentEndDate); + if (s_logger.isDebugEnabled()) { + if (!parsed) { + s_logger.debug("storage usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); + } + } + + parsed = SecurityGroupUsageParser.parse(account, currentStartDate, currentEndDate); + if (s_logger.isDebugEnabled()) { + if (!parsed) { + s_logger.debug("Security Group usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); + } + } + + parsed = LoadBalancerUsageParser.parse(account, currentStartDate, currentEndDate); + if (s_logger.isDebugEnabled()) { + if (!parsed) { + s_logger.debug("load balancer usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); + } + } + + parsed = PortForwardingUsageParser.parse(account, currentStartDate, currentEndDate); + if (s_logger.isDebugEnabled()) { + if (!parsed) { + s_logger.debug("port forwarding usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); + } + } + + parsed = NetworkOfferingUsageParser.parse(account, currentStartDate, currentEndDate); + if (s_logger.isDebugEnabled()) { + if (!parsed) { + s_logger.debug("network offering usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); + } + } + + parsed = IPAddressUsageParser.parse(account, currentStartDate, currentEndDate); + if (s_logger.isDebugEnabled()) { + if (!parsed) { + s_logger.debug("IPAddress usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); + } + } + parsed = VPNUserUsageParser.parse(account, currentStartDate, currentEndDate); + if (s_logger.isDebugEnabled()) { + if (!parsed) { + s_logger.debug("VPN user usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); + } + } + return parsed; + } + + private void createHelperRecord(UsageEventVO event) { + String eventType = event.getType(); + if (isVMEvent(eventType)) { + createVMHelperEvent(event); + } else if (isIPEvent(eventType)) { + createIPHelperEvent(event); + } else if (isVolumeEvent(eventType)) { + createVolumeHelperEvent(event); + } else if (isTemplateEvent(eventType)) { + createTemplateHelperEvent(event); + } else if (isISOEvent(eventType)) { + createISOHelperEvent(event); + } else if (isSnapshotEvent(eventType)) { + createSnapshotHelperEvent(event); + } else if (isLoadBalancerEvent(eventType)) { + createLoadBalancerHelperEvent(event); + } else if (isPortForwardingEvent(eventType)) { + createPortForwardingHelperEvent(event); + } else if (isNetworkOfferingEvent(eventType)) { + createNetworkOfferingEvent(event); + } else if (isVPNUserEvent(eventType)) { + createVPNUserEvent(event); + } else if (isSecurityGroupEvent(eventType)) { + createSecurityGroupEvent(event); + } + } + + private boolean isVMEvent(String eventType) { + if (eventType == null) return false; + return eventType.startsWith("VM."); + } + + private boolean isIPEvent(String eventType) { + if (eventType == null) return false; + return eventType.startsWith("NET.IP"); + } + + private boolean isVolumeEvent(String eventType) { + if (eventType == null) return false; + return (eventType.equals(EventTypes.EVENT_VOLUME_CREATE) || + eventType.equals(EventTypes.EVENT_VOLUME_DELETE)); + } + + private boolean isTemplateEvent(String eventType) { + if (eventType == null) return false; + return (eventType.equals(EventTypes.EVENT_TEMPLATE_CREATE) || + eventType.equals(EventTypes.EVENT_TEMPLATE_COPY) || + eventType.equals(EventTypes.EVENT_TEMPLATE_DELETE)); + } + + private boolean isISOEvent(String eventType) { + if (eventType == null) return false; + return (eventType.equals(EventTypes.EVENT_ISO_CREATE) || + eventType.equals(EventTypes.EVENT_ISO_COPY) || + eventType.equals(EventTypes.EVENT_ISO_DELETE)); + } + + private boolean isSnapshotEvent(String eventType) { + if (eventType == null) return false; + return (eventType.equals(EventTypes.EVENT_SNAPSHOT_CREATE) || + eventType.equals(EventTypes.EVENT_SNAPSHOT_DELETE)); + } + + private boolean isLoadBalancerEvent(String eventType) { + if (eventType == null) return false; + return eventType.startsWith("LB."); + } + + private boolean isPortForwardingEvent(String eventType) { + if (eventType == null) return false; + return eventType.startsWith("NET.RULE"); + } + + private boolean isNetworkOfferingEvent(String eventType) { + if (eventType == null) return false; + return (eventType.equals(EventTypes.EVENT_NETWORK_OFFERING_CREATE) || + eventType.equals(EventTypes.EVENT_NETWORK_OFFERING_DELETE) || + eventType.equals(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN) || + eventType.equals(EventTypes.EVENT_NETWORK_OFFERING_REMOVE)); + } + + private boolean isVPNUserEvent(String eventType) { + if (eventType == null) return false; + return eventType.startsWith("VPN.USER"); + } + + private boolean isSecurityGroupEvent(String eventType) { + if (eventType == null) return false; + return (eventType.equals(EventTypes.EVENT_SECURITY_GROUP_ASSIGN) || + eventType.equals(EventTypes.EVENT_SECURITY_GROUP_REMOVE)); + } + + private void createVMHelperEvent(UsageEventVO event) { + + // One record for handling VM.START and VM.STOP + // One record for handling VM.CREATE and VM.DESTROY + // VM events have the parameter "id=" + long vmId = event.getResourceId(); + Long soId = event.getOfferingId();; // service offering id + long zoneId = event.getZoneId(); + String vmName = event.getResourceName(); + + if (EventTypes.EVENT_VM_START.equals(event.getType())) { + // create a new usage_vm_instance row for this VM + try { + + SearchCriteria sc = m_usageInstanceDao.createSearchCriteria(); + sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, Long.valueOf(vmId)); + sc.addAnd("endDate", SearchCriteria.Op.NULL); + sc.addAnd("usageType", SearchCriteria.Op.EQ, UsageTypes.RUNNING_VM); + List usageInstances = m_usageInstanceDao.search(sc, null); + if (usageInstances != null) { + if (usageInstances.size() > 0) { + s_logger.error("found entries for a vm running with id: " + vmId + ", which are not stopped. Ending them all..."); + for (UsageVMInstanceVO usageInstance : usageInstances) { + usageInstance.setEndDate(event.getCreateDate()); + m_usageInstanceDao.update(usageInstance); + } + } + } + + sc = m_usageInstanceDao.createSearchCriteria(); + sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, Long.valueOf(vmId)); + sc.addAnd("endDate", SearchCriteria.Op.NULL); + sc.addAnd("usageType", SearchCriteria.Op.EQ, UsageTypes.ALLOCATED_VM); + usageInstances = m_usageInstanceDao.search(sc, null); + if (usageInstances == null || (usageInstances.size() == 0)) { + s_logger.error("Cannot find allocated vm entry for a vm running with id: " + vmId); + } + + Long templateId = event.getTemplateId(); + String hypervisorType = event.getResourceType(); + + // add this VM to the usage helper table + UsageVMInstanceVO usageInstanceNew = new UsageVMInstanceVO(UsageTypes.RUNNING_VM, zoneId, event.getAccountId(), vmId, vmName, + soId, templateId, hypervisorType, event.getCreateDate(), null); + m_usageInstanceDao.persist(usageInstanceNew); + } catch (Exception ex) { + s_logger.error("Error saving usage instance for vm: " + vmId, ex); + } + } else if (EventTypes.EVENT_VM_STOP.equals(event.getType())) { + // find the latest usage_vm_instance row, update the stop date (should be null) to the event date + // FIXME: search criteria needs to have some kind of type information so we distinguish between START/STOP and CREATE/DESTROY + SearchCriteria sc = m_usageInstanceDao.createSearchCriteria(); + sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, Long.valueOf(vmId)); + sc.addAnd("endDate", SearchCriteria.Op.NULL); + sc.addAnd("usageType", SearchCriteria.Op.EQ, UsageTypes.RUNNING_VM); + List usageInstances = m_usageInstanceDao.search(sc, null); + if (usageInstances != null) { + if (usageInstances.size() > 1) { + s_logger.warn("found multiple entries for a vm running with id: " + vmId + ", ending them all..."); + } + for (UsageVMInstanceVO usageInstance : usageInstances) { + usageInstance.setEndDate(event.getCreateDate()); + // TODO: UsageVMInstanceVO should have an ID field and we should do updates through that field since we are really + // updating one row at a time here + m_usageInstanceDao.update(usageInstance); + } + } + } else if (EventTypes.EVENT_VM_CREATE.equals(event.getType())) { + try { + Long templateId = event.getTemplateId(); + String hypervisorType = event.getResourceType(); + // add this VM to the usage helper table + UsageVMInstanceVO usageInstanceNew = new UsageVMInstanceVO(UsageTypes.ALLOCATED_VM, zoneId, event.getAccountId(), vmId, vmName, + soId, templateId, hypervisorType, event.getCreateDate(), null); + m_usageInstanceDao.persist(usageInstanceNew); + } catch (Exception ex) { + s_logger.error("Error saving usage instance for vm: " + vmId, ex); + } + } else if (EventTypes.EVENT_VM_DESTROY.equals(event.getType())) { + SearchCriteria sc = m_usageInstanceDao.createSearchCriteria(); + sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, Long.valueOf(vmId)); + sc.addAnd("endDate", SearchCriteria.Op.NULL); + sc.addAnd("usageType", SearchCriteria.Op.EQ, UsageTypes.ALLOCATED_VM); + List usageInstances = m_usageInstanceDao.search(sc, null); + if (usageInstances != null) { + if (usageInstances.size() > 1) { + s_logger.warn("found multiple entries for a vm allocated with id: " + vmId + ", detroying them all..."); + } + for (UsageVMInstanceVO usageInstance : usageInstances) { + usageInstance.setEndDate(event.getCreateDate()); + m_usageInstanceDao.update(usageInstance); + } + } + } else if (EventTypes.EVENT_VM_UPGRADE.equals(event.getType())) { + SearchCriteria sc = m_usageInstanceDao.createSearchCriteria(); + sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, Long.valueOf(vmId)); + sc.addAnd("endDate", SearchCriteria.Op.NULL); + sc.addAnd("usageType", SearchCriteria.Op.EQ, UsageTypes.ALLOCATED_VM); + List usageInstances = m_usageInstanceDao.search(sc, null); + if (usageInstances != null) { + if (usageInstances.size() > 1) { + s_logger.warn("found multiple entries for a vm allocated with id: " + vmId + ", updating end_date for all of them..."); + } + for (UsageVMInstanceVO usageInstance : usageInstances) { + usageInstance.setEndDate(event.getCreateDate()); + m_usageInstanceDao.update(usageInstance); + } + } + + Long templateId = event.getTemplateId(); + String hypervisorType = event.getResourceType(); + // add this VM to the usage helper table + UsageVMInstanceVO usageInstanceNew = new UsageVMInstanceVO(UsageTypes.ALLOCATED_VM, zoneId, event.getAccountId(), vmId, vmName, + soId, templateId, hypervisorType, event.getCreateDate(), null); + m_usageInstanceDao.persist(usageInstanceNew); + } + } + + private void createNetworkHelperEntry(UserStatisticsVO userStat, UsageNetworkVO usageNetworkStats, long timestamp) { + long currentAccountedBytesSent = 0L; + long currentAccountedBytesReceived = 0L; + if (usageNetworkStats != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("getting current accounted bytes for... accountId: " + usageNetworkStats.getAccountId() + " in zone: " + userStat.getDataCenterId() + "; abr: " + usageNetworkStats.getAggBytesReceived() + + "; abs: " + usageNetworkStats.getAggBytesSent()); + } + currentAccountedBytesSent = usageNetworkStats.getAggBytesSent(); + currentAccountedBytesReceived = usageNetworkStats.getAggBytesReceived(); + } + long bytesSent = userStat.getAggBytesSent() - currentAccountedBytesSent; + long bytesReceived = userStat.getAggBytesReceived() - currentAccountedBytesReceived; + + if (bytesSent < 0) { + s_logger.warn("Calculated negative value for bytes sent: " + bytesSent + ", user stats say: " + userStat.getAggBytesSent() + ", previous network usage was: " + currentAccountedBytesSent); + bytesSent = 0; + } + if (bytesReceived < 0) { + s_logger.warn("Calculated negative value for bytes received: " + bytesReceived + ", user stats say: " + userStat.getAggBytesReceived() + ", previous network usage was: " + currentAccountedBytesReceived); + bytesReceived = 0; + } + + long hostId = 0; + + if(userStat.getDeviceId() != null){ + hostId = userStat.getDeviceId(); + } + + UsageNetworkVO usageNetworkVO = new UsageNetworkVO(userStat.getAccountId(), userStat.getDataCenterId(), hostId, userStat.getDeviceType(), userStat.getNetworkId(), bytesSent, bytesReceived, + userStat.getAggBytesReceived(), userStat.getAggBytesSent(), timestamp); + if (s_logger.isDebugEnabled()) { + s_logger.debug("creating networkHelperEntry... accountId: " + userStat.getAccountId() + " in zone: " + userStat.getDataCenterId() + "; abr: " + userStat.getAggBytesReceived() + "; abs: " + userStat.getAggBytesSent() + + "; curABS: " + currentAccountedBytesSent + "; curABR: " + currentAccountedBytesReceived + "; ubs: " + bytesSent + "; ubr: " + bytesReceived); + } + m_usageNetworkDao.persist(usageNetworkVO); + } + + private void createIPHelperEvent(UsageEventVO event) { + + String ipAddress = event.getResourceName(); + + if (EventTypes.EVENT_NET_IP_ASSIGN.equals(event.getType())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("assigning ip address: " + ipAddress + " to account: " + event.getAccountId()); + } + Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); + long zoneId = event.getZoneId(); + long id = event.getResourceId(); + long sourceNat = event.getSize(); + boolean isSourceNat = (sourceNat == 1) ? true : false ; + boolean isSystem = (event.getTemplateId() == null || event.getTemplateId() == 0) ? false : true ; + UsageIPAddressVO ipAddressVO = new UsageIPAddressVO(id, event.getAccountId(), acct.getDomainId(), zoneId, ipAddress, isSourceNat, isSystem, event.getCreateDate(), null); + m_usageIPAddressDao.persist(ipAddressVO); + } else if (EventTypes.EVENT_NET_IP_RELEASE.equals(event.getType())) { + SearchCriteria sc = m_usageIPAddressDao.createSearchCriteria(); + sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); + sc.addAnd("address", SearchCriteria.Op.EQ, ipAddress); + sc.addAnd("released", SearchCriteria.Op.NULL); + List ipAddressVOs = m_usageIPAddressDao.search(sc, null); + if (ipAddressVOs.size() > 1) { + s_logger.warn("More that one usage entry for ip address: " + ipAddress + " assigned to account: " + event.getAccountId() + "; marking them all as released..."); + } + for (UsageIPAddressVO ipAddressVO : ipAddressVOs) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("releasing ip address: " + ipAddressVO.getAddress() + " from account: " + ipAddressVO.getAccountId()); + } + ipAddressVO.setReleased(event.getCreateDate()); // there really shouldn't be more than one + m_usageIPAddressDao.update(ipAddressVO); + } + } + } + + private void createVolumeHelperEvent(UsageEventVO event) { + + Long doId = -1L; + long zoneId = -1L; + Long templateId = -1L; + long size = -1L; + + long volId = event.getResourceId(); + if (EventTypes.EVENT_VOLUME_CREATE.equals(event.getType())) { + doId = event.getOfferingId(); + zoneId = event.getZoneId(); + templateId = event.getTemplateId(); + size = event.getSize(); + } + + if (EventTypes.EVENT_VOLUME_CREATE.equals(event.getType())) { + SearchCriteria sc = m_usageVolumeDao.createSearchCriteria(); + sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); + sc.addAnd("id", SearchCriteria.Op.EQ, volId); + sc.addAnd("deleted", SearchCriteria.Op.NULL); + List volumesVOs = m_usageVolumeDao.search(sc, null); + if (volumesVOs.size() > 0) { + //This is a safeguard to avoid double counting of volumes. + s_logger.error("Found duplicate usage entry for volume: " + volId + " assigned to account: " + event.getAccountId() + "; marking as deleted..."); + } + for (UsageVolumeVO volumesVO : volumesVOs) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("deleting volume: " + volumesVO.getId() + " from account: " + volumesVO.getAccountId()); + } + volumesVO.setDeleted(event.getCreateDate()); + m_usageVolumeDao.update(volumesVO); + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("create volume with id : " + volId + " for account: " + event.getAccountId()); + } + Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); + UsageVolumeVO volumeVO = new UsageVolumeVO(volId, zoneId, event.getAccountId(), acct.getDomainId(), doId, templateId, size, event.getCreateDate(), null); + m_usageVolumeDao.persist(volumeVO); + } else if (EventTypes.EVENT_VOLUME_DELETE.equals(event.getType())) { + SearchCriteria sc = m_usageVolumeDao.createSearchCriteria(); + sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); + sc.addAnd("id", SearchCriteria.Op.EQ, volId); + sc.addAnd("deleted", SearchCriteria.Op.NULL); + List volumesVOs = m_usageVolumeDao.search(sc, null); + if (volumesVOs.size() > 1) { + s_logger.warn("More that one usage entry for volume: " + volId + " assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); + } + for (UsageVolumeVO volumesVO : volumesVOs) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("deleting volume: " + volumesVO.getId() + " from account: " + volumesVO.getAccountId()); + } + volumesVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one + m_usageVolumeDao.update(volumesVO); + } + } + } + + private void createTemplateHelperEvent(UsageEventVO event) { + + long templateId = -1L; + long zoneId = -1L; + long templateSize = -1L; + + templateId = event.getResourceId(); + zoneId = event.getZoneId(); + if (EventTypes.EVENT_TEMPLATE_CREATE.equals(event.getType()) || EventTypes.EVENT_TEMPLATE_COPY.equals(event.getType())) { + templateSize = event.getSize(); + if(templateSize < 1){ + s_logger.error("Incorrect size for template with Id "+templateId); + return; + } + if(zoneId == -1L){ + s_logger.error("Incorrect zoneId for template with Id "+templateId); + return; + } + } + + if (EventTypes.EVENT_TEMPLATE_CREATE.equals(event.getType()) || EventTypes.EVENT_TEMPLATE_COPY.equals(event.getType())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("create template with id : " + templateId + " for account: " + event.getAccountId()); + } + List storageVOs = m_usageStorageDao.listByIdAndZone(event.getAccountId(), templateId, StorageTypes.TEMPLATE, zoneId); + if (storageVOs.size() > 0) { + s_logger.warn("Usage entry for Template: " + templateId + " assigned to account: " + event.getAccountId() + "already exists in zone "+zoneId); + return; + } + Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); + UsageStorageVO storageVO = new UsageStorageVO(templateId, zoneId, event.getAccountId(), acct.getDomainId(), StorageTypes.TEMPLATE, event.getTemplateId(), + templateSize, event.getCreateDate(), null); + m_usageStorageDao.persist(storageVO); + } else if (EventTypes.EVENT_TEMPLATE_DELETE.equals(event.getType())) { + List storageVOs; + if(zoneId != -1L){ + storageVOs = m_usageStorageDao.listByIdAndZone(event.getAccountId(), templateId, StorageTypes.TEMPLATE, zoneId); + } else { + storageVOs = m_usageStorageDao.listById(event.getAccountId(), templateId, StorageTypes.TEMPLATE); + } + if (storageVOs.size() > 1) { + s_logger.warn("More that one usage entry for storage: " + templateId + " assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); + } + for (UsageStorageVO storageVO : storageVOs) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("deleting template: " + storageVO.getId() + " from account: " + storageVO.getAccountId()); + } + storageVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one + m_usageStorageDao.update(storageVO); + } + } + } + + private void createISOHelperEvent(UsageEventVO event) { + long isoSize = -1L; + + long isoId = event.getResourceId(); + long zoneId = event.getZoneId(); + if (EventTypes.EVENT_ISO_CREATE.equals(event.getType()) || EventTypes.EVENT_ISO_COPY.equals(event.getType())) { + isoSize = event.getSize(); + } + + if (EventTypes.EVENT_ISO_CREATE.equals(event.getType()) || EventTypes.EVENT_ISO_COPY.equals(event.getType())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("create iso with id : " + isoId + " for account: " + event.getAccountId()); + } + List storageVOs = m_usageStorageDao.listByIdAndZone(event.getAccountId(), isoId, StorageTypes.ISO, zoneId); + if (storageVOs.size() > 0) { + s_logger.warn("Usage entry for ISO: " + isoId + " assigned to account: " + event.getAccountId() + "already exists in zone "+zoneId); + return; + } + Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); + UsageStorageVO storageVO = new UsageStorageVO( isoId, zoneId, event.getAccountId(), acct.getDomainId(), StorageTypes.ISO, null, + isoSize, event.getCreateDate(), null); + m_usageStorageDao.persist(storageVO); + } else if (EventTypes.EVENT_ISO_DELETE.equals(event.getType())) { + List storageVOs; + if(zoneId != -1L){ + storageVOs = m_usageStorageDao.listByIdAndZone(event.getAccountId(), isoId, StorageTypes.ISO, zoneId); + } else { + storageVOs = m_usageStorageDao.listById(event.getAccountId(), isoId, StorageTypes.ISO); + } + + if (storageVOs.size() > 1) { + s_logger.warn("More that one usage entry for storage: " + isoId + " assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); + } + for (UsageStorageVO storageVO : storageVOs) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("deleting iso: " + storageVO.getId() + " from account: " + storageVO.getAccountId()); + } + storageVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one + m_usageStorageDao.update(storageVO); + } + } + } + + private void createSnapshotHelperEvent(UsageEventVO event) { + long snapSize = -1L; + long zoneId = -1L; + + long snapId = event.getResourceId(); + if (EventTypes.EVENT_SNAPSHOT_CREATE.equals(event.getType())) { + snapSize = event.getSize(); + zoneId = event.getZoneId(); + } + + if (EventTypes.EVENT_SNAPSHOT_CREATE.equals(event.getType())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("create snapshot with id : " + snapId + " for account: " + event.getAccountId()); + } + Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); + UsageStorageVO storageVO = new UsageStorageVO( snapId, zoneId, event.getAccountId(), acct.getDomainId(), StorageTypes.SNAPSHOT, null, + snapSize, event.getCreateDate(), null); + m_usageStorageDao.persist(storageVO); + } else if (EventTypes.EVENT_SNAPSHOT_DELETE.equals(event.getType())) { + List storageVOs = m_usageStorageDao.listById(event.getAccountId(), snapId, StorageTypes.SNAPSHOT); + if (storageVOs.size() > 1) { + s_logger.warn("More that one usage entry for storage: " + snapId + " assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); + } + for (UsageStorageVO storageVO : storageVOs) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("deleting snapshot: " + storageVO.getId() + " from account: " + storageVO.getAccountId()); + } + storageVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one + m_usageStorageDao.update(storageVO); + } + } + } + + private void createLoadBalancerHelperEvent(UsageEventVO event) { + + long zoneId = -1L; + + long id = event.getResourceId(); + + if (EventTypes.EVENT_LOAD_BALANCER_CREATE.equals(event.getType())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating load balancer : " + id + " for account: " + event.getAccountId()); + } + zoneId = event.getZoneId(); + Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); + UsageLoadBalancerPolicyVO lbVO = new UsageLoadBalancerPolicyVO(id, zoneId, event.getAccountId(), acct.getDomainId(), + event.getCreateDate(), null); + m_usageLoadBalancerPolicyDao.persist(lbVO); + } else if (EventTypes.EVENT_LOAD_BALANCER_DELETE.equals(event.getType())) { + SearchCriteria sc = m_usageLoadBalancerPolicyDao.createSearchCriteria(); + sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); + sc.addAnd("id", SearchCriteria.Op.EQ, id); + sc.addAnd("deleted", SearchCriteria.Op.NULL); + List lbVOs = m_usageLoadBalancerPolicyDao.search(sc, null); + if (lbVOs.size() > 1) { + s_logger.warn("More that one usage entry for load balancer policy: " + id + " assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); + } + for (UsageLoadBalancerPolicyVO lbVO : lbVOs) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("deleting load balancer policy: " + lbVO.getId() + " from account: " + lbVO.getAccountId()); + } + lbVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one + m_usageLoadBalancerPolicyDao.update(lbVO); + } + } + } + + private void createPortForwardingHelperEvent(UsageEventVO event) { + + long zoneId = -1L; + + long id = event.getResourceId(); + + if (EventTypes.EVENT_NET_RULE_ADD.equals(event.getType())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating port forwarding rule : " + id + " for account: " + event.getAccountId()); + } + zoneId = event.getZoneId(); + Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); + UsagePortForwardingRuleVO pfVO = new UsagePortForwardingRuleVO(id, zoneId, event.getAccountId(), acct.getDomainId(), + event.getCreateDate(), null); + m_usagePortForwardingRuleDao.persist(pfVO); + } else if (EventTypes.EVENT_NET_RULE_DELETE.equals(event.getType())) { + SearchCriteria sc = m_usagePortForwardingRuleDao.createSearchCriteria(); + sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); + sc.addAnd("id", SearchCriteria.Op.EQ, id); + sc.addAnd("deleted", SearchCriteria.Op.NULL); + List pfVOs = m_usagePortForwardingRuleDao.search(sc, null); + if (pfVOs.size() > 1) { + s_logger.warn("More that one usage entry for port forwarding rule: " + id + " assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); + } + for (UsagePortForwardingRuleVO pfVO : pfVOs) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("deleting port forwarding rule: " + pfVO.getId() + " from account: " + pfVO.getAccountId()); + } + pfVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one + m_usagePortForwardingRuleDao.update(pfVO); + } + } + } + + private void createNetworkOfferingEvent(UsageEventVO event) { + + long zoneId = -1L; + + long vmId = event.getResourceId(); + long networkOfferingId = event.getOfferingId(); + + if (EventTypes.EVENT_NETWORK_OFFERING_CREATE.equals(event.getType()) || EventTypes.EVENT_NETWORK_OFFERING_ASSIGN.equals(event.getType())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating networking offering: "+ networkOfferingId +" for Vm: " + vmId + " for account: " + event.getAccountId()); + } + zoneId = event.getZoneId(); + Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); + boolean isDefault = (event.getSize() == 1) ? true : false ; + UsageNetworkOfferingVO networkOffering = new UsageNetworkOfferingVO(zoneId, event.getAccountId(), acct.getDomainId(), vmId, networkOfferingId, isDefault, event.getCreateDate(), null); + m_usageNetworkOfferingDao.persist(networkOffering); + } else if (EventTypes.EVENT_NETWORK_OFFERING_DELETE.equals(event.getType()) || EventTypes.EVENT_NETWORK_OFFERING_REMOVE.equals(event.getType())) { + SearchCriteria sc = m_usageNetworkOfferingDao.createSearchCriteria(); + sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); + sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, vmId); + sc.addAnd("networkOfferingId", SearchCriteria.Op.EQ, networkOfferingId); + sc.addAnd("deleted", SearchCriteria.Op.NULL); + List noVOs = m_usageNetworkOfferingDao.search(sc, null); + if (noVOs.size() > 1) { + s_logger.warn("More that one usage entry for networking offering: "+ networkOfferingId +" for Vm: " + vmId+" assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); + } + for (UsageNetworkOfferingVO noVO : noVOs) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("deleting network offering: " + noVO.getNetworkOfferingId() + " from Vm: " + noVO.getVmInstanceId()); + } + noVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one + m_usageNetworkOfferingDao.update(noVO); + } + } + } + + private void createVPNUserEvent(UsageEventVO event) { + + long zoneId = 0L; + + long userId = event.getResourceId(); + + if (EventTypes.EVENT_VPN_USER_ADD.equals(event.getType())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating VPN user: "+ userId + " for account: " + event.getAccountId()); + } + Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); + String userName = event.getResourceName(); + UsageVPNUserVO vpnUser = new UsageVPNUserVO(zoneId, event.getAccountId(), acct.getDomainId(), userId, userName, event.getCreateDate(), null); + m_usageVPNUserDao.persist(vpnUser); + } else if (EventTypes.EVENT_VPN_USER_REMOVE.equals(event.getType())) { + SearchCriteria sc = m_usageVPNUserDao.createSearchCriteria(); + sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); + sc.addAnd("userId", SearchCriteria.Op.EQ, userId); + sc.addAnd("deleted", SearchCriteria.Op.NULL); + List vuVOs = m_usageVPNUserDao.search(sc, null); + if (vuVOs.size() > 1) { + s_logger.warn("More that one usage entry for vpn user: "+ userId +" assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); + } + for (UsageVPNUserVO vuVO : vuVOs) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("deleting vpn user: " + vuVO.getUserId()); + } + vuVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one + m_usageVPNUserDao.update(vuVO); + } + } + } + + private void createSecurityGroupEvent(UsageEventVO event) { + + long zoneId = -1L; + + long vmId = event.getResourceId(); + long sgId = event.getOfferingId(); + + if (EventTypes.EVENT_SECURITY_GROUP_ASSIGN.equals(event.getType())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Assigning : security group"+ sgId +" to Vm: " + vmId + " for account: " + event.getAccountId()); + } + zoneId = event.getZoneId(); + Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId()); + UsageSecurityGroupVO securityGroup = new UsageSecurityGroupVO(zoneId, event.getAccountId(), acct.getDomainId(), vmId, sgId,event.getCreateDate(), null); + m_usageSecurityGroupDao.persist(securityGroup); + } else if (EventTypes.EVENT_SECURITY_GROUP_REMOVE.equals(event.getType())) { + SearchCriteria sc = m_usageSecurityGroupDao.createSearchCriteria(); + sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); + sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, vmId); + sc.addAnd("securityGroupId", SearchCriteria.Op.EQ, sgId); + sc.addAnd("deleted", SearchCriteria.Op.NULL); + List sgVOs = m_usageSecurityGroupDao.search(sc, null); + if (sgVOs.size() > 1) { + s_logger.warn("More that one usage entry for security group: "+ sgId +" for Vm: " + vmId+" assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); + } + for (UsageSecurityGroupVO sgVO : sgVOs) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("deleting security group: " + sgVO.getSecurityGroupId() + " from Vm: " + sgVO.getVmInstanceId()); + } + sgVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one + m_usageSecurityGroupDao.update(sgVO); + } + } + } + + private class Heartbeat implements Runnable { + public void run() { + Transaction usageTxn = Transaction.open(Transaction.USAGE_DB); + try { + if(!m_heartbeatLock.lock(3)) { // 3 second timeout + if(s_logger.isTraceEnabled()) + s_logger.trace("Heartbeat lock is in use by others, returning true as someone else will take over the job if required"); + return; + } + + try { + // check for one-off jobs + UsageJobVO nextJob = m_usageJobDao.getNextImmediateJob(); + if (nextJob != null) { + if (m_hostname.equals(nextJob.getHost()) && (m_pid == nextJob.getPid().intValue())) { + updateJob(nextJob.getId(), null, null, null, UsageJobVO.JOB_SCHEDULED); + scheduleParse(); + } + } + + Long jobId = m_usageJobDao.checkHeartbeat(m_hostname, m_pid, m_aggregationDuration); + if (jobId != null) { + // if I'm taking over the job...see how long it's been since the last job, and if it's more than the + // aggregation range...do a one off job to catch up. However, only do this if we are more than half + // the aggregation range away from executing the next job + long now = System.currentTimeMillis(); + long timeToJob = m_jobExecTime.getTimeInMillis() - now; + long timeSinceJob = 0; + long aggregationDurationMillis = m_aggregationDuration * 60 * 1000; + long lastSuccess = m_usageJobDao.getLastJobSuccessDateMillis(); + if (lastSuccess > 0) { + timeSinceJob = now - lastSuccess; + } + + if ((timeSinceJob > 0) && (timeSinceJob > aggregationDurationMillis)) { + if (timeToJob > (aggregationDurationMillis/2)) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("it's been " + timeSinceJob + " ms since last usage job and " + timeToJob + " ms until next job, scheduling an immediate job to catch up (aggregation duration is " + m_aggregationDuration + " minutes)"); + } + scheduleParse(); + } + } + + boolean changeOwner = updateJob(jobId, m_hostname, Integer.valueOf(m_pid), new Date(), UsageJobVO.JOB_NOT_SCHEDULED); + if (changeOwner) { + deleteOneOffJobs(m_hostname, m_pid); + } + } + } finally { + m_heartbeatLock.unlock(); + } + } catch (Exception ex) { + s_logger.error("error in heartbeat", ex); + } finally { + usageTxn.close(); + } + } + + @DB + protected boolean updateJob(Long jobId, String hostname, Integer pid, Date heartbeat, int scheduled) { + boolean changeOwner = false; + Transaction txn = Transaction.currentTxn(); + try { + txn.start(); + + // take over the job, setting our hostname/pid/heartbeat time + UsageJobVO job = m_usageJobDao.lockRow(jobId, Boolean.TRUE); + if (!job.getHost().equals(hostname) || !job.getPid().equals(pid)) { + changeOwner = true; + } + + UsageJobVO jobForUpdate = m_usageJobDao.createForUpdate(); + if (hostname != null) { + jobForUpdate.setHost(hostname); + } + if (pid != null) { + jobForUpdate.setPid(pid); + } + if (heartbeat != null) { + jobForUpdate.setHeartbeat(heartbeat); + } + jobForUpdate.setScheduled(scheduled); + m_usageJobDao.update(job.getId(), jobForUpdate); + + txn.commit(); + } catch (Exception dbEx) { + txn.rollback(); + s_logger.error("error updating usage job", dbEx); + } + return changeOwner; + } + + @DB + protected void deleteOneOffJobs(String hostname, int pid) { + SearchCriteria sc = m_usageJobDao.createSearchCriteria(); + SearchCriteria ssc = m_usageJobDao.createSearchCriteria(); + ssc.addOr("host", SearchCriteria.Op.NEQ, hostname); + ssc.addOr("pid", SearchCriteria.Op.NEQ, pid); + sc.addAnd("host", SearchCriteria.Op.SC, ssc); + sc.addAnd("endMillis", SearchCriteria.Op.EQ, Long.valueOf(0)); + sc.addAnd("jobType", SearchCriteria.Op.EQ, Integer.valueOf(UsageJobVO.JOB_TYPE_SINGLE)); + sc.addAnd("scheduled", SearchCriteria.Op.EQ, Integer.valueOf(0)); + m_usageJobDao.expunge(sc); + } + } + + private class SanityCheck implements Runnable { + public void run() { + UsageSanityChecker usc = new UsageSanityChecker(); + try { + String errors = usc.runSanityCheck(); + if(errors.length() > 0){ + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USAGE_SANITY_RESULT, 0, new Long(0), "Usage Sanity Check failed", errors); + } else { + _alertMgr.clearAlert(AlertManager.ALERT_TYPE_USAGE_SANITY_RESULT, 0, 0); + } + } catch (SQLException e) { + s_logger.error("Error in sanity check", e); + } + } + } +} diff --git a/usage/src/com/cloud/usage/UsageServer.java b/usage/src/com/cloud/usage/UsageServer.java index edefb0e50c3..15bf2581232 100644 --- a/usage/src/com/cloud/usage/UsageServer.java +++ b/usage/src/com/cloud/usage/UsageServer.java @@ -10,27 +10,27 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage; - -import org.apache.log4j.Logger; - -import com.cloud.utils.component.ComponentLocator; - -public class UsageServer { - private static final Logger s_logger = Logger.getLogger(UsageServer.class.getName()); - public static final String Name = "usage-server"; - - /** - * @param args - */ - public static void main(String[] args) { - // TODO: do we need to communicate with mgmt server? - final ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); - UsageManager mgr = _locator.getManager(UsageManager.class); - if (mgr != null) { - if (s_logger.isInfoEnabled()) { - s_logger.info("UsageServer ready..."); - } - } - } -} +package com.cloud.usage; + +import org.apache.log4j.Logger; + +import com.cloud.utils.component.ComponentLocator; + +public class UsageServer { + private static final Logger s_logger = Logger.getLogger(UsageServer.class.getName()); + public static final String Name = "usage-server"; + + /** + * @param args + */ + public static void main(String[] args) { + // TODO: do we need to communicate with mgmt server? + final ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); + UsageManager mgr = _locator.getManager(UsageManager.class); + if (mgr != null) { + if (s_logger.isInfoEnabled()) { + s_logger.info("UsageServer ready..."); + } + } + } +} diff --git a/usage/src/com/cloud/usage/parser/IPAddressUsageParser.java b/usage/src/com/cloud/usage/parser/IPAddressUsageParser.java index b1d1869cb95..555e6883ef2 100644 --- a/usage/src/com/cloud/usage/parser/IPAddressUsageParser.java +++ b/usage/src/com/cloud/usage/parser/IPAddressUsageParser.java @@ -10,163 +10,163 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage.parser; - -import java.text.DecimalFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Logger; - -import com.cloud.usage.UsageIPAddressVO; -import com.cloud.usage.UsageServer; -import com.cloud.usage.UsageTypes; -import com.cloud.usage.UsageVO; -import com.cloud.usage.dao.UsageDao; -import com.cloud.usage.dao.UsageIPAddressDao; -import com.cloud.user.AccountVO; -import com.cloud.utils.Pair; -import com.cloud.utils.component.ComponentLocator; - -public class IPAddressUsageParser { - public static final Logger s_logger = Logger.getLogger(IPAddressUsageParser.class.getName()); - - private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); - private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); - private static UsageIPAddressDao m_usageIPAddressDao = _locator.getDao(UsageIPAddressDao.class); - - - public static boolean parse(AccountVO account, Date startDate, Date endDate) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Parsing IP Address usage for account: " + account.getId()); - } - if ((endDate == null) || endDate.after(new Date())) { - endDate = new Date(); - } - - // - query usage_ip_address table with the following criteria: - // - look for an entry for accountId with start date in the given range - // - look for an entry for accountId with end date in the given range - // - look for an entry for accountId with end date null (currently running vm or owned IP) - // - look for an entry for accountId with start date before given range *and* end date after given range - List usageIPAddress = m_usageIPAddressDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate); - - if(usageIPAddress.isEmpty()){ - s_logger.debug("No IP Address usage for this period"); - return true; - } - - // This map has both the running time *and* the usage amount. - Map> usageMap = new HashMap>(); - - Map IPMap = new HashMap(); - - // loop through all the usage IPs, create a usage record for each - for (UsageIPAddressVO usageIp : usageIPAddress) { - long IpId = usageIp.getId(); - - String key = ""+IpId; - - // store the info in the IP map - IPMap.put(key, new IpInfo(usageIp.getZoneId(), IpId, usageIp.getAddress(), usageIp.isSourceNat(), usageIp.isSystem())); - - Date IpAssignDate = usageIp.getAssigned(); - Date IpReleaseDeleteDate = usageIp.getReleased(); - - if ((IpReleaseDeleteDate == null) || IpReleaseDeleteDate.after(endDate)) { - IpReleaseDeleteDate = endDate; - } - - // clip the start date to the beginning of our aggregation range if the vm has been running for a while - if (IpAssignDate.before(startDate)) { - IpAssignDate = startDate; - } - - long currentDuration = (IpReleaseDeleteDate.getTime() - IpAssignDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) - - updateIpUsageData(usageMap, key, usageIp.getId(), currentDuration); - } - - for (String ipIdKey : usageMap.keySet()) { - Pair ipTimeInfo = usageMap.get(ipIdKey); - long useTime = ipTimeInfo.second().longValue(); - - // Only create a usage record if we have a runningTime of bigger than zero. - if (useTime > 0L) { - IpInfo info = IPMap.get(ipIdKey); - createUsageRecord(info.getZoneId(), useTime, startDate, endDate, account, info.getIpId(), info.getIPAddress(), info.isSourceNat(), info.isSystem); - } - } - - return true; - } - - private static void updateIpUsageData(Map> usageDataMap, String key, long ipId, long duration) { - Pair ipUsageInfo = usageDataMap.get(key); - if (ipUsageInfo == null) { - ipUsageInfo = new Pair(new Long(ipId), new Long(duration)); - } else { - Long runningTime = ipUsageInfo.second(); - runningTime = new Long(runningTime.longValue() + duration); - ipUsageInfo = new Pair(ipUsageInfo.first(), runningTime); - } - usageDataMap.put(key, ipUsageInfo); - } - - private static void createUsageRecord(long zoneId, long runningTime, Date startDate, Date endDate, AccountVO account, long IpId, String IPAddress, boolean isSourceNat, boolean isSystem) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Total usage time " + runningTime + "ms"); - } - - float usage = runningTime / 1000f / 60f / 60f; - - DecimalFormat dFormat = new DecimalFormat("#.######"); - String usageDisplay = dFormat.format(usage); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating IP usage record with id: " + IpId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); - } - - String usageDesc = "IPAddress: "+IPAddress; - - // Create the usage record - - UsageVO usageRecord = new UsageVO(zoneId, account.getAccountId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", UsageTypes.IP_ADDRESS, new Double(usage), IpId, - (isSystem?1:0), (isSourceNat?"SourceNat":""), startDate, endDate); - m_usageDao.persist(usageRecord); - } - - private static class IpInfo { - private long zoneId; - private long IpId; - private String IPAddress; - private boolean isSourceNat; - private boolean isSystem; - - public IpInfo(long zoneId,long IpId, String IPAddress, boolean isSourceNat, boolean isSystem) { - this.zoneId = zoneId; - this.IpId = IpId; - this.IPAddress = IPAddress; - this.isSourceNat = isSourceNat; - this.isSystem = isSystem; - } - - public long getZoneId() { - return zoneId; - } - - public long getIpId() { - return IpId; - } - - public String getIPAddress() { - return IPAddress; - } - - public boolean isSourceNat() { - return isSourceNat; - } - } -} +package com.cloud.usage.parser; + +import java.text.DecimalFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.cloud.usage.UsageIPAddressVO; +import com.cloud.usage.UsageServer; +import com.cloud.usage.UsageTypes; +import com.cloud.usage.UsageVO; +import com.cloud.usage.dao.UsageDao; +import com.cloud.usage.dao.UsageIPAddressDao; +import com.cloud.user.AccountVO; +import com.cloud.utils.Pair; +import com.cloud.utils.component.ComponentLocator; + +public class IPAddressUsageParser { + public static final Logger s_logger = Logger.getLogger(IPAddressUsageParser.class.getName()); + + private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); + private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); + private static UsageIPAddressDao m_usageIPAddressDao = _locator.getDao(UsageIPAddressDao.class); + + + public static boolean parse(AccountVO account, Date startDate, Date endDate) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Parsing IP Address usage for account: " + account.getId()); + } + if ((endDate == null) || endDate.after(new Date())) { + endDate = new Date(); + } + + // - query usage_ip_address table with the following criteria: + // - look for an entry for accountId with start date in the given range + // - look for an entry for accountId with end date in the given range + // - look for an entry for accountId with end date null (currently running vm or owned IP) + // - look for an entry for accountId with start date before given range *and* end date after given range + List usageIPAddress = m_usageIPAddressDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate); + + if(usageIPAddress.isEmpty()){ + s_logger.debug("No IP Address usage for this period"); + return true; + } + + // This map has both the running time *and* the usage amount. + Map> usageMap = new HashMap>(); + + Map IPMap = new HashMap(); + + // loop through all the usage IPs, create a usage record for each + for (UsageIPAddressVO usageIp : usageIPAddress) { + long IpId = usageIp.getId(); + + String key = ""+IpId; + + // store the info in the IP map + IPMap.put(key, new IpInfo(usageIp.getZoneId(), IpId, usageIp.getAddress(), usageIp.isSourceNat(), usageIp.isSystem())); + + Date IpAssignDate = usageIp.getAssigned(); + Date IpReleaseDeleteDate = usageIp.getReleased(); + + if ((IpReleaseDeleteDate == null) || IpReleaseDeleteDate.after(endDate)) { + IpReleaseDeleteDate = endDate; + } + + // clip the start date to the beginning of our aggregation range if the vm has been running for a while + if (IpAssignDate.before(startDate)) { + IpAssignDate = startDate; + } + + long currentDuration = (IpReleaseDeleteDate.getTime() - IpAssignDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) + + updateIpUsageData(usageMap, key, usageIp.getId(), currentDuration); + } + + for (String ipIdKey : usageMap.keySet()) { + Pair ipTimeInfo = usageMap.get(ipIdKey); + long useTime = ipTimeInfo.second().longValue(); + + // Only create a usage record if we have a runningTime of bigger than zero. + if (useTime > 0L) { + IpInfo info = IPMap.get(ipIdKey); + createUsageRecord(info.getZoneId(), useTime, startDate, endDate, account, info.getIpId(), info.getIPAddress(), info.isSourceNat(), info.isSystem); + } + } + + return true; + } + + private static void updateIpUsageData(Map> usageDataMap, String key, long ipId, long duration) { + Pair ipUsageInfo = usageDataMap.get(key); + if (ipUsageInfo == null) { + ipUsageInfo = new Pair(new Long(ipId), new Long(duration)); + } else { + Long runningTime = ipUsageInfo.second(); + runningTime = new Long(runningTime.longValue() + duration); + ipUsageInfo = new Pair(ipUsageInfo.first(), runningTime); + } + usageDataMap.put(key, ipUsageInfo); + } + + private static void createUsageRecord(long zoneId, long runningTime, Date startDate, Date endDate, AccountVO account, long IpId, String IPAddress, boolean isSourceNat, boolean isSystem) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Total usage time " + runningTime + "ms"); + } + + float usage = runningTime / 1000f / 60f / 60f; + + DecimalFormat dFormat = new DecimalFormat("#.######"); + String usageDisplay = dFormat.format(usage); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating IP usage record with id: " + IpId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); + } + + String usageDesc = "IPAddress: "+IPAddress; + + // Create the usage record + + UsageVO usageRecord = new UsageVO(zoneId, account.getAccountId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", UsageTypes.IP_ADDRESS, new Double(usage), IpId, + (isSystem?1:0), (isSourceNat?"SourceNat":""), startDate, endDate); + m_usageDao.persist(usageRecord); + } + + private static class IpInfo { + private long zoneId; + private long IpId; + private String IPAddress; + private boolean isSourceNat; + private boolean isSystem; + + public IpInfo(long zoneId,long IpId, String IPAddress, boolean isSourceNat, boolean isSystem) { + this.zoneId = zoneId; + this.IpId = IpId; + this.IPAddress = IPAddress; + this.isSourceNat = isSourceNat; + this.isSystem = isSystem; + } + + public long getZoneId() { + return zoneId; + } + + public long getIpId() { + return IpId; + } + + public String getIPAddress() { + return IPAddress; + } + + public boolean isSourceNat() { + return isSourceNat; + } + } +} diff --git a/usage/src/com/cloud/usage/parser/LoadBalancerUsageParser.java b/usage/src/com/cloud/usage/parser/LoadBalancerUsageParser.java index 709de54e44c..8bcbf55f0cc 100644 --- a/usage/src/com/cloud/usage/parser/LoadBalancerUsageParser.java +++ b/usage/src/com/cloud/usage/parser/LoadBalancerUsageParser.java @@ -10,146 +10,146 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage.parser; - -import java.text.DecimalFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Logger; - -import com.cloud.usage.UsageLoadBalancerPolicyVO; -import com.cloud.usage.UsageServer; -import com.cloud.usage.UsageTypes; -import com.cloud.usage.UsageVO; -import com.cloud.usage.dao.UsageDao; -import com.cloud.usage.dao.UsageLoadBalancerPolicyDao; -import com.cloud.user.AccountVO; -import com.cloud.utils.Pair; -import com.cloud.utils.component.ComponentLocator; - -public class LoadBalancerUsageParser { - public static final Logger s_logger = Logger.getLogger(LoadBalancerUsageParser.class.getName()); - - private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); - private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); - private static UsageLoadBalancerPolicyDao m_usageLoadBalancerPolicyDao = _locator.getDao(UsageLoadBalancerPolicyDao.class); - - public static boolean parse(AccountVO account, Date startDate, Date endDate) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Parsing all LoadBalancerPolicy usage events for account: " + account.getId()); - } - if ((endDate == null) || endDate.after(new Date())) { - endDate = new Date(); - } - - // - query usage_volume table with the following criteria: - // - look for an entry for accountId with start date in the given range - // - look for an entry for accountId with end date in the given range - // - look for an entry for accountId with end date null (currently running vm or owned IP) - // - look for an entry for accountId with start date before given range *and* end date after given range - List usageLBs = m_usageLoadBalancerPolicyDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0); - - if(usageLBs.isEmpty()){ - s_logger.debug("No load balancer usage events for this period"); - return true; - } - - // This map has both the running time *and* the usage amount. - Map> usageMap = new HashMap>(); - Map lbMap = new HashMap(); - - // loop through all the load balancer policies, create a usage record for each - for (UsageLoadBalancerPolicyVO usageLB : usageLBs) { - long lbId = usageLB.getId(); - String key = ""+lbId; - - lbMap.put(key, new LBInfo(lbId, usageLB.getZoneId())); - - Date lbCreateDate = usageLB.getCreated(); - Date lbDeleteDate = usageLB.getDeleted(); - - if ((lbDeleteDate == null) || lbDeleteDate.after(endDate)) { - lbDeleteDate = endDate; - } - - // clip the start date to the beginning of our aggregation range if the vm has been running for a while - if (lbCreateDate.before(startDate)) { - lbCreateDate = startDate; - } - - long currentDuration = (lbDeleteDate.getTime() - lbCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) - - - updateLBUsageData(usageMap, key, usageLB.getId(), currentDuration); - } - - for (String lbIdKey : usageMap.keySet()) { - Pair sgtimeInfo = usageMap.get(lbIdKey); - long useTime = sgtimeInfo.second().longValue(); - - // Only create a usage record if we have a runningTime of bigger than zero. - if (useTime > 0L) { - LBInfo info = lbMap.get(lbIdKey); - createUsageRecord(UsageTypes.LOAD_BALANCER_POLICY, useTime, startDate, endDate, account, info.getId(), info.getZoneId() ); - } - } - - return true; - } - - private static void updateLBUsageData(Map> usageDataMap, String key, long lbId, long duration) { - Pair lbUsageInfo = usageDataMap.get(key); - if (lbUsageInfo == null) { - lbUsageInfo = new Pair(new Long(lbId), new Long(duration)); - } else { - Long runningTime = lbUsageInfo.second(); - runningTime = new Long(runningTime.longValue() + duration); - lbUsageInfo = new Pair(lbUsageInfo.first(), runningTime); - } - usageDataMap.put(key, lbUsageInfo); - } - - private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long lbId, long zoneId) { - // Our smallest increment is hourly for now - if (s_logger.isDebugEnabled()) { - s_logger.debug("Total running time " + runningTime + "ms"); - } - - float usage = runningTime / 1000f / 60f / 60f; - - DecimalFormat dFormat = new DecimalFormat("#.######"); - String usageDisplay = dFormat.format(usage); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating Volume usage record for load balancer: " + lbId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); - } - - // Create the usage record - String usageDesc = "Load Balancing Policy: "+lbId+" usage time"; - - //ToDo: get zone id - UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, - new Double(usage), null, null, null, null, lbId, null, startDate, endDate); - m_usageDao.persist(usageRecord); - } - - private static class LBInfo { - private long id; - private long zoneId; - - public LBInfo(long id, long zoneId) { - this.id = id; - this.zoneId = zoneId; - } - public long getZoneId() { - return zoneId; - } - public long getId() { - return id; - } - } - -} +package com.cloud.usage.parser; + +import java.text.DecimalFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.cloud.usage.UsageLoadBalancerPolicyVO; +import com.cloud.usage.UsageServer; +import com.cloud.usage.UsageTypes; +import com.cloud.usage.UsageVO; +import com.cloud.usage.dao.UsageDao; +import com.cloud.usage.dao.UsageLoadBalancerPolicyDao; +import com.cloud.user.AccountVO; +import com.cloud.utils.Pair; +import com.cloud.utils.component.ComponentLocator; + +public class LoadBalancerUsageParser { + public static final Logger s_logger = Logger.getLogger(LoadBalancerUsageParser.class.getName()); + + private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); + private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); + private static UsageLoadBalancerPolicyDao m_usageLoadBalancerPolicyDao = _locator.getDao(UsageLoadBalancerPolicyDao.class); + + public static boolean parse(AccountVO account, Date startDate, Date endDate) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Parsing all LoadBalancerPolicy usage events for account: " + account.getId()); + } + if ((endDate == null) || endDate.after(new Date())) { + endDate = new Date(); + } + + // - query usage_volume table with the following criteria: + // - look for an entry for accountId with start date in the given range + // - look for an entry for accountId with end date in the given range + // - look for an entry for accountId with end date null (currently running vm or owned IP) + // - look for an entry for accountId with start date before given range *and* end date after given range + List usageLBs = m_usageLoadBalancerPolicyDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0); + + if(usageLBs.isEmpty()){ + s_logger.debug("No load balancer usage events for this period"); + return true; + } + + // This map has both the running time *and* the usage amount. + Map> usageMap = new HashMap>(); + Map lbMap = new HashMap(); + + // loop through all the load balancer policies, create a usage record for each + for (UsageLoadBalancerPolicyVO usageLB : usageLBs) { + long lbId = usageLB.getId(); + String key = ""+lbId; + + lbMap.put(key, new LBInfo(lbId, usageLB.getZoneId())); + + Date lbCreateDate = usageLB.getCreated(); + Date lbDeleteDate = usageLB.getDeleted(); + + if ((lbDeleteDate == null) || lbDeleteDate.after(endDate)) { + lbDeleteDate = endDate; + } + + // clip the start date to the beginning of our aggregation range if the vm has been running for a while + if (lbCreateDate.before(startDate)) { + lbCreateDate = startDate; + } + + long currentDuration = (lbDeleteDate.getTime() - lbCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) + + + updateLBUsageData(usageMap, key, usageLB.getId(), currentDuration); + } + + for (String lbIdKey : usageMap.keySet()) { + Pair sgtimeInfo = usageMap.get(lbIdKey); + long useTime = sgtimeInfo.second().longValue(); + + // Only create a usage record if we have a runningTime of bigger than zero. + if (useTime > 0L) { + LBInfo info = lbMap.get(lbIdKey); + createUsageRecord(UsageTypes.LOAD_BALANCER_POLICY, useTime, startDate, endDate, account, info.getId(), info.getZoneId() ); + } + } + + return true; + } + + private static void updateLBUsageData(Map> usageDataMap, String key, long lbId, long duration) { + Pair lbUsageInfo = usageDataMap.get(key); + if (lbUsageInfo == null) { + lbUsageInfo = new Pair(new Long(lbId), new Long(duration)); + } else { + Long runningTime = lbUsageInfo.second(); + runningTime = new Long(runningTime.longValue() + duration); + lbUsageInfo = new Pair(lbUsageInfo.first(), runningTime); + } + usageDataMap.put(key, lbUsageInfo); + } + + private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long lbId, long zoneId) { + // Our smallest increment is hourly for now + if (s_logger.isDebugEnabled()) { + s_logger.debug("Total running time " + runningTime + "ms"); + } + + float usage = runningTime / 1000f / 60f / 60f; + + DecimalFormat dFormat = new DecimalFormat("#.######"); + String usageDisplay = dFormat.format(usage); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating Volume usage record for load balancer: " + lbId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); + } + + // Create the usage record + String usageDesc = "Load Balancing Policy: "+lbId+" usage time"; + + //ToDo: get zone id + UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, + new Double(usage), null, null, null, null, lbId, null, startDate, endDate); + m_usageDao.persist(usageRecord); + } + + private static class LBInfo { + private long id; + private long zoneId; + + public LBInfo(long id, long zoneId) { + this.id = id; + this.zoneId = zoneId; + } + public long getZoneId() { + return zoneId; + } + public long getId() { + return id; + } + } + +} diff --git a/usage/src/com/cloud/usage/parser/NetworkOfferingUsageParser.java b/usage/src/com/cloud/usage/parser/NetworkOfferingUsageParser.java index 5d37157dd92..d9ea3d6aecb 100644 --- a/usage/src/com/cloud/usage/parser/NetworkOfferingUsageParser.java +++ b/usage/src/com/cloud/usage/parser/NetworkOfferingUsageParser.java @@ -10,158 +10,158 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage.parser; - -import java.text.DecimalFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Logger; - -import com.cloud.usage.UsageNetworkOfferingVO; -import com.cloud.usage.UsageServer; -import com.cloud.usage.UsageTypes; -import com.cloud.usage.UsageVO; -import com.cloud.usage.dao.UsageDao; -import com.cloud.usage.dao.UsageNetworkOfferingDao; -import com.cloud.user.AccountVO; -import com.cloud.utils.Pair; -import com.cloud.utils.component.ComponentLocator; - -public class NetworkOfferingUsageParser { - public static final Logger s_logger = Logger.getLogger(NetworkOfferingUsageParser.class.getName()); - - private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); - private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); - private static UsageNetworkOfferingDao m_usageNetworkOfferingDao = _locator.getDao(UsageNetworkOfferingDao.class); - - public static boolean parse(AccountVO account, Date startDate, Date endDate) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Parsing all NetworkOffering usage events for account: " + account.getId()); - } - if ((endDate == null) || endDate.after(new Date())) { - endDate = new Date(); - } - - // - query usage_volume table with the following criteria: - // - look for an entry for accountId with start date in the given range - // - look for an entry for accountId with end date in the given range - // - look for an entry for accountId with end date null (currently running vm or owned IP) - // - look for an entry for accountId with start date before given range *and* end date after given range - List usageNOs = m_usageNetworkOfferingDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0); - - if(usageNOs.isEmpty()){ - s_logger.debug("No NetworkOffering usage events for this period"); - return true; - } - - // This map has both the running time *and* the usage amount. - Map> usageMap = new HashMap>(); - Map noMap = new HashMap(); - - // loop through all the network offerings, create a usage record for each - for (UsageNetworkOfferingVO usageNO : usageNOs) { - long vmId = usageNO.getVmInstanceId(); - long noId = usageNO.getNetworkOfferingId(); - String key = ""+vmId+"NO"+noId; - - noMap.put(key, new NOInfo(vmId, usageNO.getZoneId(), noId, usageNO.isDefault())); - - Date noCreateDate = usageNO.getCreated(); - Date noDeleteDate = usageNO.getDeleted(); - - if ((noDeleteDate == null) || noDeleteDate.after(endDate)) { - noDeleteDate = endDate; - } - - // clip the start date to the beginning of our aggregation range if the vm has been running for a while - if (noCreateDate.before(startDate)) { - noCreateDate = startDate; - } - - long currentDuration = (noDeleteDate.getTime() - noCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) - - - updateNOUsageData(usageMap, key, usageNO.getVmInstanceId(), currentDuration); - } - - for (String noIdKey : usageMap.keySet()) { - Pair notimeInfo = usageMap.get(noIdKey); - long useTime = notimeInfo.second().longValue(); - - // Only create a usage record if we have a runningTime of bigger than zero. - if (useTime > 0L) { - NOInfo info = noMap.get(noIdKey); - createUsageRecord(UsageTypes.NETWORK_OFFERING, useTime, startDate, endDate, account, info.getVmId(), info.getNOId(), info.getZoneId(), info.isDefault()); - } - } - - return true; - } - - private static void updateNOUsageData(Map> usageDataMap, String key, long vmId, long duration) { - Pair noUsageInfo = usageDataMap.get(key); - if (noUsageInfo == null) { - noUsageInfo = new Pair(new Long(vmId), new Long(duration)); - } else { - Long runningTime = noUsageInfo.second(); - runningTime = new Long(runningTime.longValue() + duration); - noUsageInfo = new Pair(noUsageInfo.first(), runningTime); - } - usageDataMap.put(key, noUsageInfo); - } - - private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long vmId, long noId, long zoneId, boolean isDefault) { - // Our smallest increment is hourly for now - if (s_logger.isDebugEnabled()) { - s_logger.debug("Total running time " + runningTime + "ms"); - } - - float usage = runningTime / 1000f / 60f / 60f; - - DecimalFormat dFormat = new DecimalFormat("#.######"); - String usageDisplay = dFormat.format(usage); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating network offering:" + noId + " usage record for Vm : " + vmId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); - } - - // Create the usage record - String usageDesc = "Network offering:" + noId + " for Vm : " + vmId + " usage time"; - - long defaultNic = (isDefault) ? 1 : 0; - UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, - new Double(usage), vmId, null, noId, null, defaultNic, null, startDate, endDate); - m_usageDao.persist(usageRecord); - } - - private static class NOInfo { - private long vmId; - private long zoneId; - private long noId; - private boolean isDefault; - - public NOInfo(long vmId, long zoneId, long noId, boolean isDefault) { - this.vmId = vmId; - this.zoneId = zoneId; - this.noId = noId; - this.isDefault = isDefault; - } - public long getZoneId() { - return zoneId; - } - public long getVmId() { - return vmId; - } - public long getNOId() { - return noId; - } - - public boolean isDefault(){ - return isDefault; - } - } - -} +package com.cloud.usage.parser; + +import java.text.DecimalFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.cloud.usage.UsageNetworkOfferingVO; +import com.cloud.usage.UsageServer; +import com.cloud.usage.UsageTypes; +import com.cloud.usage.UsageVO; +import com.cloud.usage.dao.UsageDao; +import com.cloud.usage.dao.UsageNetworkOfferingDao; +import com.cloud.user.AccountVO; +import com.cloud.utils.Pair; +import com.cloud.utils.component.ComponentLocator; + +public class NetworkOfferingUsageParser { + public static final Logger s_logger = Logger.getLogger(NetworkOfferingUsageParser.class.getName()); + + private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); + private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); + private static UsageNetworkOfferingDao m_usageNetworkOfferingDao = _locator.getDao(UsageNetworkOfferingDao.class); + + public static boolean parse(AccountVO account, Date startDate, Date endDate) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Parsing all NetworkOffering usage events for account: " + account.getId()); + } + if ((endDate == null) || endDate.after(new Date())) { + endDate = new Date(); + } + + // - query usage_volume table with the following criteria: + // - look for an entry for accountId with start date in the given range + // - look for an entry for accountId with end date in the given range + // - look for an entry for accountId with end date null (currently running vm or owned IP) + // - look for an entry for accountId with start date before given range *and* end date after given range + List usageNOs = m_usageNetworkOfferingDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0); + + if(usageNOs.isEmpty()){ + s_logger.debug("No NetworkOffering usage events for this period"); + return true; + } + + // This map has both the running time *and* the usage amount. + Map> usageMap = new HashMap>(); + Map noMap = new HashMap(); + + // loop through all the network offerings, create a usage record for each + for (UsageNetworkOfferingVO usageNO : usageNOs) { + long vmId = usageNO.getVmInstanceId(); + long noId = usageNO.getNetworkOfferingId(); + String key = ""+vmId+"NO"+noId; + + noMap.put(key, new NOInfo(vmId, usageNO.getZoneId(), noId, usageNO.isDefault())); + + Date noCreateDate = usageNO.getCreated(); + Date noDeleteDate = usageNO.getDeleted(); + + if ((noDeleteDate == null) || noDeleteDate.after(endDate)) { + noDeleteDate = endDate; + } + + // clip the start date to the beginning of our aggregation range if the vm has been running for a while + if (noCreateDate.before(startDate)) { + noCreateDate = startDate; + } + + long currentDuration = (noDeleteDate.getTime() - noCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) + + + updateNOUsageData(usageMap, key, usageNO.getVmInstanceId(), currentDuration); + } + + for (String noIdKey : usageMap.keySet()) { + Pair notimeInfo = usageMap.get(noIdKey); + long useTime = notimeInfo.second().longValue(); + + // Only create a usage record if we have a runningTime of bigger than zero. + if (useTime > 0L) { + NOInfo info = noMap.get(noIdKey); + createUsageRecord(UsageTypes.NETWORK_OFFERING, useTime, startDate, endDate, account, info.getVmId(), info.getNOId(), info.getZoneId(), info.isDefault()); + } + } + + return true; + } + + private static void updateNOUsageData(Map> usageDataMap, String key, long vmId, long duration) { + Pair noUsageInfo = usageDataMap.get(key); + if (noUsageInfo == null) { + noUsageInfo = new Pair(new Long(vmId), new Long(duration)); + } else { + Long runningTime = noUsageInfo.second(); + runningTime = new Long(runningTime.longValue() + duration); + noUsageInfo = new Pair(noUsageInfo.first(), runningTime); + } + usageDataMap.put(key, noUsageInfo); + } + + private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long vmId, long noId, long zoneId, boolean isDefault) { + // Our smallest increment is hourly for now + if (s_logger.isDebugEnabled()) { + s_logger.debug("Total running time " + runningTime + "ms"); + } + + float usage = runningTime / 1000f / 60f / 60f; + + DecimalFormat dFormat = new DecimalFormat("#.######"); + String usageDisplay = dFormat.format(usage); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating network offering:" + noId + " usage record for Vm : " + vmId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); + } + + // Create the usage record + String usageDesc = "Network offering:" + noId + " for Vm : " + vmId + " usage time"; + + long defaultNic = (isDefault) ? 1 : 0; + UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, + new Double(usage), vmId, null, noId, null, defaultNic, null, startDate, endDate); + m_usageDao.persist(usageRecord); + } + + private static class NOInfo { + private long vmId; + private long zoneId; + private long noId; + private boolean isDefault; + + public NOInfo(long vmId, long zoneId, long noId, boolean isDefault) { + this.vmId = vmId; + this.zoneId = zoneId; + this.noId = noId; + this.isDefault = isDefault; + } + public long getZoneId() { + return zoneId; + } + public long getVmId() { + return vmId; + } + public long getNOId() { + return noId; + } + + public boolean isDefault(){ + return isDefault; + } + } + +} diff --git a/usage/src/com/cloud/usage/parser/NetworkUsageParser.java b/usage/src/com/cloud/usage/parser/NetworkUsageParser.java index d9df08d8a23..ce830dc867c 100644 --- a/usage/src/com/cloud/usage/parser/NetworkUsageParser.java +++ b/usage/src/com/cloud/usage/parser/NetworkUsageParser.java @@ -10,152 +10,152 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage.parser; - -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Logger; - -import com.cloud.usage.UsageNetworkVO; -import com.cloud.usage.UsageServer; -import com.cloud.usage.UsageTypes; -import com.cloud.usage.UsageVO; -import com.cloud.usage.dao.UsageDao; -import com.cloud.usage.dao.UsageNetworkDao; -import com.cloud.user.AccountVO; -import com.cloud.utils.Pair; -import com.cloud.utils.component.ComponentLocator; -import com.cloud.utils.db.SearchCriteria; - -public class NetworkUsageParser { -public static final Logger s_logger = Logger.getLogger(NetworkUsageParser.class.getName()); - - private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); - private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); - private static UsageNetworkDao m_usageNetworkDao = _locator.getDao(UsageNetworkDao.class); - - public static boolean parse(AccountVO account, Date startDate, Date endDate) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Parsing all Network usage events for account: " + account.getId()); - } - - if ((endDate == null) || endDate.after(new Date())) { - endDate = new Date(); - } - - // - query usage_network table for all entries for userId with - // event_date in the given range - SearchCriteria sc = m_usageNetworkDao.createSearchCriteria(); - sc.addAnd("accountId", SearchCriteria.Op.EQ, account.getId()); - sc.addAnd("eventTimeMillis", SearchCriteria.Op.BETWEEN, startDate.getTime(), endDate.getTime()); - List usageNetworkVOs = m_usageNetworkDao.search(sc, null); - - Map networkUsageByZone = new HashMap(); - - // Calculate the total bytes since last parsing - for (UsageNetworkVO usageNetwork : usageNetworkVOs) { - long zoneId = usageNetwork.getZoneId(); - String key = ""+zoneId; - if(usageNetwork.getHostId() != 0){ - key += "-Host"+usageNetwork.getHostId(); - } - NetworkInfo networkInfo = networkUsageByZone.get(key); - - long bytesSent = usageNetwork.getBytesSent(); - long bytesReceived = usageNetwork.getBytesReceived(); - if (networkInfo != null) { - bytesSent += networkInfo.getBytesSent(); - bytesReceived += networkInfo.getBytesRcvd(); - } - - networkUsageByZone.put(key, new NetworkInfo(zoneId, usageNetwork.getHostId(), usageNetwork.getHostType(), usageNetwork.getNetworkId(), bytesSent, bytesReceived)); - } - - for (String key : networkUsageByZone.keySet()) { - NetworkInfo networkInfo = networkUsageByZone.get(key); - long totalBytesSent = networkInfo.getBytesSent(); - long totalBytesReceived = networkInfo.getBytesRcvd(); - - if ((totalBytesSent > 0L) || (totalBytesReceived > 0L)) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating usage record, total bytes sent:" + totalBytesSent + ", total bytes received: " + totalBytesReceived + " for account: " - + account.getId() + " in availability zone " + networkInfo.getZoneId() + ", start: " + startDate + ", end: " + endDate); - } - - Long hostId = null; - - // Create the usage record for bytes sent - String usageDesc = "network bytes sent"; - if(networkInfo.getHostId() != 0){ - hostId = networkInfo.getHostId(); - usageDesc += " for Host: "+networkInfo.getHostId(); - } - UsageVO usageRecord = new UsageVO(networkInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, totalBytesSent + " bytes sent", - UsageTypes.NETWORK_BYTES_SENT, new Double(totalBytesSent), hostId, networkInfo.getHostType(), networkInfo.getNetworkId(), startDate, endDate); - m_usageDao.persist(usageRecord); - - // Create the usage record for bytes received - usageDesc = "network bytes received"; - if(networkInfo.getHostId() != 0){ - usageDesc += " for Host: "+networkInfo.getHostId(); - } - usageRecord = new UsageVO(networkInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, totalBytesReceived + " bytes received", - UsageTypes.NETWORK_BYTES_RECEIVED, new Double(totalBytesReceived), hostId, networkInfo.getHostType(), networkInfo.getNetworkId(), startDate, endDate); - m_usageDao.persist(usageRecord); - } else { - // Don't charge anything if there were zero bytes processed - if (s_logger.isDebugEnabled()) { - s_logger.debug("No usage record (0 bytes used) generated for account: " + account.getId()); - } - } - } - - return true; - } - - private static class NetworkInfo { - private long zoneId; - private long hostId; - private String hostType; - private Long networkId; - private long bytesSent; - private long bytesRcvd; - - public NetworkInfo(long zoneId, long hostId, String hostType, Long networkId, long bytesSent, long bytesRcvd) { - this.zoneId = zoneId; - this.hostId = hostId; - this.hostType = hostType; - this.networkId = networkId; - this.bytesSent = bytesSent; - this.bytesRcvd = bytesRcvd; - } - - public long getZoneId() { - return zoneId; - } - - public long getHostId() { - return hostId; - } - - public Long getNetworkId() { - return networkId; - } - - public long getBytesSent() { - return bytesSent; - } - - public long getBytesRcvd() { - return bytesRcvd; - } - - public String getHostType(){ - return hostType; - } - - } -} +package com.cloud.usage.parser; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.cloud.usage.UsageNetworkVO; +import com.cloud.usage.UsageServer; +import com.cloud.usage.UsageTypes; +import com.cloud.usage.UsageVO; +import com.cloud.usage.dao.UsageDao; +import com.cloud.usage.dao.UsageNetworkDao; +import com.cloud.user.AccountVO; +import com.cloud.utils.Pair; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.db.SearchCriteria; + +public class NetworkUsageParser { +public static final Logger s_logger = Logger.getLogger(NetworkUsageParser.class.getName()); + + private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); + private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); + private static UsageNetworkDao m_usageNetworkDao = _locator.getDao(UsageNetworkDao.class); + + public static boolean parse(AccountVO account, Date startDate, Date endDate) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Parsing all Network usage events for account: " + account.getId()); + } + + if ((endDate == null) || endDate.after(new Date())) { + endDate = new Date(); + } + + // - query usage_network table for all entries for userId with + // event_date in the given range + SearchCriteria sc = m_usageNetworkDao.createSearchCriteria(); + sc.addAnd("accountId", SearchCriteria.Op.EQ, account.getId()); + sc.addAnd("eventTimeMillis", SearchCriteria.Op.BETWEEN, startDate.getTime(), endDate.getTime()); + List usageNetworkVOs = m_usageNetworkDao.search(sc, null); + + Map networkUsageByZone = new HashMap(); + + // Calculate the total bytes since last parsing + for (UsageNetworkVO usageNetwork : usageNetworkVOs) { + long zoneId = usageNetwork.getZoneId(); + String key = ""+zoneId; + if(usageNetwork.getHostId() != 0){ + key += "-Host"+usageNetwork.getHostId(); + } + NetworkInfo networkInfo = networkUsageByZone.get(key); + + long bytesSent = usageNetwork.getBytesSent(); + long bytesReceived = usageNetwork.getBytesReceived(); + if (networkInfo != null) { + bytesSent += networkInfo.getBytesSent(); + bytesReceived += networkInfo.getBytesRcvd(); + } + + networkUsageByZone.put(key, new NetworkInfo(zoneId, usageNetwork.getHostId(), usageNetwork.getHostType(), usageNetwork.getNetworkId(), bytesSent, bytesReceived)); + } + + for (String key : networkUsageByZone.keySet()) { + NetworkInfo networkInfo = networkUsageByZone.get(key); + long totalBytesSent = networkInfo.getBytesSent(); + long totalBytesReceived = networkInfo.getBytesRcvd(); + + if ((totalBytesSent > 0L) || (totalBytesReceived > 0L)) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating usage record, total bytes sent:" + totalBytesSent + ", total bytes received: " + totalBytesReceived + " for account: " + + account.getId() + " in availability zone " + networkInfo.getZoneId() + ", start: " + startDate + ", end: " + endDate); + } + + Long hostId = null; + + // Create the usage record for bytes sent + String usageDesc = "network bytes sent"; + if(networkInfo.getHostId() != 0){ + hostId = networkInfo.getHostId(); + usageDesc += " for Host: "+networkInfo.getHostId(); + } + UsageVO usageRecord = new UsageVO(networkInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, totalBytesSent + " bytes sent", + UsageTypes.NETWORK_BYTES_SENT, new Double(totalBytesSent), hostId, networkInfo.getHostType(), networkInfo.getNetworkId(), startDate, endDate); + m_usageDao.persist(usageRecord); + + // Create the usage record for bytes received + usageDesc = "network bytes received"; + if(networkInfo.getHostId() != 0){ + usageDesc += " for Host: "+networkInfo.getHostId(); + } + usageRecord = new UsageVO(networkInfo.getZoneId(), account.getId(), account.getDomainId(), usageDesc, totalBytesReceived + " bytes received", + UsageTypes.NETWORK_BYTES_RECEIVED, new Double(totalBytesReceived), hostId, networkInfo.getHostType(), networkInfo.getNetworkId(), startDate, endDate); + m_usageDao.persist(usageRecord); + } else { + // Don't charge anything if there were zero bytes processed + if (s_logger.isDebugEnabled()) { + s_logger.debug("No usage record (0 bytes used) generated for account: " + account.getId()); + } + } + } + + return true; + } + + private static class NetworkInfo { + private long zoneId; + private long hostId; + private String hostType; + private Long networkId; + private long bytesSent; + private long bytesRcvd; + + public NetworkInfo(long zoneId, long hostId, String hostType, Long networkId, long bytesSent, long bytesRcvd) { + this.zoneId = zoneId; + this.hostId = hostId; + this.hostType = hostType; + this.networkId = networkId; + this.bytesSent = bytesSent; + this.bytesRcvd = bytesRcvd; + } + + public long getZoneId() { + return zoneId; + } + + public long getHostId() { + return hostId; + } + + public Long getNetworkId() { + return networkId; + } + + public long getBytesSent() { + return bytesSent; + } + + public long getBytesRcvd() { + return bytesRcvd; + } + + public String getHostType(){ + return hostType; + } + + } +} diff --git a/usage/src/com/cloud/usage/parser/PortForwardingUsageParser.java b/usage/src/com/cloud/usage/parser/PortForwardingUsageParser.java index 0d160c49386..8acd631e6a3 100644 --- a/usage/src/com/cloud/usage/parser/PortForwardingUsageParser.java +++ b/usage/src/com/cloud/usage/parser/PortForwardingUsageParser.java @@ -10,146 +10,146 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage.parser; - -import java.text.DecimalFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Logger; - -import com.cloud.usage.UsagePortForwardingRuleVO; -import com.cloud.usage.UsageServer; -import com.cloud.usage.UsageTypes; -import com.cloud.usage.UsageVO; -import com.cloud.usage.dao.UsageDao; -import com.cloud.usage.dao.UsagePortForwardingRuleDao; -import com.cloud.user.AccountVO; -import com.cloud.utils.Pair; -import com.cloud.utils.component.ComponentLocator; - -public class PortForwardingUsageParser { - public static final Logger s_logger = Logger.getLogger(PortForwardingUsageParser.class.getName()); - - private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); - private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); - private static UsagePortForwardingRuleDao m_usagePFRuleDao = _locator.getDao(UsagePortForwardingRuleDao.class); - - public static boolean parse(AccountVO account, Date startDate, Date endDate) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Parsing all PortForwardingRule usage events for account: " + account.getId()); - } - if ((endDate == null) || endDate.after(new Date())) { - endDate = new Date(); - } - - // - query usage_volume table with the following criteria: - // - look for an entry for accountId with start date in the given range - // - look for an entry for accountId with end date in the given range - // - look for an entry for accountId with end date null (currently running vm or owned IP) - // - look for an entry for accountId with start date before given range *and* end date after given range - List usagePFs = m_usagePFRuleDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0); - - if(usagePFs.isEmpty()){ - s_logger.debug("No port forwarding usage events for this period"); - return true; - } - - // This map has both the running time *and* the usage amount. - Map> usageMap = new HashMap>(); - Map pfMap = new HashMap(); - - // loop through all the port forwarding rule, create a usage record for each - for (UsagePortForwardingRuleVO usagePF : usagePFs) { - long pfId = usagePF.getId(); - String key = ""+pfId; - - pfMap.put(key, new PFInfo(pfId, usagePF.getZoneId())); - - Date pfCreateDate = usagePF.getCreated(); - Date pfDeleteDate = usagePF.getDeleted(); - - if ((pfDeleteDate == null) || pfDeleteDate.after(endDate)) { - pfDeleteDate = endDate; - } - - // clip the start date to the beginning of our aggregation range if the vm has been running for a while - if (pfCreateDate.before(startDate)) { - pfCreateDate = startDate; - } - - long currentDuration = (pfDeleteDate.getTime() - pfCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) - - - updatePFUsageData(usageMap, key, usagePF.getId(), currentDuration); - } - - for (String pfIdKey : usageMap.keySet()) { - Pair sgtimeInfo = usageMap.get(pfIdKey); - long useTime = sgtimeInfo.second().longValue(); - - // Only create a usage record if we have a runningTime of bigger than zero. - if (useTime > 0L) { - PFInfo info = pfMap.get(pfIdKey); - createUsageRecord(UsageTypes.PORT_FORWARDING_RULE, useTime, startDate, endDate, account, info.getId(), info.getZoneId() ); - } - } - - return true; - } - - private static void updatePFUsageData(Map> usageDataMap, String key, long pfId, long duration) { - Pair pfUsageInfo = usageDataMap.get(key); - if (pfUsageInfo == null) { - pfUsageInfo = new Pair(new Long(pfId), new Long(duration)); - } else { - Long runningTime = pfUsageInfo.second(); - runningTime = new Long(runningTime.longValue() + duration); - pfUsageInfo = new Pair(pfUsageInfo.first(), runningTime); - } - usageDataMap.put(key, pfUsageInfo); - } - - private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long pfId, long zoneId) { - // Our smallest increment is hourly for now - if (s_logger.isDebugEnabled()) { - s_logger.debug("Total running time " + runningTime + "ms"); - } - - float usage = runningTime / 1000f / 60f / 60f; - - DecimalFormat dFormat = new DecimalFormat("#.######"); - String usageDisplay = dFormat.format(usage); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating usage record for port forwarding rule: " + pfId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); - } - - // Create the usage record - String usageDesc = "Port Forwarding Rule: "+pfId+" usage time"; - - //ToDo: get zone id - UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, - new Double(usage), null, null, null, null, pfId, null, startDate, endDate); - m_usageDao.persist(usageRecord); - } - - private static class PFInfo { - private long id; - private long zoneId; - - public PFInfo(long id, long zoneId) { - this.id = id; - this.zoneId = zoneId; - } - public long getZoneId() { - return zoneId; - } - public long getId() { - return id; - } - } - -} +package com.cloud.usage.parser; + +import java.text.DecimalFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.cloud.usage.UsagePortForwardingRuleVO; +import com.cloud.usage.UsageServer; +import com.cloud.usage.UsageTypes; +import com.cloud.usage.UsageVO; +import com.cloud.usage.dao.UsageDao; +import com.cloud.usage.dao.UsagePortForwardingRuleDao; +import com.cloud.user.AccountVO; +import com.cloud.utils.Pair; +import com.cloud.utils.component.ComponentLocator; + +public class PortForwardingUsageParser { + public static final Logger s_logger = Logger.getLogger(PortForwardingUsageParser.class.getName()); + + private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); + private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); + private static UsagePortForwardingRuleDao m_usagePFRuleDao = _locator.getDao(UsagePortForwardingRuleDao.class); + + public static boolean parse(AccountVO account, Date startDate, Date endDate) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Parsing all PortForwardingRule usage events for account: " + account.getId()); + } + if ((endDate == null) || endDate.after(new Date())) { + endDate = new Date(); + } + + // - query usage_volume table with the following criteria: + // - look for an entry for accountId with start date in the given range + // - look for an entry for accountId with end date in the given range + // - look for an entry for accountId with end date null (currently running vm or owned IP) + // - look for an entry for accountId with start date before given range *and* end date after given range + List usagePFs = m_usagePFRuleDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0); + + if(usagePFs.isEmpty()){ + s_logger.debug("No port forwarding usage events for this period"); + return true; + } + + // This map has both the running time *and* the usage amount. + Map> usageMap = new HashMap>(); + Map pfMap = new HashMap(); + + // loop through all the port forwarding rule, create a usage record for each + for (UsagePortForwardingRuleVO usagePF : usagePFs) { + long pfId = usagePF.getId(); + String key = ""+pfId; + + pfMap.put(key, new PFInfo(pfId, usagePF.getZoneId())); + + Date pfCreateDate = usagePF.getCreated(); + Date pfDeleteDate = usagePF.getDeleted(); + + if ((pfDeleteDate == null) || pfDeleteDate.after(endDate)) { + pfDeleteDate = endDate; + } + + // clip the start date to the beginning of our aggregation range if the vm has been running for a while + if (pfCreateDate.before(startDate)) { + pfCreateDate = startDate; + } + + long currentDuration = (pfDeleteDate.getTime() - pfCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) + + + updatePFUsageData(usageMap, key, usagePF.getId(), currentDuration); + } + + for (String pfIdKey : usageMap.keySet()) { + Pair sgtimeInfo = usageMap.get(pfIdKey); + long useTime = sgtimeInfo.second().longValue(); + + // Only create a usage record if we have a runningTime of bigger than zero. + if (useTime > 0L) { + PFInfo info = pfMap.get(pfIdKey); + createUsageRecord(UsageTypes.PORT_FORWARDING_RULE, useTime, startDate, endDate, account, info.getId(), info.getZoneId() ); + } + } + + return true; + } + + private static void updatePFUsageData(Map> usageDataMap, String key, long pfId, long duration) { + Pair pfUsageInfo = usageDataMap.get(key); + if (pfUsageInfo == null) { + pfUsageInfo = new Pair(new Long(pfId), new Long(duration)); + } else { + Long runningTime = pfUsageInfo.second(); + runningTime = new Long(runningTime.longValue() + duration); + pfUsageInfo = new Pair(pfUsageInfo.first(), runningTime); + } + usageDataMap.put(key, pfUsageInfo); + } + + private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long pfId, long zoneId) { + // Our smallest increment is hourly for now + if (s_logger.isDebugEnabled()) { + s_logger.debug("Total running time " + runningTime + "ms"); + } + + float usage = runningTime / 1000f / 60f / 60f; + + DecimalFormat dFormat = new DecimalFormat("#.######"); + String usageDisplay = dFormat.format(usage); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating usage record for port forwarding rule: " + pfId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); + } + + // Create the usage record + String usageDesc = "Port Forwarding Rule: "+pfId+" usage time"; + + //ToDo: get zone id + UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, + new Double(usage), null, null, null, null, pfId, null, startDate, endDate); + m_usageDao.persist(usageRecord); + } + + private static class PFInfo { + private long id; + private long zoneId; + + public PFInfo(long id, long zoneId) { + this.id = id; + this.zoneId = zoneId; + } + public long getZoneId() { + return zoneId; + } + public long getId() { + return id; + } + } + +} diff --git a/usage/src/com/cloud/usage/parser/SecurityGroupUsageParser.java b/usage/src/com/cloud/usage/parser/SecurityGroupUsageParser.java index f8b03ae5434..097944cdc70 100644 --- a/usage/src/com/cloud/usage/parser/SecurityGroupUsageParser.java +++ b/usage/src/com/cloud/usage/parser/SecurityGroupUsageParser.java @@ -10,151 +10,151 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage.parser; - -import java.text.DecimalFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Logger; - -import com.cloud.usage.UsageSecurityGroupVO; -import com.cloud.usage.UsageServer; -import com.cloud.usage.UsageTypes; -import com.cloud.usage.UsageVO; -import com.cloud.usage.dao.UsageDao; -import com.cloud.usage.dao.UsageSecurityGroupDao; -import com.cloud.user.AccountVO; -import com.cloud.utils.Pair; -import com.cloud.utils.component.ComponentLocator; - -public class SecurityGroupUsageParser { - public static final Logger s_logger = Logger.getLogger(SecurityGroupUsageParser.class.getName()); - - private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); - private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); - private static UsageSecurityGroupDao m_usageSecurityGroupDao = _locator.getDao(UsageSecurityGroupDao.class); - - public static boolean parse(AccountVO account, Date startDate, Date endDate) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Parsing all SecurityGroup usage events for account: " + account.getId()); - } - if ((endDate == null) || endDate.after(new Date())) { - endDate = new Date(); - } - - // - query usage_volume table with the following criteria: - // - look for an entry for accountId with start date in the given range - // - look for an entry for accountId with end date in the given range - // - look for an entry for accountId with end date null (currently running vm or owned IP) - // - look for an entry for accountId with start date before given range *and* end date after given range - List usageSGs = m_usageSecurityGroupDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0); - - if(usageSGs.isEmpty()){ - s_logger.debug("No SecurityGroup usage events for this period"); - return true; - } - - // This map has both the running time *and* the usage amount. - Map> usageMap = new HashMap>(); - Map sgMap = new HashMap(); - - // loop through all the security groups, create a usage record for each - for (UsageSecurityGroupVO usageSG : usageSGs) { - long vmId = usageSG.getVmInstanceId(); - long sgId = usageSG.getSecurityGroupId(); - String key = ""+vmId+"SG"+sgId; - - sgMap.put(key, new SGInfo(vmId, usageSG.getZoneId(), sgId)); - - Date sgCreateDate = usageSG.getCreated(); - Date sgDeleteDate = usageSG.getDeleted(); - - if ((sgDeleteDate == null) || sgDeleteDate.after(endDate)) { - sgDeleteDate = endDate; - } - - // clip the start date to the beginning of our aggregation range if the vm has been running for a while - if (sgCreateDate.before(startDate)) { - sgCreateDate = startDate; - } - - long currentDuration = (sgDeleteDate.getTime() - sgCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) - - - updateSGUsageData(usageMap, key, usageSG.getVmInstanceId(), currentDuration); - } - - for (String sgIdKey : usageMap.keySet()) { - Pair sgtimeInfo = usageMap.get(sgIdKey); - long useTime = sgtimeInfo.second().longValue(); - - // Only create a usage record if we have a runningTime of bigger than zero. - if (useTime > 0L) { - SGInfo info = sgMap.get(sgIdKey); - createUsageRecord(UsageTypes.SECURITY_GROUP, useTime, startDate, endDate, account, info.getVmId(), info.getSGId(), info.getZoneId()); - } - } - - return true; - } - - private static void updateSGUsageData(Map> usageDataMap, String key, long vmId, long duration) { - Pair sgUsageInfo = usageDataMap.get(key); - if (sgUsageInfo == null) { - sgUsageInfo = new Pair(new Long(vmId), new Long(duration)); - } else { - Long runningTime = sgUsageInfo.second(); - runningTime = new Long(runningTime.longValue() + duration); - sgUsageInfo = new Pair(sgUsageInfo.first(), runningTime); - } - usageDataMap.put(key, sgUsageInfo); - } - - private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long vmId, long sgId, long zoneId) { - // Our smallest increment is hourly for now - if (s_logger.isDebugEnabled()) { - s_logger.debug("Total running time " + runningTime + "ms"); - } - - float usage = runningTime / 1000f / 60f / 60f; - - DecimalFormat dFormat = new DecimalFormat("#.######"); - String usageDisplay = dFormat.format(usage); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating security group:" + sgId + " usage record for Vm : " + vmId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); - } - - // Create the usage record - String usageDesc = "Security Group: " + sgId + " for Vm : " + vmId + " usage time"; - - UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, - new Double(usage), vmId, null, null, null, sgId, null, startDate, endDate); - m_usageDao.persist(usageRecord); - } - - private static class SGInfo { - private long vmId; - private long zoneId; - private long sgId; - - public SGInfo(long vmId, long zoneId, long sgId) { - this.vmId = vmId; - this.zoneId = zoneId; - this.sgId = sgId; - } - public long getZoneId() { - return zoneId; - } - public long getVmId() { - return vmId; - } - public long getSGId() { - return sgId; - } - } - -} +package com.cloud.usage.parser; + +import java.text.DecimalFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.cloud.usage.UsageSecurityGroupVO; +import com.cloud.usage.UsageServer; +import com.cloud.usage.UsageTypes; +import com.cloud.usage.UsageVO; +import com.cloud.usage.dao.UsageDao; +import com.cloud.usage.dao.UsageSecurityGroupDao; +import com.cloud.user.AccountVO; +import com.cloud.utils.Pair; +import com.cloud.utils.component.ComponentLocator; + +public class SecurityGroupUsageParser { + public static final Logger s_logger = Logger.getLogger(SecurityGroupUsageParser.class.getName()); + + private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); + private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); + private static UsageSecurityGroupDao m_usageSecurityGroupDao = _locator.getDao(UsageSecurityGroupDao.class); + + public static boolean parse(AccountVO account, Date startDate, Date endDate) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Parsing all SecurityGroup usage events for account: " + account.getId()); + } + if ((endDate == null) || endDate.after(new Date())) { + endDate = new Date(); + } + + // - query usage_volume table with the following criteria: + // - look for an entry for accountId with start date in the given range + // - look for an entry for accountId with end date in the given range + // - look for an entry for accountId with end date null (currently running vm or owned IP) + // - look for an entry for accountId with start date before given range *and* end date after given range + List usageSGs = m_usageSecurityGroupDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0); + + if(usageSGs.isEmpty()){ + s_logger.debug("No SecurityGroup usage events for this period"); + return true; + } + + // This map has both the running time *and* the usage amount. + Map> usageMap = new HashMap>(); + Map sgMap = new HashMap(); + + // loop through all the security groups, create a usage record for each + for (UsageSecurityGroupVO usageSG : usageSGs) { + long vmId = usageSG.getVmInstanceId(); + long sgId = usageSG.getSecurityGroupId(); + String key = ""+vmId+"SG"+sgId; + + sgMap.put(key, new SGInfo(vmId, usageSG.getZoneId(), sgId)); + + Date sgCreateDate = usageSG.getCreated(); + Date sgDeleteDate = usageSG.getDeleted(); + + if ((sgDeleteDate == null) || sgDeleteDate.after(endDate)) { + sgDeleteDate = endDate; + } + + // clip the start date to the beginning of our aggregation range if the vm has been running for a while + if (sgCreateDate.before(startDate)) { + sgCreateDate = startDate; + } + + long currentDuration = (sgDeleteDate.getTime() - sgCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) + + + updateSGUsageData(usageMap, key, usageSG.getVmInstanceId(), currentDuration); + } + + for (String sgIdKey : usageMap.keySet()) { + Pair sgtimeInfo = usageMap.get(sgIdKey); + long useTime = sgtimeInfo.second().longValue(); + + // Only create a usage record if we have a runningTime of bigger than zero. + if (useTime > 0L) { + SGInfo info = sgMap.get(sgIdKey); + createUsageRecord(UsageTypes.SECURITY_GROUP, useTime, startDate, endDate, account, info.getVmId(), info.getSGId(), info.getZoneId()); + } + } + + return true; + } + + private static void updateSGUsageData(Map> usageDataMap, String key, long vmId, long duration) { + Pair sgUsageInfo = usageDataMap.get(key); + if (sgUsageInfo == null) { + sgUsageInfo = new Pair(new Long(vmId), new Long(duration)); + } else { + Long runningTime = sgUsageInfo.second(); + runningTime = new Long(runningTime.longValue() + duration); + sgUsageInfo = new Pair(sgUsageInfo.first(), runningTime); + } + usageDataMap.put(key, sgUsageInfo); + } + + private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long vmId, long sgId, long zoneId) { + // Our smallest increment is hourly for now + if (s_logger.isDebugEnabled()) { + s_logger.debug("Total running time " + runningTime + "ms"); + } + + float usage = runningTime / 1000f / 60f / 60f; + + DecimalFormat dFormat = new DecimalFormat("#.######"); + String usageDisplay = dFormat.format(usage); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating security group:" + sgId + " usage record for Vm : " + vmId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); + } + + // Create the usage record + String usageDesc = "Security Group: " + sgId + " for Vm : " + vmId + " usage time"; + + UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, + new Double(usage), vmId, null, null, null, sgId, null, startDate, endDate); + m_usageDao.persist(usageRecord); + } + + private static class SGInfo { + private long vmId; + private long zoneId; + private long sgId; + + public SGInfo(long vmId, long zoneId, long sgId) { + this.vmId = vmId; + this.zoneId = zoneId; + this.sgId = sgId; + } + public long getZoneId() { + return zoneId; + } + public long getVmId() { + return vmId; + } + public long getSGId() { + return sgId; + } + } + +} diff --git a/usage/src/com/cloud/usage/parser/StorageUsageParser.java b/usage/src/com/cloud/usage/parser/StorageUsageParser.java index a61c24baf37..ea974eaa0c4 100644 --- a/usage/src/com/cloud/usage/parser/StorageUsageParser.java +++ b/usage/src/com/cloud/usage/parser/StorageUsageParser.java @@ -10,192 +10,192 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage.parser; - -import java.text.DecimalFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Logger; - -import com.cloud.usage.StorageTypes; -import com.cloud.usage.UsageServer; -import com.cloud.usage.UsageStorageVO; -import com.cloud.usage.UsageTypes; -import com.cloud.usage.UsageVO; -import com.cloud.usage.dao.UsageDao; -import com.cloud.usage.dao.UsageStorageDao; -import com.cloud.user.AccountVO; -import com.cloud.utils.Pair; -import com.cloud.utils.component.ComponentLocator; - -public class StorageUsageParser { - public static final Logger s_logger = Logger.getLogger(StorageUsageParser.class.getName()); - - private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); - private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); - private static UsageStorageDao m_usageStorageDao = _locator.getDao(UsageStorageDao.class); - - public static boolean parse(AccountVO account, Date startDate, Date endDate) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Parsing all Storage usage events for account: " + account.getId()); - } - if ((endDate == null) || endDate.after(new Date())) { - endDate = new Date(); - } - - // - query usage_volume table with the following criteria: - // - look for an entry for accountId with start date in the given range - // - look for an entry for accountId with end date in the given range - // - look for an entry for accountId with end date null (currently running vm or owned IP) - // - look for an entry for accountId with start date before given range *and* end date after given range - List usageUsageStorages = m_usageStorageDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0); - - if(usageUsageStorages.isEmpty()){ - s_logger.debug("No Storage usage events for this period"); - return true; - } - - // This map has both the running time *and* the usage amount. - Map> usageMap = new HashMap>(); - - Map storageMap = new HashMap(); - - // loop through all the usage volumes, create a usage record for each - for (UsageStorageVO usageStorage : usageUsageStorages) { - long storageId = usageStorage.getId(); - int storage_type = usageStorage.getStorageType(); - long size = usageStorage.getSize(); - long zoneId = usageStorage.getZoneId(); - Long sourceId = usageStorage.getSourceId(); - - String key = ""+storageId+"Z"+zoneId+"T"+storage_type; - - // store the info in the storage map - storageMap.put(key, new StorageInfo(zoneId, storageId, storage_type, sourceId, size)); - - Date storageCreateDate = usageStorage.getCreated(); - Date storageDeleteDate = usageStorage.getDeleted(); - - if ((storageDeleteDate == null) || storageDeleteDate.after(endDate)) { - storageDeleteDate = endDate; - } - - // clip the start date to the beginning of our aggregation range if the vm has been running for a while - if (storageCreateDate.before(startDate)) { - storageCreateDate = startDate; - } - - long currentDuration = (storageDeleteDate.getTime() - storageCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) - - updateStorageUsageData(usageMap, key, usageStorage.getId(), currentDuration); - } - - for (String storageIdKey : usageMap.keySet()) { - Pair storagetimeInfo = usageMap.get(storageIdKey); - long useTime = storagetimeInfo.second().longValue(); - - // Only create a usage record if we have a runningTime of bigger than zero. - if (useTime > 0L) { - StorageInfo info = storageMap.get(storageIdKey); - createUsageRecord(info.getZoneId(), info.getStorageType(), useTime, startDate, endDate, account, info.getStorageId(), info.getSourceId(), info.getSize()); - } - } - - return true; - } - - private static void updateStorageUsageData(Map> usageDataMap, String key, long storageId, long duration) { - Pair volUsageInfo = usageDataMap.get(key); - if (volUsageInfo == null) { - volUsageInfo = new Pair(new Long(storageId), new Long(duration)); - } else { - Long runningTime = volUsageInfo.second(); - runningTime = new Long(runningTime.longValue() + duration); - volUsageInfo = new Pair(volUsageInfo.first(), runningTime); - } - usageDataMap.put(key, volUsageInfo); - } - - private static void createUsageRecord(long zoneId, int type, long runningTime, Date startDate, Date endDate, AccountVO account, long storageId, Long sourceId, long size) { - // Our smallest increment is hourly for now - if (s_logger.isDebugEnabled()) { - s_logger.debug("Total running time " + runningTime + "ms"); - } - - float usage = runningTime / 1000f / 60f / 60f; - - DecimalFormat dFormat = new DecimalFormat("#.######"); - String usageDisplay = dFormat.format(usage); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating Storage usage record for type: "+ type + " with id: " + storageId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); - } - - String usageDesc = ""; - Long tmplSourceId = null; - - int usage_type = 0; - switch(type){ - case StorageTypes.TEMPLATE: - usage_type = UsageTypes.TEMPLATE; - usageDesc += "Template "; - tmplSourceId = sourceId; - break; - case StorageTypes.ISO: - usage_type = UsageTypes.ISO; - usageDesc += "ISO "; - break; - case StorageTypes.SNAPSHOT: - usage_type = UsageTypes.SNAPSHOT; - usageDesc += "Snapshot "; - break; - } - // Create the usage record - usageDesc += "Id:"+storageId+" Size:"+size; - - //ToDo: get zone id - UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", usage_type, - new Double(usage), null, null, null, tmplSourceId, storageId, size, startDate, endDate); - m_usageDao.persist(usageRecord); - } - - private static class StorageInfo { - private long zoneId; - private long storageId; - private int storageType; - private Long sourceId; - private long size; - - public StorageInfo(long zoneId, long storageId, int storageType, Long sourceId, long size) { - this.zoneId = zoneId; - this.storageId = storageId; - this.storageType = storageType; - this.sourceId = sourceId; - this.size = size; - } - - public long getZoneId() { - return zoneId; - } - - public long getStorageId() { - return storageId; - } - - public int getStorageType() { - return storageType; - } - - public long getSourceId() { - return sourceId; - } - - - public long getSize() { - return size; - } - } -} +package com.cloud.usage.parser; + +import java.text.DecimalFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.cloud.usage.StorageTypes; +import com.cloud.usage.UsageServer; +import com.cloud.usage.UsageStorageVO; +import com.cloud.usage.UsageTypes; +import com.cloud.usage.UsageVO; +import com.cloud.usage.dao.UsageDao; +import com.cloud.usage.dao.UsageStorageDao; +import com.cloud.user.AccountVO; +import com.cloud.utils.Pair; +import com.cloud.utils.component.ComponentLocator; + +public class StorageUsageParser { + public static final Logger s_logger = Logger.getLogger(StorageUsageParser.class.getName()); + + private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); + private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); + private static UsageStorageDao m_usageStorageDao = _locator.getDao(UsageStorageDao.class); + + public static boolean parse(AccountVO account, Date startDate, Date endDate) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Parsing all Storage usage events for account: " + account.getId()); + } + if ((endDate == null) || endDate.after(new Date())) { + endDate = new Date(); + } + + // - query usage_volume table with the following criteria: + // - look for an entry for accountId with start date in the given range + // - look for an entry for accountId with end date in the given range + // - look for an entry for accountId with end date null (currently running vm or owned IP) + // - look for an entry for accountId with start date before given range *and* end date after given range + List usageUsageStorages = m_usageStorageDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0); + + if(usageUsageStorages.isEmpty()){ + s_logger.debug("No Storage usage events for this period"); + return true; + } + + // This map has both the running time *and* the usage amount. + Map> usageMap = new HashMap>(); + + Map storageMap = new HashMap(); + + // loop through all the usage volumes, create a usage record for each + for (UsageStorageVO usageStorage : usageUsageStorages) { + long storageId = usageStorage.getId(); + int storage_type = usageStorage.getStorageType(); + long size = usageStorage.getSize(); + long zoneId = usageStorage.getZoneId(); + Long sourceId = usageStorage.getSourceId(); + + String key = ""+storageId+"Z"+zoneId+"T"+storage_type; + + // store the info in the storage map + storageMap.put(key, new StorageInfo(zoneId, storageId, storage_type, sourceId, size)); + + Date storageCreateDate = usageStorage.getCreated(); + Date storageDeleteDate = usageStorage.getDeleted(); + + if ((storageDeleteDate == null) || storageDeleteDate.after(endDate)) { + storageDeleteDate = endDate; + } + + // clip the start date to the beginning of our aggregation range if the vm has been running for a while + if (storageCreateDate.before(startDate)) { + storageCreateDate = startDate; + } + + long currentDuration = (storageDeleteDate.getTime() - storageCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) + + updateStorageUsageData(usageMap, key, usageStorage.getId(), currentDuration); + } + + for (String storageIdKey : usageMap.keySet()) { + Pair storagetimeInfo = usageMap.get(storageIdKey); + long useTime = storagetimeInfo.second().longValue(); + + // Only create a usage record if we have a runningTime of bigger than zero. + if (useTime > 0L) { + StorageInfo info = storageMap.get(storageIdKey); + createUsageRecord(info.getZoneId(), info.getStorageType(), useTime, startDate, endDate, account, info.getStorageId(), info.getSourceId(), info.getSize()); + } + } + + return true; + } + + private static void updateStorageUsageData(Map> usageDataMap, String key, long storageId, long duration) { + Pair volUsageInfo = usageDataMap.get(key); + if (volUsageInfo == null) { + volUsageInfo = new Pair(new Long(storageId), new Long(duration)); + } else { + Long runningTime = volUsageInfo.second(); + runningTime = new Long(runningTime.longValue() + duration); + volUsageInfo = new Pair(volUsageInfo.first(), runningTime); + } + usageDataMap.put(key, volUsageInfo); + } + + private static void createUsageRecord(long zoneId, int type, long runningTime, Date startDate, Date endDate, AccountVO account, long storageId, Long sourceId, long size) { + // Our smallest increment is hourly for now + if (s_logger.isDebugEnabled()) { + s_logger.debug("Total running time " + runningTime + "ms"); + } + + float usage = runningTime / 1000f / 60f / 60f; + + DecimalFormat dFormat = new DecimalFormat("#.######"); + String usageDisplay = dFormat.format(usage); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating Storage usage record for type: "+ type + " with id: " + storageId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); + } + + String usageDesc = ""; + Long tmplSourceId = null; + + int usage_type = 0; + switch(type){ + case StorageTypes.TEMPLATE: + usage_type = UsageTypes.TEMPLATE; + usageDesc += "Template "; + tmplSourceId = sourceId; + break; + case StorageTypes.ISO: + usage_type = UsageTypes.ISO; + usageDesc += "ISO "; + break; + case StorageTypes.SNAPSHOT: + usage_type = UsageTypes.SNAPSHOT; + usageDesc += "Snapshot "; + break; + } + // Create the usage record + usageDesc += "Id:"+storageId+" Size:"+size; + + //ToDo: get zone id + UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", usage_type, + new Double(usage), null, null, null, tmplSourceId, storageId, size, startDate, endDate); + m_usageDao.persist(usageRecord); + } + + private static class StorageInfo { + private long zoneId; + private long storageId; + private int storageType; + private Long sourceId; + private long size; + + public StorageInfo(long zoneId, long storageId, int storageType, Long sourceId, long size) { + this.zoneId = zoneId; + this.storageId = storageId; + this.storageType = storageType; + this.sourceId = sourceId; + this.size = size; + } + + public long getZoneId() { + return zoneId; + } + + public long getStorageId() { + return storageId; + } + + public int getStorageType() { + return storageType; + } + + public long getSourceId() { + return sourceId; + } + + + public long getSize() { + return size; + } + } +} diff --git a/usage/src/com/cloud/usage/parser/UsageParser.java b/usage/src/com/cloud/usage/parser/UsageParser.java index 1b909a86a83..204ed4a305f 100644 --- a/usage/src/com/cloud/usage/parser/UsageParser.java +++ b/usage/src/com/cloud/usage/parser/UsageParser.java @@ -10,22 +10,22 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage.parser; - -import java.util.Date; - -import org.apache.log4j.Logger; - -public abstract class UsageParser implements Runnable { - public static final Logger s_logger = Logger.getLogger(UsageParser.class.getName()); - - public void run() { - try { - parse(null); - } catch (Exception e) { - s_logger.warn("Error while parsing usage events", e); - } - } - - public abstract void parse(Date endDate); -} +package com.cloud.usage.parser; + +import java.util.Date; + +import org.apache.log4j.Logger; + +public abstract class UsageParser implements Runnable { + public static final Logger s_logger = Logger.getLogger(UsageParser.class.getName()); + + public void run() { + try { + parse(null); + } catch (Exception e) { + s_logger.warn("Error while parsing usage events", e); + } + } + + public abstract void parse(Date endDate); +} diff --git a/usage/src/com/cloud/usage/parser/VMInstanceUsageParser.java b/usage/src/com/cloud/usage/parser/VMInstanceUsageParser.java index 5aada74f3e7..3c542fb856e 100644 --- a/usage/src/com/cloud/usage/parser/VMInstanceUsageParser.java +++ b/usage/src/com/cloud/usage/parser/VMInstanceUsageParser.java @@ -10,187 +10,187 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage.parser; - -import java.text.DecimalFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Logger; - -import com.cloud.usage.UsageServer; -import com.cloud.usage.UsageTypes; -import com.cloud.usage.UsageVMInstanceVO; -import com.cloud.usage.UsageVO; -import com.cloud.usage.dao.UsageDao; -import com.cloud.usage.dao.UsageVMInstanceDao; -import com.cloud.user.AccountVO; -import com.cloud.utils.Pair; -import com.cloud.utils.component.ComponentLocator; - -public class VMInstanceUsageParser { - public static final Logger s_logger = Logger.getLogger(VMInstanceUsageParser.class.getName()); - - private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); - private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); - private static UsageVMInstanceDao m_usageInstanceDao = _locator.getDao(UsageVMInstanceDao.class); - - public static boolean parse(AccountVO account, Date startDate, Date endDate) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Parsing all VMInstance usage events for account: " + account.getId()); - } - if ((endDate == null) || endDate.after(new Date())) { - endDate = new Date(); - } - - // - query usage_vm_instance table with the following criteria: - // - look for an entry for accountId with start date in the given range - // - look for an entry for accountId with end date in the given range - // - look for an entry for accountId with end date null (currently running vm or owned IP) - // - look for an entry for accountId with start date before given range *and* end date after given range - List usageInstances = m_usageInstanceDao.getUsageRecords(account.getId(), startDate, endDate); -//ToDo: Add domainID for getting usage records - - // This map has both the running time *and* the usage amount. - Map> usageVMUptimeMap = new HashMap>(); - Map> allocatedVMMap = new HashMap>(); - - Map vmServiceOfferingMap = new HashMap(); - - // loop through all the usage instances, create a usage record for each - for (UsageVMInstanceVO usageInstance : usageInstances) { - long vmId = usageInstance.getVmInstanceId(); - long soId = usageInstance.getSerivceOfferingId(); - long zoneId = usageInstance.getZoneId(); - long tId = usageInstance.getTemplateId(); - int usageType = usageInstance.getUsageType(); - String key = vmId + "-" + soId + "-" + usageType; - - // store the info in the service offering map - vmServiceOfferingMap.put(key, new VMInfo(vmId, zoneId, soId, tId, usageInstance.getHypervisorType())); - - Date vmStartDate = usageInstance.getStartDate(); - Date vmEndDate = usageInstance.getEndDate(); - - if ((vmEndDate == null) || vmEndDate.after(endDate)) { - vmEndDate = endDate; - } - - // clip the start date to the beginning of our aggregation range if the vm has been running for a while - if (vmStartDate.before(startDate)) { - vmStartDate = startDate; - } - - long currentDuration = (vmEndDate.getTime() - vmStartDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) - - switch (usageType) { - case UsageTypes.ALLOCATED_VM: - updateVmUsageData(allocatedVMMap, key, usageInstance.getVmName(), currentDuration); - break; - case UsageTypes.RUNNING_VM: - updateVmUsageData(usageVMUptimeMap, key, usageInstance.getVmName(), currentDuration); - break; - } - } - - for (String vmIdKey : usageVMUptimeMap.keySet()) { - Pair vmUptimeInfo = usageVMUptimeMap.get(vmIdKey); - long runningTime = vmUptimeInfo.second().longValue(); - - // Only create a usage record if we have a runningTime of bigger than zero. - if (runningTime > 0L) { - VMInfo info = vmServiceOfferingMap.get(vmIdKey); - createUsageRecord(UsageTypes.RUNNING_VM, runningTime, startDate, endDate, account, info.getVirtualMachineId(), vmUptimeInfo.first(), info.getZoneId(), - info.getServiceOfferingId(), info.getTemplateId(), info.getHypervisorType()); - } - } - - for (String vmIdKey : allocatedVMMap.keySet()) { - Pair vmAllocInfo = allocatedVMMap.get(vmIdKey); - long allocatedTime = vmAllocInfo.second().longValue(); - - // Only create a usage record if we have a runningTime of bigger than zero. - if (allocatedTime > 0L) { - VMInfo info = vmServiceOfferingMap.get(vmIdKey); - createUsageRecord(UsageTypes.ALLOCATED_VM, allocatedTime, startDate, endDate, account, info.getVirtualMachineId(), vmAllocInfo.first(), info.getZoneId(), - info.getServiceOfferingId(), info.getTemplateId(), info.getHypervisorType()); - } - } - - return true; - } - - private static void updateVmUsageData(Map> usageDataMap, String key, String vmName, long duration) { - Pair vmUsageInfo = usageDataMap.get(key); - if (vmUsageInfo == null) { - vmUsageInfo = new Pair(vmName, new Long(duration)); - } else { - Long runningTime = vmUsageInfo.second(); - runningTime = new Long(runningTime.longValue() + duration); - vmUsageInfo = new Pair(vmUsageInfo.first(), runningTime); - } - usageDataMap.put(key, vmUsageInfo); - } - - private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long vmId, String vmName, long zoneId, long serviceOfferingId, long templateId, String hypervisorType) { - // Our smallest increment is hourly for now - if (s_logger.isDebugEnabled()) { - s_logger.debug("Total running time " + runningTime + "ms"); - } - - float usage = runningTime / 1000f / 60f / 60f; - - DecimalFormat dFormat = new DecimalFormat("#.######"); - String usageDisplay = dFormat.format(usage); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating VM usage record for vm: " + vmName + ", type: " + type + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); - } - - // Create the usage record - String usageDesc = vmName; - if (type == UsageTypes.ALLOCATED_VM) { - usageDesc += " allocated"; - } else { - usageDesc += " running time"; - } - usageDesc += " (ServiceOffering: " + serviceOfferingId + ") (Template: " + templateId + ")"; - UsageVO usageRecord = new UsageVO(Long.valueOf(zoneId), account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, - new Double(usage), Long.valueOf(vmId), vmName, Long.valueOf(serviceOfferingId), Long.valueOf(templateId), Long.valueOf(vmId), startDate, endDate, hypervisorType); - m_usageDao.persist(usageRecord); - } - - private static class VMInfo { - private long virtualMachineId; - private long zoneId; - private long serviceOfferingId; - private long templateId; - private String hypervisorType; - - public VMInfo(long vmId, long zId, long soId, long tId, String hypervisorType) { - virtualMachineId = vmId; - zoneId = zId; - serviceOfferingId = soId; - templateId = tId; - this.hypervisorType = hypervisorType; - } - - public long getZoneId() { - return zoneId; - } - public long getVirtualMachineId() { - return virtualMachineId; - } - public long getServiceOfferingId() { - return serviceOfferingId; - } - public long getTemplateId() { - return templateId; - } - private String getHypervisorType(){ - return hypervisorType; - } - } -} +package com.cloud.usage.parser; + +import java.text.DecimalFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.cloud.usage.UsageServer; +import com.cloud.usage.UsageTypes; +import com.cloud.usage.UsageVMInstanceVO; +import com.cloud.usage.UsageVO; +import com.cloud.usage.dao.UsageDao; +import com.cloud.usage.dao.UsageVMInstanceDao; +import com.cloud.user.AccountVO; +import com.cloud.utils.Pair; +import com.cloud.utils.component.ComponentLocator; + +public class VMInstanceUsageParser { + public static final Logger s_logger = Logger.getLogger(VMInstanceUsageParser.class.getName()); + + private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); + private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); + private static UsageVMInstanceDao m_usageInstanceDao = _locator.getDao(UsageVMInstanceDao.class); + + public static boolean parse(AccountVO account, Date startDate, Date endDate) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Parsing all VMInstance usage events for account: " + account.getId()); + } + if ((endDate == null) || endDate.after(new Date())) { + endDate = new Date(); + } + + // - query usage_vm_instance table with the following criteria: + // - look for an entry for accountId with start date in the given range + // - look for an entry for accountId with end date in the given range + // - look for an entry for accountId with end date null (currently running vm or owned IP) + // - look for an entry for accountId with start date before given range *and* end date after given range + List usageInstances = m_usageInstanceDao.getUsageRecords(account.getId(), startDate, endDate); +//ToDo: Add domainID for getting usage records + + // This map has both the running time *and* the usage amount. + Map> usageVMUptimeMap = new HashMap>(); + Map> allocatedVMMap = new HashMap>(); + + Map vmServiceOfferingMap = new HashMap(); + + // loop through all the usage instances, create a usage record for each + for (UsageVMInstanceVO usageInstance : usageInstances) { + long vmId = usageInstance.getVmInstanceId(); + long soId = usageInstance.getSerivceOfferingId(); + long zoneId = usageInstance.getZoneId(); + long tId = usageInstance.getTemplateId(); + int usageType = usageInstance.getUsageType(); + String key = vmId + "-" + soId + "-" + usageType; + + // store the info in the service offering map + vmServiceOfferingMap.put(key, new VMInfo(vmId, zoneId, soId, tId, usageInstance.getHypervisorType())); + + Date vmStartDate = usageInstance.getStartDate(); + Date vmEndDate = usageInstance.getEndDate(); + + if ((vmEndDate == null) || vmEndDate.after(endDate)) { + vmEndDate = endDate; + } + + // clip the start date to the beginning of our aggregation range if the vm has been running for a while + if (vmStartDate.before(startDate)) { + vmStartDate = startDate; + } + + long currentDuration = (vmEndDate.getTime() - vmStartDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) + + switch (usageType) { + case UsageTypes.ALLOCATED_VM: + updateVmUsageData(allocatedVMMap, key, usageInstance.getVmName(), currentDuration); + break; + case UsageTypes.RUNNING_VM: + updateVmUsageData(usageVMUptimeMap, key, usageInstance.getVmName(), currentDuration); + break; + } + } + + for (String vmIdKey : usageVMUptimeMap.keySet()) { + Pair vmUptimeInfo = usageVMUptimeMap.get(vmIdKey); + long runningTime = vmUptimeInfo.second().longValue(); + + // Only create a usage record if we have a runningTime of bigger than zero. + if (runningTime > 0L) { + VMInfo info = vmServiceOfferingMap.get(vmIdKey); + createUsageRecord(UsageTypes.RUNNING_VM, runningTime, startDate, endDate, account, info.getVirtualMachineId(), vmUptimeInfo.first(), info.getZoneId(), + info.getServiceOfferingId(), info.getTemplateId(), info.getHypervisorType()); + } + } + + for (String vmIdKey : allocatedVMMap.keySet()) { + Pair vmAllocInfo = allocatedVMMap.get(vmIdKey); + long allocatedTime = vmAllocInfo.second().longValue(); + + // Only create a usage record if we have a runningTime of bigger than zero. + if (allocatedTime > 0L) { + VMInfo info = vmServiceOfferingMap.get(vmIdKey); + createUsageRecord(UsageTypes.ALLOCATED_VM, allocatedTime, startDate, endDate, account, info.getVirtualMachineId(), vmAllocInfo.first(), info.getZoneId(), + info.getServiceOfferingId(), info.getTemplateId(), info.getHypervisorType()); + } + } + + return true; + } + + private static void updateVmUsageData(Map> usageDataMap, String key, String vmName, long duration) { + Pair vmUsageInfo = usageDataMap.get(key); + if (vmUsageInfo == null) { + vmUsageInfo = new Pair(vmName, new Long(duration)); + } else { + Long runningTime = vmUsageInfo.second(); + runningTime = new Long(runningTime.longValue() + duration); + vmUsageInfo = new Pair(vmUsageInfo.first(), runningTime); + } + usageDataMap.put(key, vmUsageInfo); + } + + private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long vmId, String vmName, long zoneId, long serviceOfferingId, long templateId, String hypervisorType) { + // Our smallest increment is hourly for now + if (s_logger.isDebugEnabled()) { + s_logger.debug("Total running time " + runningTime + "ms"); + } + + float usage = runningTime / 1000f / 60f / 60f; + + DecimalFormat dFormat = new DecimalFormat("#.######"); + String usageDisplay = dFormat.format(usage); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating VM usage record for vm: " + vmName + ", type: " + type + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); + } + + // Create the usage record + String usageDesc = vmName; + if (type == UsageTypes.ALLOCATED_VM) { + usageDesc += " allocated"; + } else { + usageDesc += " running time"; + } + usageDesc += " (ServiceOffering: " + serviceOfferingId + ") (Template: " + templateId + ")"; + UsageVO usageRecord = new UsageVO(Long.valueOf(zoneId), account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, + new Double(usage), Long.valueOf(vmId), vmName, Long.valueOf(serviceOfferingId), Long.valueOf(templateId), Long.valueOf(vmId), startDate, endDate, hypervisorType); + m_usageDao.persist(usageRecord); + } + + private static class VMInfo { + private long virtualMachineId; + private long zoneId; + private long serviceOfferingId; + private long templateId; + private String hypervisorType; + + public VMInfo(long vmId, long zId, long soId, long tId, String hypervisorType) { + virtualMachineId = vmId; + zoneId = zId; + serviceOfferingId = soId; + templateId = tId; + this.hypervisorType = hypervisorType; + } + + public long getZoneId() { + return zoneId; + } + public long getVirtualMachineId() { + return virtualMachineId; + } + public long getServiceOfferingId() { + return serviceOfferingId; + } + public long getTemplateId() { + return templateId; + } + private String getHypervisorType(){ + return hypervisorType; + } + } +} diff --git a/usage/src/com/cloud/usage/parser/VPNUserUsageParser.java b/usage/src/com/cloud/usage/parser/VPNUserUsageParser.java index 504e08c420a..10bb15673d8 100644 --- a/usage/src/com/cloud/usage/parser/VPNUserUsageParser.java +++ b/usage/src/com/cloud/usage/parser/VPNUserUsageParser.java @@ -10,146 +10,146 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage.parser; - -import java.text.DecimalFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Logger; - -import com.cloud.usage.UsageVPNUserVO; -import com.cloud.usage.UsageServer; -import com.cloud.usage.UsageTypes; -import com.cloud.usage.UsageVO; -import com.cloud.usage.dao.UsageDao; -import com.cloud.usage.dao.UsageVPNUserDao; -import com.cloud.user.AccountVO; -import com.cloud.utils.Pair; -import com.cloud.utils.component.ComponentLocator; - -public class VPNUserUsageParser { - public static final Logger s_logger = Logger.getLogger(VPNUserUsageParser.class.getName()); - - private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); - private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); - private static UsageVPNUserDao m_usageVPNUserDao = _locator.getDao(UsageVPNUserDao.class); - - public static boolean parse(AccountVO account, Date startDate, Date endDate) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Parsing all VPN user usage events for account: " + account.getId()); - } - if ((endDate == null) || endDate.after(new Date())) { - endDate = new Date(); - } - - List usageVUs = m_usageVPNUserDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0); - - if(usageVUs.isEmpty()){ - s_logger.debug("No VPN user usage events for this period"); - return true; - } - - // This map has both the running time *and* the usage amount. - Map> usageMap = new HashMap>(); - Map vuMap = new HashMap(); - - // loop through all the VPN user usage, create a usage record for each - for (UsageVPNUserVO usageVU : usageVUs) { - long userId = usageVU.getUserId(); - String userName = usageVU.getUsername(); - String key = ""+userId+"VU"+userName; - - vuMap.put(key, new VUInfo(userId, usageVU.getZoneId(), userName)); - - Date vuCreateDate = usageVU.getCreated(); - Date vuDeleteDate = usageVU.getDeleted(); - - if ((vuDeleteDate == null) || vuDeleteDate.after(endDate)) { - vuDeleteDate = endDate; - } - - // clip the start date to the beginning of our aggregation range if the vm has been running for a while - if (vuCreateDate.before(startDate)) { - vuCreateDate = startDate; - } - - long currentDuration = (vuDeleteDate.getTime() - vuCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) - - - updateVUUsageData(usageMap, key, usageVU.getUserId(), currentDuration); - } - - for (String vuIdKey : usageMap.keySet()) { - Pair vutimeInfo = usageMap.get(vuIdKey); - long useTime = vutimeInfo.second().longValue(); - - // Only create a usage record if we have a runningTime of bigger than zero. - if (useTime > 0L) { - VUInfo info = vuMap.get(vuIdKey); - createUsageRecord(UsageTypes.VPN_USERS, useTime, startDate, endDate, account, info.getUserId(), info.getUserName(), info.getZoneId()); - } - } - - return true; - } - - private static void updateVUUsageData(Map> usageDataMap, String key, long userId, long duration) { - Pair vuUsageInfo = usageDataMap.get(key); - if (vuUsageInfo == null) { - vuUsageInfo = new Pair(new Long(userId), new Long(duration)); - } else { - Long runningTime = vuUsageInfo.second(); - runningTime = new Long(runningTime.longValue() + duration); - vuUsageInfo = new Pair(vuUsageInfo.first(), runningTime); - } - usageDataMap.put(key, vuUsageInfo); - } - - private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long userId, String userName, long zoneId) { - // Our smallest increment is hourly for now - if (s_logger.isDebugEnabled()) { - s_logger.debug("Total running time " + runningTime + "ms"); - } - - float usage = runningTime / 1000f / 60f / 60f; - - DecimalFormat dFormat = new DecimalFormat("#.######"); - String usageDisplay = dFormat.format(usage); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating VPN user:" + userId + " usage record, usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); - } - - // Create the usage record - String usageDesc = "VPN User: " + userName + ", Id: "+ userId + " usage time"; - - UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, - new Double(usage), null, null, null, null, userId, null, startDate, endDate); - m_usageDao.persist(usageRecord); - } - - private static class VUInfo { - private long userId; - private long zoneId; - private String userName; - - public VUInfo(long userId, long zoneId, String userName) { - this.userId = userId; - this.zoneId = zoneId; - this.userName = userName; - } - public long getZoneId() { - return zoneId; - } - public long getUserId() { - return userId; - } - public String getUserName() { - return userName; - } - } - -} +package com.cloud.usage.parser; + +import java.text.DecimalFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.cloud.usage.UsageVPNUserVO; +import com.cloud.usage.UsageServer; +import com.cloud.usage.UsageTypes; +import com.cloud.usage.UsageVO; +import com.cloud.usage.dao.UsageDao; +import com.cloud.usage.dao.UsageVPNUserDao; +import com.cloud.user.AccountVO; +import com.cloud.utils.Pair; +import com.cloud.utils.component.ComponentLocator; + +public class VPNUserUsageParser { + public static final Logger s_logger = Logger.getLogger(VPNUserUsageParser.class.getName()); + + private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); + private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); + private static UsageVPNUserDao m_usageVPNUserDao = _locator.getDao(UsageVPNUserDao.class); + + public static boolean parse(AccountVO account, Date startDate, Date endDate) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Parsing all VPN user usage events for account: " + account.getId()); + } + if ((endDate == null) || endDate.after(new Date())) { + endDate = new Date(); + } + + List usageVUs = m_usageVPNUserDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0); + + if(usageVUs.isEmpty()){ + s_logger.debug("No VPN user usage events for this period"); + return true; + } + + // This map has both the running time *and* the usage amount. + Map> usageMap = new HashMap>(); + Map vuMap = new HashMap(); + + // loop through all the VPN user usage, create a usage record for each + for (UsageVPNUserVO usageVU : usageVUs) { + long userId = usageVU.getUserId(); + String userName = usageVU.getUsername(); + String key = ""+userId+"VU"+userName; + + vuMap.put(key, new VUInfo(userId, usageVU.getZoneId(), userName)); + + Date vuCreateDate = usageVU.getCreated(); + Date vuDeleteDate = usageVU.getDeleted(); + + if ((vuDeleteDate == null) || vuDeleteDate.after(endDate)) { + vuDeleteDate = endDate; + } + + // clip the start date to the beginning of our aggregation range if the vm has been running for a while + if (vuCreateDate.before(startDate)) { + vuCreateDate = startDate; + } + + long currentDuration = (vuDeleteDate.getTime() - vuCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) + + + updateVUUsageData(usageMap, key, usageVU.getUserId(), currentDuration); + } + + for (String vuIdKey : usageMap.keySet()) { + Pair vutimeInfo = usageMap.get(vuIdKey); + long useTime = vutimeInfo.second().longValue(); + + // Only create a usage record if we have a runningTime of bigger than zero. + if (useTime > 0L) { + VUInfo info = vuMap.get(vuIdKey); + createUsageRecord(UsageTypes.VPN_USERS, useTime, startDate, endDate, account, info.getUserId(), info.getUserName(), info.getZoneId()); + } + } + + return true; + } + + private static void updateVUUsageData(Map> usageDataMap, String key, long userId, long duration) { + Pair vuUsageInfo = usageDataMap.get(key); + if (vuUsageInfo == null) { + vuUsageInfo = new Pair(new Long(userId), new Long(duration)); + } else { + Long runningTime = vuUsageInfo.second(); + runningTime = new Long(runningTime.longValue() + duration); + vuUsageInfo = new Pair(vuUsageInfo.first(), runningTime); + } + usageDataMap.put(key, vuUsageInfo); + } + + private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long userId, String userName, long zoneId) { + // Our smallest increment is hourly for now + if (s_logger.isDebugEnabled()) { + s_logger.debug("Total running time " + runningTime + "ms"); + } + + float usage = runningTime / 1000f / 60f / 60f; + + DecimalFormat dFormat = new DecimalFormat("#.######"); + String usageDisplay = dFormat.format(usage); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating VPN user:" + userId + " usage record, usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); + } + + // Create the usage record + String usageDesc = "VPN User: " + userName + ", Id: "+ userId + " usage time"; + + UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, + new Double(usage), null, null, null, null, userId, null, startDate, endDate); + m_usageDao.persist(usageRecord); + } + + private static class VUInfo { + private long userId; + private long zoneId; + private String userName; + + public VUInfo(long userId, long zoneId, String userName) { + this.userId = userId; + this.zoneId = zoneId; + this.userName = userName; + } + public long getZoneId() { + return zoneId; + } + public long getUserId() { + return userId; + } + public String getUserName() { + return userName; + } + } + +} diff --git a/usage/src/com/cloud/usage/parser/VolumeUsageParser.java b/usage/src/com/cloud/usage/parser/VolumeUsageParser.java index e40d1ceaf28..a5319797c4f 100644 --- a/usage/src/com/cloud/usage/parser/VolumeUsageParser.java +++ b/usage/src/com/cloud/usage/parser/VolumeUsageParser.java @@ -10,170 +10,170 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.usage.parser; - -import java.text.DecimalFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Logger; - -import com.cloud.usage.UsageServer; -import com.cloud.usage.UsageTypes; -import com.cloud.usage.UsageVO; -import com.cloud.usage.UsageVolumeVO; -import com.cloud.usage.dao.UsageDao; -import com.cloud.usage.dao.UsageVolumeDao; -import com.cloud.user.AccountVO; -import com.cloud.utils.Pair; -import com.cloud.utils.component.ComponentLocator; - -public class VolumeUsageParser { - public static final Logger s_logger = Logger.getLogger(VolumeUsageParser.class.getName()); - - private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); - private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); - private static UsageVolumeDao m_usageVolumeDao = _locator.getDao(UsageVolumeDao.class); - - public static boolean parse(AccountVO account, Date startDate, Date endDate) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Parsing all Volume usage events for account: " + account.getId()); - } - if ((endDate == null) || endDate.after(new Date())) { - endDate = new Date(); - } - - // - query usage_volume table with the following criteria: - // - look for an entry for accountId with start date in the given range - // - look for an entry for accountId with end date in the given range - // - look for an entry for accountId with end date null (currently running vm or owned IP) - // - look for an entry for accountId with start date before given range *and* end date after given range - List usageUsageVols = m_usageVolumeDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0); - - if(usageUsageVols.isEmpty()){ - s_logger.debug("No volume usage events for this period"); - return true; - } - - // This map has both the running time *and* the usage amount. - Map> usageMap = new HashMap>(); - - Map diskOfferingMap = new HashMap(); - - // loop through all the usage volumes, create a usage record for each - for (UsageVolumeVO usageVol : usageUsageVols) { - long volId = usageVol.getId(); - Long doId = usageVol.getDiskOfferingId(); - long zoneId = usageVol.getZoneId(); - Long templateId = usageVol.getTemplateId(); - long size = usageVol.getSize(); - String key = ""+volId; - - diskOfferingMap.put(key, new VolInfo(volId, zoneId, doId, templateId, size)); - - Date volCreateDate = usageVol.getCreated(); - Date volDeleteDate = usageVol.getDeleted(); - - if ((volDeleteDate == null) || volDeleteDate.after(endDate)) { - volDeleteDate = endDate; - } - - // clip the start date to the beginning of our aggregation range if the vm has been running for a while - if (volCreateDate.before(startDate)) { - volCreateDate = startDate; - } - - long currentDuration = (volDeleteDate.getTime() - volCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) - - - updateVolUsageData(usageMap, key, usageVol.getId(), currentDuration); - } - - for (String volIdKey : usageMap.keySet()) { - Pair voltimeInfo = usageMap.get(volIdKey); - long useTime = voltimeInfo.second().longValue(); - - // Only create a usage record if we have a runningTime of bigger than zero. - if (useTime > 0L) { - VolInfo info = diskOfferingMap.get(volIdKey); - createUsageRecord(UsageTypes.VOLUME, useTime, startDate, endDate, account, info.getVolumeId(), info.getZoneId(), info.getDiskOfferingId(), info.getTemplateId(), info.getSize()); - } - } - - return true; - } - - private static void updateVolUsageData(Map> usageDataMap, String key, long volId, long duration) { - Pair volUsageInfo = usageDataMap.get(key); - if (volUsageInfo == null) { - volUsageInfo = new Pair(new Long(volId), new Long(duration)); - } else { - Long runningTime = volUsageInfo.second(); - runningTime = new Long(runningTime.longValue() + duration); - volUsageInfo = new Pair(volUsageInfo.first(), runningTime); - } - usageDataMap.put(key, volUsageInfo); - } - - private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long volId, long zoneId, Long doId, Long templateId, long size) { - // Our smallest increment is hourly for now - if (s_logger.isDebugEnabled()) { - s_logger.debug("Total running time " + runningTime + "ms"); - } - - float usage = runningTime / 1000f / 60f / 60f; - - DecimalFormat dFormat = new DecimalFormat("#.######"); - String usageDisplay = dFormat.format(usage); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating Volume usage record for vol: " + volId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); - } - - // Create the usage record - String usageDesc = "Volume Id: "+volId+" usage time"; - - if(templateId != null){ - usageDesc += " (Template: " +templateId+ ")"; - } else if(doId != null){ - usageDesc += " (DiskOffering: " +doId+ ")"; - } - - UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, - new Double(usage), null, null, doId, templateId, volId, size, startDate, endDate); - m_usageDao.persist(usageRecord); - } - - private static class VolInfo { - private long volId; - private long zoneId; - private Long diskOfferingId; - private Long templateId; - private long size; - - public VolInfo(long volId, long zoneId, Long diskOfferingId, Long templateId, long size) { - this.volId = volId; - this.zoneId = zoneId; - this.diskOfferingId = diskOfferingId; - this.templateId = templateId; - this.size = size; - } - public long getZoneId() { - return zoneId; - } - public long getVolumeId() { - return volId; - } - public Long getDiskOfferingId() { - return diskOfferingId; - } - public Long getTemplateId() { - return templateId; - } - public long getSize() { - return size; - } - } -} +package com.cloud.usage.parser; + +import java.text.DecimalFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.cloud.usage.UsageServer; +import com.cloud.usage.UsageTypes; +import com.cloud.usage.UsageVO; +import com.cloud.usage.UsageVolumeVO; +import com.cloud.usage.dao.UsageDao; +import com.cloud.usage.dao.UsageVolumeDao; +import com.cloud.user.AccountVO; +import com.cloud.utils.Pair; +import com.cloud.utils.component.ComponentLocator; + +public class VolumeUsageParser { + public static final Logger s_logger = Logger.getLogger(VolumeUsageParser.class.getName()); + + private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage"); + private static UsageDao m_usageDao = _locator.getDao(UsageDao.class); + private static UsageVolumeDao m_usageVolumeDao = _locator.getDao(UsageVolumeDao.class); + + public static boolean parse(AccountVO account, Date startDate, Date endDate) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Parsing all Volume usage events for account: " + account.getId()); + } + if ((endDate == null) || endDate.after(new Date())) { + endDate = new Date(); + } + + // - query usage_volume table with the following criteria: + // - look for an entry for accountId with start date in the given range + // - look for an entry for accountId with end date in the given range + // - look for an entry for accountId with end date null (currently running vm or owned IP) + // - look for an entry for accountId with start date before given range *and* end date after given range + List usageUsageVols = m_usageVolumeDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0); + + if(usageUsageVols.isEmpty()){ + s_logger.debug("No volume usage events for this period"); + return true; + } + + // This map has both the running time *and* the usage amount. + Map> usageMap = new HashMap>(); + + Map diskOfferingMap = new HashMap(); + + // loop through all the usage volumes, create a usage record for each + for (UsageVolumeVO usageVol : usageUsageVols) { + long volId = usageVol.getId(); + Long doId = usageVol.getDiskOfferingId(); + long zoneId = usageVol.getZoneId(); + Long templateId = usageVol.getTemplateId(); + long size = usageVol.getSize(); + String key = ""+volId; + + diskOfferingMap.put(key, new VolInfo(volId, zoneId, doId, templateId, size)); + + Date volCreateDate = usageVol.getCreated(); + Date volDeleteDate = usageVol.getDeleted(); + + if ((volDeleteDate == null) || volDeleteDate.after(endDate)) { + volDeleteDate = endDate; + } + + // clip the start date to the beginning of our aggregation range if the vm has been running for a while + if (volCreateDate.before(startDate)) { + volCreateDate = startDate; + } + + long currentDuration = (volDeleteDate.getTime() - volCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge) + + + updateVolUsageData(usageMap, key, usageVol.getId(), currentDuration); + } + + for (String volIdKey : usageMap.keySet()) { + Pair voltimeInfo = usageMap.get(volIdKey); + long useTime = voltimeInfo.second().longValue(); + + // Only create a usage record if we have a runningTime of bigger than zero. + if (useTime > 0L) { + VolInfo info = diskOfferingMap.get(volIdKey); + createUsageRecord(UsageTypes.VOLUME, useTime, startDate, endDate, account, info.getVolumeId(), info.getZoneId(), info.getDiskOfferingId(), info.getTemplateId(), info.getSize()); + } + } + + return true; + } + + private static void updateVolUsageData(Map> usageDataMap, String key, long volId, long duration) { + Pair volUsageInfo = usageDataMap.get(key); + if (volUsageInfo == null) { + volUsageInfo = new Pair(new Long(volId), new Long(duration)); + } else { + Long runningTime = volUsageInfo.second(); + runningTime = new Long(runningTime.longValue() + duration); + volUsageInfo = new Pair(volUsageInfo.first(), runningTime); + } + usageDataMap.put(key, volUsageInfo); + } + + private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long volId, long zoneId, Long doId, Long templateId, long size) { + // Our smallest increment is hourly for now + if (s_logger.isDebugEnabled()) { + s_logger.debug("Total running time " + runningTime + "ms"); + } + + float usage = runningTime / 1000f / 60f / 60f; + + DecimalFormat dFormat = new DecimalFormat("#.######"); + String usageDisplay = dFormat.format(usage); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating Volume usage record for vol: " + volId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); + } + + // Create the usage record + String usageDesc = "Volume Id: "+volId+" usage time"; + + if(templateId != null){ + usageDesc += " (Template: " +templateId+ ")"; + } else if(doId != null){ + usageDesc += " (DiskOffering: " +doId+ ")"; + } + + UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, + new Double(usage), null, null, doId, templateId, volId, size, startDate, endDate); + m_usageDao.persist(usageRecord); + } + + private static class VolInfo { + private long volId; + private long zoneId; + private Long diskOfferingId; + private Long templateId; + private long size; + + public VolInfo(long volId, long zoneId, Long diskOfferingId, Long templateId, long size) { + this.volId = volId; + this.zoneId = zoneId; + this.diskOfferingId = diskOfferingId; + this.templateId = templateId; + this.size = size; + } + public long getZoneId() { + return zoneId; + } + public long getVolumeId() { + return volId; + } + public Long getDiskOfferingId() { + return diskOfferingId; + } + public Long getTemplateId() { + return templateId; + } + public long getSize() { + return size; + } + } +}