You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mu...@apache.org on 2012/06/22 03:56:11 UTC

[5/6] moving out NetScaler network element code from CloudStack core into plugins/network-elements/netscaler

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/49b88472/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..c7b31f3
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java
@@ -0,0 +1,1533 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License.  Citrix Systems, Inc.
+// reserves all rights not expressly granted by 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.
+// 
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.network.resource;
+
+import java.util.List;
+import java.util.Map;
+import javax.naming.ConfigurationException;
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.routing.CreateLoadBalancerApplianceCommand;
+import com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand;
+import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer;
+import com.cloud.agent.api.ExternalNetworkResourceUsageCommand;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupExternalLoadBalancerCommand;
+import com.cloud.agent.api.routing.IpAssocAnswer;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
+import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
+import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.LoadBalancerTO;
+import com.cloud.agent.api.to.StaticNatRuleTO;
+import com.cloud.agent.api.to.LoadBalancerTO.DestinationTO;
+import com.cloud.agent.api.to.LoadBalancerTO.StickinessPolicyTO;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
+import com.cloud.resource.ServerResource;
+import com.cloud.serializer.GsonHelper;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.exception.ExecutionException;
+import com.cloud.utils.net.NetUtils;
+import com.google.gson.Gson;
+
+import com.citrix.netscaler.nitro.service.nitro_service;
+import com.citrix.netscaler.nitro.util.filtervalue;
+import com.citrix.netscaler.nitro.resource.base.base_response;
+import com.citrix.netscaler.nitro.exception.nitro_exception;
+import com.citrix.netscaler.nitro.resource.config.ns.nsconfig;
+import com.citrix.netscaler.nitro.resource.config.lb.lbvserver;
+import com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding;
+import com.citrix.netscaler.nitro.resource.config.network.*;
+import com.citrix.netscaler.nitro.resource.config.ns.*;
+import com.citrix.netscaler.nitro.resource.config.basic.server_service_binding;
+import com.citrix.netscaler.nitro.resource.stat.lb.lbvserver_stats;
+import com.citrix.sdx.nitro.resource.config.device_profile;
+import com.citrix.sdx.nitro.resource.config.ns;
+import com.citrix.sdx.nitro.resource.config.mps;
+import com.citrix.sdx.nitro.resource.config.xen_vpx_image;
+
+import org.apache.log4j.Logger;
+
+class NitroError {
+    static final int NS_RESOURCE_EXISTS = 273;
+    static final int NS_RESOURCE_NOT_EXISTS=258;
+    static final int NS_NO_SERIVCE = 344;
+    static final int NS_OPERATION_NOT_PERMITTED = 257;
+    static final int NS_INTERFACE_ALREADY_BOUND_TO_VLAN = 2080;
+}
+
+public class NetscalerResource implements ServerResource {
+
+    // deployment configuration
+    private String _name;
+    private String _zoneId;
+    private String _physicalNetworkId;
+    private String _ip;
+    private String _username;
+    private String _password;
+    private String _publicInterface;
+    private String _privateInterface;
+    private Integer _numRetries; 
+    private String _guid;
+    private boolean _inline;
+    private boolean _isSdx;
+    private boolean _cloudManaged;
+    private String _deviceName;
+    private String _publicIP;
+    private String _publicIPNetmask;
+    private String _publicIPGateway;
+    private String _publicIPVlan;
+
+    private static final Logger s_logger = Logger.getLogger(NetscalerResource.class);
+    protected Gson _gson;
+    private String _objectNamePathSep = "-";
+
+    // interface to interact with VPX and MPX devices
+    com.citrix.netscaler.nitro.service.nitro_service _netscalerService ;
+
+    // interface to interact with service VM of the SDX appliance
+    com.citrix.sdx.nitro.service.nitro_service _netscalerSdxService;
+
+    Long _timeout = new Long(100000);
+    base_response apiCallResult;
+
+    public NetscalerResource () {
+        _gson = GsonHelper.getGsonLogger();
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        try {
+            _name = (String) params.get("name");
+            if (_name == null) {
+                throw new ConfigurationException("Unable to find name in the configuration parameters");
+            }
+
+            _zoneId = (String) params.get("zoneId");
+            if (_zoneId == null) {
+                throw new ConfigurationException("Unable to find zone Id  in the configuration parameters");
+            }
+
+            _physicalNetworkId = (String) params.get("physicalNetworkId");
+            if (_physicalNetworkId == null) {
+                throw new ConfigurationException("Unable to find physical network id in the configuration parameters");
+            }
+
+            _ip = (String) params.get("ip");
+            if (_ip == null) {
+                throw new ConfigurationException("Unable to find IP address in the configuration parameters");
+            }
+
+            _username = (String) params.get("username");
+            if (_username == null) {
+                throw new ConfigurationException("Unable to find username in the configuration parameters");
+            }
+
+            _password = (String) params.get("password");
+            if (_password == null) {
+                throw new ConfigurationException("Unable to find password in the configuration parameters");
+            }
+
+            _publicInterface = (String) params.get("publicinterface");
+            if (_publicInterface == null) {
+                throw new ConfigurationException("Unable to find public interface in the configuration parameters");
+            }
+
+            _privateInterface = (String) params.get("privateinterface");
+            if (_privateInterface == null) {
+                throw new ConfigurationException("Unable to find private interface in the configuration parameters");
+            }
+
+            _numRetries = NumbersUtil.parseInt((String) params.get("numretries"), 2);
+
+            _guid = (String)params.get("guid");
+            if (_guid == null) {
+                throw new ConfigurationException("Unable to find the guid in the configuration parameters");
+            }
+
+            _deviceName = (String) params.get("deviceName");
+            if (_deviceName == null) {
+                throw new ConfigurationException("Unable to find the device name in the configuration parameters");
+            }
+
+            _isSdx = _deviceName.equalsIgnoreCase("NetscalerSDXLoadBalancer");
+
+            _inline = Boolean.parseBoolean((String) params.get("inline"));
+
+            if (((String) params.get("cloudmanaged")) != null) {
+                _cloudManaged = Boolean.parseBoolean((String) params.get("cloudmanaged"));
+            }
+
+            // validate device configuration parameters
+            login();
+            validateDeviceType(_deviceName);
+            validateInterfaces(_publicInterface, _privateInterface);
+            
+            //enable load balancing feature 
+            enableLoadBalancingFeature();
+
+            //if the the device is cloud stack provisioned then make it part of the public network
+            if (_cloudManaged) {
+                _publicIP = (String) params.get("publicip");
+                _publicIPGateway = (String) params.get("publicipgateway");
+                _publicIPNetmask = (String) params.get("publicipnetmask");
+                _publicIPVlan = (String) params.get("publicipvlan");
+                if ("untagged".equalsIgnoreCase(_publicIPVlan)) {
+                	// if public network is un-tagged just add subnet IP
+                    addSubnetIP(_publicIP, _publicIPNetmask);
+                } else {
+                	// if public network is tagged then add vlan and bind subnet IP to the vlan
+                    addGuestVlanAndSubnet(Long.parseLong(_publicIPVlan), _publicIP, _publicIPNetmask, false);
+                }
+            }
+
+            return true;
+        } catch (Exception e) {
+            throw new ConfigurationException(e.getMessage());
+        }
+    }
+
+    private void login() throws ExecutionException {
+        try {
+            if (!_isSdx) {
+                _netscalerService = new nitro_service(_ip, "https");
+                _netscalerService.set_credential(_username, _password);
+                _netscalerService.set_timeout(_timeout);
+                apiCallResult = _netscalerService.login();
+                if (apiCallResult.errorcode != 0) {
+                    throw new ExecutionException ("Failed to log in to Netscaler device at " + _ip + " due to error " + apiCallResult.errorcode + " and message " + apiCallResult.message);
+                }
+            } else {
+                _netscalerSdxService = new com.citrix.sdx.nitro.service.nitro_service(_ip, "https");
+                _netscalerSdxService.set_credential(_username, _password);
+                com.citrix.sdx.nitro.resource.base.login login  = _netscalerSdxService.login();
+                if (login == null) {
+                    throw new ExecutionException ("Failed to log in to Netscaler device at " + _ip + " due to error " + apiCallResult.errorcode + " and message " + apiCallResult.message);
+                }
+            }
+        } catch (nitro_exception e) {
+            throw new ExecutionException("Failed to log in to Netscaler device at " + _ip + " due to " + e.getMessage());
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to log in to Netscaler device at " + _ip + " due to " + e.getMessage());
+        }
+    }
+
+    private void enableLoadBalancingFeature() throws ExecutionException {
+        if (_isSdx) {
+            return;
+        }
+        try {
+            String[] features = _netscalerService.get_enabled_features();
+            if (features != null) {
+                for (String feature : features) {
+                    if (feature.equalsIgnoreCase("LB")) {
+                        return;
+                    }
+                }
+            }
+
+            // enable load balancing on the device
+            String[] feature = new String[1];
+            feature[0] = "LB";
+            apiCallResult = _netscalerService.enable_features(feature);
+            if (apiCallResult.errorcode != 0) {
+                throw new ExecutionException("Enabling load balancing feature on the device failed.");
+            }
+        } catch (nitro_exception e) {
+            throw new ExecutionException("Enabling load balancing feature on the device failed  due to " + e.getMessage());
+        } catch (Exception e) {
+            throw new ExecutionException("Enabling load balancing feature on the device failed due to " + e.getMessage());
+        }
+    }
+
+    private void validateInterfaces(String publicInterface, String privateInterface) throws ExecutionException {
+        try {
+            if (!_isSdx && !_cloudManaged) {
+                Interface publicIf = Interface.get(_netscalerService, publicInterface);
+                Interface privateIf = Interface.get(_netscalerService, privateInterface);
+                if (publicIf != null || privateIf != null) {
+                    return;
+                } else {
+                    throw new ExecutionException("Invalid interface name specified for public/private interfaces.");
+                }
+            }
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                throw new ExecutionException("Invalid interface name specified for public and private interfaces.");
+            } else {
+                throw new ExecutionException("Failed to verify public interface and private intefaces are valid due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify public interface and private intefaces are valid due to " + e.getMessage());
+        }
+    }
+
+    private void validateDeviceType(String deviceType) throws ExecutionException {
+        try {
+            if (!_isSdx && !_cloudManaged) {
+                nshardware nsHw =  com.citrix.netscaler.nitro.resource.config.ns.nshardware.get(_netscalerService);
+                if (nsHw == null) {
+                    throw new ExecutionException("Failed to get the hardware description of the Netscaler device at " + _ip);
+                } else {
+                    if ((_deviceName.equalsIgnoreCase("NetscalerMPXLoadBalancer") && nsHw.get_hwdescription().contains("MPX"))
+                            || (_deviceName.equalsIgnoreCase("NetscalerVPXLoadBalancer") && nsHw.get_hwdescription().contains("NetScaler Virtual Appliance"))) {
+                        return;
+                    }
+                    throw new ExecutionException("Netscalar device type specified does not match with the actuall device type.");
+                }
+            } else if (_isSdx) {
+                mps serviceVM = mps.get(_netscalerSdxService);
+                if (serviceVM != null) {
+                    if (serviceVM.get_platform().contains("SDX") || serviceVM.get_product().contains("SDX")) {
+                        return;
+                    } else {
+                        throw new ExecutionException("Netscalar device type specified does not match with the actuall device type.");
+                    }
+                } else {
+                    throw new ExecutionException("Failed to get the hardware details of the Netscaler device at " + _ip);
+                }
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify device type specified when matching with actuall device type due to " + e.getMessage());
+        }
+    }
+
+    @Override
+    public StartupCommand[] initialize() {
+        StartupExternalLoadBalancerCommand cmd = new StartupExternalLoadBalancerCommand();
+        cmd.setName(_name);
+        cmd.setDataCenter(_zoneId);
+        cmd.setPod("");
+        cmd.setPrivateIpAddress(_ip);
+        cmd.setStorageIpAddress("");
+        cmd.setVersion("");
+        cmd.setGuid(_guid);
+        return new StartupCommand[]{cmd};
+    }
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+        return executeRequest(cmd, _numRetries);
+    }
+
+    private Answer executeRequest(Command cmd, int numRetries) {
+        if (cmd instanceof ReadyCommand) {
+            return execute((ReadyCommand) cmd);
+        } else if (cmd instanceof MaintainCommand) {
+            return execute((MaintainCommand) cmd);
+        } else if (cmd instanceof IpAssocCommand) {
+            return execute((IpAssocCommand) cmd, numRetries);
+        } else if (cmd instanceof LoadBalancerConfigCommand) {
+            return execute((LoadBalancerConfigCommand) cmd, numRetries);
+        } else if (cmd instanceof ExternalNetworkResourceUsageCommand) {
+            return execute((ExternalNetworkResourceUsageCommand) cmd, numRetries);
+        } else if (cmd instanceof CreateLoadBalancerApplianceCommand) {
+            return execute((CreateLoadBalancerApplianceCommand) cmd, numRetries);
+        } else if (cmd instanceof DestroyLoadBalancerApplianceCommand) {
+            return execute((DestroyLoadBalancerApplianceCommand) cmd, numRetries);
+        } else if (cmd instanceof SetStaticNatRulesCommand) {
+            return execute((SetStaticNatRulesCommand) cmd, numRetries);
+        } else {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    private Answer execute(ReadyCommand cmd) {
+        return new ReadyAnswer(cmd);
+    }
+
+    protected Answer execute(MaintainCommand cmd) {
+        return new MaintainAnswer(cmd);
+    }
+
+    private synchronized Answer execute(IpAssocCommand cmd, int numRetries) {
+        if (_isSdx) {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+
+        String[] results = new String[cmd.getIpAddresses().length];
+        int i = 0;
+        try {        
+            IpAddressTO[] ips = cmd.getIpAddresses();
+            for (IpAddressTO ip : ips) {
+                long guestVlanTag = Long.valueOf(ip.getVlanId());
+                String vlanSelfIp = ip.getVlanGateway();
+                String vlanNetmask = ip.getVlanNetmask();
+
+                if (ip.isAdd()) {
+                    // Add a new guest VLAN and its subnet and bind it to private interface
+                    addGuestVlanAndSubnet(guestVlanTag, vlanSelfIp, vlanNetmask, true);
+                } else {
+                    // Check and delete guest VLAN with this tag, self IP, and netmask
+                    deleteGuestVlan(guestVlanTag, vlanSelfIp, vlanNetmask);
+                }
+
+                saveConfiguration();
+                results[i++] = ip.getPublicIp() + " - success";
+                String action = ip.isAdd() ? "associate" : "remove";
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Netscaler load balancer " + _ip + " successfully executed IPAssocCommand to " + action + " IP " + ip);
+                }
+            }
+        } catch (ExecutionException e) {
+            s_logger.error("Netscaler loadbalancer " + _ip+ " failed to execute IPAssocCommand due to " + e.getMessage());
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            } else {
+                results[i++] = IpAssocAnswer.errorResult;
+            }
+        }
+
+        return new IpAssocAnswer(cmd, results);
+    }
+
+    private synchronized Answer execute(LoadBalancerConfigCommand cmd, int numRetries) {
+        try {
+            if (_isSdx) {
+                return Answer.createUnsupportedCommandAnswer(cmd);
+            }
+
+            LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers();
+            if (loadBalancers == null) {
+                return new Answer(cmd);
+            }
+
+            for (LoadBalancerTO loadBalancer : loadBalancers) {
+                String srcIp = loadBalancer.getSrcIp();
+                int srcPort = loadBalancer.getSrcPort();
+                String lbProtocol = getNetScalerProtocol(loadBalancer);
+                String lbAlgorithm = loadBalancer.getAlgorithm();
+                String nsVirtualServerName  = generateNSVirtualServerName(srcIp, srcPort);
+
+                boolean destinationsToAdd = false;
+                for (DestinationTO destination : loadBalancer.getDestinations()) {
+                    if (!destination.isRevoked()) {
+                        destinationsToAdd = true;
+                        break;
+                    }
+                }
+
+                if (!loadBalancer.isRevoked() && destinationsToAdd) {
+
+                    // create a load balancing virtual server
+                    addLBVirtualServer(nsVirtualServerName, srcIp, srcPort, lbAlgorithm, lbProtocol, loadBalancer.getStickinessPolicies());
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Created load balancing virtual server " + nsVirtualServerName + " on the Netscaler device");
+                    }
+
+                    for (DestinationTO destination : loadBalancer.getDestinations()) {
+                        
+                        String nsServerName = generateNSServerName(destination.getDestIp());
+                        String nsServiceName = generateNSServiceName(destination.getDestIp(), destination.getDestPort());
+                        
+                        if (!destination.isRevoked()) {
+                            // add a new destination to deployed load balancing rule
+
+                            // add a new server
+                            if (!nsServerExists(nsServerName)) {
+                                com.citrix.netscaler.nitro.resource.config.basic.server nsServer = new com.citrix.netscaler.nitro.resource.config.basic.server();
+                                nsServer.set_name(nsServerName);
+                                nsServer.set_ipaddress(destination.getDestIp());
+                                apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.add(_netscalerService, nsServer);
+                                if ((apiCallResult.errorcode != 0) && (apiCallResult.errorcode != NitroError.NS_RESOURCE_EXISTS)) {
+                                    throw new ExecutionException("Failed to add server " + destination.getDestIp() + " due to" + apiCallResult.message);
+                                }
+                            }
+
+                            // create a new service using the server added
+                            if (!nsServiceExists(nsServiceName)) {
+                                com.citrix.netscaler.nitro.resource.config.basic.service newService = new com.citrix.netscaler.nitro.resource.config.basic.service();
+                                newService.set_name(nsServiceName);
+                                newService.set_port(destination.getDestPort());
+                                newService.set_servername(nsServerName);
+                                newService.set_state("ENABLED");
+                                newService.set_servicetype(lbProtocol);
+
+                                apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.add(_netscalerService, newService);
+                                if (apiCallResult.errorcode != 0) {
+                                    throw new ExecutionException("Failed to create service " + nsServiceName + " using server " + nsServerName + " due to" + apiCallResult.message);
+                                }
+                            }
+
+                            //bind service to load balancing virtual server    
+                            if (!nsServiceBindingExists(nsVirtualServerName, nsServiceName)) {
+                                com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding svcBinding = new com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding();
+                                svcBinding.set_name(nsVirtualServerName);
+                                svcBinding.set_servicename(nsServiceName);
+                                apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.add(_netscalerService, svcBinding);
+                                
+                                if (apiCallResult.errorcode != 0) {
+                                    throw new ExecutionException("Failed to bind service: " + nsServiceName + " to the lb virtual server: " + nsVirtualServerName + " on Netscaler device");
+                                }
+                            }
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Successfully added LB destination: " + destination.getDestIp() + ":" + destination.getDestPort() + " to load balancer " + srcIp + ":" + srcPort);
+                            }
+                        } else {
+                            // remove a destination from the deployed load balancing rule
+                            com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, nsVirtualServerName);
+                            if (serviceBindings != null) {
+                                for (com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding binding : serviceBindings) {
+                                    if (nsServiceName.equalsIgnoreCase(binding.get_servicename())) {
+                                        // delete the binding
+                                        apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.delete(_netscalerService, binding);
+                                        if (apiCallResult.errorcode != 0) {
+                                            throw new ExecutionException("Failed to delete the binding between the virtual server: " + nsVirtualServerName + " and service:" + nsServiceName + " due to" + apiCallResult.message);
+                                        }
+    
+                                        // check if service is bound to any other virtual server
+                                        if (!isServiceBoundToVirtualServer(nsServiceName)) {
+                                            // no lb virtual servers are bound to this service so delete it
+                                            apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, nsServiceName);
+                                            if (apiCallResult.errorcode != 0) {
+                                                throw new ExecutionException("Failed to delete service: " + nsServiceName + " due to " + apiCallResult.message);
+                                            }
+                                        }
+    
+                                        // delete the server if there is no associated services
+                                        server_service_binding[] services = server_service_binding.get(_netscalerService, nsServerName);
+                                        if ((services == null) || (services.length == 0)) {
+                                            apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, nsServerName);
+                                            if (apiCallResult.errorcode != 0) {
+                                                throw new ExecutionException("Failed to remove server:" + nsServerName + " due to " + apiCallResult.message);
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                         }
+                    }
+                } else {
+                    // delete the implemented load balancing rule and its destinations 
+                    lbvserver lbserver = getVirtualServerIfExisits(nsVirtualServerName);
+                    if (lbserver != null) {
+                        //unbind the all services associated with this virtual server
+                        com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, nsVirtualServerName);
+                        
+                        if (serviceBindings != null) {
+                            for (com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding binding : serviceBindings) {
+                                String serviceName = binding.get_servicename();
+                                apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.delete(_netscalerService, binding);
+                                if (apiCallResult.errorcode != 0) {
+                                    throw new ExecutionException("Failed to unbind service from the lb virtual server: " + nsVirtualServerName + " due to " + apiCallResult.message);
+                                }
+        
+                                com.citrix.netscaler.nitro.resource.config.basic.service svc = com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService, serviceName);
+                                String nsServerName = svc.get_servername();
+
+                                // check if service is bound to any other virtual server
+                                if (!isServiceBoundToVirtualServer(serviceName)) {
+                                    // no lb virtual servers are bound to this service so delete it
+                                    apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, serviceName);
+                                    if (apiCallResult.errorcode != 0) {
+                                        throw new ExecutionException("Failed to delete service: " + serviceName + " due to " + apiCallResult.message);
+                                    }
+                                }
+
+                                //delete the server if no more services attached
+                                server_service_binding[] services = server_service_binding.get(_netscalerService, nsServerName);
+                                if ((services == null) || (services.length == 0)) {
+                                    apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, nsServerName);
+                                    if (apiCallResult.errorcode != 0) {
+                                        throw new ExecutionException("Failed to remove server:" + nsServerName + " due to " + apiCallResult.message);
+                                    }
+                                }
+                            }
+                        }
+                        removeLBVirtualServer(nsVirtualServerName);
+                    }
+                }
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Successfully executed resource LoadBalancerConfigCommand: " + _gson.toJson(cmd));
+            }
+
+            saveConfiguration();
+            return new Answer(cmd);
+        } catch (ExecutionException e) {
+            s_logger.error("Failed to execute LoadBalancerConfigCommand due to " + e.getMessage());
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            } else {
+                return new Answer(cmd, e);
+            }
+        }  catch (Exception e) {
+            s_logger.error("Failed to execute LoadBalancerConfigCommand due to " + e.getMessage());
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            } else {
+                return new Answer(cmd, e);
+            }
+        } 
+    }
+
+    private synchronized Answer execute(CreateLoadBalancerApplianceCommand cmd, int numRetries) {
+
+        if (!_isSdx) {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+
+        try {
+            String vpxName = "Cloud-VPX-"+cmd.getLoadBalancerIP();
+            String username = "admin";
+            String password = "admin";
+
+            ns ns_obj = new ns();
+            ns_obj.set_name(vpxName);
+            ns_obj.set_ip_address(cmd.getLoadBalancerIP());
+            ns_obj.set_netmask(cmd.getNetmask());
+            ns_obj.set_gateway(cmd.getGateway());
+            ns_obj.set_username(username);
+            ns_obj.set_password(password);
+
+            // configure VPX instances with defaults
+            ns_obj.set_feature_license("Standard");
+            ns_obj.set_memory_total(new Double(2048));
+            ns_obj.set_throughput(new Double(1000));
+            ns_obj.set_pps(new Double(1000000));
+            ns_obj.set_number_of_ssl_cores(0);
+
+            // use the first device profile available on the SDX to create an instance of VPX
+            device_profile[] profiles = device_profile.get(_netscalerSdxService);
+            if (!(profiles != null && profiles.length >= 1)) {
+            	new Answer(cmd, new ExecutionException("Failed to create VPX instance on the netscaler SDX device " + _ip +
+            			" as there are no admin profile to use for creating VPX."));
+            }
+            String profileName = profiles[0].get_name();
+            ns_obj.set_nsroot_profile(profileName);
+
+            // use the first VPX image of the available VPX images on the SDX to create an instance of VPX
+            // TODO: should enable the option to choose the template while adding the SDX device in to CloudStack
+            xen_vpx_image[] vpxImages = xen_vpx_image.get(_netscalerSdxService);
+            if (!(vpxImages != null && vpxImages.length >= 1)) {
+            	new Answer(cmd, new ExecutionException("Failed to create VPX instance on the netscaler SDX device " + _ip +
+            			" as there are no VPX images on SDX to use for creating VPX."));
+            }
+            String imageName = vpxImages[0].get_file_name();
+            ns_obj.set_image_name(imageName);
+
+            String publicIf = _publicInterface;
+            String privateIf = _privateInterface;
+
+            // enable only the interfaces that will be used by VPX
+            enableVPXInterfaces(_publicInterface, _privateInterface, ns_obj);
+
+            // create new VPX instance
+            ns newVpx = ns.add(_netscalerSdxService, ns_obj);
+
+            if (newVpx == null) {
+                new Answer(cmd, new ExecutionException("Failed to create VPX instance on the netscaler SDX device " + _ip));
+            }
+
+            // wait for VPX instance to start-up
+            long startTick = System.currentTimeMillis();
+            long startWaitMilliSeconds = 600000;
+            while(!newVpx.get_ns_state().equalsIgnoreCase("up") && System.currentTimeMillis() - startTick < startWaitMilliSeconds) {
+                try { 
+                    Thread.sleep(10000);
+                } catch(InterruptedException e) {
+                }
+                ns refreshNsObj = new ns();
+                refreshNsObj.set_id(newVpx.get_id());
+                newVpx = ns.get(_netscalerSdxService, refreshNsObj);
+            }
+
+            // if vpx instance never came up then error out
+            if (!newVpx.get_ns_state().equalsIgnoreCase("up")) {
+                return new Answer(cmd, new ExecutionException("Failed to start VPX instance " + vpxName + " created on the netscaler SDX device " + _ip));
+            }
+
+            // wait till NS service in side VPX is actually ready
+            startTick = System.currentTimeMillis();
+            boolean nsServiceUp = false;
+            long nsServiceWaitMilliSeconds = 60000;
+            while (System.currentTimeMillis() - startTick < nsServiceWaitMilliSeconds) {
+                try {
+                    nitro_service _netscalerService = new nitro_service(cmd.getLoadBalancerIP(), "https");
+                    _netscalerService.set_credential(username, password);
+                    _netscalerService.set_timeout(_timeout);
+                    apiCallResult = _netscalerService.login();
+                    if (apiCallResult.errorcode == 0) {
+                        nsServiceUp = true;
+                        break;
+                    }
+                } catch (Exception e) {
+                    Thread.sleep(10000);
+                    continue;
+                }
+            }
+
+            if (!nsServiceUp) {
+                return new Answer(cmd, new ExecutionException("Failed to create VPX instance " + vpxName + " on the netscaler SDX device " + _ip));
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Successfully provisioned VPX instance " + vpxName + " on the Netscaler SDX device " + _ip);
+            }
+
+            // physical interfaces on the SDX range from 10/1 to 10/8 & 1/1 to 1/8 of which two different port or same port can be used for public and private interfaces
+            // However the VPX instances created will have interface range start from 10/1 but will only have as many interfaces enabled while creating the VPX instance
+            // So due to this, we need to map public & private interface on SDX to correct public & private interface of VPX
+
+            int publicIfnum = Integer.parseInt(_publicInterface.substring(_publicInterface.lastIndexOf("/") + 1));
+            int privateIfnum = Integer.parseInt(_privateInterface.substring(_privateInterface.lastIndexOf("/") + 1));
+
+            if (_publicInterface.startsWith("10/") && _privateInterface.startsWith("10/")) {
+                if (publicIfnum == privateIfnum) {
+                    publicIf = "10/1";
+                    privateIf = "10/1";
+                } else if (publicIfnum > privateIfnum) {
+                    privateIf = "10/1";
+                    publicIf = "10/2";
+                } else {
+                    publicIf = "10/1";
+                    privateIf = "10/2";
+                }
+            } else if (_publicInterface.startsWith("1/") && _privateInterface.startsWith("1/")) {
+                if (publicIfnum == privateIfnum) {
+                    publicIf = "1/1";
+                    privateIf = "1/1";
+                } else if (publicIfnum > privateIfnum) {
+                    privateIf = "1/1";
+                    publicIf = "1/2";
+                } else {
+                    publicIf = "1/1";
+                    privateIf = "1/2";
+                }
+            } else if (_publicInterface.startsWith("1/") && _privateInterface.startsWith("10/")) {
+                publicIf = "1/1";
+                privateIf = "10/1";
+            } else if (_publicInterface.startsWith("10/") && _privateInterface.startsWith("1/")) {
+                publicIf = "10/1";
+                privateIf = "1/1";
+            }
+
+            return new CreateLoadBalancerApplianceAnswer(cmd, true, "provisioned VPX instance", "NetscalerVPXLoadBalancer", "Netscaler", new NetscalerResource(),
+                    publicIf, privateIf, _username, _password);
+        } catch (Exception e) {
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            }
+            return new CreateLoadBalancerApplianceAnswer(cmd, false, "failed to provisioned VPX instance due to " + e.getMessage(), null, null, null, null, null, null, null);
+        }
+    }
+
+    private void enableVPXInterfaces(String publicIf, String privateIf, ns ns_obj) {
+        // enable VPX to use 10 gigabit Ethernet interfaces if public/private interface
+        // on SDX is a 10Gig interface
+        if (publicIf.equals("10/1") || privateIf.equals("10/1")) {
+            ns_obj.set_if_10_1(new Boolean(true));
+        }
+
+        if (publicIf.equals("10/2") || privateIf.equals("10/2")) {
+            ns_obj.set_if_10_2(new Boolean(true));
+        }
+
+        if (publicIf.equals("10/3") || privateIf.equals("10/3")) {
+            ns_obj.set_if_10_3(new Boolean(true));
+        }
+
+        if (publicIf.equals("10/4") || privateIf.equals("10/4")) {
+            ns_obj.set_if_10_4(new Boolean(true));
+        }
+
+        if (publicIf.equals("10/5") || privateIf.equals("10/5")) {
+            ns_obj.set_if_10_5(new Boolean(true));
+        }
+
+        if (publicIf.equals("10/6") || privateIf.equals("10/6")) {
+            ns_obj.set_if_10_6(new Boolean(true));
+        }
+
+        if (publicIf.equals("10/7") || privateIf.equals("10/7")) {
+            ns_obj.set_if_10_7(new Boolean(true));
+        }
+
+        if (publicIf.equals("10/8") || privateIf.equals("10/8")) {
+            ns_obj.set_if_10_8(new Boolean(true));
+        }
+
+        // enable VPX to use 1 gigabit Ethernet interfaces if public/private interface
+        // on SDX is a 1Gig interface
+        if (publicIf.equals("1/1") || privateIf.equals("1/1")) {
+            ns_obj.set_if_1_1(new Boolean(true));
+        }
+
+        if (publicIf.equals("1/2") || privateIf.equals("1/2")) {
+            ns_obj.set_if_1_2(new Boolean(true));
+        }
+
+        if (publicIf.equals("1/3") || privateIf.equals("1/3")) {
+            ns_obj.set_if_1_3(new Boolean(true));
+        }
+
+        if (publicIf.equals("1/4") || privateIf.equals("1/4")) {
+            ns_obj.set_if_1_4(new Boolean(true));
+        }
+
+        if (publicIf.equals("1/5") || privateIf.equals("1/5")) {
+            ns_obj.set_if_1_5(new Boolean(true));
+        }
+
+        if (publicIf.equals("1/6") || privateIf.equals("1/6")) {
+            ns_obj.set_if_1_6(new Boolean(true));
+        }
+
+        if (publicIf.equals("1/7") || privateIf.equals("1/7")) {
+            ns_obj.set_if_1_7(new Boolean(true));
+        }
+
+        if (publicIf.equals("1/8") || privateIf.equals("1/8")) {
+            ns_obj.set_if_1_8(new Boolean(true));
+        }
+    }
+
+    private synchronized Answer execute(DestroyLoadBalancerApplianceCommand cmd, int numRetries) {
+        String vpxName = "Cloud-VPX-"+cmd.getLoadBalancerIP();
+        if (!_isSdx) {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+
+        try {
+            ns vpxToDelete =null;
+            ns[] vpxInstances = ns.get(_netscalerSdxService);
+            for (ns vpx : vpxInstances) {
+                if (vpx.get_name().equals(vpxName)) {
+                    vpxToDelete = vpx;
+                    break;
+                }
+            }
+
+            if (vpxToDelete == null) {
+                String msg = "There is no VPX instance " + vpxName + " on the Netscaler SDX device " + _ip + " to delete";
+                s_logger.warn(msg);
+                return new DestroyLoadBalancerApplianceAnswer(cmd, true, msg);
+            }
+
+            // destroy the VPX instance
+            ns nsDelObj = new ns();
+            nsDelObj.set_id(vpxToDelete.get_id());
+            vpxToDelete = ns.delete(_netscalerSdxService, nsDelObj);
+            String msg =  "Deleted VPX instance " + vpxName + " on Netscaler SDX " + _ip + " successfully.";
+            s_logger.info(msg);
+            return new DestroyLoadBalancerApplianceAnswer(cmd, true,msg);
+        } catch (Exception e) {
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            }
+            return new DestroyLoadBalancerApplianceAnswer(cmd, false, "Failed to delete VPX instance " + vpxName + " on Netscaler SDX " + _ip);
+        }
+    }
+
+    private synchronized Answer execute(SetStaticNatRulesCommand cmd, int numRetries) {
+
+        if (_isSdx) {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+
+        String[] results = new String[cmd.getRules().length];
+        int i = 0;
+        boolean endResult = true;
+
+        try {
+            for (StaticNatRuleTO rule : cmd.getRules()) {
+                String srcIp = rule.getSrcIp();
+                String dstIP = rule.getDstIp();
+                String iNatRuleName = generateInatRuleName(srcIp, dstIP);
+                inat iNatRule = null;
+
+                if (!rule.revoked()) {
+                    try {
+                        iNatRule = inat.get(_netscalerService, iNatRuleName);
+                    } catch (nitro_exception e) {
+                        if (e.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) {
+                            throw e;
+                        }
+                    }
+
+                    if (iNatRule == null) {
+                        iNatRule = new inat();
+                        iNatRule.set_name(iNatRuleName);
+                        iNatRule.set_publicip(srcIp);
+                        iNatRule.set_privateip(dstIP);
+                        iNatRule.set_usnip("OFF");
+                        iNatRule.set_usip("ON");
+                        try {
+                            apiCallResult = inat.add(_netscalerService, iNatRule);
+                        } catch (nitro_exception e) {
+                            if (e.getErrorCode() != NitroError.NS_RESOURCE_EXISTS) {
+                                throw e;
+                            }
+                        }
+                        s_logger.debug("Created Inat rule on the Netscaler device " + _ip + " to enable static NAT from " +  srcIp + " to " + dstIP);
+                    }
+                } else {
+                    try {
+                        inat.delete(_netscalerService, iNatRuleName);
+                    } catch (nitro_exception e) {
+                        if (e.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) {
+                            throw e;
+                        }
+                    }
+                    s_logger.debug("Deleted Inat rule on the Netscaler device " + _ip + " to remove static NAT from " +  srcIp + " to " + dstIP);
+                }
+
+                saveConfiguration();
+                results[i++] = "Static nat rule from " + srcIp + " to " + dstIP + " successfully " + (rule.revoked() ? " revoked.":" created.");
+            }
+        }  catch (Exception e) {
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            }
+            results[i++] = "Configuring static nat rule failed due to " + e.getMessage();
+            endResult = false;
+            return new SetStaticNatRulesAnswer(cmd, results, endResult);
+        }
+
+        return new SetStaticNatRulesAnswer(cmd, results, endResult);
+    }
+
+    private synchronized Answer execute(ExternalNetworkResourceUsageCommand cmd, int numRetries) {
+        try {
+            if (!_isSdx) {
+                return getPublicIpBytesSentAndReceived(cmd);
+            } else {
+                return Answer.createUnsupportedCommandAnswer(cmd);
+            }
+        } catch (ExecutionException e) {
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            } else {
+                return new ExternalNetworkResourceUsageAnswer(cmd, e);
+            }
+        }
+    }
+
+    private void addSubnetIP(String snip, String netmask)  throws ExecutionException {
+        try {
+            nsip selfIp = new nsip();
+            selfIp.set_ipaddress(snip);
+            selfIp.set_netmask(netmask);
+            selfIp.set_type("SNIP");
+            apiCallResult = nsip.add(_netscalerService, selfIp);
+            if (apiCallResult.errorcode != 0) {
+                throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to "+ apiCallResult.message);
+            }
+        } catch (nitro_exception e) {
+            throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to " + e.getMessage());
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to " + e.getMessage());
+        }
+    }
+
+    private void addGuestVlanAndSubnet(long vlanTag, String vlanSelfIp, String vlanNetmask, boolean guestVlan) throws ExecutionException {
+        try {
+            // add vlan object for guest VLAN
+            if (!nsVlanExists(vlanTag)) {
+                try {
+                    vlan vlanObj = new vlan();
+                    vlanObj.set_id(vlanTag);
+                    apiCallResult = vlan.add(_netscalerService, vlanObj);
+                    if (apiCallResult.errorcode != 0) {
+                        throw new ExecutionException("Failed to add new vlan with tag:" + vlanTag + "on the NetScaler device due to " +  apiCallResult.message);
+                    }
+                } catch (nitro_exception e) {
+                    throw new ExecutionException("Failed to add new vlan with tag:" + vlanTag + "on the NetScaler device due to " + e.getMessage());
+                }
+            }
+
+            // add subnet IP object for this guest network
+            if (!nsSnipExists(vlanSelfIp)) {
+                try {
+                    nsip selfIp = new nsip();
+                    selfIp.set_ipaddress(vlanSelfIp);
+                    selfIp.set_netmask(vlanNetmask);
+                    selfIp.set_type("SNIP");
+                    apiCallResult = nsip.add(_netscalerService, selfIp);
+                    if (apiCallResult.errorcode != 0) {
+                        throw new ExecutionException("Failed to add SNIP object for the guest network on the Netscaler device due to "+ apiCallResult.message);
+                    }
+                } catch (nitro_exception e) {
+                    throw new ExecutionException("Failed to add SNIP object for the guest network on the Netscaler device due to " + e.getMessage());
+                }
+            }
+
+            // bind the vlan object to subnet IP object
+            if (!nsVlanNsipBindingExists(vlanTag, vlanSelfIp)) {
+                try {
+                    vlan_nsip_binding ipVlanBinding = new vlan_nsip_binding();
+                    ipVlanBinding.set_id(vlanTag);
+                    ipVlanBinding.set_ipaddress(vlanSelfIp);
+                    ipVlanBinding.set_netmask(vlanNetmask);
+                    apiCallResult = vlan_nsip_binding.add(_netscalerService, ipVlanBinding);
+                    if (apiCallResult.errorcode != 0) {
+                        throw new ExecutionException("Failed to bind VLAN with tag:" + vlanTag + " to the subnet due to " + apiCallResult.message);
+                    }
+                } catch (nitro_exception e) {
+                    throw new ExecutionException("Failed to bind VLAN with tage:"+ vlanTag + " to the subnet due to " + e.getMessage());
+                }
+            }
+
+            // bind vlan object to the private interface
+            try {
+                vlan_interface_binding vlanBinding = new vlan_interface_binding();
+                if (guestVlan) {
+                    vlanBinding.set_ifnum(_privateInterface);
+                } else {
+                    vlanBinding.set_ifnum(_publicInterface);
+                }
+                vlanBinding.set_tagged(true);
+                vlanBinding.set_id(vlanTag);
+                apiCallResult = vlan_interface_binding.add(_netscalerService, vlanBinding);
+                if (apiCallResult.errorcode != 0) {
+                    String vlanInterface = guestVlan ? _privateInterface : _publicInterface;
+                    throw new ExecutionException("Failed to bind vlan with tag:" + vlanTag + " with the interface " + vlanInterface + " due to " + apiCallResult.message);
+                }
+            } catch (nitro_exception e)  {
+                if (!(e.getErrorCode() == NitroError.NS_INTERFACE_ALREADY_BOUND_TO_VLAN)) {
+                    throw new ExecutionException("Failed to bind VLAN "+ vlanTag + " with interface on the Netscaler device due to " + e.getMessage());
+                }
+            }
+        }  catch (nitro_exception e) {
+            throw new ExecutionException("Failed to implement guest network on the Netscaler device due to " + e.getMessage());
+        }  catch (Exception e) {
+            throw new ExecutionException("Failed to implement guest network on the Netscaler device due to " + e.getMessage());
+        }
+    }
+
+    private void deleteGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask) throws ExecutionException {
+        try {
+
+            // Delete all servers and associated services from this guest VLAN
+            deleteServersInGuestVlan(vlanTag, vlanSelfIp, vlanNetmask);
+
+            // unbind vlan to the private interface
+            try {
+                vlan_interface_binding vlanIfBinding = new vlan_interface_binding();
+                vlanIfBinding.set_id(vlanTag);
+                vlanIfBinding.set_ifnum(_privateInterface);
+                vlanIfBinding.set_tagged(true);
+                apiCallResult = vlan_interface_binding.delete(_netscalerService, vlanIfBinding);
+                if (apiCallResult.errorcode != 0) {
+                    throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the private interface due to " + apiCallResult.message);
+                }
+            } catch (nitro_exception e) {
+                // if Vlan to interface binding does not exist then ignore the exception and proceed
+                if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) {
+                    throw new ExecutionException("Failed to unbind vlan from the interface while shutdown of guest network on the Netscaler device due to " + e.getMessage());
+                }
+            }
+
+            // unbind the vlan to subnet
+            try {              
+                vlan_nsip_binding vlanSnipBinding = new vlan_nsip_binding();
+                vlanSnipBinding.set_netmask(vlanNetmask);
+                vlanSnipBinding.set_ipaddress(vlanSelfIp);
+                vlanSnipBinding.set_id(vlanTag);
+                apiCallResult = vlan_nsip_binding.delete(_netscalerService, vlanSnipBinding);
+                if (apiCallResult.errorcode != 0) {
+                    throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the subnet due to " + apiCallResult.message);
+                }
+            } catch (nitro_exception e) {
+                // if Vlan to subnet binding does not exist then ignore the exception and proceed
+                if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) {
+                    throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the subnet due to " + e.getMessage());
+                }
+            }
+
+            // remove subnet IP
+            try {
+                nsip subnetIp = nsip.get(_netscalerService, vlanSelfIp);
+                apiCallResult = nsip.delete(_netscalerService, subnetIp);
+                if (apiCallResult.errorcode != 0) {
+                    throw new ExecutionException("Failed to remove subnet ip:" + vlanSelfIp + " from the NetScaler device due to" + apiCallResult.message);
+                }
+            } catch (nitro_exception e) {
+                // if subnet SNIP does not exist then ignore the exception and proceed
+                if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) {
+                    throw new ExecutionException("Failed to remove subnet ip:" + vlanSelfIp + " from the NetScaler device due to" + e.getMessage());
+                }
+            }
+
+            // remove the vlan from the NetScaler device
+            if (nsVlanExists(vlanTag)) {
+                // remove vlan
+                apiCallResult = com.citrix.netscaler.nitro.resource.config.network.vlan.delete(_netscalerService, vlanTag);
+                if (apiCallResult.errorcode != 0) {
+                    throw new ExecutionException("Failed to remove vlan with tag:" + vlanTag + "due to" + apiCallResult.message);
+                }
+            } 
+        }  catch (nitro_exception e) {
+            throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device due to " + e.getMessage());
+        }  catch (Exception e) {
+            throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device due to " + e.getMessage());
+        }
+    }
+
+    private boolean nsVlanExists(long vlanTag) throws ExecutionException {
+        try {
+            if (vlan.get(_netscalerService, new Long(vlanTag)) != null) {
+                return true;
+            } else {
+                return false;
+            }
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return false;
+            } else {
+                throw new ExecutionException("Failed to verify  VLAN exists on the NetScaler device due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify  VLAN exists on the NetScaler device due to " + e.getMessage());
+        }
+    }
+
+    private boolean nsSnipExists(String subnetIP) throws ExecutionException {
+        try {
+            nsip snip = nsip.get(_netscalerService, subnetIP);
+            return (snip != null);
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return false;
+            } else {
+                throw new ExecutionException("Failed to verify if SNIP exists on the NetScaler device due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify if SNIP exists on the NetScaler device due to " + e.getMessage());
+        }
+    }
+
+    private boolean nsServerExists(String serverName) throws ExecutionException {
+        try {
+            if (com.citrix.netscaler.nitro.resource.config.basic.server.get(_netscalerService, serverName) != null) {
+                return true;
+            } else {
+                return false;
+            }
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return false;
+            } else {
+                throw new ExecutionException("Failed to verify Server " + serverName + " exists on the NetScaler device due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify Server " + serverName + " exists on the NetScaler device due to " + e.getMessage());
+        }
+    }
+
+    private boolean nsVlanNsipBindingExists(long vlanTag, String vlanSelfIp) throws ExecutionException {
+        try {
+            vlan_nsip_binding[] vlanNsipBindings = vlan_nsip_binding.get(_netscalerService, vlanTag);
+            if (vlanNsipBindings != null && vlanNsipBindings[0] != null && vlanNsipBindings[0].get_ipaddress().equalsIgnoreCase(vlanSelfIp)) {
+                return true;
+            } else {
+                return false;
+            }
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return false;
+            } else {
+                throw new ExecutionException("Failed to verify Vlan " + vlanTag + " to SNIP " + vlanSelfIp + " binding exists due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify Vlan " + vlanTag + " to SNIP " + vlanSelfIp + " binding exists due to " + e.getMessage());
+        }
+    }
+
+    private lbvserver getVirtualServerIfExisits(String lbVServerName ) throws ExecutionException {
+        try {
+            return lbvserver.get(_netscalerService, lbVServerName);
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return null;
+            } else {
+                throw new ExecutionException(e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException(e.getMessage());
+        }
+    }
+
+    private boolean isServiceBoundToVirtualServer(String serviceName) throws ExecutionException {
+        try {
+            lbvserver[] lbservers = lbvserver.get(_netscalerService);
+            for (lbvserver vserver : lbservers) {
+                filtervalue[] filter = new filtervalue[1];
+                filter[0] = new filtervalue("servicename", serviceName);
+                lbvserver_service_binding[] result = (lbvserver_service_binding[]) lbvserver_service_binding.get_filtered(_netscalerService, vserver.get_name(), filter);
+                if (result != null && result.length > 0) {
+                    return true;
+                }
+            }
+            return false;
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify service " + serviceName + " is bound to any virtual server due to " + e.getMessage());
+        }
+    }
+    
+    private boolean nsServiceExists(String serviceName) throws ExecutionException {
+        try {
+            if (com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService, serviceName) != null) {
+                return true;
+            } else {
+                return false;
+            }
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_NO_SERIVCE) {
+                return false;
+            } else {
+                throw new ExecutionException("Failed to verify service " +  serviceName + " exists due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify service " +  serviceName + " exists due to " + e.getMessage());
+        }
+    }
+
+    private boolean nsServiceBindingExists(String lbVirtualServer, String serviceName) throws ExecutionException {
+        try {
+            com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, lbVirtualServer);
+            if (serviceBindings != null) {
+                for (com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding binding : serviceBindings) {
+                    if (serviceName.equalsIgnoreCase(binding.get_servicename())) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        } catch (nitro_exception e) {
+            throw new ExecutionException("Failed to verify lb vserver " + lbVirtualServer + "and service " +  serviceName + " binding exists due to " + e.getMessage());
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify lb vserver " + lbVirtualServer + "and service " +  serviceName + " binding exists due to " + e.getMessage());
+        }
+    }
+
+    private void deleteServersInGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask) throws ExecutionException {
+        try {
+            com.citrix.netscaler.nitro.resource.config.basic.server[] serverList = com.citrix.netscaler.nitro.resource.config.basic.server.get(_netscalerService);
+
+            if (serverList == null) {
+                return;
+            }
+
+            // remove the server and services associated with guest vlan
+            for (com.citrix.netscaler.nitro.resource.config.basic.server server : serverList) {
+                // check if server belong to same subnet as one associated with vlan
+                if (NetUtils.sameSubnet(vlanSelfIp, server.get_ipaddress(), vlanNetmask)) {
+                    // first remove services associated with this server
+                    com.citrix.netscaler.nitro.resource.config.basic.service serveicesList[] = com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService);
+                    if (serveicesList != null) {
+                        for (com.citrix.netscaler.nitro.resource.config.basic.service svc : serveicesList) {
+                            if (svc.get_servername().equals(server.get_ipaddress())) {
+                                apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, svc.get_name());
+                                if (apiCallResult.errorcode != 0) {
+                                    throw new ExecutionException("Failed to remove service:" + svc.get_name());
+                                }
+                            }
+                        }
+                    }
+                    // remove the server
+                    apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, server.get_name());
+                    if (apiCallResult.errorcode != 0) {
+                        throw new ExecutionException("Failed to remove server:" + server.get_name());
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to delete server and services in the guest vlan:" + vlanTag + " on the Netscaler device due to: "+ e.getMessage());
+        }
+    }
+
+    private String getNetScalerProtocol(LoadBalancerTO loadBalancer) throws ExecutionException {
+        String port = Integer.toString(loadBalancer.getSrcPort());
+        String lbProtocol = loadBalancer.getProtocol();
+        StickinessPolicyTO[] stickyPolicies = loadBalancer.getStickinessPolicies();
+        String nsProtocol = "TCP";
+
+        if ((stickyPolicies != null) && (stickyPolicies.length > 0) && (stickyPolicies[0] != null)){
+            StickinessPolicyTO stickinessPolicy = stickyPolicies[0];
+            if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName()) ||
+                    (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName()))) {
+                nsProtocol = "HTTP";
+                return nsProtocol;
+            }
+        }
+
+        if (port.equals(NetUtils.HTTP_PORT)) {
+            nsProtocol = "HTTP";
+        } else if (NetUtils.TCP_PROTO.equalsIgnoreCase(lbProtocol)) {
+            nsProtocol = "TCP";
+        } else if (NetUtils.UDP_PROTO.equalsIgnoreCase(lbProtocol)) {
+            nsProtocol = "UDP";
+        }
+
+        return nsProtocol;
+    }
+
+    private void addLBVirtualServer(String virtualServerName, String publicIp, int publicPort, String lbAlgorithm, String protocol, StickinessPolicyTO[] stickyPolicies) throws ExecutionException {
+        try {
+            String lbMethod;
+            if ("roundrobin".equalsIgnoreCase(lbAlgorithm)) {
+                lbMethod = "ROUNDROBIN";
+            } else if ("leastconn".equalsIgnoreCase(lbAlgorithm)) {
+                lbMethod = "LEASTCONNECTION";
+            } else if ("source".equalsIgnoreCase(lbAlgorithm)) {
+                lbMethod = "SOURCEIPHASH";
+            } else {
+                throw new ExecutionException("Got invalid load balancing algorithm: " + lbAlgorithm + " in the load balancing rule");
+            }
+
+            boolean vserverExisis = false;
+            lbvserver vserver = getVirtualServerIfExisits(virtualServerName);
+            if (vserver == null) {
+                vserver = new lbvserver();
+            } else {
+                if (!vserver.get_servicetype().equalsIgnoreCase(protocol)) {
+                    throw new ExecutionException("Can not update virtual server:" + virtualServerName + " as current protocol:" + vserver.get_servicetype() + " of virtual server is different from the "
+                            + " intended protocol:" + protocol);
+                }
+                vserverExisis = true;
+            }
+            vserver.set_name(virtualServerName);
+            vserver.set_ipv46(publicIp);
+            vserver.set_port(publicPort);
+            vserver.set_servicetype(protocol);
+            vserver.set_lbmethod(lbMethod);
+
+            // netmask can only be set for source IP load balancer algorithm
+            if (!lbMethod.equalsIgnoreCase("SOURCEIPHASH")) {
+                vserver.set_netmask(null);
+                vserver.set_v6netmasklen(null);
+            }
+
+            if ((stickyPolicies != null) && (stickyPolicies.length > 0) && (stickyPolicies[0] != null)){
+                long timeout = 2;// netscaler default 2 min
+                String cookieName = null;
+                StickinessPolicyTO stickinessPolicy = stickyPolicies[0];
+
+                // get the session persistence parameters
+                List<Pair<String, String>> paramsList = stickinessPolicy.getParams();
+                for(Pair<String,String> param : paramsList) {
+                    if ("holdtime".equalsIgnoreCase(param.first())) {
+                        timeout = Long.parseLong(param.second()); 
+                    } else if ("name".equalsIgnoreCase(param.first())) {
+                        cookieName = param.second();
+                    }
+                }
+
+                // configure virtual server based on the persistence method
+                if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
+                    vserver.set_persistencetype("COOKIEINSERT");
+                } else if (StickinessMethodType.SourceBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
+                    vserver.set_persistencetype("SOURCEIP");
+                } else if (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
+                    vserver.set_persistencetype("RULE");
+                    vserver.set_rule("HTTP.REQ.HEADER(\"COOKIE\").VALUE(0).typecast_nvlist_t('=',';').value(\"" + cookieName + "\")");
+                    vserver.set_resrule("HTTP.RES.HEADER(\"SET-COOKIE\").VALUE(0).typecast_nvlist_t('=',';').value(\"" + cookieName + "\")");
+                } else {
+                    throw new ExecutionException("Got invalid session persistence method: " + stickinessPolicy.getMethodName() + " in the load balancing rule");
+                }
+
+                // set session persistence timeout
+                vserver.set_timeout(timeout);
+            } else {
+                if (vserver.get_persistencetype() != null) {
+                    // delete the LB stickyness policy
+                    vserver.set_persistencetype("NONE");
+                }
+            }
+
+            if (vserverExisis) {
+                apiCallResult = lbvserver.update(_netscalerService,vserver);
+            } else {
+                apiCallResult = lbvserver.add(_netscalerService,vserver);
+            }
+            if (apiCallResult.errorcode != 0) {
+                throw new ExecutionException("Failed to create new load balancing virtual server:" + virtualServerName + " due to " + apiCallResult.message);
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Created load balancing virtual server " + virtualServerName + " on the Netscaler device");
+            }
+        } catch (nitro_exception e) {
+            throw new ExecutionException("Failed to create new virtual server:" + virtualServerName + " due to " + e.getMessage());
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to create new virtual server:" + virtualServerName + " due to " + e.getMessage());
+        }
+    }
+
+    private void removeLBVirtualServer (String virtualServerName) throws ExecutionException {
+        try {
+            lbvserver vserver = lbvserver.get(_netscalerService, virtualServerName);
+            if (vserver == null) {
+                return;
+            }
+            apiCallResult = lbvserver.delete(_netscalerService, vserver);
+            if (apiCallResult.errorcode != 0) {
+                throw new ExecutionException("Failed to delete virtual server:" + virtualServerName + " due to " + apiCallResult.message);
+            }
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return;
+            } else {
+                throw new ExecutionException("Failed remove virtual server:" + virtualServerName +" due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to remove virtual server:" + virtualServerName +" due to " + e.getMessage());
+        }
+    }
+
+    private void saveConfiguration() throws ExecutionException {
+        try {
+            apiCallResult = nsconfig.save(_netscalerService);
+            if (apiCallResult.errorcode != 0) {
+                throw new ExecutionException("Error occured while saving configuration changes to Netscaler device due to " + apiCallResult.message);
+            }
+        } catch (nitro_exception e) {
+            throw new ExecutionException("Failed to save configuration changes to Netscaler device due to " + e.getMessage());
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to save configuration changes to Netscaler device due to " + e.getMessage());
+        }
+    }
+
+    private ExternalNetworkResourceUsageAnswer getPublicIpBytesSentAndReceived(ExternalNetworkResourceUsageCommand cmd) throws ExecutionException {
+        ExternalNetworkResourceUsageAnswer answer = new ExternalNetworkResourceUsageAnswer(cmd);
+
+        try {
+            lbvserver_stats[] stats = lbvserver_stats.get(_netscalerService);
+
+            if (stats == null || stats.length == 0) {
+                return answer;
+            }
+
+            for (lbvserver_stats stat_entry : stats) {
+                String lbvserverName = stat_entry.get_name();
+                lbvserver vserver = lbvserver.get(_netscalerService, lbvserverName);
+                if(vserver != null){
+                    String lbVirtualServerIp = vserver.get_ipv46();
+    
+                    long[] bytesSentAndReceived = answer.ipBytes.get(lbVirtualServerIp);
+                    if (bytesSentAndReceived == null) {
+                        bytesSentAndReceived = new long[]{0, 0};
+                    }
+                    bytesSentAndReceived[0] += stat_entry.get_totalrequestbytes();
+                    bytesSentAndReceived[1] += stat_entry.get_totalresponsebytes();
+    
+                    if (bytesSentAndReceived[0] >= 0 && bytesSentAndReceived[1] >= 0) {
+                        answer.ipBytes.put(lbVirtualServerIp, bytesSentAndReceived);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            s_logger.error("Failed to get bytes sent and recived statistics due to " + e);
+            throw new ExecutionException(e.getMessage());
+        }
+
+        return answer;
+    }
+
+    private Answer retry(Command cmd, int numRetries) {
+        int numRetriesRemaining = numRetries - 1;
+        s_logger.warn("Retrying " + cmd.getClass().getSimpleName() + ". Number of retries remaining: " + numRetriesRemaining);
+        return executeRequest(cmd, numRetriesRemaining);
+    }
+
+    private boolean shouldRetry(int numRetries) {
+        try {
+            if (numRetries > 0) {
+                login();
+                return true;
+            }
+        } catch (Exception e) {
+            s_logger.error("Failed to log in to Netscaler device at " + _ip + " due to " + e.getMessage());
+        }
+        return false;
+    }
+
+    private String generateInatRuleName(String srcIp, String dstIP) {
+        return genObjectName("Cloud-Inat", srcIp);
+    }
+
+    private String generateNSVirtualServerName(String srcIp, long srcPort) {
+        return genObjectName("Cloud-VirtualServer", srcIp, srcPort);
+    }
+
+    private String generateNSServerName(String serverIP) {
+        return genObjectName("Cloud-Server-",  serverIP);
+    }
+
+    private String generateNSServiceName(String ip, long port) {
+        return genObjectName("Cloud-Service", ip, port);
+    }
+
+    private String genObjectName(Object... args) {
+        String objectName = "";
+        for (int i = 0; i < args.length; i++) {
+            objectName += args[i];
+            if (i != args.length -1) {
+                objectName += _objectNamePathSep;
+            }
+        }
+        return objectName;
+    }
+
+    @Override
+    public IAgentControl getAgentControl() {
+        return null;
+    }
+
+    @Override
+    public PingCommand getCurrentStatus(long id) {
+        return new PingCommand(Host.Type.ExternalLoadBalancer, id);
+    }
+
+    @Override
+    public Type getType() {
+        return Host.Type.ExternalLoadBalancer;
+    }
+
+    @Override
+    public void setAgentControl(IAgentControl agentControl) {
+        return;
+    }
+    
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }    
+
+    @Override
+    public void disconnected() {
+        return;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/49b88472/server/src/com/cloud/api/commands/AddNetscalerLoadBalancerCmd.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/commands/AddNetscalerLoadBalancerCmd.java b/server/src/com/cloud/api/commands/AddNetscalerLoadBalancerCmd.java
deleted file mode 100644
index 283293f..0000000
--- a/server/src/com/cloud/api/commands/AddNetscalerLoadBalancerCmd.java
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2012 Citrix Systems, Inc. Licensed under the
-// Apache License, Version 2.0 (the "License"); you may not use this
-// file except in compliance with the License.  Citrix Systems, Inc.
-// reserves all rights not expressly granted by 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.
-// 
-// Automatically generated by addcopyright.py at 04/03/2012
-package com.cloud.api.commands;
-
-import org.apache.log4j.Logger;
-import com.cloud.api.ApiConstants;
-import com.cloud.api.BaseAsyncCmd;
-import com.cloud.api.BaseCmd;
-import com.cloud.api.IdentityMapper;
-import com.cloud.api.Implementation;
-import com.cloud.api.Parameter;
-import com.cloud.api.PlugService;
-import com.cloud.api.ServerApiException;
-import com.cloud.api.response.NetscalerLoadBalancerResponse;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.ExternalLoadBalancerDeviceVO;
-import com.cloud.network.element.NetscalerLoadBalancerElementService;
-import com.cloud.user.UserContext;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-@Implementation(responseObject=NetscalerLoadBalancerResponse.class, description="Adds a netscaler load balancer device")
-public class AddNetscalerLoadBalancerCmd extends BaseAsyncCmd {
-
-    public static final Logger s_logger = Logger.getLogger(AddNetscalerLoadBalancerCmd.class.getName());
-    private static final String s_name = "addnetscalerloadbalancerresponse";
-    @PlugService NetscalerLoadBalancerElementService _netsclarLbService;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @IdentityMapper(entityTableName="physical_network")
-    @Parameter(name=ApiConstants.PHYSICAL_NETWORK_ID, type=CommandType.LONG, required=true, description="the Physical Network ID")
-    private Long physicalNetworkId;
-
-    @Parameter(name=ApiConstants.URL, type=CommandType.STRING, required = true, description="URL of the netscaler load balancer appliance.")
-    private String url;
-
-    @Parameter(name=ApiConstants.USERNAME, type=CommandType.STRING, required = true, description="Credentials to reach netscaler load balancer device")
-    private String username;
-    
-    @Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, required = true, description="Credentials to reach netscaler load balancer device")
-    private String password;
-
-    @Parameter(name = ApiConstants.NETWORK_DEVICE_TYPE, type = CommandType.STRING, required = true, description = "Netscaler device type supports NetscalerMPXLoadBalancer, NetscalerVPXLoadBalancer, NetscalerSDXLoadBalancer")
-    private String deviceType;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getPhysicalNetworkId() {
-        return physicalNetworkId;
-    }
-
-    public String getUrl() {
-        return url;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public String getDeviceType() {
-        return deviceType;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException {
-        try {
-            ExternalLoadBalancerDeviceVO lbDeviceVO = _netsclarLbService.addNetscalerLoadBalancer(this);
-            if (lbDeviceVO != null) {
-                NetscalerLoadBalancerResponse response = _netsclarLbService.createNetscalerLoadBalancerResponse(lbDeviceVO);
-                response.setObjectName("netscalerloadbalancer");
-                response.setResponseName(getCommandName());
-                this.setResponseObject(response);
-            } else {
-                throw new ServerApiException(BaseAsyncCmd.INTERNAL_ERROR, "Failed to add netscaler load balancer due to internal error.");
-            }
-        }  catch (InvalidParameterValueException invalidParamExcp) {
-            throw new ServerApiException(BaseCmd.PARAM_ERROR, invalidParamExcp.getMessage());
-        } catch (CloudRuntimeException runtimeExcp) {
-            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, runtimeExcp.getMessage());
-        }
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Adding a netscaler load balancer device";
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_EXTERNAL_LB_DEVICE_ADD;
-    }
- 
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return UserContext.current().getCaller().getId();
-    }
-}