From e07a8b3f513d695ec639e261d604bdf7bc8dc6f4 Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Mon, 1 Jul 2013 18:59:14 +0530 Subject: [PATCH] CLOUDSTACK-3282:[GSLB] Unable to add multiple LB rules to same GSLB rule -fixing regression due to adding GSLB monitor for GSLB service -code to add/delete GSLB monitor and GSLB service-monitor binding is made idempotenet so as to succeed if the resource exists. --- .../network/resource/NetscalerResource.java | 121 +++++++++++++----- .../GlobalLoadBalancingRulesServiceImpl.java | 5 +- 2 files changed, 92 insertions(+), 34 deletions(-) diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java index 263e13b42f3..d25d4160e6b 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java @@ -905,46 +905,27 @@ public class NetscalerResource implements ServerResource { GSLB.createVserverServiceBinding(_netscalerService, serviceName, vserverName); // create a monitor for the service running on the site - lbmonitor newmonitor = new lbmonitor(); - String monitorName = GSLB.generateGslbServiceMonitorName(servicePublicIp); - newmonitor.set_type("TCP"); - newmonitor.set_servicename(serviceName); - newmonitor.set_monitorname(monitorName); - newmonitor.set_state("ENABLED"); - lbmonitor.add(_netscalerService, newmonitor); + GSLB.createGslbServiceMonitor(_netscalerService, servicePublicIp, serviceName); - // bind the monitor to the GSLB servie - try { - gslbservice_lbmonitor_binding monitorBinding = new gslbservice_lbmonitor_binding(); - monitorBinding.set_monitor_name(monitorName); - monitorBinding.set_servicename(serviceName); - gslbservice_lbmonitor_binding.add(_netscalerService, monitorBinding); - } catch (Exception e) { - // TODO: Nitro API version 10.* is not compatible for NetScalers 9.*, so may fail - // against NetScaler version lesser than 10 hence ignore the exception - s_logger.warn("Failed to bind monitor to GSLB service due to " + e.getMessage()); - } + // bind the monitor to the GSLB service + GSLB.createGslbServiceGslbMonitorBinding(_netscalerService, servicePublicIp, serviceName); } else { + + String monitorName = GSLB.generateGslbServiceMonitorName(servicePublicIp); + + // delete GSLB service and GSLB monitor binding + GSLB.deleteGslbServiceGslbMonitorBinding(_netscalerService, monitorName, serviceName); + + // delete the GSLB service monitor + GSLB.deleteGslbServiceMonitor(_netscalerService, monitorName); + // Unbind GSLB service with GSLB virtual server GSLB.deleteVserverServiceBinding(_netscalerService, serviceName, vserverName); // delete 'gslbservice' object gslbservice service = GSLB.getServiceObject(_netscalerService, serviceName); GSLB.deleteService(_netscalerService, serviceName); - - // delete the GSLB service monitor - String monitorName = GSLB.generateGslbServiceMonitorName(servicePublicIp); - try { - lbmonitor serviceMonitor = lbmonitor.get(_netscalerService, monitorName); - if (serviceMonitor != null) { - lbmonitor.delete(_netscalerService, serviceMonitor); - } - } catch (nitro_exception ne) { - if (ne.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) { - s_logger.warn("Failed to delete monitor "+ monitorName + " for GSLB service due to " + ne.getMessage()); - } - } } if (site.forRevoke()) { // delete the site if its for revoke @@ -969,9 +950,16 @@ public class NetscalerResource implements ServerResource { String servicePublicIp = site.getServicePublicIp(); String servicePublicPort = site.getServicePort(); String siteName = GSLB.generateUniqueSiteName(sitePrivateIP, sitePublicIP, site.getDataCenterId()); + String serviceName = GSLB.generateUniqueServiceName(siteName, servicePublicIp, servicePublicPort); + String monitorName = GSLB.generateGslbServiceMonitorName(servicePublicIp); + + // delete GSLB service and GSLB monitor binding + GSLB.deleteGslbServiceGslbMonitorBinding(_netscalerService, servicePublicIp, serviceName); + + // delete the GSLB service monitor + GSLB.deleteGslbServiceMonitor(_netscalerService, monitorName); // remove binding between virtual server and services - String serviceName = GSLB.generateUniqueServiceName(siteName, servicePublicIp, servicePublicPort); GSLB.deleteVserverServiceBinding(_netscalerService, serviceName, vserverName); // delete service object @@ -1460,6 +1448,75 @@ public class NetscalerResource implements ServerResource { } } + private static void createGslbServiceMonitor(nitro_service nsService, String servicePublicIp, + String serviceName) throws ExecutionException { + try { + lbmonitor newmonitor = new lbmonitor(); + String monitorName = generateGslbServiceMonitorName(servicePublicIp); + newmonitor.set_type("TCP"); + newmonitor.set_servicename(serviceName); + newmonitor.set_monitorname(monitorName); + newmonitor.set_state("ENABLED"); + lbmonitor.add(nsService, newmonitor); + } catch (nitro_exception ne) { + if (ne.getErrorCode() == NitroError.NS_RESOURCE_EXISTS) { + return; + } + } catch (Exception e) { + String errMsg = "Failed to create GSLB monitor for service public ip" + servicePublicIp; + if (s_logger.isDebugEnabled()) { + s_logger.debug(errMsg); + } + throw new ExecutionException(errMsg); + } + } + + private static void deleteGslbServiceMonitor(nitro_service nsService, String monitorName) + throws ExecutionException { + try { + lbmonitor serviceMonitor = lbmonitor.get(nsService, monitorName); + if (serviceMonitor != null) { + lbmonitor.delete(nsService, serviceMonitor); + } + } catch (nitro_exception ne) { + if (ne.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) { + String errMsg = "Failed to delete monitor "+ monitorName + " for GSLB service due to " + ne.getMessage(); + s_logger.debug(errMsg); + throw new com.cloud.utils.exception.ExecutionException(errMsg); + } + } catch (Exception e) { + String errMsg = "Failed to delete monitor "+ monitorName + " for GSLB service due to " + e.getMessage(); + s_logger.debug(errMsg); + throw new com.cloud.utils.exception.ExecutionException(errMsg); + } + } + + private static void createGslbServiceGslbMonitorBinding(nitro_service nsService, String servicePublicIp, + String serviceName) { + try { + String monitorName = GSLB.generateGslbServiceMonitorName(servicePublicIp); + gslbservice_lbmonitor_binding monitorBinding = new gslbservice_lbmonitor_binding(); + monitorBinding.set_monitor_name(monitorName); + monitorBinding.set_servicename(serviceName); + gslbservice_lbmonitor_binding.add(nsService, monitorBinding); + } catch (Exception e) { + // TODO: Nitro API version 10.* is not compatible for NetScalers 9.*, so may fail + // against NetScaler version lesser than 10 hence ignore the exception + s_logger.warn("Failed to bind monitor to GSLB service due to " + e.getMessage()); + } + } + + private static void deleteGslbServiceGslbMonitorBinding(nitro_service nsService, String monitorName, + String serviceName) { + try { + gslbservice_lbmonitor_binding[] monitorBindings = gslbservice_lbmonitor_binding.get(nsService, serviceName); + gslbservice_lbmonitor_binding.delete(nsService, monitorBindings); + } catch (Exception e) { + s_logger.warn("Failed to delet GSLB monitor " + monitorName + "and GSLB service " + serviceName + + " binding due to " + e.getMessage()); + } + } + // get 'gslbsite' object corresponding to a site name private static gslbsite getSiteObject(nitro_service client, String siteName) { try { diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java index 483c19af431..0642390398b 100644 --- a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java +++ b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java @@ -648,8 +648,9 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR try { _gslbProvider.applyGlobalLoadBalancerRule(zoneId.first(), zoneId.second(), gslbConfigCmd); } catch (ResourceUnavailableException e) { - s_logger.warn("Failed to configure GSLB rul in the zone " + zoneId + " due to " + e.getMessage()); - throw new CloudRuntimeException("Failed to configure GSLB rul in the zone"); + String msg = "Failed to configure GSLB rule in the zone " + zoneId.first() + " due to " + e.getMessage(); + s_logger.warn(msg); + throw new CloudRuntimeException(msg); } }