You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ki...@apache.org on 2013/06/28 08:45:11 UTC
git commit: updated refs/heads/master-6-17-stable to 6b38d14
Updated Branches:
refs/heads/master-6-17-stable 3faf768d7 -> 6b38d1465
CLOUDSTACK-650: Rename ExternalLBUsageMgr to more generic ExternalDeviceUsageManager since it contains firewall usage also. Most of the functionality is already fixed in CLOUDSTACK-1289
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/6b38d146
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/6b38d146
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/6b38d146
Branch: refs/heads/master-6-17-stable
Commit: 6b38d1465a9ee79d599eb1440830935eaa19a27a
Parents: 3faf768
Author: Kishan Kavala <ki...@cloud.com>
Authored: Fri Jun 28 12:08:33 2013 +0530
Committer: Kishan Kavala <ki...@cloud.com>
Committed: Fri Jun 28 12:09:58 2013 +0530
----------------------------------------------------------------------
client/tomcatconf/applicationContext.xml.in | 2 +-
.../network/ExternalDeviceUsageManager.java | 33 +
.../network/ExternalDeviceUsageManagerImpl.java | 673 +++++++++++++++++++
.../ExternalLoadBalancerUsageManager.java | 33 -
.../ExternalLoadBalancerUsageManagerImpl.java | 673 -------------------
.../lb/LoadBalancingRulesManagerImpl.java | 16 +-
6 files changed, 715 insertions(+), 715 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b38d146/client/tomcatconf/applicationContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in
index 049e483..bc8466c 100644
--- a/client/tomcatconf/applicationContext.xml.in
+++ b/client/tomcatconf/applicationContext.xml.in
@@ -691,7 +691,7 @@
<bean id="dataStoreProviderManagerImpl" class="org.apache.cloudstack.storage.datastore.provider.DataStoreProviderManagerImpl" />
<bean id="elasticLoadBalancerManagerImpl" class="com.cloud.network.lb.ElasticLoadBalancerManagerImpl" />
<bean id="entityManagerImpl" class="com.cloud.dao.EntityManagerImpl" />
- <bean id="externalLoadBalancerUsageManagerImpl" class="com.cloud.network.ExternalLoadBalancerUsageManagerImpl" />
+ <bean id="externalDeviceUsageManagerImpl" class="com.cloud.network.ExternalDeviceUsageManagerImpl" />
<bean id="externalNetworkDeviceManagerImpl" class="com.cloud.network.ExternalNetworkDeviceManagerImpl" />
<bean id="firewallManagerImpl" class="com.cloud.network.firewall.FirewallManagerImpl" />
<bean id="hypervisorGuruManagerImpl" class="com.cloud.hypervisor.HypervisorGuruManagerImpl" />
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b38d146/server/src/com/cloud/network/ExternalDeviceUsageManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/ExternalDeviceUsageManager.java b/server/src/com/cloud/network/ExternalDeviceUsageManager.java
new file mode 100644
index 0000000..474002b
--- /dev/null
+++ b/server/src/com/cloud/network/ExternalDeviceUsageManager.java
@@ -0,0 +1,33 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.network;
+
+import com.cloud.utils.component.Manager;
+
+/* ExternalDeviceUsageManager implements a periodic task that retrieves and updates the network usage stats from all external load balancer and firewall devices.
+ */
+
+public interface ExternalDeviceUsageManager extends Manager{
+
+ /**
+ * updates the network usage stats for a LB rule, associated with an external LB device, that is being revoked as part of Delete LB rule or release IP actions
+ * @param loadBalancerRuleId
+ */
+ public void updateExternalLoadBalancerNetworkUsageStats(long loadBalancerRuleId);
+
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b38d146/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java b/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java
new file mode 100644
index 0000000..606586e
--- /dev/null
+++ b/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java
@@ -0,0 +1,673 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.network;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer;
+import com.cloud.agent.api.ExternalNetworkResourceUsageCommand;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.network.dao.ExternalFirewallDeviceDao;
+import com.cloud.network.dao.ExternalFirewallDeviceVO;
+import com.cloud.network.dao.ExternalLoadBalancerDeviceDao;
+import com.cloud.network.dao.ExternalLoadBalancerDeviceVO;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.InlineLoadBalancerNicMapDao;
+import com.cloud.network.dao.InlineLoadBalancerNicMapVO;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.LoadBalancerVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkExternalFirewallDao;
+import com.cloud.network.dao.NetworkExternalFirewallVO;
+import com.cloud.network.dao.NetworkExternalLoadBalancerDao;
+import com.cloud.network.dao.NetworkExternalLoadBalancerVO;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.rules.LoadBalancerContainer.Scheme;
+import com.cloud.network.rules.PortForwardingRuleVO;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.user.AccountManager;
+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.NumbersUtil;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.ExecutionException;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
+
+@Component
+@Local(value = { ExternalDeviceUsageManager.class })
+public class ExternalDeviceUsageManagerImpl extends ManagerBase implements ExternalDeviceUsageManager {
+
+ String _name;
+ @Inject
+ NetworkExternalLoadBalancerDao _networkExternalLBDao;
+ @Inject
+ ExternalLoadBalancerDeviceDao _externalLoadBalancerDeviceDao;
+ @Inject
+ HostDao _hostDao;
+ @Inject
+ DataCenterDao _dcDao;
+ @Inject
+ InlineLoadBalancerNicMapDao _inlineLoadBalancerNicMapDao;
+ @Inject
+ NicDao _nicDao;
+ @Inject
+ AgentManager _agentMgr;
+ @Inject
+ ResourceManager _resourceMgr;
+ @Inject
+ IPAddressDao _ipAddressDao;
+ @Inject
+ VlanDao _vlanDao;
+ @Inject
+ NetworkOfferingDao _networkOfferingDao;
+ @Inject
+ AccountDao _accountDao;
+ @Inject
+ PhysicalNetworkDao _physicalNetworkDao;
+ @Inject
+ PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
+ @Inject
+ AccountManager _accountMgr;
+ @Inject
+ UserStatisticsDao _userStatsDao;
+ @Inject
+ NetworkDao _networkDao;
+ @Inject
+ DomainRouterDao _routerDao;
+ @Inject
+ LoadBalancerDao _loadBalancerDao;
+ @Inject
+ PortForwardingRulesDao _portForwardingRulesDao;
+ @Inject
+ ConfigurationDao _configDao;
+ @Inject
+ HostDetailsDao _hostDetailDao;
+ @Inject
+ NetworkExternalLoadBalancerDao _networkLBDao;
+ @Inject
+ NetworkServiceMapDao _ntwkSrvcProviderDao;
+ @Inject
+ NetworkExternalFirewallDao _networkExternalFirewallDao;
+ @Inject
+ ExternalFirewallDeviceDao _externalFirewallDeviceDao;
+ @Inject
+ protected HostPodDao _podDao = null;
+ @Inject
+ NetworkModel _networkModel;
+
+
+ ScheduledExecutorService _executor;
+ private int _externalNetworkStatsInterval;
+ private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalDeviceUsageManagerImpl.class);
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ _externalNetworkStatsInterval = NumbersUtil.parseInt(_configDao.getValue(Config.ExternalNetworkStatsInterval.key()), 300);
+ if (_externalNetworkStatsInterval > 0) {
+ _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ExternalNetworkMonitor"));
+ }
+ return true;
+
+ }
+
+ @Override
+ public boolean start() {
+ if (_externalNetworkStatsInterval > 0) {
+ _executor.scheduleAtFixedRate(new ExternalDeviceNetworkUsageTask(), _externalNetworkStatsInterval, _externalNetworkStatsInterval, TimeUnit.SECONDS);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return _name;
+ }
+
+ private ExternalLoadBalancerDeviceVO getExternalLoadBalancerForNetwork(Network network) {
+ NetworkExternalLoadBalancerVO lbDeviceForNetwork = _networkExternalLBDao.findByNetworkId(network.getId());
+ if (lbDeviceForNetwork != null) {
+ long lbDeviceId = lbDeviceForNetwork.getExternalLBDeviceId();
+ ExternalLoadBalancerDeviceVO lbDeviceVo = _externalLoadBalancerDeviceDao.findById(lbDeviceId);
+ assert (lbDeviceVo != null);
+ return lbDeviceVo;
+ }
+ return null;
+ }
+
+ private ExternalFirewallDeviceVO getExternalFirewallForNetwork(Network network) {
+ NetworkExternalFirewallVO fwDeviceForNetwork = _networkExternalFirewallDao.findByNetworkId(network.getId());
+ if (fwDeviceForNetwork != null) {
+ long fwDeviceId = fwDeviceForNetwork.getExternalFirewallDeviceId();
+ ExternalFirewallDeviceVO fwDevice = _externalFirewallDeviceDao.findById(fwDeviceId);
+ assert(fwDevice != null);
+ return fwDevice;
+ }
+ return null;
+ }
+
+ @Override
+ public void updateExternalLoadBalancerNetworkUsageStats(long loadBalancerRuleId){
+
+ LoadBalancerVO lb = _loadBalancerDao.findById(loadBalancerRuleId);
+ if(lb == null){
+ if(s_logger.isDebugEnabled()){
+ s_logger.debug("Cannot update usage stats, LB rule is not found");
+ }
+ return;
+ }
+ long networkId = lb.getNetworkId();
+ Network network = _networkDao.findById(networkId);
+ if(network == null){
+ if(s_logger.isDebugEnabled()){
+ s_logger.debug("Cannot update usage stats, Network is not found");
+ }
+ return;
+ }
+
+ ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
+ if (lbDeviceVO == null) {
+ if(s_logger.isDebugEnabled()){
+ s_logger.debug("Cannot update usage stats, No external LB device found");
+ }
+ return;
+ }
+
+ // Get network stats from the external load balancer
+ ExternalNetworkResourceUsageAnswer lbAnswer = null;
+ HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
+ if (externalLoadBalancer != null) {
+ ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand();
+ lbAnswer = (ExternalNetworkResourceUsageAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
+ if (lbAnswer == null || !lbAnswer.getResult()) {
+ String details = (lbAnswer != null) ? lbAnswer.getDetails() : "details unavailable";
+ String msg = "Unable to get external load balancer stats for network" + networkId + " due to: " + details + ".";
+ s_logger.error(msg);
+ return;
+ }
+ }
+
+ long accountId = lb.getAccountId();
+ AccountVO account = _accountDao.findById(accountId);
+ if (account == null) {
+ s_logger.debug("Skipping stats update for external LB for account with ID " + accountId);
+ return;
+ }
+
+ String publicIp = _networkModel.getIp(lb.getSourceIpAddressId()).getAddress().addr();
+ DataCenterVO zone = _dcDao.findById(network.getDataCenterId());
+ String statsEntryIdentifier = "account " + account.getAccountName() + ", zone " + zone.getName() + ", network ID " + networkId + ", host ID " + externalLoadBalancer.getName();
+
+ long newCurrentBytesSent = 0;
+ long newCurrentBytesReceived = 0;
+
+ if (publicIp != null) {
+ long[] bytesSentAndReceived = null;
+ statsEntryIdentifier += ", public IP: " + publicIp;
+ boolean inline = _networkModel.isNetworkInlineMode(network);
+ if (externalLoadBalancer.getType().equals(Host.Type.ExternalLoadBalancer) && inline) {
+ // Look up stats for the guest IP address that's mapped to the public IP address
+ InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(publicIp);
+
+ if (mapping != null) {
+ NicVO nic = _nicDao.findById(mapping.getNicId());
+ String loadBalancingIpAddress = nic.getIp4Address();
+ bytesSentAndReceived = lbAnswer.ipBytes.get(loadBalancingIpAddress);
+
+ if (bytesSentAndReceived != null) {
+ bytesSentAndReceived[0] = 0;
+ }
+ }
+ } else {
+ bytesSentAndReceived = lbAnswer.ipBytes.get(publicIp);
+ }
+
+ if (bytesSentAndReceived == null) {
+ s_logger.debug("Didn't get an external network usage answer for public IP " + publicIp);
+ } else {
+ newCurrentBytesSent += bytesSentAndReceived[0];
+ newCurrentBytesReceived += bytesSentAndReceived[1];
+ }
+
+ UserStatisticsVO userStats;
+ final Transaction txn = Transaction.currentTxn();
+ try {
+ txn.start();
+ userStats = _userStatsDao.lock(accountId, zone.getId(), networkId, publicIp, externalLoadBalancer.getId(), externalLoadBalancer.getType().toString());
+
+ if(userStats != null){
+ long oldNetBytesSent = userStats.getNetBytesSent();
+ long oldNetBytesReceived = userStats.getNetBytesReceived();
+ long oldCurrentBytesSent = userStats.getCurrentBytesSent();
+ long oldCurrentBytesReceived = userStats.getCurrentBytesReceived();
+ String warning = "Received an external network stats byte count that was less than the stored value. Zone ID: " + userStats.getDataCenterId() + ", account ID: " + userStats.getAccountId() + ".";
+
+ userStats.setCurrentBytesSent(newCurrentBytesSent);
+ if (oldCurrentBytesSent > newCurrentBytesSent) {
+ s_logger.warn(warning + "Stored bytes sent: " + oldCurrentBytesSent + ", new bytes sent: " + newCurrentBytesSent + ".");
+ userStats.setNetBytesSent(oldNetBytesSent + oldCurrentBytesSent);
+ }
+
+ userStats.setCurrentBytesReceived(newCurrentBytesReceived);
+ if (oldCurrentBytesReceived > newCurrentBytesReceived) {
+ s_logger.warn(warning + "Stored bytes received: " + oldCurrentBytesReceived + ", new bytes received: " + newCurrentBytesReceived + ".");
+ userStats.setNetBytesReceived(oldNetBytesReceived + oldCurrentBytesReceived);
+ }
+
+ if (_userStatsDao.update(userStats.getId(), userStats)) {
+ s_logger.debug("Successfully updated stats for " + statsEntryIdentifier);
+ } else {
+ s_logger.debug("Failed to update stats for " + statsEntryIdentifier);
+ }
+ }else {
+ s_logger.warn("Unable to find user stats entry for " + statsEntryIdentifier);
+ }
+
+ txn.commit();
+ }catch (final Exception e) {
+ txn.rollback();
+ throw new CloudRuntimeException("Problem getting stats after reboot/stop ", e);
+ }
+ }
+ }
+
+ protected class ExternalDeviceNetworkUsageTask implements Runnable {
+
+ public ExternalDeviceNetworkUsageTask() {
+
+ }
+
+ @Override
+ public void run() {
+ GlobalLock scanLock = GlobalLock.getInternLock("ExternalDeviceNetworkUsageManagerImpl");
+ try {
+ if (scanLock.lock(20)) {
+ try {
+ runExternalDeviceNetworkUsageTask();
+ } finally {
+ scanLock.unlock();
+ }
+ }
+ } catch (Exception e) {
+ s_logger.warn("Problems while getting external device usage", e);
+ } finally {
+ scanLock.releaseRef();
+ }
+ }
+
+ private void runExternalDeviceNetworkUsageTask() {
+ s_logger.debug("External devices stats collector is running...");
+
+ for (DataCenterVO zone : _dcDao.listAll()) {
+ List<DomainRouterVO> domainRoutersInZone = _routerDao.listByDataCenter(zone.getId());
+ if (domainRoutersInZone == null) {
+ continue;
+ }
+ Map<Long, ExternalNetworkResourceUsageAnswer> lbDeviceUsageAnswerMap = new HashMap<Long, ExternalNetworkResourceUsageAnswer>();
+ Map<Long, ExternalNetworkResourceUsageAnswer> fwDeviceUsageAnswerMap = new HashMap<Long, ExternalNetworkResourceUsageAnswer>();
+ List<Long> accountsProcessed = new ArrayList<Long>();
+
+ for (DomainRouterVO domainRouter : domainRoutersInZone) {
+ long accountId = domainRouter.getAccountId();
+
+ if (accountsProcessed.contains(new Long(accountId))) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("Networks for Account " + accountId + " are already processed for external network usage, so skipping usage check.");
+ }
+ continue;
+ }
+
+ long zoneId = zone.getId();
+
+ List<NetworkVO> networksForAccount = _networkDao.listByZoneAndGuestType(accountId, zoneId, Network.GuestType.Isolated, false);
+ if (networksForAccount == null) {
+ continue;
+ }
+
+ for (NetworkVO network : networksForAccount) {
+ if (!_networkModel.networkIsConfiguredForExternalNetworking(zoneId, network.getId())) {
+ s_logger.debug("Network " + network.getId() + " is not configured for external networking, so skipping usage check.");
+ continue;
+ }
+
+ ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
+ ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
+ if (lbDeviceVO == null && fwDeviceVO == null) {
+ continue;
+ }
+
+ // Get network stats from the external firewall
+ ExternalNetworkResourceUsageAnswer firewallAnswer = null;
+ HostVO externalFirewall = null;
+ if(fwDeviceVO != null){
+ externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
+ if (externalFirewall != null) {
+ Long fwDeviceId = new Long(externalFirewall.getId());
+ if(!fwDeviceUsageAnswerMap.containsKey(fwDeviceId)){
+ try{
+ ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand();
+ firewallAnswer = (ExternalNetworkResourceUsageAnswer) _agentMgr.easySend(externalFirewall.getId(), cmd);
+ if (firewallAnswer == null || !firewallAnswer.getResult()) {
+ String details = (firewallAnswer != null) ? firewallAnswer.getDetails() : "details unavailable";
+ String msg = "Unable to get external firewall stats for network" + zone.getName() + " due to: " + details + ".";
+ s_logger.error(msg);
+ } else {
+ fwDeviceUsageAnswerMap.put(fwDeviceId, firewallAnswer);
+ }
+ } catch (Exception e){
+ String msg = "Unable to get external firewall stats for network" + zone.getName();
+ s_logger.error(msg, e);
+ }
+ } else {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("Reusing usage Answer for device id " + fwDeviceId + "for Network " + network.getId());
+ }
+ firewallAnswer = fwDeviceUsageAnswerMap.get(fwDeviceId);
+ }
+ }}
+
+ // Get network stats from the external load balancer
+ ExternalNetworkResourceUsageAnswer lbAnswer = null;
+ HostVO externalLoadBalancer = null;
+ if(lbDeviceVO !=null){
+ externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
+ if (externalLoadBalancer != null) {
+ Long lbDeviceId = new Long(externalLoadBalancer.getId());
+ if (!lbDeviceUsageAnswerMap.containsKey(lbDeviceId)) {
+ try {
+ ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand();
+ lbAnswer = (ExternalNetworkResourceUsageAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
+ if (lbAnswer == null || !lbAnswer.getResult()) {
+ String details = (lbAnswer != null) ? lbAnswer.getDetails() : "details unavailable";
+ String msg = "Unable to get external load balancer stats for " + zone.getName() + " due to: " + details + ".";
+ s_logger.error(msg);
+ } else {
+ lbDeviceUsageAnswerMap.put(lbDeviceId, lbAnswer);
+ }
+ } catch (Exception e){
+ String msg = "Unable to get external load balancer stats for " + zone.getName();
+ s_logger.error(msg, e);
+ }
+ } else {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("Reusing usage Answer for device id " + lbDeviceId + "for Network " + network.getId());
+ }
+ lbAnswer = lbDeviceUsageAnswerMap.get(lbDeviceId);
+ }
+ }
+ }
+
+ if(firewallAnswer == null && lbAnswer == null){
+ continue;
+ }
+
+ AccountVO account = _accountDao.findById(accountId);
+ if (account == null) {
+ s_logger.debug("Skipping stats update for account with ID " + accountId);
+ continue;
+ }
+
+ if (!manageStatsEntries(true, accountId, zoneId, network, externalFirewall, firewallAnswer, externalLoadBalancer, lbAnswer)) {
+ continue;
+ }
+
+ manageStatsEntries(false, accountId, zoneId, network, externalFirewall, firewallAnswer, externalLoadBalancer, lbAnswer);
+ }
+
+ accountsProcessed.add(new Long(accountId));
+ }
+ }
+ }
+
+ private boolean updateBytes(UserStatisticsVO userStats, long newCurrentBytesSent, long newCurrentBytesReceived) {
+ long oldNetBytesSent = userStats.getNetBytesSent();
+ long oldNetBytesReceived = userStats.getNetBytesReceived();
+ long oldCurrentBytesSent = userStats.getCurrentBytesSent();
+ long oldCurrentBytesReceived = userStats.getCurrentBytesReceived();
+ String warning = "Received an external network stats byte count that was less than the stored value. Zone ID: " + userStats.getDataCenterId() + ", account ID: " + userStats.getAccountId() + ".";
+
+ userStats.setCurrentBytesSent(newCurrentBytesSent);
+ if (oldCurrentBytesSent > newCurrentBytesSent) {
+ s_logger.warn(warning + "Stored bytes sent: " + oldCurrentBytesSent + ", new bytes sent: " + newCurrentBytesSent + ".");
+ userStats.setNetBytesSent(oldNetBytesSent + oldCurrentBytesSent);
+ }
+
+ userStats.setCurrentBytesReceived(newCurrentBytesReceived);
+ if (oldCurrentBytesReceived > newCurrentBytesReceived) {
+ s_logger.warn(warning + "Stored bytes received: " + oldCurrentBytesReceived + ", new bytes received: " + newCurrentBytesReceived + ".");
+ userStats.setNetBytesReceived(oldNetBytesReceived + oldCurrentBytesReceived);
+ }
+
+ return _userStatsDao.update(userStats.getId(), userStats);
+ }
+
+ // Creates a new stats entry for the specified parameters, if one doesn't already exist.
+ private boolean createStatsEntry(long accountId, long zoneId, long networkId, String publicIp, long hostId) {
+ HostVO host = _hostDao.findById(hostId);
+ UserStatisticsVO userStats = _userStatsDao.findBy(accountId, zoneId, networkId, publicIp, hostId, host.getType().toString());
+ if (userStats == null) {
+ return (_userStatsDao.persist(new UserStatisticsVO(accountId, zoneId, publicIp, hostId, host.getType().toString(), networkId)) != null);
+ } else {
+ return true;
+ }
+ }
+
+ // Updates an existing stats entry with new data from the specified usage answer.
+ private boolean updateStatsEntry(long accountId, long zoneId, long networkId, String publicIp, long hostId, ExternalNetworkResourceUsageAnswer answer, boolean inline) {
+ AccountVO account = _accountDao.findById(accountId);
+ DataCenterVO zone = _dcDao.findById(zoneId);
+ NetworkVO network = _networkDao.findById(networkId);
+ HostVO host = _hostDao.findById(hostId);
+ String statsEntryIdentifier = "account " + account.getAccountName() + ", zone " + zone.getName() + ", network ID " + networkId + ", host ID " + host.getName();
+
+ long newCurrentBytesSent = 0;
+ long newCurrentBytesReceived = 0;
+
+ if (publicIp != null) {
+ long[] bytesSentAndReceived = null;
+ statsEntryIdentifier += ", public IP: " + publicIp;
+
+ if (host.getType().equals(Host.Type.ExternalLoadBalancer) && inline) {
+ // Look up stats for the guest IP address that's mapped to the public IP address
+ InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(publicIp);
+
+ if (mapping != null) {
+ NicVO nic = _nicDao.findById(mapping.getNicId());
+ String loadBalancingIpAddress = nic.getIp4Address();
+ bytesSentAndReceived = answer.ipBytes.get(loadBalancingIpAddress);
+
+ if (bytesSentAndReceived != null) {
+ bytesSentAndReceived[0] = 0;
+ }
+ }
+ } else {
+ bytesSentAndReceived = answer.ipBytes.get(publicIp);
+ }
+
+ if (bytesSentAndReceived == null) {
+ s_logger.debug("Didn't get an external network usage answer for public IP " + publicIp);
+ } else {
+ newCurrentBytesSent += bytesSentAndReceived[0];
+ newCurrentBytesReceived += bytesSentAndReceived[1];
+ }
+ } else {
+ URI broadcastURI = network.getBroadcastUri();
+ if (broadcastURI == null) {
+ s_logger.debug("Not updating stats for guest network with ID " + network.getId() + " because the network is not implemented.");
+ return true;
+ } else {
+ long vlanTag = Integer.parseInt(broadcastURI.getHost());
+ long[] bytesSentAndReceived = answer.guestVlanBytes.get(String.valueOf(vlanTag));
+
+ if (bytesSentAndReceived == null) {
+ s_logger.warn("Didn't get an external network usage answer for guest VLAN " + vlanTag);
+ } else {
+ newCurrentBytesSent += bytesSentAndReceived[0];
+ newCurrentBytesReceived += bytesSentAndReceived[1];
+ }
+ }
+ }
+
+ UserStatisticsVO userStats;
+ try {
+ userStats = _userStatsDao.lock(accountId, zoneId, networkId, publicIp, hostId, host.getType().toString());
+ } catch (Exception e) {
+ s_logger.warn("Unable to find user stats entry for " + statsEntryIdentifier);
+ return false;
+ }
+
+ if (updateBytes(userStats, newCurrentBytesSent, newCurrentBytesReceived)) {
+ s_logger.debug("Successfully updated stats for " + statsEntryIdentifier);
+ return true;
+ } else {
+ s_logger.debug("Failed to update stats for " + statsEntryIdentifier);
+ return false;
+ }
+ }
+
+ private boolean createOrUpdateStatsEntry(boolean create, long accountId, long zoneId, long networkId, String publicIp, long hostId, ExternalNetworkResourceUsageAnswer answer, boolean inline) {
+ if (create) {
+ return createStatsEntry(accountId, zoneId, networkId, publicIp, hostId);
+ } else {
+ return updateStatsEntry(accountId, zoneId, networkId, publicIp, hostId, answer, inline);
+ }
+ }
+
+ /*
+ * Creates/updates all necessary stats entries for an account and zone.
+ * Stats entries are created for source NAT IP addresses, static NAT rules, port forwarding rules, and load
+ * balancing rules
+ */
+ private boolean manageStatsEntries(boolean create, long accountId, long zoneId, Network network,
+ HostVO externalFirewall, ExternalNetworkResourceUsageAnswer firewallAnswer,
+ HostVO externalLoadBalancer, ExternalNetworkResourceUsageAnswer lbAnswer) {
+ String accountErrorMsg = "Failed to update external network stats entry. Details: account ID = " + accountId;
+ Transaction txn = Transaction.open(Transaction.CLOUD_DB);
+ try {
+ txn.start();
+ String networkErrorMsg = accountErrorMsg + ", network ID = " + network.getId();
+
+ boolean sharedSourceNat = false;
+ Map<Network.Capability, String> sourceNatCapabilities = _networkModel.getNetworkServiceCapabilities(network.getId(), Network.Service.SourceNat);
+ if (sourceNatCapabilities != null) {
+ String supportedSourceNatTypes = sourceNatCapabilities.get(Network.Capability.SupportedSourceNatTypes).toLowerCase();
+ if (supportedSourceNatTypes.contains("zone")) {
+ sharedSourceNat = true;
+ }
+ }
+
+ if(externalFirewall != null && firewallAnswer != null){
+ if (!sharedSourceNat) {
+ // Manage the entry for this network's source NAT IP address
+ List<IPAddressVO> sourceNatIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), true);
+ if (sourceNatIps.size() == 1) {
+ String publicIp = sourceNatIps.get(0).getAddress().addr();
+ if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer, false)) {
+ throw new ExecutionException(networkErrorMsg + ", source NAT IP = " + publicIp);
+ }
+ }
+
+ // Manage one entry for each static NAT rule in this network
+ List<IPAddressVO> staticNatIps = _ipAddressDao.listStaticNatPublicIps(network.getId());
+ for (IPAddressVO staticNatIp : staticNatIps) {
+ String publicIp = staticNatIp.getAddress().addr();
+ if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer, false)) {
+ throw new ExecutionException(networkErrorMsg + ", static NAT rule public IP = " + publicIp);
+ }
+ }
+
+ // Manage one entry for each port forwarding rule in this network
+ List<PortForwardingRuleVO> portForwardingRules = _portForwardingRulesDao.listByNetwork(network.getId());
+ for (PortForwardingRuleVO portForwardingRule : portForwardingRules) {
+ String publicIp = _networkModel.getIp(portForwardingRule.getSourceIpAddressId()).getAddress().addr();
+ if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer, false)) {
+ throw new ExecutionException(networkErrorMsg + ", port forwarding rule public IP = " + publicIp);
+ }
+ }
+ } else {
+ // Manage the account-wide entry for the external firewall
+ if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), null, externalFirewall.getId(), firewallAnswer, false)) {
+ throw new ExecutionException(networkErrorMsg);
+ }
+ }
+ }
+
+ // If an external load balancer is added, manage one entry for each load balancing rule in this network
+ if (externalLoadBalancer != null && lbAnswer != null) {
+ boolean inline = _networkModel.isNetworkInlineMode(network);
+ List<LoadBalancerVO> loadBalancers = _loadBalancerDao.listByNetworkIdAndScheme(network.getId(), Scheme.Public);
+ for (LoadBalancerVO loadBalancer : loadBalancers) {
+ String publicIp = _networkModel.getIp(loadBalancer.getSourceIpAddressId()).getAddress().addr();
+ if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalLoadBalancer.getId(), lbAnswer, inline)) {
+ throw new ExecutionException(networkErrorMsg + ", load balancing rule public IP = " + publicIp);
+ }
+ }
+ }
+ return txn.commit();
+ } catch (Exception e) {
+ s_logger.warn("Exception: ", e);
+ txn.rollback();
+ return false;
+ } finally {
+ txn.close();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b38d146/server/src/com/cloud/network/ExternalLoadBalancerUsageManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/ExternalLoadBalancerUsageManager.java b/server/src/com/cloud/network/ExternalLoadBalancerUsageManager.java
deleted file mode 100644
index 886cd78..0000000
--- a/server/src/com/cloud/network/ExternalLoadBalancerUsageManager.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network;
-
-import com.cloud.utils.component.Manager;
-
-/* ExternalLoadBalancerUsageManager implements a periodic task that retrieves and updates the network usage stats from all external load balancer devices.
- */
-
-public interface ExternalLoadBalancerUsageManager extends Manager{
-
- /**
- * updates the network usage stats for a LB rule, associated with an external LB device, that is being revoked as part of Delete LB rule or release IP actions
- * @param loadBalancerRuleId
- */
- public void updateExternalLoadBalancerNetworkUsageStats(long loadBalancerRuleId);
-
-
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b38d146/server/src/com/cloud/network/ExternalLoadBalancerUsageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/ExternalLoadBalancerUsageManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerUsageManagerImpl.java
deleted file mode 100644
index 2c8031c..0000000
--- a/server/src/com/cloud/network/ExternalLoadBalancerUsageManagerImpl.java
+++ /dev/null
@@ -1,673 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer;
-import com.cloud.agent.api.ExternalNetworkResourceUsageCommand;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.host.dao.HostDetailsDao;
-import com.cloud.network.dao.ExternalFirewallDeviceDao;
-import com.cloud.network.dao.ExternalFirewallDeviceVO;
-import com.cloud.network.dao.ExternalLoadBalancerDeviceDao;
-import com.cloud.network.dao.ExternalLoadBalancerDeviceVO;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.InlineLoadBalancerNicMapDao;
-import com.cloud.network.dao.InlineLoadBalancerNicMapVO;
-import com.cloud.network.dao.LoadBalancerDao;
-import com.cloud.network.dao.LoadBalancerVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkExternalFirewallDao;
-import com.cloud.network.dao.NetworkExternalFirewallVO;
-import com.cloud.network.dao.NetworkExternalLoadBalancerDao;
-import com.cloud.network.dao.NetworkExternalLoadBalancerVO;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
-import com.cloud.network.rules.LoadBalancerContainer.Scheme;
-import com.cloud.network.rules.PortForwardingRuleVO;
-import com.cloud.network.rules.dao.PortForwardingRulesDao;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.user.AccountManager;
-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.NumbersUtil;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.ExecutionException;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.NicDao;
-
-@Component
-@Local(value = { ExternalLoadBalancerUsageManager.class })
-public class ExternalLoadBalancerUsageManagerImpl extends ManagerBase implements ExternalLoadBalancerUsageManager {
-
- @Inject
- NetworkExternalLoadBalancerDao _networkExternalLBDao;
- @Inject
- ExternalLoadBalancerDeviceDao _externalLoadBalancerDeviceDao;
- @Inject
- HostDao _hostDao;
- @Inject
- DataCenterDao _dcDao;
- @Inject
- NetworkModel _networkMgr;
- @Inject
- InlineLoadBalancerNicMapDao _inlineLoadBalancerNicMapDao;
- @Inject
- NicDao _nicDao;
- @Inject
- AgentManager _agentMgr;
- @Inject
- ResourceManager _resourceMgr;
- @Inject
- IPAddressDao _ipAddressDao;
- @Inject
- VlanDao _vlanDao;
- @Inject
- NetworkOfferingDao _networkOfferingDao;
- @Inject
- AccountDao _accountDao;
- @Inject
- PhysicalNetworkDao _physicalNetworkDao;
- @Inject
- PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
- @Inject
- AccountManager _accountMgr;
- @Inject
- UserStatisticsDao _userStatsDao;
- @Inject
- NetworkDao _networkDao;
- @Inject
- DomainRouterDao _routerDao;
- @Inject
- LoadBalancerDao _loadBalancerDao;
- @Inject
- PortForwardingRulesDao _portForwardingRulesDao;
- @Inject
- ConfigurationDao _configDao;
- @Inject
- HostDetailsDao _hostDetailDao;
- @Inject
- NetworkExternalLoadBalancerDao _networkLBDao;
- @Inject
- NetworkServiceMapDao _ntwkSrvcProviderDao;
- @Inject
- NetworkExternalFirewallDao _networkExternalFirewallDao;
- @Inject
- ExternalFirewallDeviceDao _externalFirewallDeviceDao;
- @Inject
- protected HostPodDao _podDao = null;
-
- ScheduledExecutorService _executor;
- private int _externalNetworkStatsInterval;
- private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalLoadBalancerUsageManagerImpl.class);
-
- @Override
- public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
- _externalNetworkStatsInterval = NumbersUtil.parseInt(_configDao.getValue(Config.ExternalNetworkStatsInterval.key()), 300);
- if (_externalNetworkStatsInterval > 0) {
- _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ExternalNetworkMonitor"));
- }
- return true;
-
- }
-
- @Override
- public boolean start() {
- if (_externalNetworkStatsInterval > 0) {
- _executor.scheduleAtFixedRate(new ExternalDeviceNetworkUsageTask(), _externalNetworkStatsInterval, _externalNetworkStatsInterval, TimeUnit.SECONDS);
- }
- return true;
- }
-
- @Override
- public boolean stop() {
- return true;
- }
-
- @Override
- public String getName() {
- return _name;
- }
-
- private ExternalLoadBalancerDeviceVO getExternalLoadBalancerForNetwork(Network network) {
- NetworkExternalLoadBalancerVO lbDeviceForNetwork = _networkExternalLBDao.findByNetworkId(network.getId());
- if (lbDeviceForNetwork != null) {
- long lbDeviceId = lbDeviceForNetwork.getExternalLBDeviceId();
- ExternalLoadBalancerDeviceVO lbDeviceVo = _externalLoadBalancerDeviceDao.findById(lbDeviceId);
- assert (lbDeviceVo != null);
- return lbDeviceVo;
- }
- return null;
- }
-
- private ExternalFirewallDeviceVO getExternalFirewallForNetwork(Network network) {
- NetworkExternalFirewallVO fwDeviceForNetwork = _networkExternalFirewallDao.findByNetworkId(network.getId());
- if (fwDeviceForNetwork != null) {
- long fwDeviceId = fwDeviceForNetwork.getExternalFirewallDeviceId();
- ExternalFirewallDeviceVO fwDevice = _externalFirewallDeviceDao.findById(fwDeviceId);
- assert(fwDevice != null);
- return fwDevice;
- }
- return null;
- }
-
- @Override
- public void updateExternalLoadBalancerNetworkUsageStats(long loadBalancerRuleId){
-
- LoadBalancerVO lb = _loadBalancerDao.findById(loadBalancerRuleId);
- if(lb == null){
- if(s_logger.isDebugEnabled()){
- s_logger.debug("Cannot update usage stats, LB rule is not found");
- }
- return;
- }
- long networkId = lb.getNetworkId();
- Network network = _networkDao.findById(networkId);
- if(network == null){
- if(s_logger.isDebugEnabled()){
- s_logger.debug("Cannot update usage stats, Network is not found");
- }
- return;
- }
-
- ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
- if (lbDeviceVO == null) {
- if(s_logger.isDebugEnabled()){
- s_logger.debug("Cannot update usage stats, No external LB device found");
- }
- return;
- }
-
- // Get network stats from the external load balancer
- ExternalNetworkResourceUsageAnswer lbAnswer = null;
- HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
- if (externalLoadBalancer != null) {
- ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand();
- lbAnswer = (ExternalNetworkResourceUsageAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
- if (lbAnswer == null || !lbAnswer.getResult()) {
- String details = (lbAnswer != null) ? lbAnswer.getDetails() : "details unavailable";
- String msg = "Unable to get external load balancer stats for network" + networkId + " due to: " + details + ".";
- s_logger.error(msg);
- return;
- }
- }
-
- long accountId = lb.getAccountId();
- AccountVO account = _accountDao.findById(accountId);
- if (account == null) {
- s_logger.debug("Skipping stats update for external LB for account with ID " + accountId);
- return;
- }
-
- String publicIp = _networkMgr.getIp(lb.getSourceIpAddressId()).getAddress().addr();
- DataCenterVO zone = _dcDao.findById(network.getDataCenterId());
- String statsEntryIdentifier = "account " + account.getAccountName() + ", zone " + zone.getName() + ", network ID " + networkId + ", host ID " + externalLoadBalancer.getName();
-
- long newCurrentBytesSent = 0;
- long newCurrentBytesReceived = 0;
-
- if (publicIp != null) {
- long[] bytesSentAndReceived = null;
- statsEntryIdentifier += ", public IP: " + publicIp;
- boolean inline = _networkMgr.isNetworkInlineMode(network);
- if (externalLoadBalancer.getType().equals(Host.Type.ExternalLoadBalancer) && inline) {
- // Look up stats for the guest IP address that's mapped to the public IP address
- InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(publicIp);
-
- if (mapping != null) {
- NicVO nic = _nicDao.findById(mapping.getNicId());
- String loadBalancingIpAddress = nic.getIp4Address();
- bytesSentAndReceived = lbAnswer.ipBytes.get(loadBalancingIpAddress);
-
- if (bytesSentAndReceived != null) {
- bytesSentAndReceived[0] = 0;
- }
- }
- } else {
- bytesSentAndReceived = lbAnswer.ipBytes.get(publicIp);
- }
-
- if (bytesSentAndReceived == null) {
- s_logger.debug("Didn't get an external network usage answer for public IP " + publicIp);
- } else {
- newCurrentBytesSent += bytesSentAndReceived[0];
- newCurrentBytesReceived += bytesSentAndReceived[1];
- }
-
- UserStatisticsVO userStats;
- final Transaction txn = Transaction.currentTxn();
- try {
- txn.start();
- userStats = _userStatsDao.lock(accountId, zone.getId(), networkId, publicIp, externalLoadBalancer.getId(), externalLoadBalancer.getType().toString());
-
- if(userStats != null){
- long oldNetBytesSent = userStats.getNetBytesSent();
- long oldNetBytesReceived = userStats.getNetBytesReceived();
- long oldCurrentBytesSent = userStats.getCurrentBytesSent();
- long oldCurrentBytesReceived = userStats.getCurrentBytesReceived();
- String warning = "Received an external network stats byte count that was less than the stored value. Zone ID: " + userStats.getDataCenterId() + ", account ID: " + userStats.getAccountId() + ".";
-
- userStats.setCurrentBytesSent(newCurrentBytesSent);
- if (oldCurrentBytesSent > newCurrentBytesSent) {
- s_logger.warn(warning + "Stored bytes sent: " + oldCurrentBytesSent + ", new bytes sent: " + newCurrentBytesSent + ".");
- userStats.setNetBytesSent(oldNetBytesSent + oldCurrentBytesSent);
- }
-
- userStats.setCurrentBytesReceived(newCurrentBytesReceived);
- if (oldCurrentBytesReceived > newCurrentBytesReceived) {
- s_logger.warn(warning + "Stored bytes received: " + oldCurrentBytesReceived + ", new bytes received: " + newCurrentBytesReceived + ".");
- userStats.setNetBytesReceived(oldNetBytesReceived + oldCurrentBytesReceived);
- }
-
- if (_userStatsDao.update(userStats.getId(), userStats)) {
- s_logger.debug("Successfully updated stats for " + statsEntryIdentifier);
- } else {
- s_logger.debug("Failed to update stats for " + statsEntryIdentifier);
- }
- }else {
- s_logger.warn("Unable to find user stats entry for " + statsEntryIdentifier);
- }
-
- txn.commit();
- }catch (final Exception e) {
- txn.rollback();
- throw new CloudRuntimeException("Problem getting stats after reboot/stop ", e);
- }
- }
- }
-
- protected class ExternalDeviceNetworkUsageTask implements Runnable {
-
- public ExternalDeviceNetworkUsageTask() {
-
- }
-
- @Override
- public void run() {
- GlobalLock scanLock = GlobalLock.getInternLock("ExternalDeviceNetworkUsageManagerImpl");
- try {
- if (scanLock.lock(20)) {
- try {
- runExternalDeviceNetworkUsageTask();
- } finally {
- scanLock.unlock();
- }
- }
- } catch (Exception e) {
- s_logger.warn("Problems while getting external device usage", e);
- } finally {
- scanLock.releaseRef();
- }
- }
-
- private void runExternalDeviceNetworkUsageTask() {
- s_logger.debug("External devices stats collector is running...");
-
- for (DataCenterVO zone : _dcDao.listAll()) {
- List<DomainRouterVO> domainRoutersInZone = _routerDao.listByDataCenter(zone.getId());
- if (domainRoutersInZone == null) {
- continue;
- }
- Map<Long, ExternalNetworkResourceUsageAnswer> lbDeviceUsageAnswerMap = new HashMap<Long, ExternalNetworkResourceUsageAnswer>();
- Map<Long, ExternalNetworkResourceUsageAnswer> fwDeviceUsageAnswerMap = new HashMap<Long, ExternalNetworkResourceUsageAnswer>();
- List<Long> accountsProcessed = new ArrayList<Long>();
-
- for (DomainRouterVO domainRouter : domainRoutersInZone) {
- long accountId = domainRouter.getAccountId();
-
- if (accountsProcessed.contains(new Long(accountId))) {
- if (s_logger.isTraceEnabled()) {
- s_logger.trace("Networks for Account " + accountId + " are already processed for external network usage, so skipping usage check.");
- }
- continue;
- }
-
- long zoneId = zone.getId();
-
- List<NetworkVO> networksForAccount = _networkDao.listByZoneAndGuestType(accountId, zoneId, Network.GuestType.Isolated, false);
- if (networksForAccount == null) {
- continue;
- }
-
- for (NetworkVO network : networksForAccount) {
- if (!_networkMgr.networkIsConfiguredForExternalNetworking(zoneId, network.getId())) {
- s_logger.debug("Network " + network.getId() + " is not configured for external networking, so skipping usage check.");
- continue;
- }
-
- ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
- ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
- if (lbDeviceVO == null && fwDeviceVO == null) {
- continue;
- }
-
- // Get network stats from the external firewall
- ExternalNetworkResourceUsageAnswer firewallAnswer = null;
- HostVO externalFirewall = null;
- if(fwDeviceVO != null){
- externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
- if (externalFirewall != null) {
- Long fwDeviceId = new Long(externalFirewall.getId());
- if(!fwDeviceUsageAnswerMap.containsKey(fwDeviceId)){
- try{
- ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand();
- firewallAnswer = (ExternalNetworkResourceUsageAnswer) _agentMgr.easySend(externalFirewall.getId(), cmd);
- if (firewallAnswer == null || !firewallAnswer.getResult()) {
- String details = (firewallAnswer != null) ? firewallAnswer.getDetails() : "details unavailable";
- String msg = "Unable to get external firewall stats for network" + zone.getName() + " due to: " + details + ".";
- s_logger.error(msg);
- } else {
- fwDeviceUsageAnswerMap.put(fwDeviceId, firewallAnswer);
- }
- } catch (Exception e){
- String msg = "Unable to get external firewall stats for network" + zone.getName();
- s_logger.error(msg, e);
- }
- } else {
- if (s_logger.isTraceEnabled()) {
- s_logger.trace("Reusing usage Answer for device id " + fwDeviceId + "for Network " + network.getId());
- }
- firewallAnswer = fwDeviceUsageAnswerMap.get(fwDeviceId);
- }
- }}
-
- // Get network stats from the external load balancer
- ExternalNetworkResourceUsageAnswer lbAnswer = null;
- HostVO externalLoadBalancer = null;
- if(lbDeviceVO !=null){
- externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
- if (externalLoadBalancer != null) {
- Long lbDeviceId = new Long(externalLoadBalancer.getId());
- if (!lbDeviceUsageAnswerMap.containsKey(lbDeviceId)) {
- try {
- ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand();
- lbAnswer = (ExternalNetworkResourceUsageAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
- if (lbAnswer == null || !lbAnswer.getResult()) {
- String details = (lbAnswer != null) ? lbAnswer.getDetails() : "details unavailable";
- String msg = "Unable to get external load balancer stats for " + zone.getName() + " due to: " + details + ".";
- s_logger.error(msg);
- } else {
- lbDeviceUsageAnswerMap.put(lbDeviceId, lbAnswer);
- }
- } catch (Exception e){
- String msg = "Unable to get external load balancer stats for " + zone.getName();
- s_logger.error(msg, e);
- }
- } else {
- if (s_logger.isTraceEnabled()) {
- s_logger.trace("Reusing usage Answer for device id " + lbDeviceId + "for Network " + network.getId());
- }
- lbAnswer = lbDeviceUsageAnswerMap.get(lbDeviceId);
- }
- }
- }
-
- if(firewallAnswer == null && lbAnswer == null){
- continue;
- }
-
- AccountVO account = _accountDao.findById(accountId);
- if (account == null) {
- s_logger.debug("Skipping stats update for account with ID " + accountId);
- continue;
- }
-
- if (!manageStatsEntries(true, accountId, zoneId, network, externalFirewall, firewallAnswer, externalLoadBalancer, lbAnswer)) {
- continue;
- }
-
- manageStatsEntries(false, accountId, zoneId, network, externalFirewall, firewallAnswer, externalLoadBalancer, lbAnswer);
- }
-
- accountsProcessed.add(new Long(accountId));
- }
- }
- }
-
- private boolean updateBytes(UserStatisticsVO userStats, long newCurrentBytesSent, long newCurrentBytesReceived) {
- long oldNetBytesSent = userStats.getNetBytesSent();
- long oldNetBytesReceived = userStats.getNetBytesReceived();
- long oldCurrentBytesSent = userStats.getCurrentBytesSent();
- long oldCurrentBytesReceived = userStats.getCurrentBytesReceived();
- String warning = "Received an external network stats byte count that was less than the stored value. Zone ID: " + userStats.getDataCenterId() + ", account ID: " + userStats.getAccountId() + ".";
-
- userStats.setCurrentBytesSent(newCurrentBytesSent);
- if (oldCurrentBytesSent > newCurrentBytesSent) {
- s_logger.warn(warning + "Stored bytes sent: " + oldCurrentBytesSent + ", new bytes sent: " + newCurrentBytesSent + ".");
- userStats.setNetBytesSent(oldNetBytesSent + oldCurrentBytesSent);
- }
-
- userStats.setCurrentBytesReceived(newCurrentBytesReceived);
- if (oldCurrentBytesReceived > newCurrentBytesReceived) {
- s_logger.warn(warning + "Stored bytes received: " + oldCurrentBytesReceived + ", new bytes received: " + newCurrentBytesReceived + ".");
- userStats.setNetBytesReceived(oldNetBytesReceived + oldCurrentBytesReceived);
- }
-
- return _userStatsDao.update(userStats.getId(), userStats);
- }
-
- // Creates a new stats entry for the specified parameters, if one doesn't already exist.
- private boolean createStatsEntry(long accountId, long zoneId, long networkId, String publicIp, long hostId) {
- HostVO host = _hostDao.findById(hostId);
- UserStatisticsVO userStats = _userStatsDao.findBy(accountId, zoneId, networkId, publicIp, hostId, host.getType().toString());
- if (userStats == null) {
- return (_userStatsDao.persist(new UserStatisticsVO(accountId, zoneId, publicIp, hostId, host.getType().toString(), networkId)) != null);
- } else {
- return true;
- }
- }
-
- // Updates an existing stats entry with new data from the specified usage answer.
- private boolean updateStatsEntry(long accountId, long zoneId, long networkId, String publicIp, long hostId, ExternalNetworkResourceUsageAnswer answer, boolean inline) {
- AccountVO account = _accountDao.findById(accountId);
- DataCenterVO zone = _dcDao.findById(zoneId);
- NetworkVO network = _networkDao.findById(networkId);
- HostVO host = _hostDao.findById(hostId);
- String statsEntryIdentifier = "account " + account.getAccountName() + ", zone " + zone.getName() + ", network ID " + networkId + ", host ID " + host.getName();
-
- long newCurrentBytesSent = 0;
- long newCurrentBytesReceived = 0;
-
- if (publicIp != null) {
- long[] bytesSentAndReceived = null;
- statsEntryIdentifier += ", public IP: " + publicIp;
-
- if (host.getType().equals(Host.Type.ExternalLoadBalancer) && inline) {
- // Look up stats for the guest IP address that's mapped to the public IP address
- InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(publicIp);
-
- if (mapping != null) {
- NicVO nic = _nicDao.findById(mapping.getNicId());
- String loadBalancingIpAddress = nic.getIp4Address();
- bytesSentAndReceived = answer.ipBytes.get(loadBalancingIpAddress);
-
- if (bytesSentAndReceived != null) {
- bytesSentAndReceived[0] = 0;
- }
- }
- } else {
- bytesSentAndReceived = answer.ipBytes.get(publicIp);
- }
-
- if (bytesSentAndReceived == null) {
- s_logger.debug("Didn't get an external network usage answer for public IP " + publicIp);
- } else {
- newCurrentBytesSent += bytesSentAndReceived[0];
- newCurrentBytesReceived += bytesSentAndReceived[1];
- }
- } else {
- URI broadcastURI = network.getBroadcastUri();
- if (broadcastURI == null) {
- s_logger.debug("Not updating stats for guest network with ID " + network.getId() + " because the network is not implemented.");
- return true;
- } else {
- long vlanTag = Integer.parseInt(broadcastURI.getHost());
- long[] bytesSentAndReceived = answer.guestVlanBytes.get(String.valueOf(vlanTag));
-
- if (bytesSentAndReceived == null) {
- s_logger.warn("Didn't get an external network usage answer for guest VLAN " + vlanTag);
- } else {
- newCurrentBytesSent += bytesSentAndReceived[0];
- newCurrentBytesReceived += bytesSentAndReceived[1];
- }
- }
- }
-
- UserStatisticsVO userStats;
- try {
- userStats = _userStatsDao.lock(accountId, zoneId, networkId, publicIp, hostId, host.getType().toString());
- } catch (Exception e) {
- s_logger.warn("Unable to find user stats entry for " + statsEntryIdentifier);
- return false;
- }
-
- if (updateBytes(userStats, newCurrentBytesSent, newCurrentBytesReceived)) {
- s_logger.debug("Successfully updated stats for " + statsEntryIdentifier);
- return true;
- } else {
- s_logger.debug("Failed to update stats for " + statsEntryIdentifier);
- return false;
- }
- }
-
- private boolean createOrUpdateStatsEntry(boolean create, long accountId, long zoneId, long networkId, String publicIp, long hostId, ExternalNetworkResourceUsageAnswer answer, boolean inline) {
- if (create) {
- return createStatsEntry(accountId, zoneId, networkId, publicIp, hostId);
- } else {
- return updateStatsEntry(accountId, zoneId, networkId, publicIp, hostId, answer, inline);
- }
- }
-
- /*
- * Creates/updates all necessary stats entries for an account and zone.
- * Stats entries are created for source NAT IP addresses, static NAT rules, port forwarding rules, and load
- * balancing rules
- */
- private boolean manageStatsEntries(boolean create, long accountId, long zoneId, Network network,
- HostVO externalFirewall, ExternalNetworkResourceUsageAnswer firewallAnswer,
- HostVO externalLoadBalancer, ExternalNetworkResourceUsageAnswer lbAnswer) {
- String accountErrorMsg = "Failed to update external network stats entry. Details: account ID = " + accountId;
- Transaction txn = Transaction.open(Transaction.CLOUD_DB);
- try {
- txn.start();
- String networkErrorMsg = accountErrorMsg + ", network ID = " + network.getId();
-
- boolean sharedSourceNat = false;
- Map<Network.Capability, String> sourceNatCapabilities = _networkMgr.getNetworkServiceCapabilities(network.getId(), Network.Service.SourceNat);
- if (sourceNatCapabilities != null) {
- String supportedSourceNatTypes = sourceNatCapabilities.get(Network.Capability.SupportedSourceNatTypes).toLowerCase();
- if (supportedSourceNatTypes.contains("zone")) {
- sharedSourceNat = true;
- }
- }
-
- if(externalFirewall != null && firewallAnswer != null){
- if (!sharedSourceNat) {
- // Manage the entry for this network's source NAT IP address
- List<IPAddressVO> sourceNatIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), true);
- if (sourceNatIps.size() == 1) {
- String publicIp = sourceNatIps.get(0).getAddress().addr();
- if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer, false)) {
- throw new ExecutionException(networkErrorMsg + ", source NAT IP = " + publicIp);
- }
- }
-
- // Manage one entry for each static NAT rule in this network
- List<IPAddressVO> staticNatIps = _ipAddressDao.listStaticNatPublicIps(network.getId());
- for (IPAddressVO staticNatIp : staticNatIps) {
- String publicIp = staticNatIp.getAddress().addr();
- if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer, false)) {
- throw new ExecutionException(networkErrorMsg + ", static NAT rule public IP = " + publicIp);
- }
- }
-
- // Manage one entry for each port forwarding rule in this network
- List<PortForwardingRuleVO> portForwardingRules = _portForwardingRulesDao.listByNetwork(network.getId());
- for (PortForwardingRuleVO portForwardingRule : portForwardingRules) {
- String publicIp = _networkMgr.getIp(portForwardingRule.getSourceIpAddressId()).getAddress().addr();
- if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer, false)) {
- throw new ExecutionException(networkErrorMsg + ", port forwarding rule public IP = " + publicIp);
- }
- }
- } else {
- // Manage the account-wide entry for the external firewall
- if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), null, externalFirewall.getId(), firewallAnswer, false)) {
- throw new ExecutionException(networkErrorMsg);
- }
- }
- }
-
- // If an external load balancer is added, manage one entry for each load balancing rule in this network
- if (externalLoadBalancer != null && lbAnswer != null) {
- boolean inline = _networkMgr.isNetworkInlineMode(network);
- List<LoadBalancerVO> loadBalancers = _loadBalancerDao.listByNetworkIdAndScheme(network.getId(), Scheme.Public);
- for (LoadBalancerVO loadBalancer : loadBalancers) {
- String publicIp = _networkMgr.getIp(loadBalancer.getSourceIpAddressId()).getAddress().addr();
-
- if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalLoadBalancer.getId(), lbAnswer, inline)) {
- throw new ExecutionException(networkErrorMsg + ", load balancing rule public IP = " + publicIp);
- }
- }
- }
- return txn.commit();
- } catch (Exception e) {
- s_logger.warn("Exception: ", e);
- txn.rollback();
- return false;
- } finally {
- txn.close();
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b38d146/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
index 67d31ab..470d9b8 100755
--- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
+++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
@@ -30,6 +30,12 @@ import java.util.Set;
import javax.ejb.Local;
import javax.inject.Inject;
+import com.cloud.network.ExternalDeviceUsageManager;
+import com.cloud.network.IpAddress;
+import com.cloud.network.LBHealthCheckPolicyVO;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkManager;
+import com.cloud.network.NetworkModel;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBHealthCheckPolicyCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd;
@@ -63,15 +69,9 @@ import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.ExternalLoadBalancerUsageManager;
-import com.cloud.network.IpAddress;
-import com.cloud.network.LBHealthCheckPolicyVO;
-import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkManager;
-import com.cloud.network.NetworkModel;
import com.cloud.network.addr.PublicIp;
import com.cloud.network.as.AutoScalePolicy;
import com.cloud.network.as.AutoScalePolicyConditionMapVO;
@@ -210,7 +210,7 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
ConfigurationManager _configMgr;
@Inject
- ExternalLoadBalancerUsageManager _externalLBUsageMgr;
+ ExternalDeviceUsageManager _externalDeviceUsageMgr;
@Inject
NetworkServiceMapDao _ntwkSrvcDao;
@Inject
@@ -1214,7 +1214,7 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
NetworkVO network = _networkDao.findById(lb.getNetworkId());
if (network != null) {
if (_networkModel.networkIsConfiguredForExternalNetworking(network.getDataCenterId(), network.getId())) {
- _externalLBUsageMgr.updateExternalLoadBalancerNetworkUsageStats(loadBalancerId);
+ _externalDeviceUsageMgr.updateExternalLoadBalancerNetworkUsageStats(loadBalancerId);
}
}