diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 9eab10a0b70..6975c370528 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -211,6 +211,7 @@ public enum Config { UsageStatsJobAggregationRange("Premium", ManagementServer.class, Integer.class, "usage.stats.job.aggregation.range", "1440", "The range of time for aggregating the user statistics specified in minutes (e.g. 1440 for daily, 60 for hourly.", null), UsageStatsJobExecTime("Premium", ManagementServer.class, String.class, "usage.stats.job.exec.time", "00:15", "The time at which the usage statistics aggregation job will run as an HH24:MM time, e.g. 00:30 to run at 12:30am.", null), EnableUsageServer("Premium", ManagementServer.class, Boolean.class, "enable.usage.server", "true", "Flag for enabling usage", null), + TrafficSentinelHostName("Premium", ManagementServer.class, String.class, "traffic.sentinel.hostname", null, "Hostname of the Traffic Sentinel in http:// format for querying direct network usage", null), // Hidden UseSecondaryStorageVm("Hidden", ManagementServer.class, Boolean.class, "secondary.storage.vm", "false", "Deploys a VM per zone to manage secondary storage if true, otherwise secondary storage is mounted on management server", null), diff --git a/server/src/com/cloud/network/dao/IPAddressDao.java b/server/src/com/cloud/network/dao/IPAddressDao.java index 73e67499e4c..deb301f3c9e 100644 --- a/server/src/com/cloud/network/dao/IPAddressDao.java +++ b/server/src/com/cloud/network/dao/IPAddressDao.java @@ -49,5 +49,7 @@ public interface IPAddressDao extends GenericDao { IPAddressVO findByAssociatedVmId(long vmId); IPAddressVO findByAccountAndIp(long accountId, String ipAddress); + + IPAddressVO findByIpAddress(String ipAddress); } diff --git a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java index d848bfdb3c4..a339c054f32 100644 --- a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java +++ b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java @@ -267,4 +267,11 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen return findOneBy(sc); } + + @Override + public IPAddressVO findByIpAddress(String ipAddress) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("ipAddress", ipAddress); + return findOneBy(sc); + } } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index d42ec084e98..4632da40ef1 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -17,12 +17,18 @@ */ package com.cloud.network.router; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.StringTokenizer; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -281,6 +287,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian int _routerStatsInterval = 300; private ServiceOfferingVO _offering; + private String trafficSentinelHostname; ScheduledExecutorService _executor; @@ -564,6 +571,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian _offering = _serviceOfferingDao.persistSystemServiceOffering(_offering); _systemAcct = _accountService.getSystemAccount(); + + trafficSentinelHostname = configs.get("traffic.sentinel.hostname"); s_logger.info("DomainRouterManager is configured."); @@ -634,6 +643,67 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Override public void run() { + //Direct Network Usage + URL trafficSentinel; + try { + //Query traffic Sentinel + if(trafficSentinelHostname != null){ + trafficSentinel = new URL(trafficSentinelHostname+"/inmsf/Query?script=var+q+%3D+Query.topN(%22historytrmx%22,%0D%0A+++++++++++++++++%22ipsource,bytes%22,%0D%0A+++++++++++++++++%22sourcezone+!%3D+EXTERNAL" + + "+%26+destinationzone+%3D+EXTERNAL%22,%0D%0A+++++++++++++++++%22end+-+5+minutes,+end%22,%0D%0A+++++++++++++++++%22bytes%22,%0D%0A+++++++++++++++++100000);%0D%0A%0D%0Avar+totalsSent+%3D+" + + "{};%0D%0A%0D%0Avar+t+%3D+q.run(%0D%0A++function(row,table)+{%0D%0A++++if(row[0])+{++++%0D%0A++++++totalsSent[row[0]]+%3D+row[1];%0D%0A++++}%0D%0A++});%0D%0A%0D%0Avar+totalsRcvd+%3D+{};" + + "%0D%0A%0D%0Avar+q+%3D+Query.topN(%22historytrmx%22,%0D%0A+++++++++++++++++%22ipdestination,bytes%22,%0D%0A+++++++++++++++++%22destinationzone+!%3D+EXTERNAL+%26+sourcezone+%3D+EXTERNAL%22," + + "%0D%0A+++++++++++++++++%22end+-+5minutes,+end%22,%0D%0A+++++++++++++++++%22bytes%22,%0D%0A+++++++++++++++++100000);%0D%0A%0D%0Avar+t+%3D+q.run(%0D%0A++function(row,table)+{%0D%0A++++" + + "if(row[0])+{%0D%0A++++++totalsRcvd[row[0]]+%3D+row[1];%0D%0A++++}%0D%0A++});%0D%0A%0D%0Afor+(var+addr+in+totalsSent)+{%0D%0A++++var+TS+%3D+0;%0D%0A++++var+TR+%3D+0;%0D%0A++++if(totalsSent[addr])" + + "+TS+%3D+totalsSent[addr];%0D%0A++++if(totalsRcvd[addr])+TR+%3D+totalsRcvd[addr];%0D%0A++++println(addr+%2B+%22,%22+%2B+TS+%2B+%22,%22+%2B+TR);%0D%0A}&authenticate=basic&resultFormat=txt"); + + BufferedReader in = new BufferedReader( + new InputStreamReader(trafficSentinel.openStream())); + + String inputLine; + + while ((inputLine = in.readLine()) != null){ + //Parse the script output + StringTokenizer st = new StringTokenizer(inputLine, ","); + if(st.countTokens() == 3){ + String publicIp = st.nextToken(); + //Find the account owning the IP + IPAddressVO ipaddress = _ipAddressDao.findByIpAddress(publicIp); + if(ipaddress == null){ + continue; + } + Long bytesSent = new Long(st.nextToken()); + Long bytesRcvd = new Long(st.nextToken()); + if(bytesSent == null || bytesRcvd == null){ + s_logger.debug("Incorrect bytes for IP: "+publicIp); + } + Transaction txn = Transaction.open(Transaction.CLOUD_DB); + txn.start(); + //update user_statistics + UserStatisticsVO stats = _statsDao.lock(ipaddress.getAccountId(), ipaddress.getDataCenterId(), null, 0L, "DirectNetwork"); + if (stats == null) { + stats = new UserStatisticsVO(ipaddress.getAccountId(), ipaddress.getDataCenterId(), null, 0L, "DirectNetwork", null); + stats.setCurrentBytesSent(bytesSent); + stats.setCurrentBytesReceived(bytesRcvd); + _statsDao.persist(stats); + } else { + stats.setCurrentBytesSent(stats.getCurrentBytesSent() + bytesSent); + stats.setCurrentBytesReceived(stats.getCurrentBytesReceived() + bytesRcvd); + _statsDao.update(stats.getId(), stats); + } + txn.commit(); + txn.close(); + } + } + + in.close(); + } + } catch (MalformedURLException e1) { + s_logger.info("Invalid T raffic Sentinel URL",e1); + } catch (IOException e) { + s_logger.debug("Error in direct network usage accounting",e); + } + + final List routers = _routerDao.listUpByHostId(null); s_logger.debug("Found " + routers.size() + " running routers. ");