CLOUDSTACK-8590 - Refactoring NiciraNVP resource - Adding command wrappers NiciraNvpCreateLogicalSwitchCommandWrapper and NiciraNvpDeleteLogicalSwitchCommandWrapper - Refactoring the retry mechanism - Applying the new retry mechanism to current wrappers and old methods in NiciraNvpResource - Adding 2 tests - Fixing the testRetries() in NiciraNvpResourceTest class
Signed-off-by: wilderrodrigues <wrodrig...@schubergphilis.com> Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/28c1da96 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/28c1da96 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/28c1da96 Branch: refs/heads/reporter Commit: 28c1da969da66cb7d29c4f899ff39dde935624d4 Parents: 27c9651 Author: wilderrodrigues <wrodrig...@schubergphilis.com> Authored: Tue Jun 30 09:47:57 2015 +0200 Committer: wilderrodrigues <wrodrig...@schubergphilis.com> Committed: Wed Jul 1 15:04:57 2015 +0200 ---------------------------------------------------------------------- .../network/resource/NiciraNvpResource.java | 144 ++++++------------- ...iraNvpCreateLogicalSwitchCommandWrapper.java | 12 +- ...iraNvpDeleteLogicalSwitchCommandWrapper.java | 49 +++++++ .../network/utils/CommandRetryUtility.java | 90 ++++++++++++ .../resource/NiciraNvpRequestWrapperTest.java | 26 ++++ .../network/resource/NiciraNvpResourceTest.java | 10 +- 6 files changed, 224 insertions(+), 107 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/28c1da96/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java ---------------------------------------------------------------------- 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 5242154..1ab1992 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 @@ -42,8 +42,6 @@ import com.cloud.agent.api.CreateLogicalSwitchPortAnswer; import com.cloud.agent.api.CreateLogicalSwitchPortCommand; import com.cloud.agent.api.DeleteLogicalRouterAnswer; import com.cloud.agent.api.DeleteLogicalRouterCommand; -import com.cloud.agent.api.DeleteLogicalSwitchAnswer; -import com.cloud.agent.api.DeleteLogicalSwitchCommand; import com.cloud.agent.api.DeleteLogicalSwitchPortAnswer; import com.cloud.agent.api.DeleteLogicalSwitchPortCommand; import com.cloud.agent.api.FindLogicalSwitchPortAnswer; @@ -74,6 +72,7 @@ import com.cloud.network.nicira.RouterNextHop; import com.cloud.network.nicira.SingleDefaultRouteImplicitRoutingConfig; import com.cloud.network.nicira.SourceNatRule; import com.cloud.network.nicira.VifAttachment; +import com.cloud.network.utils.CommandRetryUtility; import com.cloud.resource.ServerResource; public class NiciraNvpResource implements ServerResource { @@ -81,14 +80,15 @@ public class NiciraNvpResource implements ServerResource { private static final Logger s_logger = Logger.getLogger(NiciraNvpResource.class); public static final int NAME_MAX_LEN = 40; + public static final int NUM_RETRIES = 2; private String name; private String guid; private String zoneId; - private int numRetries; private NiciraNvpApi niciraNvpApi; private NiciraNvpUtilities niciraNvpUtilities; + private CommandRetryUtility retryUtility; protected NiciraNvpApi createNiciraNvpApi() { return new NiciraNvpApi(); @@ -112,8 +112,6 @@ public class NiciraNvpResource implements ServerResource { throw new ConfigurationException("Unable to find zone"); } - numRetries = 2; - final String ip = (String)params.get("ip"); if (ip == null) { throw new ConfigurationException("Unable to find IP"); @@ -130,6 +128,8 @@ public class NiciraNvpResource implements ServerResource { } niciraNvpUtilities = NiciraNvpUtilities.getInstance(); + retryUtility = CommandRetryUtility.getInstance(); + retryUtility.setServerResource(this); niciraNvpApi = createNiciraNvpApi(); niciraNvpApi.setControllerAddress(ip); @@ -146,8 +146,8 @@ public class NiciraNvpResource implements ServerResource { return niciraNvpUtilities; } - public int getNumRetries() { - return numRetries; + public CommandRetryUtility getRetryUtility() { + return retryUtility; } @Override @@ -201,11 +201,6 @@ public class NiciraNvpResource implements ServerResource { @Override public Answer executeRequest(final Command cmd) { - return executeRequest(cmd, numRetries); - } - - public Answer executeRequest(final Command cmd, final int numRetries) { - final NiciraNvpRequestWrapper wrapper = NiciraNvpRequestWrapper.getInstance(); try { return wrapper.execute(cmd, this); @@ -214,26 +209,24 @@ public class NiciraNvpResource implements ServerResource { // [TODO] Remove when all the commands are refactored. } - if (cmd instanceof DeleteLogicalSwitchCommand) { - return executeRequest((DeleteLogicalSwitchCommand)cmd, numRetries); - } else if (cmd instanceof CreateLogicalSwitchPortCommand) { - return executeRequest((CreateLogicalSwitchPortCommand)cmd, numRetries); + if (cmd instanceof CreateLogicalSwitchPortCommand) { + return executeRequest((CreateLogicalSwitchPortCommand)cmd, NUM_RETRIES); } else if (cmd instanceof DeleteLogicalSwitchPortCommand) { - return executeRequest((DeleteLogicalSwitchPortCommand)cmd, numRetries); + return executeRequest((DeleteLogicalSwitchPortCommand)cmd, NUM_RETRIES); } else if (cmd instanceof UpdateLogicalSwitchPortCommand) { - return executeRequest((UpdateLogicalSwitchPortCommand)cmd, numRetries); + return executeRequest((UpdateLogicalSwitchPortCommand)cmd, NUM_RETRIES); } else if (cmd instanceof FindLogicalSwitchPortCommand) { - return executeRequest((FindLogicalSwitchPortCommand)cmd, numRetries); + return executeRequest((FindLogicalSwitchPortCommand)cmd, NUM_RETRIES); } else if (cmd instanceof CreateLogicalRouterCommand) { - return executeRequest((CreateLogicalRouterCommand)cmd, numRetries); + return executeRequest((CreateLogicalRouterCommand)cmd, NUM_RETRIES); } else if (cmd instanceof DeleteLogicalRouterCommand) { - return executeRequest((DeleteLogicalRouterCommand)cmd, numRetries); + return executeRequest((DeleteLogicalRouterCommand)cmd, NUM_RETRIES); } else if (cmd instanceof ConfigureStaticNatRulesOnLogicalRouterCommand) { - return executeRequest((ConfigureStaticNatRulesOnLogicalRouterCommand)cmd, numRetries); + return executeRequest((ConfigureStaticNatRulesOnLogicalRouterCommand)cmd, NUM_RETRIES); } else if (cmd instanceof ConfigurePortForwardingRulesOnLogicalRouterCommand) { - return executeRequest((ConfigurePortForwardingRulesOnLogicalRouterCommand)cmd, numRetries); + return executeRequest((ConfigurePortForwardingRulesOnLogicalRouterCommand)cmd, NUM_RETRIES); } else if (cmd instanceof ConfigurePublicIpsOnLogicalRouterCommand) { - return executeRequest((ConfigurePublicIpsOnLogicalRouterCommand)cmd, numRetries); + return executeRequest((ConfigurePublicIpsOnLogicalRouterCommand)cmd, NUM_RETRIES); } s_logger.debug("Received unsupported command " + cmd.toString()); return Answer.createUnsupportedCommandAnswer(cmd); @@ -252,20 +245,7 @@ public class NiciraNvpResource implements ServerResource { public void setAgentControl(final IAgentControl agentControl) { } - private Answer executeRequest(final DeleteLogicalSwitchCommand cmd, int numRetries) { - try { - niciraNvpApi.deleteLogicalSwitch(cmd.getLogicalSwitchUuid()); - return new DeleteLogicalSwitchAnswer(cmd, true, "Logicalswitch " + cmd.getLogicalSwitchUuid() + " deleted"); - } catch (final NiciraNvpApiException e) { - if (numRetries > 0) { - return retry(cmd, --numRetries); - } else { - return new DeleteLogicalSwitchAnswer(cmd, e); - } - } - } - - private Answer executeRequest(final CreateLogicalSwitchPortCommand cmd, int numRetries) { + private Answer executeRequest(final CreateLogicalSwitchPortCommand cmd, final int numRetries) { final String logicalSwitchUuid = cmd.getLogicalSwitchUuid(); final String attachmentUuid = cmd.getAttachmentUuid(); @@ -285,29 +265,22 @@ public class NiciraNvpResource implements ServerResource { } return new CreateLogicalSwitchPortAnswer(cmd, true, "Logical switch port " + newPort.getUuid() + " created", newPort.getUuid()); } catch (final NiciraNvpApiException e) { - if (numRetries > 0) { - return retry(cmd, --numRetries); - } else { - return new CreateLogicalSwitchPortAnswer(cmd, e); - } + retryUtility.addRetry(cmd, NUM_RETRIES); + return retryUtility.retry(cmd, CreateLogicalSwitchPortAnswer.class, e); } - } - private Answer executeRequest(final DeleteLogicalSwitchPortCommand cmd, int numRetries) { + private Answer executeRequest(final DeleteLogicalSwitchPortCommand cmd, final int numRetries) { try { niciraNvpApi.deleteLogicalSwitchPort(cmd.getLogicalSwitchUuid(), cmd.getLogicalSwitchPortUuid()); return new DeleteLogicalSwitchPortAnswer(cmd, true, "Logical switch port " + cmd.getLogicalSwitchPortUuid() + " deleted"); } catch (final NiciraNvpApiException e) { - if (numRetries > 0) { - return retry(cmd, --numRetries); - } else { - return new DeleteLogicalSwitchPortAnswer(cmd, e); - } + retryUtility.addRetry(cmd, NUM_RETRIES); + return retryUtility.retry(cmd, DeleteLogicalSwitchPortAnswer.class, e); } } - private Answer executeRequest(final UpdateLogicalSwitchPortCommand cmd, int numRetries) { + private Answer executeRequest(final UpdateLogicalSwitchPortCommand cmd, final int numRetries) { final String logicalSwitchUuid = cmd.getLogicalSwitchUuid(); final String logicalSwitchPortUuid = cmd.getLogicalSwitchPortUuid(); final String attachmentUuid = cmd.getAttachmentUuid(); @@ -320,16 +293,12 @@ public class NiciraNvpResource implements ServerResource { niciraNvpApi.updateLogicalSwitchPortAttachment(logicalSwitchUuid, logicalSwitchPortUuid, new VifAttachment(attachmentUuid)); return new UpdateLogicalSwitchPortAnswer(cmd, true, "Attachment for " + logicalSwitchPortUuid + " updated", logicalSwitchPortUuid); } catch (final NiciraNvpApiException e) { - if (numRetries > 0) { - return retry(cmd, --numRetries); - } else { - return new UpdateLogicalSwitchPortAnswer(cmd, e); - } + retryUtility.addRetry(cmd, NUM_RETRIES); + return retryUtility.retry(cmd, UpdateLogicalSwitchPortAnswer.class, e); } - } - private Answer executeRequest(final FindLogicalSwitchPortCommand cmd, int numRetries) { + private Answer executeRequest(final FindLogicalSwitchPortCommand cmd, final int numRetries) { final String logicalSwitchUuid = cmd.getLogicalSwitchUuid(); final String logicalSwitchPortUuid = cmd.getLogicalSwitchPortUuid(); @@ -341,15 +310,12 @@ public class NiciraNvpResource implements ServerResource { return new FindLogicalSwitchPortAnswer(cmd, true, "Logical switchport " + logicalSwitchPortUuid + " found", logicalSwitchPortUuid); } } catch (final NiciraNvpApiException e) { - if (numRetries > 0) { - return retry(cmd, --numRetries); - } else { - return new FindLogicalSwitchPortAnswer(cmd, e); - } + retryUtility.addRetry(cmd, NUM_RETRIES); + return retryUtility.retry(cmd, FindLogicalSwitchPortAnswer.class, e); } } - private Answer executeRequest(final CreateLogicalRouterCommand cmd, int numRetries) { + private Answer executeRequest(final CreateLogicalRouterCommand cmd, final int numRetries) { final String routerName = cmd.getName(); final String gatewayServiceUuid = cmd.getGatewayServiceUuid(); final String logicalSwitchUuid = cmd.getLogicalSwitchUuid(); @@ -438,28 +404,22 @@ public class NiciraNvpResource implements ServerResource { return new CreateLogicalRouterAnswer(cmd, true, "Logical Router created (uuid " + lrc.getUuid() + ")", lrc.getUuid()); } catch (final NiciraNvpApiException e) { - if (numRetries > 0) { - return retry(cmd, --numRetries); - } else { - return new CreateLogicalRouterAnswer(cmd, e); - } + retryUtility.addRetry(cmd, NUM_RETRIES); + return retryUtility.retry(cmd, CreateLogicalRouterAnswer.class, e); } } - private Answer executeRequest(final DeleteLogicalRouterCommand cmd, int numRetries) { + private Answer executeRequest(final DeleteLogicalRouterCommand cmd, final int numRetries) { try { niciraNvpApi.deleteLogicalRouter(cmd.getLogicalRouterUuid()); return new DeleteLogicalRouterAnswer(cmd, true, "Logical Router deleted (uuid " + cmd.getLogicalRouterUuid() + ")"); } catch (final NiciraNvpApiException e) { - if (numRetries > 0) { - return retry(cmd, --numRetries); - } else { - return new DeleteLogicalRouterAnswer(cmd, e); - } + retryUtility.addRetry(cmd, NUM_RETRIES); + return retryUtility.retry(cmd, DeleteLogicalRouterAnswer.class, e); } } - private Answer executeRequest(final ConfigurePublicIpsOnLogicalRouterCommand cmd, int numRetries) { + private Answer executeRequest(final ConfigurePublicIpsOnLogicalRouterCommand cmd, final int numRetries) { try { final NiciraNvpList<LogicalRouterPort> ports = niciraNvpApi.findLogicalRouterPortByGatewayServiceUuid(cmd.getLogicalRouterUuid(), cmd.getL3GatewayServiceUuid()); if (ports.getResultCount() != 1) { @@ -472,16 +432,12 @@ public class NiciraNvpResource implements ServerResource { return new ConfigurePublicIpsOnLogicalRouterAnswer(cmd, true, "Configured " + cmd.getPublicCidrs().size() + " ip addresses on logical router uuid " + cmd.getLogicalRouterUuid()); } catch (final NiciraNvpApiException e) { - if (numRetries > 0) { - return retry(cmd, --numRetries); - } else { - return new ConfigurePublicIpsOnLogicalRouterAnswer(cmd, e); - } + retryUtility.addRetry(cmd, NUM_RETRIES); + return retryUtility.retry(cmd, ConfigurePublicIpsOnLogicalRouterAnswer.class, e); } - } - private Answer executeRequest(final ConfigureStaticNatRulesOnLogicalRouterCommand cmd, int numRetries) { + private Answer executeRequest(final ConfigureStaticNatRulesOnLogicalRouterCommand cmd, final int numRetries) { try { final NiciraNvpList<NatRule> existingRules = niciraNvpApi.findNatRulesByLogicalRouterUuid(cmd.getLogicalRouterUuid()); // Rules of the game (also known as assumptions-that-will-make-stuff-break-later-on) @@ -542,15 +498,12 @@ public class NiciraNvpResource implements ServerResource { } return new ConfigureStaticNatRulesOnLogicalRouterAnswer(cmd, true, cmd.getRules().size() + " StaticNat rules applied"); } catch (final NiciraNvpApiException e) { - if (numRetries > 0) { - return retry(cmd, --numRetries); - } else { - return new ConfigureStaticNatRulesOnLogicalRouterAnswer(cmd, e); - } + retryUtility.addRetry(cmd, NUM_RETRIES); + return retryUtility.retry(cmd, ConfigureStaticNatRulesOnLogicalRouterAnswer.class, e); } } - private Answer executeRequest(final ConfigurePortForwardingRulesOnLogicalRouterCommand cmd, int numRetries) { + private Answer executeRequest(final ConfigurePortForwardingRulesOnLogicalRouterCommand cmd, final int numRetries) { try { final NiciraNvpList<NatRule> existingRules = niciraNvpApi.findNatRulesByLogicalRouterUuid(cmd.getLogicalRouterUuid()); // Rules of the game (also known as assumptions-that-will-make-stuff-break-later-on) @@ -619,18 +572,9 @@ public class NiciraNvpResource implements ServerResource { } return new ConfigurePortForwardingRulesOnLogicalRouterAnswer(cmd, true, cmd.getRules().size() + " PortForwarding rules applied"); } catch (final NiciraNvpApiException e) { - if (numRetries > 0) { - return retry(cmd, --numRetries); - } else { - return new ConfigurePortForwardingRulesOnLogicalRouterAnswer(cmd, e); - } + retryUtility.addRetry(cmd, NUM_RETRIES); + return retryUtility.retry(cmd, ConfigurePortForwardingRulesOnLogicalRouterAnswer.class, e); } - - } - - public Answer retry(final Command cmd, final int numRetries) { - s_logger.warn("Retrying " + cmd.getClass().getSimpleName() + ". Number of retries remaining: " + numRetries); - return executeRequest(cmd, numRetries); } private String natRuleToString(final NatRule rule) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/28c1da96/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/wrapper/NiciraNvpCreateLogicalSwitchCommandWrapper.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/wrapper/NiciraNvpCreateLogicalSwitchCommandWrapper.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/wrapper/NiciraNvpCreateLogicalSwitchCommandWrapper.java index 6fc6cf0..7d66ada 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/wrapper/NiciraNvpCreateLogicalSwitchCommandWrapper.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/wrapper/NiciraNvpCreateLogicalSwitchCommandWrapper.java @@ -19,6 +19,8 @@ package com.cloud.network.resource.wrapper; +import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES; + import java.util.ArrayList; import java.util.List; @@ -32,6 +34,7 @@ import com.cloud.network.nicira.NiciraNvpTag; import com.cloud.network.nicira.TransportZoneBinding; import com.cloud.network.resource.NiciraNvpResource; import com.cloud.network.resource.NiciraNvpUtilities; +import com.cloud.network.utils.CommandRetryUtility; import com.cloud.resource.CommandWrapper; import com.cloud.resource.ResourceWrapper; @@ -62,12 +65,9 @@ public final class NiciraNvpCreateLogicalSwitchCommandWrapper extends CommandWra final String switchUuid = logicalSwitch.getUuid(); return new CreateLogicalSwitchAnswer(command, true, "Logicalswitch " + switchUuid + " created", switchUuid); } catch (final NiciraNvpApiException e) { - int numRetries = niciraNvpResource.getNumRetries(); - if (numRetries > 0) { - return niciraNvpResource.retry(command, --numRetries); - } else { - return new CreateLogicalSwitchAnswer(command, e); - } + final CommandRetryUtility retryUtility = niciraNvpResource.getRetryUtility(); + retryUtility.addRetry(command, NUM_RETRIES); + return retryUtility.retry(command, CreateLogicalSwitchAnswer.class, e); } } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/28c1da96/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/wrapper/NiciraNvpDeleteLogicalSwitchCommandWrapper.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/wrapper/NiciraNvpDeleteLogicalSwitchCommandWrapper.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/wrapper/NiciraNvpDeleteLogicalSwitchCommandWrapper.java new file mode 100644 index 0000000..f7b8ab9 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/wrapper/NiciraNvpDeleteLogicalSwitchCommandWrapper.java @@ -0,0 +1,49 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.network.resource.wrapper; + +import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.DeleteLogicalSwitchAnswer; +import com.cloud.agent.api.DeleteLogicalSwitchCommand; +import com.cloud.network.nicira.NiciraNvpApi; +import com.cloud.network.nicira.NiciraNvpApiException; +import com.cloud.network.resource.NiciraNvpResource; +import com.cloud.network.utils.CommandRetryUtility; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = DeleteLogicalSwitchCommand.class) +public final class NiciraNvpDeleteLogicalSwitchCommandWrapper extends CommandWrapper<DeleteLogicalSwitchCommand, Answer, NiciraNvpResource> { + + @Override + public Answer execute(final DeleteLogicalSwitchCommand command, final NiciraNvpResource niciraNvpResource) { + try { + final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi(); + niciraNvpApi.deleteLogicalSwitch(command.getLogicalSwitchUuid()); + return new DeleteLogicalSwitchAnswer(command, true, "Logicalswitch " + command.getLogicalSwitchUuid() + " deleted"); + } catch (final NiciraNvpApiException e) { + final CommandRetryUtility retryUtility = niciraNvpResource.getRetryUtility(); + retryUtility.addRetry(command, NUM_RETRIES); + return retryUtility.retry(command, DeleteLogicalSwitchAnswer.class, e); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/28c1da96/plugins/network-elements/nicira-nvp/src/com/cloud/network/utils/CommandRetryUtility.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/utils/CommandRetryUtility.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/utils/CommandRetryUtility.java new file mode 100644 index 0000000..6244821 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/utils/CommandRetryUtility.java @@ -0,0 +1,90 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +package com.cloud.network.utils; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.network.resource.NiciraNvpResource; +import com.cloud.resource.ServerResource; +import com.cloud.utils.exception.CloudRuntimeException; + +public class CommandRetryUtility { + + private static final Logger s_logger = Logger.getLogger(NiciraNvpResource.class); + + private static final int ZERO = 0; + private static CommandRetryUtility instance; + + static { + instance = new CommandRetryUtility(); + } + + private final ConcurrentHashMap<Command, Integer> commandsToRetry; + private ServerResource serverResource; + + private CommandRetryUtility() { + commandsToRetry = new ConcurrentHashMap<Command, Integer>(); + } + + public static CommandRetryUtility getInstance() { + return instance; + } + + public void setServerResource(final ServerResource serverResource) { + this.serverResource = serverResource; + } + + public boolean addRetry(final Command command, final int retries) { + if (commandsToRetry.containsKey(command)) { + // A retry already exists for this command, do not add it again. + // Once all retries are executed, the command will be removed from the map. + return false; + } + commandsToRetry.put(command, retries); + return true; + } + + public Answer retry(final Command command, final Class<? extends Answer> answerClass, final Exception error) { + if (commandsToRetry.containsKey(command)) { + Integer numRetries = commandsToRetry.get(command); + + if (numRetries > ZERO) { + commandsToRetry.put(command, --numRetries); + + s_logger.warn("Retrying " + command.getClass().getSimpleName() + ". Number of retries remaining: " + numRetries); + + return serverResource.executeRequest(command); + } else { + commandsToRetry.remove(command); + } + } + try { + final Constructor<? extends Answer> answerConstructor = answerClass.getConstructor(Command.class, Exception.class); + return answerConstructor.newInstance(command, error); + } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new CloudRuntimeException(e); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/28c1da96/plugins/network-elements/nicira-nvp/test/com/cloud/network/resource/NiciraNvpRequestWrapperTest.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/test/com/cloud/network/resource/NiciraNvpRequestWrapperTest.java b/plugins/network-elements/nicira-nvp/test/com/cloud/network/resource/NiciraNvpRequestWrapperTest.java index a7349ad..70e10e1 100644 --- a/plugins/network-elements/nicira-nvp/test/com/cloud/network/resource/NiciraNvpRequestWrapperTest.java +++ b/plugins/network-elements/nicira-nvp/test/com/cloud/network/resource/NiciraNvpRequestWrapperTest.java @@ -22,6 +22,7 @@ package com.cloud.network.resource; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.when; import org.junit.Test; @@ -30,6 +31,7 @@ import org.mockito.Mockito; import com.cloud.agent.api.Answer; import com.cloud.agent.api.CreateLogicalSwitchCommand; +import com.cloud.agent.api.DeleteLogicalSwitchCommand; import com.cloud.agent.api.MaintainCommand; import com.cloud.agent.api.ReadyCommand; import com.cloud.network.nicira.LogicalSwitch; @@ -99,4 +101,28 @@ public class NiciraNvpRequestWrapperTest { assertTrue(answer.getResult()); } + + @Test + public void testDeleteLogicalSwitchCommandWrapper() { + final NiciraNvpApi niciraNvpApi = Mockito.mock(NiciraNvpApi.class); + + final String logicalSwitchUuid = "d2e05a9e-7120-4487-a5fc-414ab36d9345"; + + final DeleteLogicalSwitchCommand command = new DeleteLogicalSwitchCommand(logicalSwitchUuid); + + when(niciraNvpResource.getNiciraNvpApi()).thenReturn(niciraNvpApi); + + try { + doNothing().when(niciraNvpApi).deleteLogicalSwitch(command.getLogicalSwitchUuid()); + } catch (final NiciraNvpApiException e) { + fail(e.getMessage()); + } + + final NiciraNvpRequestWrapper wrapper = NiciraNvpRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, niciraNvpResource); + + assertTrue(answer.getResult()); + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/28c1da96/plugins/network-elements/nicira-nvp/test/com/cloud/network/resource/NiciraNvpResourceTest.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/test/com/cloud/network/resource/NiciraNvpResourceTest.java b/plugins/network-elements/nicira-nvp/test/com/cloud/network/resource/NiciraNvpResourceTest.java index 23fe82a..b8b81b2 100644 --- a/plugins/network-elements/nicira-nvp/test/com/cloud/network/resource/NiciraNvpResourceTest.java +++ b/plugins/network-elements/nicira-nvp/test/com/cloud/network/resource/NiciraNvpResourceTest.java @@ -85,12 +85,16 @@ import com.cloud.network.nicira.NiciraNvpApi; import com.cloud.network.nicira.NiciraNvpApiException; import com.cloud.network.nicira.NiciraNvpList; import com.cloud.network.nicira.SourceNatRule; +import com.cloud.network.utils.CommandRetryUtility; public class NiciraNvpResourceTest { NiciraNvpApi nvpApi = mock(NiciraNvpApi.class); NiciraNvpResource resource; Map<String, Object> parameters; + private NiciraNvpUtilities niciraNvpUtilities; + private CommandRetryUtility retryUtility; + @Before public void setUp() throws ConfigurationException { resource = new NiciraNvpResource() { @@ -107,6 +111,10 @@ public class NiciraNvpResourceTest { parameters.put("guid", "aaaaa-bbbbb-ccccc"); parameters.put("zoneId", "blublub"); parameters.put("adminpass", "adminpass"); + + niciraNvpUtilities = NiciraNvpUtilities.getInstance(); + retryUtility = CommandRetryUtility.getInstance(); + retryUtility.setServerResource(resource); } @Test(expected = ConfigurationException.class) @@ -295,7 +303,7 @@ public class NiciraNvpResourceTest { doThrow(new NiciraNvpApiException()).when(nvpApi).updateLogicalSwitchPortAttachment((String)any(), (String)any(), (Attachment)any()); final UpdateLogicalSwitchPortAnswer dlspa = - (UpdateLogicalSwitchPortAnswer)resource.executeRequest(new UpdateLogicalSwitchPortCommand("aaaa", "bbbb", "cccc", "owner", "nicname")); + (UpdateLogicalSwitchPortAnswer)resource.executeRequest(new UpdateLogicalSwitchPortCommand("aaaa", "bbbb", "cccc", "owner", "nicname")); assertFalse(dlspa.getResult()); }