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());
     }
 

Reply via email to