From 65daade79aa438f4be9a3fc8f50bd857ea783687 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Wed, 1 Aug 2012 14:11:32 +0200 Subject: [PATCH] Add a "ping" function to the resource and allow commands to be retried. --- .../network/nicira/ControlClusterStatus.java | 66 ++++++++++++++++ .../cloud/network/nicira/NiciraNvpApi.java | 17 +++- .../network/resource/NiciraNvpResource.java | 77 +++++++++++++++---- 3 files changed, 140 insertions(+), 20 deletions(-) create mode 100644 plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/ControlClusterStatus.java diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/ControlClusterStatus.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/ControlClusterStatus.java new file mode 100644 index 00000000000..c0daaed7a9b --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/ControlClusterStatus.java @@ -0,0 +1,66 @@ +package com.cloud.network.nicira; + +public class ControlClusterStatus { + private String cluster_status; + private Stats node_stats; + private Stats lqueue_stats; + private Stats lport_stats; + private Stats lrouterport_stats; + private Stats lswitch_stats; + private Stats zone_stats; + private Stats lrouter_stats; + private Stats security_profile_stats; + + public String getClusterStatus() { + return cluster_status; + } + + public Stats getNodeStats() { + return node_stats; + } + + public Stats getLqueueStats() { + return lqueue_stats; + } + + public Stats getLportStats() { + return lport_stats; + } + + public Stats getLrouterportStats() { + return lrouterport_stats; + } + + public Stats getLswitchStats() { + return lswitch_stats; + } + + public Stats getZoneStats() { + return zone_stats; + } + + public Stats getLrouterStats() { + return lrouter_stats; + } + + public Stats getSecurityProfileStats() { + return security_profile_stats; + } + + public class Stats { + private int error_state_count; + private int registered_count; + private int active_count; + + public int getErrorStateCount() { + return error_state_count; + } + public int getRegisteredCount() { + return registered_count; + } + public int getActiveCount() { + return active_count; + } + + } +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java index c2cf9c5b362..ff756fca592 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java @@ -172,6 +172,13 @@ public class NiciraNvpApi { return lsp.getUuid(); } + public ControlClusterStatus getControlClusterStatus() throws NiciraNvpApiException { + String uri = "/ws.v1/control-cluster/status"; + ControlClusterStatus ccs = executeRetrieveObject(new TypeToken(){}.getType(), uri, null); + + return ccs; + } + private void executeUpdateObject(T newObject, String uri, Map parameters) throws NiciraNvpApiException { String url; try { @@ -272,11 +279,13 @@ public class NiciraNvpApi { GetMethod gm = new GetMethod(url); gm.setRequestHeader("Content-Type", "application/json"); - List nameValuePairs = new ArrayList(parameters.size()); - for (Entry e : parameters.entrySet()) { - nameValuePairs.add(new NameValuePair(e.getKey(), e.getValue())); + if (parameters != null && !parameters.isEmpty()) { + List nameValuePairs = new ArrayList(parameters.size()); + for (Entry e : parameters.entrySet()) { + nameValuePairs.add(new NameValuePair(e.getKey(), e.getValue())); + } + gm.setQueryString(nameValuePairs.toArray(new NameValuePair[0])); } - gm.setQueryString(nameValuePairs.toArray(new NameValuePair[0])); executeMethod(gm); diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java index 69fd26f0d86..546173feee3 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java @@ -28,6 +28,7 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupNiciraNvpCommand; import com.cloud.host.Host; import com.cloud.host.Host.Type; +import com.cloud.network.nicira.ControlClusterStatus; import com.cloud.network.nicira.LogicalSwitch; import com.cloud.network.nicira.LogicalSwitchPort; import com.cloud.network.nicira.NiciraNvpApi; @@ -46,6 +47,7 @@ public class NiciraNvpResource implements ServerResource { private String _adminpass; private String _guid; private String _zoneId; + private int _numRetries; private NiciraNvpApi _niciraNvpApi; @@ -83,6 +85,8 @@ public class NiciraNvpResource implements ServerResource { throw new ConfigurationException("Unable to find zone"); } + _numRetries = 2; + try { _niciraNvpApi = new NiciraNvpApi(_ip, _adminuser, _adminpass); } catch (NiciraNvpApiException e) { @@ -126,13 +130,28 @@ public class NiciraNvpResource implements ServerResource { return new StartupCommand[] { sc }; } - @Override - public PingCommand getCurrentStatus(long id) { + @Override + public PingCommand getCurrentStatus(long id) { + try { + ControlClusterStatus ccs = _niciraNvpApi.getControlClusterStatus(); + if (!"stable".equals(ccs.getClusterStatus())) { + s_logger.error("ControlCluster state is not stable: " + + ccs.getClusterStatus()); + return null; + } + } catch (NiciraNvpApiException e) { + s_logger.error("getControlClusterStatus failed", e); + return null; + } return new PingCommand(Host.Type.L2Networking, id); - } + } @Override public Answer executeRequest(Command cmd) { + return executeRequest(cmd, _numRetries); + } + + public Answer executeRequest(Command cmd, int numRetries) { if (cmd instanceof ReadyCommand) { return executeRequest((ReadyCommand) cmd); } @@ -140,16 +159,16 @@ public class NiciraNvpResource implements ServerResource { return executeRequest((MaintainCommand)cmd); } else if (cmd instanceof CreateLogicalSwitchCommand) { - return executeRequest((CreateLogicalSwitchCommand)cmd); + return executeRequest((CreateLogicalSwitchCommand)cmd, numRetries); } else if (cmd instanceof DeleteLogicalSwitchCommand) { - return executeRequest((DeleteLogicalSwitchCommand) cmd); + return executeRequest((DeleteLogicalSwitchCommand) cmd, numRetries); } else if (cmd instanceof CreateLogicalSwitchPortCommand) { - return executeRequest((CreateLogicalSwitchPortCommand) cmd); + return executeRequest((CreateLogicalSwitchPortCommand) cmd, numRetries); } else if (cmd instanceof DeleteLogicalSwitchPortCommand) { - return executeRequest((DeleteLogicalSwitchPortCommand) cmd); + return executeRequest((DeleteLogicalSwitchPortCommand) cmd, numRetries); } s_logger.debug("Received unsupported command " + cmd.toString()); return Answer.createUnsupportedCommandAnswer(cmd); @@ -168,7 +187,7 @@ public class NiciraNvpResource implements ServerResource { public void setAgentControl(IAgentControl agentControl) { } - private Answer executeRequest(CreateLogicalSwitchCommand cmd) { + private Answer executeRequest(CreateLogicalSwitchCommand cmd, int numRetries) { LogicalSwitch logicalSwitch = new LogicalSwitch(); logicalSwitch.setDisplay_name("lswitch-" + cmd.getName()); logicalSwitch.setPort_isolation_enabled(false); @@ -187,21 +206,31 @@ public class NiciraNvpResource implements ServerResource { logicalSwitch = _niciraNvpApi.createLogicalSwitch(logicalSwitch); return new CreateLogicalSwitchAnswer(cmd, true, "Logicalswitch " + logicalSwitch.getUuid() + " created", logicalSwitch.getUuid()); } catch (NiciraNvpApiException e) { - return new CreateLogicalSwitchAnswer(cmd, e); + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new CreateLogicalSwitchAnswer(cmd, e); + } } } - private Answer executeRequest(DeleteLogicalSwitchCommand cmd) { + private Answer executeRequest(DeleteLogicalSwitchCommand cmd, int numRetries) { try { _niciraNvpApi.deleteLogicalSwitch(cmd.getLogicalSwitchUuid()); return new DeleteLogicalSwitchAnswer(cmd, true, "Logicalswitch " + cmd.getLogicalSwitchUuid() + " deleted"); } catch (NiciraNvpApiException e) { - return new DeleteLogicalSwitchAnswer(cmd, e); + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new DeleteLogicalSwitchAnswer(cmd, e); + } } } - private Answer executeRequest(CreateLogicalSwitchPortCommand cmd) { + private Answer executeRequest(CreateLogicalSwitchPortCommand cmd, int numRetries) { String logicalSwitchUuid = cmd.getLogicalSwitchUuid(); String attachmentUuid = cmd.getAttachmentUuid(); @@ -215,17 +244,27 @@ public class NiciraNvpResource implements ServerResource { _niciraNvpApi.modifyLogicalSwitchPortAttachment(cmd.getLogicalSwitchUuid(), newPort.getUuid(), new VifAttachment(attachmentUuid)); return new CreateLogicalSwitchPortAnswer(cmd, true, "Logical switch port " + newPort.getUuid() + " created", newPort.getUuid()); } catch (NiciraNvpApiException e) { - return new CreateLogicalSwitchPortAnswer(cmd, e); + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new CreateLogicalSwitchPortAnswer(cmd, e); + } } } - private Answer executeRequest(DeleteLogicalSwitchPortCommand cmd) { + private Answer executeRequest(DeleteLogicalSwitchPortCommand cmd, int numRetries) { try { _niciraNvpApi.deleteLogicalSwitchPort(cmd.getLogicalSwitchUuid(), cmd.getLogicalSwitchPortUuid()); return new DeleteLogicalSwitchPortAnswer(cmd, true, "Logical switch port " + cmd.getLogicalSwitchPortUuid() + " deleted"); } catch (NiciraNvpApiException e) { - return new DeleteLogicalSwitchPortAnswer(cmd, e); + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new DeleteLogicalSwitchPortAnswer(cmd, e); + } } } @@ -236,5 +275,11 @@ public class NiciraNvpResource implements ServerResource { private Answer executeRequest(MaintainCommand cmd) { return new MaintainAnswer(cmd); } - + + 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); + } + }