From 6e405efe01495a6f32ddbc16cb8ecbe4ecb59c19 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Wed, 22 Jun 2011 15:24:04 -0700 Subject: [PATCH] bug 10311: Update UpdateNetworkCmd, allow change networkOfferingId And restart/re-implement the network if networkOfferingId is changed. --- .../cloud/api/commands/UpdateNetworkCmd.java | 7 +++- api/src/com/cloud/network/NetworkService.java | 2 +- .../com/cloud/network/NetworkManagerImpl.java | 40 ++++++++++++++++++- server/src/com/cloud/network/NetworkVO.java | 4 ++ .../network/element/VirtualRouterElement.java | 27 +++++++++---- 5 files changed, 68 insertions(+), 12 deletions(-) diff --git a/api/src/com/cloud/api/commands/UpdateNetworkCmd.java b/api/src/com/cloud/api/commands/UpdateNetworkCmd.java index 8add07d7eba..0aa4fd6426f 100644 --- a/api/src/com/cloud/api/commands/UpdateNetworkCmd.java +++ b/api/src/com/cloud/api/commands/UpdateNetworkCmd.java @@ -59,6 +59,8 @@ public class UpdateNetworkCmd extends BaseCmd { @Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING, description="network domain") private String networkDomain; + @Parameter(name=ApiConstants.NETWORK_OFFERING_ID, type=CommandType.LONG, description="network offering ID") + private Long networkOfferingId; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -84,6 +86,9 @@ public class UpdateNetworkCmd extends BaseCmd { return networkDomain; } + private Long getNetworkOfferingId() { + return networkOfferingId == null ? 0 : networkOfferingId; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// @@ -107,7 +112,7 @@ public class UpdateNetworkCmd extends BaseCmd { @Override public void execute() throws InsufficientCapacityException, ConcurrentOperationException{ - Network result = _networkService.updateNetwork(getId(), getNetworkName(), getDisplayText(), tags, UserContext.current().getCaller(), getNetworkDomain()); + Network result = _networkService.updateNetwork(getId(), getNetworkName(), getDisplayText(), tags, UserContext.current().getCaller(), getNetworkDomain(), getNetworkOfferingId()); if (result != null) { NetworkResponse response = _responseGenerator.createNetworkResponse(result); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 4a14ce50d68..d44a9f02448 100644 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -81,7 +81,7 @@ public interface NetworkService { Long getDedicatedNetworkDomain(long networkId); - Network updateNetwork(long networkId, String name, String displayText, List tags, Account caller, String domainSuffix); + Network updateNetwork(long networkId, String name, String displayText, List tags, Account caller, String domainSuffix, long networkOfferingId); Integer getNetworkRate(long networkId, Long vmId); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 4ac57b6854c..494b551eee1 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -2360,11 +2360,12 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag s_logger.debug("Restarting network " + networkId + "..."); + ReservationContext context = new ReservationContextImpl(null, null, null, caller); if (restartElements) { s_logger.debug("Restarting network elements for the network " + network); for (NetworkElement element : _networkElements) { // stop and start the network element - if (!element.restart(network, null)) { + if (!element.restart(network, context)) { s_logger.warn("Failed to restart network element(s) as a part of network id" + networkId + " restart"); success = false; } @@ -2904,7 +2905,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @ActionEvent(eventType = EventTypes.EVENT_NETWORK_UPDATE, eventDescription = "updating network", async = false) - public Network updateNetwork(long networkId, String name, String displayText, List tags, Account caller, String domainSuffix) { + public Network updateNetwork(long networkId, String name, String displayText, List tags, Account caller, String domainSuffix, long networkOfferingId) { // verify input parameters NetworkVO network = _networksDao.findById(networkId); @@ -2960,8 +2961,43 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (tags != null) { network.setTags(tags); } + + long oldNetworkOfferingId = network.getNetworkOfferingId(); + if (networkOfferingId != 0) { + NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId); + if (networkOffering == null || networkOffering.isSystemOnly()) { + throw new InvalidParameterValueException("Unable to find network offering by id " + networkOfferingId); + } + if (networkOffering.getAvailability() == Availability.Unavailable) { + throw new InvalidParameterValueException("Can't update network; network offering id=" + networkOfferingId + " is " + networkOffering.getAvailability()); + } + network.setNetworkOfferingId(networkOfferingId); + } _networksDao.update(networkId, network); + + if ((networkOfferingId != 0) && (networkOfferingId != oldNetworkOfferingId)) { + s_logger.info("Try to restart the network since the networkofferingID is changed"); + // Don't allow to restart network if it's not in Implemented/Setup state + if (!(network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup)) { + s_logger.warn("Network is not in the right state to be restarted. Correct states are: " + Network.State.Implemented + ", " + Network.State.Setup); + } + + boolean success = true; + try { + // Restart network - network elements restart is required + success = restartNetwork(networkId, true, caller); + } catch (Exception e) { + s_logger.warn("Fail to restart the network: " + e); + success = false; + } + + if (success) { + s_logger.debug("Network id=" + networkId + " is restarted successfully."); + } else { + s_logger.warn("Network id=" + networkId + " failed to restart."); + } + } return network; diff --git a/server/src/com/cloud/network/NetworkVO.java b/server/src/com/cloud/network/NetworkVO.java index b98a188b49c..597eee8ea23 100644 --- a/server/src/com/cloud/network/NetworkVO.java +++ b/server/src/com/cloud/network/NetworkVO.java @@ -291,6 +291,10 @@ public class NetworkVO implements Network { return networkOfferingId; } + public void setNetworkOfferingId(long networkOfferingId) { + this.networkOfferingId = networkOfferingId; + } + public void setMode(Mode mode) { this.mode = mode; } diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index cadbb3e01c7..74c2569f2e8 100644 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -31,6 +31,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.host.dao.HostDao; import com.cloud.network.Network; import com.cloud.network.Network.Capability; import com.cloud.network.Network.GuestIpType; @@ -49,7 +50,9 @@ import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.RulesManager; import com.cloud.network.vpn.RemoteAccessVpnElement; import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.org.Cluster; import com.cloud.user.AccountManager; import com.cloud.uservm.UserVm; import com.cloud.utils.component.Inject; @@ -82,6 +85,7 @@ public class VirtualRouterElement extends DhcpElement implements NetworkElement, @Inject DomainRouterDao _routerDao; @Inject LoadBalancerDao _lbDao; @Inject AccountManager _accountMgr; + @Inject HostDao _hostDao; private boolean canHandle(GuestIpType ipType, DataCenter dc) { String provider = dc.getGatewayProvider(); @@ -128,29 +132,36 @@ public class VirtualRouterElement extends DhcpElement implements NetworkElement, public boolean restart(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException{ DataCenter dc = _configMgr.getZone(network.getDataCenterId()); DeployDestination dest = new DeployDestination(dc, null, null, null); + + NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId()); + + // We need to re-implement the network since the redundancy capability may changed List routers = _routerDao.findByNetwork(network.getId()); if (routers == null || routers.isEmpty()) { s_logger.trace("Can't find virtual router element in network " + network.getId()); return true; } - VirtualRouter result = null; + /* Get the host_id in order to find the cluster */ + long host_id = 0; + boolean result = true; boolean ret = true; for (DomainRouterVO router : routers) { if (canHandle(network.getGuestType(), dest.getDataCenter())) { - if (router.getState() == State.Stopped) { - result = _routerMgr.startRouter(router.getId(), false); - } else { - result = _routerMgr.rebootRouter(router.getId(), false); - } - if (result == null) { - s_logger.warn("Failed to restart virtual router element " + router + " as a part of netowrk " + network + " restart"); + host_id = router.getHostId(); + _routerMgr.stopRouter(router.getId(), true); + result = _routerMgr.destroyRouter(router.getId()); + if (!result) { + s_logger.warn("Failed to destroy virtual router element " + router + " as a part of netowrk " + network + " restart"); ret = false; } } else { s_logger.trace("Virtual router element doesn't handle network restart for the network " + network); } } + Cluster cluster = _configMgr.getCluster(_hostDao.findById(host_id).getClusterId()); + dest = new DeployDestination(dc, null, cluster, null); + implement(network, networkOffering, dest, context); return ret; }