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 <wrodrigues@schubergphilis.com>
This commit is contained in:
wilderrodrigues 2015-06-30 09:47:57 +02:00
parent 27c9651b32
commit 28c1da969d
6 changed files with 224 additions and 107 deletions

View File

@ -42,8 +42,6 @@ import com.cloud.agent.api.CreateLogicalSwitchPortAnswer;
import com.cloud.agent.api.CreateLogicalSwitchPortCommand; import com.cloud.agent.api.CreateLogicalSwitchPortCommand;
import com.cloud.agent.api.DeleteLogicalRouterAnswer; import com.cloud.agent.api.DeleteLogicalRouterAnswer;
import com.cloud.agent.api.DeleteLogicalRouterCommand; 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.DeleteLogicalSwitchPortAnswer;
import com.cloud.agent.api.DeleteLogicalSwitchPortCommand; import com.cloud.agent.api.DeleteLogicalSwitchPortCommand;
import com.cloud.agent.api.FindLogicalSwitchPortAnswer; 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.SingleDefaultRouteImplicitRoutingConfig;
import com.cloud.network.nicira.SourceNatRule; import com.cloud.network.nicira.SourceNatRule;
import com.cloud.network.nicira.VifAttachment; import com.cloud.network.nicira.VifAttachment;
import com.cloud.network.utils.CommandRetryUtility;
import com.cloud.resource.ServerResource; import com.cloud.resource.ServerResource;
public class NiciraNvpResource implements 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); private static final Logger s_logger = Logger.getLogger(NiciraNvpResource.class);
public static final int NAME_MAX_LEN = 40; public static final int NAME_MAX_LEN = 40;
public static final int NUM_RETRIES = 2;
private String name; private String name;
private String guid; private String guid;
private String zoneId; private String zoneId;
private int numRetries;
private NiciraNvpApi niciraNvpApi; private NiciraNvpApi niciraNvpApi;
private NiciraNvpUtilities niciraNvpUtilities; private NiciraNvpUtilities niciraNvpUtilities;
private CommandRetryUtility retryUtility;
protected NiciraNvpApi createNiciraNvpApi() { protected NiciraNvpApi createNiciraNvpApi() {
return new NiciraNvpApi(); return new NiciraNvpApi();
@ -112,8 +112,6 @@ public class NiciraNvpResource implements ServerResource {
throw new ConfigurationException("Unable to find zone"); throw new ConfigurationException("Unable to find zone");
} }
numRetries = 2;
final String ip = (String)params.get("ip"); final String ip = (String)params.get("ip");
if (ip == null) { if (ip == null) {
throw new ConfigurationException("Unable to find IP"); throw new ConfigurationException("Unable to find IP");
@ -130,6 +128,8 @@ public class NiciraNvpResource implements ServerResource {
} }
niciraNvpUtilities = NiciraNvpUtilities.getInstance(); niciraNvpUtilities = NiciraNvpUtilities.getInstance();
retryUtility = CommandRetryUtility.getInstance();
retryUtility.setServerResource(this);
niciraNvpApi = createNiciraNvpApi(); niciraNvpApi = createNiciraNvpApi();
niciraNvpApi.setControllerAddress(ip); niciraNvpApi.setControllerAddress(ip);
@ -146,8 +146,8 @@ public class NiciraNvpResource implements ServerResource {
return niciraNvpUtilities; return niciraNvpUtilities;
} }
public int getNumRetries() { public CommandRetryUtility getRetryUtility() {
return numRetries; return retryUtility;
} }
@Override @Override
@ -201,11 +201,6 @@ public class NiciraNvpResource implements ServerResource {
@Override @Override
public Answer executeRequest(final Command cmd) { public Answer executeRequest(final Command cmd) {
return executeRequest(cmd, numRetries);
}
public Answer executeRequest(final Command cmd, final int numRetries) {
final NiciraNvpRequestWrapper wrapper = NiciraNvpRequestWrapper.getInstance(); final NiciraNvpRequestWrapper wrapper = NiciraNvpRequestWrapper.getInstance();
try { try {
return wrapper.execute(cmd, this); return wrapper.execute(cmd, this);
@ -214,26 +209,24 @@ public class NiciraNvpResource implements ServerResource {
// [TODO] Remove when all the commands are refactored. // [TODO] Remove when all the commands are refactored.
} }
if (cmd instanceof DeleteLogicalSwitchCommand) { if (cmd instanceof CreateLogicalSwitchPortCommand) {
return executeRequest((DeleteLogicalSwitchCommand)cmd, numRetries); return executeRequest((CreateLogicalSwitchPortCommand)cmd, NUM_RETRIES);
} else if (cmd instanceof CreateLogicalSwitchPortCommand) {
return executeRequest((CreateLogicalSwitchPortCommand)cmd, numRetries);
} else if (cmd instanceof DeleteLogicalSwitchPortCommand) { } else if (cmd instanceof DeleteLogicalSwitchPortCommand) {
return executeRequest((DeleteLogicalSwitchPortCommand)cmd, numRetries); return executeRequest((DeleteLogicalSwitchPortCommand)cmd, NUM_RETRIES);
} else if (cmd instanceof UpdateLogicalSwitchPortCommand) { } else if (cmd instanceof UpdateLogicalSwitchPortCommand) {
return executeRequest((UpdateLogicalSwitchPortCommand)cmd, numRetries); return executeRequest((UpdateLogicalSwitchPortCommand)cmd, NUM_RETRIES);
} else if (cmd instanceof FindLogicalSwitchPortCommand) { } else if (cmd instanceof FindLogicalSwitchPortCommand) {
return executeRequest((FindLogicalSwitchPortCommand)cmd, numRetries); return executeRequest((FindLogicalSwitchPortCommand)cmd, NUM_RETRIES);
} else if (cmd instanceof CreateLogicalRouterCommand) { } else if (cmd instanceof CreateLogicalRouterCommand) {
return executeRequest((CreateLogicalRouterCommand)cmd, numRetries); return executeRequest((CreateLogicalRouterCommand)cmd, NUM_RETRIES);
} else if (cmd instanceof DeleteLogicalRouterCommand) { } else if (cmd instanceof DeleteLogicalRouterCommand) {
return executeRequest((DeleteLogicalRouterCommand)cmd, numRetries); return executeRequest((DeleteLogicalRouterCommand)cmd, NUM_RETRIES);
} else if (cmd instanceof ConfigureStaticNatRulesOnLogicalRouterCommand) { } else if (cmd instanceof ConfigureStaticNatRulesOnLogicalRouterCommand) {
return executeRequest((ConfigureStaticNatRulesOnLogicalRouterCommand)cmd, numRetries); return executeRequest((ConfigureStaticNatRulesOnLogicalRouterCommand)cmd, NUM_RETRIES);
} else if (cmd instanceof ConfigurePortForwardingRulesOnLogicalRouterCommand) { } else if (cmd instanceof ConfigurePortForwardingRulesOnLogicalRouterCommand) {
return executeRequest((ConfigurePortForwardingRulesOnLogicalRouterCommand)cmd, numRetries); return executeRequest((ConfigurePortForwardingRulesOnLogicalRouterCommand)cmd, NUM_RETRIES);
} else if (cmd instanceof ConfigurePublicIpsOnLogicalRouterCommand) { } else if (cmd instanceof ConfigurePublicIpsOnLogicalRouterCommand) {
return executeRequest((ConfigurePublicIpsOnLogicalRouterCommand)cmd, numRetries); return executeRequest((ConfigurePublicIpsOnLogicalRouterCommand)cmd, NUM_RETRIES);
} }
s_logger.debug("Received unsupported command " + cmd.toString()); s_logger.debug("Received unsupported command " + cmd.toString());
return Answer.createUnsupportedCommandAnswer(cmd); return Answer.createUnsupportedCommandAnswer(cmd);
@ -252,20 +245,7 @@ public class NiciraNvpResource implements ServerResource {
public void setAgentControl(final IAgentControl agentControl) { public void setAgentControl(final IAgentControl agentControl) {
} }
private Answer executeRequest(final DeleteLogicalSwitchCommand cmd, int numRetries) { private Answer executeRequest(final CreateLogicalSwitchPortCommand cmd, final 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) {
final String logicalSwitchUuid = cmd.getLogicalSwitchUuid(); final String logicalSwitchUuid = cmd.getLogicalSwitchUuid();
final String attachmentUuid = cmd.getAttachmentUuid(); 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()); return new CreateLogicalSwitchPortAnswer(cmd, true, "Logical switch port " + newPort.getUuid() + " created", newPort.getUuid());
} catch (final NiciraNvpApiException e) { } catch (final NiciraNvpApiException e) {
if (numRetries > 0) { retryUtility.addRetry(cmd, NUM_RETRIES);
return retry(cmd, --numRetries); return retryUtility.retry(cmd, CreateLogicalSwitchPortAnswer.class, e);
} else {
return new CreateLogicalSwitchPortAnswer(cmd, e);
}
} }
} }
private Answer executeRequest(final DeleteLogicalSwitchPortCommand cmd, int numRetries) { private Answer executeRequest(final DeleteLogicalSwitchPortCommand cmd, final int numRetries) {
try { try {
niciraNvpApi.deleteLogicalSwitchPort(cmd.getLogicalSwitchUuid(), cmd.getLogicalSwitchPortUuid()); niciraNvpApi.deleteLogicalSwitchPort(cmd.getLogicalSwitchUuid(), cmd.getLogicalSwitchPortUuid());
return new DeleteLogicalSwitchPortAnswer(cmd, true, "Logical switch port " + cmd.getLogicalSwitchPortUuid() + " deleted"); return new DeleteLogicalSwitchPortAnswer(cmd, true, "Logical switch port " + cmd.getLogicalSwitchPortUuid() + " deleted");
} catch (final NiciraNvpApiException e) { } catch (final NiciraNvpApiException e) {
if (numRetries > 0) { retryUtility.addRetry(cmd, NUM_RETRIES);
return retry(cmd, --numRetries); return retryUtility.retry(cmd, DeleteLogicalSwitchPortAnswer.class, e);
} else {
return new DeleteLogicalSwitchPortAnswer(cmd, 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 logicalSwitchUuid = cmd.getLogicalSwitchUuid();
final String logicalSwitchPortUuid = cmd.getLogicalSwitchPortUuid(); final String logicalSwitchPortUuid = cmd.getLogicalSwitchPortUuid();
final String attachmentUuid = cmd.getAttachmentUuid(); final String attachmentUuid = cmd.getAttachmentUuid();
@ -320,16 +293,12 @@ public class NiciraNvpResource implements ServerResource {
niciraNvpApi.updateLogicalSwitchPortAttachment(logicalSwitchUuid, logicalSwitchPortUuid, new VifAttachment(attachmentUuid)); niciraNvpApi.updateLogicalSwitchPortAttachment(logicalSwitchUuid, logicalSwitchPortUuid, new VifAttachment(attachmentUuid));
return new UpdateLogicalSwitchPortAnswer(cmd, true, "Attachment for " + logicalSwitchPortUuid + " updated", logicalSwitchPortUuid); return new UpdateLogicalSwitchPortAnswer(cmd, true, "Attachment for " + logicalSwitchPortUuid + " updated", logicalSwitchPortUuid);
} catch (final NiciraNvpApiException e) { } catch (final NiciraNvpApiException e) {
if (numRetries > 0) { retryUtility.addRetry(cmd, NUM_RETRIES);
return retry(cmd, --numRetries); return retryUtility.retry(cmd, UpdateLogicalSwitchPortAnswer.class, e);
} else {
return new UpdateLogicalSwitchPortAnswer(cmd, 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 logicalSwitchUuid = cmd.getLogicalSwitchUuid();
final String logicalSwitchPortUuid = cmd.getLogicalSwitchPortUuid(); final String logicalSwitchPortUuid = cmd.getLogicalSwitchPortUuid();
@ -341,15 +310,12 @@ public class NiciraNvpResource implements ServerResource {
return new FindLogicalSwitchPortAnswer(cmd, true, "Logical switchport " + logicalSwitchPortUuid + " found", logicalSwitchPortUuid); return new FindLogicalSwitchPortAnswer(cmd, true, "Logical switchport " + logicalSwitchPortUuid + " found", logicalSwitchPortUuid);
} }
} catch (final NiciraNvpApiException e) { } catch (final NiciraNvpApiException e) {
if (numRetries > 0) { retryUtility.addRetry(cmd, NUM_RETRIES);
return retry(cmd, --numRetries); return retryUtility.retry(cmd, FindLogicalSwitchPortAnswer.class, e);
} else {
return new FindLogicalSwitchPortAnswer(cmd, 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 routerName = cmd.getName();
final String gatewayServiceUuid = cmd.getGatewayServiceUuid(); final String gatewayServiceUuid = cmd.getGatewayServiceUuid();
final String logicalSwitchUuid = cmd.getLogicalSwitchUuid(); 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()); return new CreateLogicalRouterAnswer(cmd, true, "Logical Router created (uuid " + lrc.getUuid() + ")", lrc.getUuid());
} catch (final NiciraNvpApiException e) { } catch (final NiciraNvpApiException e) {
if (numRetries > 0) { retryUtility.addRetry(cmd, NUM_RETRIES);
return retry(cmd, --numRetries); return retryUtility.retry(cmd, CreateLogicalRouterAnswer.class, e);
} else {
return new CreateLogicalRouterAnswer(cmd, e);
}
} }
} }
private Answer executeRequest(final DeleteLogicalRouterCommand cmd, int numRetries) { private Answer executeRequest(final DeleteLogicalRouterCommand cmd, final int numRetries) {
try { try {
niciraNvpApi.deleteLogicalRouter(cmd.getLogicalRouterUuid()); niciraNvpApi.deleteLogicalRouter(cmd.getLogicalRouterUuid());
return new DeleteLogicalRouterAnswer(cmd, true, "Logical Router deleted (uuid " + cmd.getLogicalRouterUuid() + ")"); return new DeleteLogicalRouterAnswer(cmd, true, "Logical Router deleted (uuid " + cmd.getLogicalRouterUuid() + ")");
} catch (final NiciraNvpApiException e) { } catch (final NiciraNvpApiException e) {
if (numRetries > 0) { retryUtility.addRetry(cmd, NUM_RETRIES);
return retry(cmd, --numRetries); return retryUtility.retry(cmd, DeleteLogicalRouterAnswer.class, e);
} else {
return new DeleteLogicalRouterAnswer(cmd, e);
}
} }
} }
private Answer executeRequest(final ConfigurePublicIpsOnLogicalRouterCommand cmd, int numRetries) { private Answer executeRequest(final ConfigurePublicIpsOnLogicalRouterCommand cmd, final int numRetries) {
try { try {
final NiciraNvpList<LogicalRouterPort> ports = niciraNvpApi.findLogicalRouterPortByGatewayServiceUuid(cmd.getLogicalRouterUuid(), cmd.getL3GatewayServiceUuid()); final NiciraNvpList<LogicalRouterPort> ports = niciraNvpApi.findLogicalRouterPortByGatewayServiceUuid(cmd.getLogicalRouterUuid(), cmd.getL3GatewayServiceUuid());
if (ports.getResultCount() != 1) { 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 " + return new ConfigurePublicIpsOnLogicalRouterAnswer(cmd, true, "Configured " + cmd.getPublicCidrs().size() + " ip addresses on logical router uuid " +
cmd.getLogicalRouterUuid()); cmd.getLogicalRouterUuid());
} catch (final NiciraNvpApiException e) { } catch (final NiciraNvpApiException e) {
if (numRetries > 0) { retryUtility.addRetry(cmd, NUM_RETRIES);
return retry(cmd, --numRetries); return retryUtility.retry(cmd, ConfigurePublicIpsOnLogicalRouterAnswer.class, e);
} else {
return new ConfigurePublicIpsOnLogicalRouterAnswer(cmd, e);
}
} }
} }
private Answer executeRequest(final ConfigureStaticNatRulesOnLogicalRouterCommand cmd, int numRetries) { private Answer executeRequest(final ConfigureStaticNatRulesOnLogicalRouterCommand cmd, final int numRetries) {
try { try {
final NiciraNvpList<NatRule> existingRules = niciraNvpApi.findNatRulesByLogicalRouterUuid(cmd.getLogicalRouterUuid()); final NiciraNvpList<NatRule> existingRules = niciraNvpApi.findNatRulesByLogicalRouterUuid(cmd.getLogicalRouterUuid());
// Rules of the game (also known as assumptions-that-will-make-stuff-break-later-on) // 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"); return new ConfigureStaticNatRulesOnLogicalRouterAnswer(cmd, true, cmd.getRules().size() + " StaticNat rules applied");
} catch (final NiciraNvpApiException e) { } catch (final NiciraNvpApiException e) {
if (numRetries > 0) { retryUtility.addRetry(cmd, NUM_RETRIES);
return retry(cmd, --numRetries); return retryUtility.retry(cmd, ConfigureStaticNatRulesOnLogicalRouterAnswer.class, e);
} else {
return new ConfigureStaticNatRulesOnLogicalRouterAnswer(cmd, e);
}
} }
} }
private Answer executeRequest(final ConfigurePortForwardingRulesOnLogicalRouterCommand cmd, int numRetries) { private Answer executeRequest(final ConfigurePortForwardingRulesOnLogicalRouterCommand cmd, final int numRetries) {
try { try {
final NiciraNvpList<NatRule> existingRules = niciraNvpApi.findNatRulesByLogicalRouterUuid(cmd.getLogicalRouterUuid()); final NiciraNvpList<NatRule> existingRules = niciraNvpApi.findNatRulesByLogicalRouterUuid(cmd.getLogicalRouterUuid());
// Rules of the game (also known as assumptions-that-will-make-stuff-break-later-on) // 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"); return new ConfigurePortForwardingRulesOnLogicalRouterAnswer(cmd, true, cmd.getRules().size() + " PortForwarding rules applied");
} catch (final NiciraNvpApiException e) { } catch (final NiciraNvpApiException e) {
if (numRetries > 0) { retryUtility.addRetry(cmd, NUM_RETRIES);
return retry(cmd, --numRetries); return retryUtility.retry(cmd, ConfigurePortForwardingRulesOnLogicalRouterAnswer.class, e);
} else {
return new ConfigurePortForwardingRulesOnLogicalRouterAnswer(cmd, 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) { private String natRuleToString(final NatRule rule) {

View File

@ -19,6 +19,8 @@
package com.cloud.network.resource.wrapper; package com.cloud.network.resource.wrapper;
import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -32,6 +34,7 @@ import com.cloud.network.nicira.NiciraNvpTag;
import com.cloud.network.nicira.TransportZoneBinding; import com.cloud.network.nicira.TransportZoneBinding;
import com.cloud.network.resource.NiciraNvpResource; import com.cloud.network.resource.NiciraNvpResource;
import com.cloud.network.resource.NiciraNvpUtilities; import com.cloud.network.resource.NiciraNvpUtilities;
import com.cloud.network.utils.CommandRetryUtility;
import com.cloud.resource.CommandWrapper; import com.cloud.resource.CommandWrapper;
import com.cloud.resource.ResourceWrapper; import com.cloud.resource.ResourceWrapper;
@ -62,12 +65,9 @@ public final class NiciraNvpCreateLogicalSwitchCommandWrapper extends CommandWra
final String switchUuid = logicalSwitch.getUuid(); final String switchUuid = logicalSwitch.getUuid();
return new CreateLogicalSwitchAnswer(command, true, "Logicalswitch " + switchUuid + " created", switchUuid); return new CreateLogicalSwitchAnswer(command, true, "Logicalswitch " + switchUuid + " created", switchUuid);
} catch (final NiciraNvpApiException e) { } catch (final NiciraNvpApiException e) {
int numRetries = niciraNvpResource.getNumRetries(); final CommandRetryUtility retryUtility = niciraNvpResource.getRetryUtility();
if (numRetries > 0) { retryUtility.addRetry(command, NUM_RETRIES);
return niciraNvpResource.retry(command, --numRetries); return retryUtility.retry(command, CreateLogicalSwitchAnswer.class, e);
} else {
return new CreateLogicalSwitchAnswer(command, e);
}
} }
} }
} }

View File

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

View File

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

View File

@ -22,6 +22,7 @@ package com.cloud.network.resource;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.junit.Test; import org.junit.Test;
@ -30,6 +31,7 @@ import org.mockito.Mockito;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CreateLogicalSwitchCommand; import com.cloud.agent.api.CreateLogicalSwitchCommand;
import com.cloud.agent.api.DeleteLogicalSwitchCommand;
import com.cloud.agent.api.MaintainCommand; import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.ReadyCommand;
import com.cloud.network.nicira.LogicalSwitch; import com.cloud.network.nicira.LogicalSwitch;
@ -99,4 +101,28 @@ public class NiciraNvpRequestWrapperTest {
assertTrue(answer.getResult()); 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());
}
} }

View File

@ -85,12 +85,16 @@ import com.cloud.network.nicira.NiciraNvpApi;
import com.cloud.network.nicira.NiciraNvpApiException; import com.cloud.network.nicira.NiciraNvpApiException;
import com.cloud.network.nicira.NiciraNvpList; import com.cloud.network.nicira.NiciraNvpList;
import com.cloud.network.nicira.SourceNatRule; import com.cloud.network.nicira.SourceNatRule;
import com.cloud.network.utils.CommandRetryUtility;
public class NiciraNvpResourceTest { public class NiciraNvpResourceTest {
NiciraNvpApi nvpApi = mock(NiciraNvpApi.class); NiciraNvpApi nvpApi = mock(NiciraNvpApi.class);
NiciraNvpResource resource; NiciraNvpResource resource;
Map<String, Object> parameters; Map<String, Object> parameters;
private NiciraNvpUtilities niciraNvpUtilities;
private CommandRetryUtility retryUtility;
@Before @Before
public void setUp() throws ConfigurationException { public void setUp() throws ConfigurationException {
resource = new NiciraNvpResource() { resource = new NiciraNvpResource() {
@ -107,6 +111,10 @@ public class NiciraNvpResourceTest {
parameters.put("guid", "aaaaa-bbbbb-ccccc"); parameters.put("guid", "aaaaa-bbbbb-ccccc");
parameters.put("zoneId", "blublub"); parameters.put("zoneId", "blublub");
parameters.put("adminpass", "adminpass"); parameters.put("adminpass", "adminpass");
niciraNvpUtilities = NiciraNvpUtilities.getInstance();
retryUtility = CommandRetryUtility.getInstance();
retryUtility.setServerResource(resource);
} }
@Test(expected = ConfigurationException.class) @Test(expected = ConfigurationException.class)
@ -295,7 +303,7 @@ public class NiciraNvpResourceTest {
doThrow(new NiciraNvpApiException()).when(nvpApi).updateLogicalSwitchPortAttachment((String)any(), (String)any(), (Attachment)any()); doThrow(new NiciraNvpApiException()).when(nvpApi).updateLogicalSwitchPortAttachment((String)any(), (String)any(), (Attachment)any());
final UpdateLogicalSwitchPortAnswer dlspa = 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()); assertFalse(dlspa.getResult());
} }