diff --git a/api/src/main/java/com/cloud/network/VirtualNetworkApplianceService.java b/api/src/main/java/com/cloud/network/VirtualNetworkApplianceService.java index 98fb8be7c7a..39756ef259a 100644 --- a/api/src/main/java/com/cloud/network/VirtualNetworkApplianceService.java +++ b/api/src/main/java/com/cloud/network/VirtualNetworkApplianceService.java @@ -26,6 +26,7 @@ import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.router.VirtualRouter; import com.cloud.user.Account; +import com.cloud.vm.Nic; public interface VirtualNetworkApplianceService { /** @@ -74,4 +75,6 @@ public interface VirtualNetworkApplianceService { * @return */ boolean performRouterHealthChecks(long routerId); + + void collectNetworkStatistics(T router, Nic nic); } diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/DomainRouterDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/DomainRouterDaoImpl.java index 135f96f28f3..dc71f898970 100644 --- a/engine/schema/src/main/java/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -383,12 +383,14 @@ public class DomainRouterDaoImpl extends GenericDaoBase im final RouterNetworkVO routerNtwkMap = new RouterNetworkVO(router.getId(), guestNetwork.getId(), guestNetwork.getGuestType()); _routerNetworkDao.persist(routerNtwkMap); //2) create user stats entry for the network - UserStatisticsVO stats = - _userStatsDao.findBy(router.getAccountId(), router.getDataCenterId(), guestNetwork.getId(), null, router.getId(), router.getType().toString()); - if (stats == null) { - stats = - new UserStatisticsVO(router.getAccountId(), router.getDataCenterId(), null, router.getId(), router.getType().toString(), guestNetwork.getId()); - _userStatsDao.persist(stats); + if (router.getVpcId() == null) { + UserStatisticsVO stats = + _userStatsDao.findBy(router.getAccountId(), router.getDataCenterId(), guestNetwork.getId(), null, router.getId(), router.getType().toString()); + if (stats == null) { + stats = + new UserStatisticsVO(router.getAccountId(), router.getDataCenterId(), null, router.getId(), router.getType().toString(), guestNetwork.getId()); + _userStatsDao.persist(stats); + } } txn.commit(); } diff --git a/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 1103ff9c058..2b6032f42d3 100644 --- a/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -732,100 +732,7 @@ Configurable, StateListener routerNics = _nicDao.listByVmId(router.getId()); - for (final Nic routerNic : routerNics) { - final Network network = _networkModel.getNetwork(routerNic.getNetworkId()); - // Send network usage command for public nic in VPC VR - // Send network usage command for isolated guest nic of non) VPC VR - - //[TODO] Avoiding the NPE now, but I have to find out what is going on with the network. - Wilder Rodrigues - if (network == null) { - s_logger.error("Could not find a network with ID => " + routerNic.getNetworkId() + ". It might be a problem!"); - continue; - } - if (forVpc && network.getTrafficType() == TrafficType.Public || !forVpc && network.getTrafficType() == TrafficType.Guest - && network.getGuestType() == Network.GuestType.Isolated) { - final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), forVpc, routerNic.getIPv4Address()); - final String routerType = router.getType().toString(); - final UserStatisticsVO previousStats = _userStatsDao.findBy(router.getAccountId(), router.getDataCenterId(), network.getId(), - forVpc ? routerNic.getIPv4Address() : null, router.getId(), routerType); - NetworkUsageAnswer answer = null; - try { - answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd); - } catch (final Exception e) { - s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId(), e); - continue; - } - - if (answer != null) { - if (!answer.getResult()) { - s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId() - + "; details: " + answer.getDetails()); - continue; - } - try { - if (answer.getBytesReceived() == 0 && answer.getBytesSent() == 0) { - s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics"); - continue; - } - final NetworkUsageAnswer answerFinal = answer; - Transaction.execute(new TransactionCallbackNoReturn() { - @Override - public void doInTransactionWithoutResult(final TransactionStatus status) { - final UserStatisticsVO stats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterId(), network.getId(), - forVpc ? routerNic.getIPv4Address() : null, router.getId(), routerType); - if (stats == null) { - s_logger.warn("unable to find stats for account: " + router.getAccountId()); - return; - } - - if (previousStats != null - && (previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived() || previousStats.getCurrentBytesSent() != stats - .getCurrentBytesSent())) { - s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + "Ignoring current answer. Router: " - + answerFinal.getRouterName() + " Rcvd: " + answerFinal.getBytesReceived() + "Sent: " + answerFinal.getBytesSent()); - return; - } - - if (stats.getCurrentBytesReceived() > answerFinal.getBytesReceived()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Received # of bytes that's less than the last one. " - + "Assuming something went wrong and persisting it. Router: " + answerFinal.getRouterName() + " Reported: " - + toHumanReadableSize(answerFinal.getBytesReceived()) + " Stored: " + toHumanReadableSize(stats.getCurrentBytesReceived())); - } - stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); - } - stats.setCurrentBytesReceived(answerFinal.getBytesReceived()); - if (stats.getCurrentBytesSent() > answerFinal.getBytesSent()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Received # of bytes that's less than the last one. " - + "Assuming something went wrong and persisting it. Router: " + answerFinal.getRouterName() + " Reported: " - + toHumanReadableSize(answerFinal.getBytesSent()) + " Stored: " + toHumanReadableSize(stats.getCurrentBytesSent())); - } - stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); - } - stats.setCurrentBytesSent(answerFinal.getBytesSent()); - if (!_dailyOrHourly) { - // update agg bytes - stats.setAggBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); - stats.setAggBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); - } - _userStatsDao.update(stats.getId(), stats); - } - }); - - } catch (final Exception e) { - s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + " Rx: " + toHumanReadableSize(answer.getBytesReceived()) + "; Tx: " - + toHumanReadableSize(answer.getBytesSent())); - } - } - } - } - } + collectNetworkStatistics(router, null); } } catch (final Exception e) { s_logger.warn("Error while collecting network stats", e); @@ -3057,6 +2964,11 @@ Configurable, StateListener void collectNetworkStatistics(final T router, final Nic nic) { if (router == null) { return; } @@ -3065,12 +2977,23 @@ Configurable, StateListener routerNics = _nicDao.listByVmId(router.getId()); + List routerNics = new ArrayList(); + if (nic != null) { + routerNics.add(nic); + } else { + routerNics.addAll(_nicDao.listByVmId(router.getId())); + } for (final Nic routerNic : routerNics) { final Network network = _networkModel.getNetwork(routerNic.getNetworkId()); // Send network usage command for public nic in VPC VR // Send network usage command for isolated guest nic of non VPC // VR + + //[TODO] Avoiding the NPE now, but I have to find out what is going on with the network. - Wilder Rodrigues + if (network == null) { + s_logger.error("Could not find a network with ID => " + routerNic.getNetworkId() + ". It might be a problem!"); + continue; + } if (forVpc && network.getTrafficType() == TrafficType.Public || !forVpc && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Isolated) { final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), forVpc, routerNic.getIPv4Address()); diff --git a/server/src/main/java/com/cloud/network/rules/NicPlugInOutRules.java b/server/src/main/java/com/cloud/network/rules/NicPlugInOutRules.java index 6ee5e85f271..b671e33df08 100644 --- a/server/src/main/java/com/cloud/network/rules/NicPlugInOutRules.java +++ b/server/src/main/java/com/cloud/network/rules/NicPlugInOutRules.java @@ -40,6 +40,7 @@ import com.cloud.network.NetworkModel; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.IsolationType; import com.cloud.network.PublicIpAddress; +import com.cloud.network.VpcVirtualNetworkApplianceService; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressVO; @@ -84,6 +85,7 @@ public class NicPlugInOutRules extends RuleApplier { NetworkModel networkModel = visitor.getVirtualNetworkApplianceFactory().getNetworkModel(); VirtualMachineManager itMgr = visitor.getVirtualNetworkApplianceFactory().getItMgr(); NicDao nicDao = visitor.getVirtualNetworkApplianceFactory().getNicDao(); + VpcVirtualNetworkApplianceService routerService = visitor.getVirtualNetworkApplianceFactory().getRouterService(); // de-associate IPs before unplugging nics if (!nicsToUnplug.isEmpty()) { @@ -107,6 +109,12 @@ public class NicPlugInOutRules extends RuleApplier { // 1) Unplug the nics for (Entry entry : nicsToUnplug.entrySet()) { + PublicIpAddress ip = entry.getValue(); + NicVO nic = nicDao.findByIp4AddressAndNetworkIdAndInstanceId(ip.getNetworkId(), _router.getId(), ip.getAddress().addr()); + if (nic != null) { + s_logger.info("Collect network statistics for nic " + nic + " from router " + _router); + routerService.collectNetworkStatistics(_router, nic); + } Network publicNtwk = null; try { publicNtwk = networkModel.getNetwork(entry.getValue().getNetworkId()); diff --git a/server/src/main/java/com/cloud/network/rules/VirtualNetworkApplianceFactory.java b/server/src/main/java/com/cloud/network/rules/VirtualNetworkApplianceFactory.java index 9d4660da557..d96673d42d3 100644 --- a/server/src/main/java/com/cloud/network/rules/VirtualNetworkApplianceFactory.java +++ b/server/src/main/java/com/cloud/network/rules/VirtualNetworkApplianceFactory.java @@ -26,6 +26,7 @@ import com.cloud.dc.dao.HostPodDao; import com.cloud.dc.dao.VlanDao; import com.cloud.network.IpAddressManager; import com.cloud.network.NetworkModel; +import com.cloud.network.VpcVirtualNetworkApplianceService; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; @@ -98,6 +99,8 @@ public class VirtualNetworkApplianceFactory { @Inject private NetworkTopologyContext _networkTopologyContext; + @Inject + private VpcVirtualNetworkApplianceService _routerService; public NetworkModel getNetworkModel() { return _networkModel; @@ -190,4 +193,8 @@ public class VirtualNetworkApplianceFactory { public FirewallRulesDao getFirewallRulesDao() { return _rulesDao; } + + public VpcVirtualNetworkApplianceService getRouterService() { + return _routerService; + } } diff --git a/server/src/test/java/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java b/server/src/test/java/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java index 45bf4c1763b..176fd8e68ea 100644 --- a/server/src/test/java/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java +++ b/server/src/test/java/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java @@ -41,6 +41,7 @@ import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.utils.component.ManagerBase; import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.Nic; import com.cloud.vm.VirtualMachineProfile; @Component @@ -280,4 +281,10 @@ public class MockVpcVirtualNetworkApplianceManager extends ManagerBase implement // TODO Auto-generated method stub return false; } -} \ No newline at end of file + + @Override + public void collectNetworkStatistics(T router, Nic nic) { + // TODO Auto-generated method stub + return; + } +} diff --git a/systemvm/debian/opt/cloud/bin/cs/CsAddress.py b/systemvm/debian/opt/cloud/bin/cs/CsAddress.py index 44b69500b4c..dfea7019f7a 100755 --- a/systemvm/debian/opt/cloud/bin/cs/CsAddress.py +++ b/systemvm/debian/opt/cloud/bin/cs/CsAddress.py @@ -476,11 +476,6 @@ class CsIP: "-A PREROUTING -m state --state NEW -i %s -s %s ! -d %s/32 -j ACL_OUTBOUND_%s" % (self.dev, guestNetworkCidr, self.address['gateway'], self.dev)]) - self.fw.append(["", "front", "-A NETWORK_STATS_%s -i %s -d %s" % - ("eth1", "eth1", guestNetworkCidr)]) - self.fw.append(["", "front", "-A NETWORK_STATS_%s -o %s -s %s" % - ("eth1", "eth1", guestNetworkCidr)]) - if self.is_private_gateway(): self.fw.append(["filter", "", "-A FORWARD -d %s -o %s -j ACL_INBOUND_%s" % (self.address['network'], self.dev, self.dev)]) @@ -518,6 +513,10 @@ class CsIP: ["mangle", "", "-A VPN_STATS_%s -i %s -m mark --mark 0x524/0xffffffff" % (self.dev, self.dev)]) self.fw.append( ["", "front", "-A FORWARD -j NETWORK_STATS_%s" % self.dev]) + self.fw.append( + ["", "front", "-A NETWORK_STATS_%s -s %s -o %s" % (self.dev, self.cl.get_vpccidr(), self.dev)]) + self.fw.append( + ["", "front", "-A NETWORK_STATS_%s -d %s -i %s" % (self.dev, self.cl.get_vpccidr(), self.dev)]) self.fw.append(["", "front", "-A FORWARD -j NETWORK_STATS"]) self.fw.append(["", "front", "-A INPUT -j NETWORK_STATS"])