Merge pull request #737 from miguelaferreira/feature/mferreira/ncx-follow-redirects-gardened-rebase

CLOUDSTACK-8758: Handle redirects in communication with NXS controller (a.k.a. Nicira NVP)When an NSX controller node is part of a cluster it will redirect API calls to the master controller. Because the ACS management server does not follow such redirects, if there is a change of master within a NSX cluster, the NSX device (a.k.a.  NiciraNvp) needs to be reconfigured (via the management server DB).

The goal of this PR is to enable ACS management server to follow HTTP redirects sent by NSX controllers. However, other changes were made to the cloud-utils module that provides the REST client that the NSX plugin uses.

Cosmetic changes:
* Upgrade maven module structure for cloud-utils and cloud-plugin-netowkr-nvp to comply with maven default
* Several refactorings on both modules to consistently format the code, remove unused code, declare final when possible, remove auto generated comments, etc

Other changes:
* Upgrade HTTP library used in REST client to version 4.5 of Apache HTTP Components
* Implement generic REST client that supports HTTP redirects
* Implement NSX specific REST client
* Simplify NSX api implementation
* Previously existing unit tests for both the REST client and NSX api were either maintained in the same test classes, moved to new test classes (because code under tests also moved), or removed (because code under tests was also removed)
* New Marvin tests for NSX controllers

Testing:
* Ran all unit tests present in the project
* Ran Java Integration tests for NSX api targeting both a master and a slave controller
* Ran new Marvin test for NSX controller
* Manual inspection of logs to confirm redirection is taking place

* pr/737:
  Use NSX specific RestClient in API implementation (NiciraNvpApi)
  Refactor NSX api implementation (NiciraNvpApi)
  Add NSX specific RestClient implementation
  Delegate HTTP protocol activity in RESTServiceConnector to RestClient
  Add basic RestClient implentation based on HTTP Components 4.5
  Code clean up in cloud-plugin-network-nvp project
  Code clean up in cloud-utils project
  Refactor cloud-plugin-network-nvp project into Maven default structure
  Refactor cloud-utils project into Maven default structure
  Fix unit-test library dependencies
  Add Marvin test for Nicira NVP plugin
  Create Nicira NVP devices and enable plugin at deploy

Signed-off-by: Remi Bergsma <github@remi.nl>
This commit is contained in:
Remi Bergsma 2015-08-25 20:44:50 +02:00
commit 44ba14d17b
309 changed files with 4037 additions and 2635 deletions

View File

@ -18,7 +18,8 @@
under the License. under the License.
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>cloud-plugin-network-nvp</artifactId> <artifactId>cloud-plugin-network-nvp</artifactId>
<name>Apache CloudStack Plugin - Network Nicira NVP</name> <name>Apache CloudStack Plugin - Network Nicira NVP</name>
@ -29,10 +30,29 @@
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<dependencies>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-utils</artifactId>
<version>4.6.0-SNAPSHOT</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build> <build>
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<outputDirectory>target/classes</outputDirectory>
<testOutputDirectory>target/test-classes</testOutputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<testResources> <testResources>
<testResource> <testResource>
<directory>test/resources</directory> <directory>src/test/resources</directory>
<filtering>true</filtering> <filtering>true</filtering>
</testResource> </testResource>
</testResources> </testResources>

View File

@ -1,658 +0,0 @@
//
// 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.nicira;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
import com.cloud.utils.rest.CloudstackRESTException;
import com.cloud.utils.rest.RESTServiceConnector;
import com.cloud.utils.rest.RESTValidationStrategy;
@SuppressWarnings("rawtypes")
public class NiciraNvpApi {
protected static final String GET_METHOD_TYPE = "get";
protected static final String DELETE_METHOD_TYPE = "delete";
protected static final String PUT_METHOD_TYPE = "put";
protected static final String POST_METHOD_TYPE = "post";
protected static final String SEC_PROFILE_URI_PREFIX = "/ws.v1/security-profile";
protected static final String ACL_URI_PREFIX = "/ws.v1/acl";
private static final String SWITCH_URI_PREFIX = "/ws.v1/lswitch";
private static final String ROUTER_URI_PREFIX = "/ws.v1/lrouter";
private static final String LOGIN_URL = "/ws.v1/login";
protected RESTServiceConnector restConnector;
protected final static Map<Class, String> prefixMap;
protected final static Map<Class, Type> listTypeMap;
protected final static Map<String, String> defaultListParams;
static {
prefixMap = new HashMap<Class, String>();
prefixMap.put(SecurityProfile.class, SEC_PROFILE_URI_PREFIX);
prefixMap.put(Acl.class, ACL_URI_PREFIX);
prefixMap.put(LogicalSwitch.class, SWITCH_URI_PREFIX);
prefixMap.put(LogicalRouter.class, ROUTER_URI_PREFIX);
listTypeMap = new HashMap<Class, Type>();
listTypeMap.put(SecurityProfile.class, new TypeToken<NiciraNvpList<SecurityProfile>>() {
}.getType());
listTypeMap.put(Acl.class, new TypeToken<NiciraNvpList<Acl>>() {
}.getType());
listTypeMap.put(LogicalSwitch.class, new TypeToken<NiciraNvpList<LogicalSwitch>>() {
}.getType());
listTypeMap.put(LogicalRouter.class, new TypeToken<NiciraNvpList<LogicalRouter>>() {
}.getType());
defaultListParams = new HashMap<String, String>();
defaultListParams.put("fields", "*");
}
public NiciraNvpApi() {
final List<Class<?>> classList = new ArrayList<Class<?>>();
classList.add(NatRule.class);
classList.add(RoutingConfig.class);
final List<JsonDeserializer<?>> deserializerList = new ArrayList<JsonDeserializer<?>>();
deserializerList.add(new NatRuleAdapter());
deserializerList.add(new RoutingConfigAdapter());
restConnector = new RESTServiceConnector(new RESTValidationStrategy(LOGIN_URL), classList, deserializerList);
}
public NiciraNvpApi(final String address, final String username, final String password) {
this();
restConnector.setControllerAddress(address);
restConnector.setAdminCredentials(username, password);
}
public void setControllerAddress(final String address) {
restConnector.setControllerAddress(address);
}
public void setAdminCredentials(final String username, final String password) {
restConnector.setAdminCredentials(username, password);
}
/**
* POST
*
* @param entity
* @return
* @throws NiciraNvpApiException
*/
protected <T> T create(final T entity) throws NiciraNvpApiException {
final String uri = prefixMap.get(entity.getClass());
return createWithUri(entity, uri);
}
/**
* POST
*
* @param entity
* @return
* @throws NiciraNvpApiException
*/
protected <T> T createWithUri(final T entity, final String uri) throws NiciraNvpApiException {
T createdEntity;
try {
createdEntity = restConnector.executeCreateObject(entity, new TypeToken<T>() {
}.getType(), uri, Collections.<String, String> emptyMap());
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
return createdEntity;
}
/**
* GET list of items
*
* @return
* @throws NiciraNvpApiException
*/
protected <T> NiciraNvpList<T> find(final Class<T> clazz) throws NiciraNvpApiException {
return find(null, clazz);
}
/**
* GET list of items
*
* @param uuid
* @return
* @throws NiciraNvpApiException
*/
public <T> NiciraNvpList<T> find(final String uuid, final Class<T> clazz) throws NiciraNvpApiException {
final String uri = prefixMap.get(clazz);
Map<String, String> params = defaultListParams;
if (uuid != null) {
params = new HashMap<String, String>(defaultListParams);
params.put("uuid", uuid);
}
NiciraNvpList<T> entities;
try {
entities = restConnector.executeRetrieveObject(listTypeMap.get(clazz), uri, params);
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
if (entities == null) {
throw new NiciraNvpApiException("Unexpected response from API");
}
return entities;
}
/**
* PUT item given a UUID as key and an item object
* with the new data
*
* @param item
* @param uuid
* @throws NiciraNvpApiException
*/
public <T> void update(final T item, final String uuid)
throws NiciraNvpApiException {
final String uri = prefixMap.get(item.getClass()) + "/" + uuid;
updateWithUri(item, uri);
}
/**
* PUT item given a UUID as key and an item object
* with the new data
*
* @param item
* @param uuid
* @throws NiciraNvpApiException
*/
public <T> void updateWithUri(final T item, final String uri)
throws NiciraNvpApiException {
try {
restConnector.executeUpdateObject(item, uri, Collections.<String, String> emptyMap());
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
}
/**
* DELETE Security Profile given a UUID as key
*
* @param securityProfileUuid
* @throws NiciraNvpApiException
*/
public <T> void delete(final String uuid, final Class<T> clazz)
throws NiciraNvpApiException {
final String uri = prefixMap.get(clazz) + "/" + uuid;
deleteWithUri(uri);
}
/**
* DELETE Security Profile given a UUID as key
*
* @param securityProfileUuid
* @throws NiciraNvpApiException
*/
public <T> void deleteWithUri(final String uri)
throws NiciraNvpApiException {
try {
restConnector.executeDeleteObject(uri);
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
}
/**
* POST {@link SecurityProfile}
*
* @param securityProfile
* @return
* @throws NiciraNvpApiException
*/
public SecurityProfile createSecurityProfile(final SecurityProfile securityProfile) throws NiciraNvpApiException {
return create(securityProfile);
}
/**
* GET list of {@link SecurityProfile}
*
* @return
* @throws NiciraNvpApiException
*/
public NiciraNvpList<SecurityProfile> findSecurityProfile() throws NiciraNvpApiException {
return findSecurityProfile(null);
}
/**
* GET list of {@link SecurityProfile} filtered by UUID
*
* We could have invoked the service:
* SEC_PROFILE_URI_PREFIX + "/" + securityProfileUuid
* but it is not working currently
*
* @param uuid
* @return
* @throws NiciraNvpApiException
*/
public NiciraNvpList<SecurityProfile> findSecurityProfile(final String uuid) throws NiciraNvpApiException {
return find(uuid, SecurityProfile.class);
}
/**
* PUT {@link SecurityProfile} given a UUID as key and a {@link SecurityProfile}
* with the new data
*
* @param securityProfile
* @param securityProfileUuid
* @throws NiciraNvpApiException
*/
public void updateSecurityProfile(final SecurityProfile securityProfile,
final String securityProfileUuid)
throws NiciraNvpApiException {
update(securityProfile, securityProfileUuid);
}
/**
* DELETE Security Profile given a UUID as key
*
* @param securityProfileUuid
* @throws NiciraNvpApiException
*/
public void deleteSecurityProfile(final String securityProfileUuid)
throws NiciraNvpApiException {
delete(securityProfileUuid, SecurityProfile.class);
}
/**
* POST {@link Acl}
*
* @param acl
* @return
* @throws NiciraNvpApiException
*/
public Acl createAcl(final Acl acl) throws NiciraNvpApiException {
return create(acl);
}
/**
* GET list of {@link Acl}
*
* @return
* @throws NiciraNvpApiException
*/
public NiciraNvpList<Acl> findAcl() throws NiciraNvpApiException {
return findAcl(null);
}
/**
* GET list of {@link Acl} filtered by UUID
*
* @param uuid
* @return
* @throws NiciraNvpApiException
*/
public NiciraNvpList<Acl> findAcl(final String uuid) throws NiciraNvpApiException {
return find(uuid, Acl.class);
}
/**
* PUT {@link Acl} given a UUID as key and a {@link Acl}
* with the new data
*
* @param acl
* @param aclUuid
* @throws NiciraNvpApiException
*/
public void updateAcl(final Acl acl,
final String aclUuid)
throws NiciraNvpApiException {
update(acl, aclUuid);
}
/**
* DELETE Acl given a UUID as key
*
* @param acl
* @throws NiciraNvpApiException
*/
public void deleteAcl(final String aclUuid) throws NiciraNvpApiException {
delete(aclUuid, Acl.class);
}
public LogicalSwitch createLogicalSwitch(final LogicalSwitch logicalSwitch) throws NiciraNvpApiException {
return create(logicalSwitch);
}
/**
* GET list of {@link LogicalSwitch}
*
* @return
* @throws NiciraNvpApiException
*/
public NiciraNvpList<LogicalSwitch> findLogicalSwitch() throws NiciraNvpApiException {
return findLogicalSwitch(null);
}
/**
* GET list of {@link LogicalSwitch} filtered by UUID
*
* @param uuid
* @return
* @throws NiciraNvpApiException
*/
public NiciraNvpList<LogicalSwitch> findLogicalSwitch(final String uuid) throws NiciraNvpApiException {
return find(uuid, LogicalSwitch.class);
}
/**
* PUT {@link LogicalSwitch} given a UUID as key and a {@link LogicalSwitch}
* with the new data
*
* @param logicalSwitch
* @param logicalSwitchUuid
* @throws NiciraNvpApiException
*/
public void updateLogicalSwitch(final LogicalSwitch logicalSwitch,
final String logicalSwitchUuid)
throws NiciraNvpApiException {
update(logicalSwitch, logicalSwitchUuid);
}
public void deleteLogicalSwitch(final String uuid) throws NiciraNvpApiException {
delete(uuid, LogicalSwitch.class);
}
public LogicalSwitchPort createLogicalSwitchPort(final String logicalSwitchUuid, final LogicalSwitchPort logicalSwitchPort) throws NiciraNvpApiException {
final String uri = SWITCH_URI_PREFIX + "/" + logicalSwitchUuid + "/lport";
return createWithUri(logicalSwitchPort, uri);
}
public void updateLogicalSwitchPort(final String logicalSwitchUuid, final LogicalSwitchPort logicalSwitchPort) throws NiciraNvpApiException {
final String uri = SWITCH_URI_PREFIX + "/" + logicalSwitchUuid + "/lport/" + logicalSwitchPort.getUuid();
updateWithUri(logicalSwitchPort, uri);
}
public void updateLogicalSwitchPortAttachment(final String logicalSwitchUuid, final String logicalSwitchPortUuid,
final Attachment attachment) throws NiciraNvpApiException {
final String uri = SWITCH_URI_PREFIX + "/" + logicalSwitchUuid + "/lport/" + logicalSwitchPortUuid + "/attachment";
updateWithUri(attachment, uri);
}
public void deleteLogicalSwitchPort(final String logicalSwitchUuid, final String logicalSwitchPortUuid) throws NiciraNvpApiException {
final String uri = SWITCH_URI_PREFIX + "/" + logicalSwitchUuid + "/lport/" + logicalSwitchPortUuid;
deleteWithUri(uri);
}
public String findLogicalSwitchPortUuidByVifAttachmentUuid(final String logicalSwitchUuid, final String vifAttachmentUuid) throws NiciraNvpApiException {
final String uri = SWITCH_URI_PREFIX + "/" + logicalSwitchUuid + "/lport";
final Map<String, String> params = new HashMap<String, String>();
params.put("attachment_vif_uuid", vifAttachmentUuid);
params.put("fields", "uuid");
NiciraNvpList<LogicalSwitchPort> lspl;
try {
lspl = restConnector.executeRetrieveObject(new TypeToken<NiciraNvpList<LogicalSwitchPort>>() {
}.getType(), uri, params);
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
if (lspl == null || lspl.getResultCount() != 1) {
throw new NiciraNvpApiException("Unexpected response from API");
}
final LogicalSwitchPort lsp = lspl.getResults().get(0);
return lsp.getUuid();
}
public ControlClusterStatus getControlClusterStatus() throws NiciraNvpApiException {
final String uri = "/ws.v1/control-cluster/status";
ControlClusterStatus ccs;
try {
ccs = restConnector.executeRetrieveObject(new TypeToken<ControlClusterStatus>() {
}.getType(), uri, null);
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
return ccs;
}
public NiciraNvpList<LogicalSwitchPort> findLogicalSwitchPortsByUuid(final String logicalSwitchUuid, final String logicalSwitchPortUuid) throws NiciraNvpApiException {
final String uri = SWITCH_URI_PREFIX + "/" + logicalSwitchUuid + "/lport";
final Map<String, String> params = new HashMap<String, String>();
params.put("uuid", logicalSwitchPortUuid);
params.put("fields", "uuid");
NiciraNvpList<LogicalSwitchPort> lspl;
try {
lspl = restConnector.executeRetrieveObject(new TypeToken<NiciraNvpList<LogicalSwitchPort>>() {
}.getType(), uri, params);
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
if (lspl == null) {
throw new NiciraNvpApiException("Unexpected response from API");
}
return lspl;
}
public NiciraNvpList<LogicalRouterPort> findLogicalRouterPortsByUuid(final String logicalRouterUuid, final String logicalRouterPortUuid) throws NiciraNvpApiException {
final String uri = ROUTER_URI_PREFIX + "/" + logicalRouterUuid + "/lport";
final Map<String, String> params = new HashMap<String, String>();
params.put("uuid", logicalRouterPortUuid);
params.put("fields", "uuid");
NiciraNvpList<LogicalRouterPort> lrpl;
try {
lrpl = restConnector.executeRetrieveObject(new TypeToken<NiciraNvpList<LogicalRouterPort>>() {
}.getType(), uri, params);
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
if (lrpl == null) {
throw new NiciraNvpApiException("Unexpected response from API");
}
return lrpl;
}
public LogicalRouter createLogicalRouter(final LogicalRouter logicalRouter) throws NiciraNvpApiException {
return create(logicalRouter);
}
/**
* GET list of {@link LogicalRouter}
*
* @return
* @throws NiciraNvpApiException
*/
public NiciraNvpList<LogicalRouter> findLogicalRouter() throws NiciraNvpApiException {
return findLogicalRouter(null);
}
/**
* GET list of {@link LogicalRouter} filtered by UUID
*
* @param uuid
* @return
* @throws NiciraNvpApiException
*/
public NiciraNvpList<LogicalRouter> findLogicalRouter(final String uuid) throws NiciraNvpApiException {
return find(uuid, LogicalRouter.class);
}
public LogicalRouter findOneLogicalRouterByUuid(final String logicalRouterUuid) throws NiciraNvpApiException {
return findLogicalRouter(logicalRouterUuid).getResults().get(0);
}
public void updateLogicalRouter(final LogicalRouter logicalRouter,
final String logicalRouterUuid)
throws NiciraNvpApiException {
update(logicalRouter, logicalRouterUuid);
}
public void deleteLogicalRouter(final String logicalRouterUuid) throws NiciraNvpApiException {
final String uri = ROUTER_URI_PREFIX + "/" + logicalRouterUuid;
deleteWithUri(uri);
}
public LogicalRouterPort createLogicalRouterPort(final String logicalRouterUuid, final LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException {
final String uri = ROUTER_URI_PREFIX + "/" + logicalRouterUuid + "/lport";
return createWithUri(logicalRouterPort, uri);
}
public void deleteLogicalRouterPort(final String logicalRouterUuid, final String logicalRouterPortUuid) throws NiciraNvpApiException {
final String uri = ROUTER_URI_PREFIX + "/" + logicalRouterUuid + "/lport/" + logicalRouterPortUuid;
deleteWithUri(uri);
}
public void updateLogicalRouterPort(final String logicalRouterUuid, final LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException {
final String uri = ROUTER_URI_PREFIX + "/" + logicalRouterUuid + "/lport/" + logicalRouterPort.getUuid();
updateWithUri(logicalRouterPort, uri);
}
public void updateLogicalRouterPortAttachment(final String logicalRouterUuid, final String logicalRouterPortUuid, final Attachment attachment)
throws NiciraNvpApiException {
final String uri = ROUTER_URI_PREFIX + "/" + logicalRouterUuid + "/lport/" + logicalRouterPortUuid + "/attachment";
updateWithUri(attachment, uri);
}
public NatRule createLogicalRouterNatRule(final String logicalRouterUuid, final NatRule natRule) throws NiciraNvpApiException {
final String uri = ROUTER_URI_PREFIX + "/" + logicalRouterUuid + "/nat";
return createWithUri(natRule, uri);
}
public void updateLogicalRouterNatRule(final String logicalRouterUuid, final NatRule natRule) throws NiciraNvpApiException {
final String uri = ROUTER_URI_PREFIX + "/" + logicalRouterUuid + "/nat/" + natRule.getUuid();
updateWithUri(natRule, uri);
}
public void deleteLogicalRouterNatRule(final String logicalRouterUuid, final UUID natRuleUuid) throws NiciraNvpApiException {
final String uri = ROUTER_URI_PREFIX + "/" + logicalRouterUuid + "/nat/" + natRuleUuid.toString();
deleteWithUri(uri);
}
public NiciraNvpList<LogicalRouterPort> findLogicalRouterPortByGatewayServiceAndVlanId(final String logicalRouterUuid, final String gatewayServiceUuid,
final long vlanId) throws NiciraNvpApiException {
final String uri = ROUTER_URI_PREFIX + "/" + logicalRouterUuid + "/lport";
final Map<String, String> params = new HashMap<String, String>();
params.put("attachment_gwsvc_uuid", gatewayServiceUuid);
params.put("attachment_vlan", "0");
params.put("fields", "*");
try {
return restConnector.executeRetrieveObject(new TypeToken<NiciraNvpList<LogicalRouterPort>>() {
}.getType(), uri, params);
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
}
public NiciraNvpList<NatRule> findNatRulesByLogicalRouterUuid(final String logicalRouterUuid) throws NiciraNvpApiException {
final String uri = ROUTER_URI_PREFIX + "/" + logicalRouterUuid + "/nat";
final Map<String, String> params = new HashMap<String, String>();
params.put("fields", "*");
try {
return restConnector.executeRetrieveObject(new TypeToken<NiciraNvpList<NatRule>>() {
}.getType(), uri, params);
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
}
public NiciraNvpList<LogicalRouterPort> findLogicalRouterPortByGatewayServiceUuid(final String logicalRouterUuid, final String l3GatewayServiceUuid)
throws NiciraNvpApiException {
final String uri = ROUTER_URI_PREFIX + "/" + logicalRouterUuid + "/lport";
final Map<String, String> params = new HashMap<String, String>();
params.put("fields", "*");
params.put("attachment_gwsvc_uuid", l3GatewayServiceUuid);
try {
return restConnector.executeRetrieveObject(new TypeToken<NiciraNvpList<LogicalRouterPort>>() {
}.getType(), uri, params);
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
}
public static class NatRuleAdapter implements JsonDeserializer<NatRule> {
@Override
public NatRule deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = jsonElement.getAsJsonObject();
if (!jsonObject.has("type")) {
throw new JsonParseException("Deserializing as a NatRule, but no type present in the json object");
}
final String natRuleType = jsonObject.get("type").getAsString();
if ("SourceNatRule".equals(natRuleType)) {
return context.deserialize(jsonElement, SourceNatRule.class);
} else if ("DestinationNatRule".equals(natRuleType)) {
return context.deserialize(jsonElement, DestinationNatRule.class);
}
throw new JsonParseException("Failed to deserialize type \"" + natRuleType + "\"");
}
}
public static class RoutingConfigAdapter implements JsonDeserializer<RoutingConfig> {
private static final String ROUTING_TABLE_ROUTING_CONFIG = "RoutingTableRoutingConfig";
private static final String SINGLE_DEFAULT_ROUTE_IMPLICIT_ROUTING_CONFIG = "SingleDefaultRouteImplicitRoutingConfig";
@Override
public RoutingConfig deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = jsonElement.getAsJsonObject();
if (!jsonObject.has("type")) {
throw new JsonParseException("Deserializing as a RoutingConfig, but no type present in the json object");
}
final String routingConfigType = jsonObject.get("type").getAsString();
if (SINGLE_DEFAULT_ROUTE_IMPLICIT_ROUTING_CONFIG.equals(routingConfigType)) {
return context.deserialize(jsonElement, SingleDefaultRouteImplicitRoutingConfig.class);
} else if (ROUTING_TABLE_ROUTING_CONFIG.equals(routingConfigType)) {
return context.deserialize(jsonElement, RoutingTableRoutingConfig.class);
}
throw new JsonParseException("Failed to deserialize type \"" + routingConfigType + "\"");
}
}
}

View File

@ -98,14 +98,14 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru {
public NiciraNvpGuestNetworkGuru() { public NiciraNvpGuestNetworkGuru() {
super(); super();
_isolationMethods = new IsolationMethod[] {IsolationMethod.STT, IsolationMethod.VXLAN}; _isolationMethods = new IsolationMethod[] { IsolationMethod.STT, IsolationMethod.VXLAN };
} }
@Override @Override
protected boolean canHandle(final NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) { protected boolean canHandle(final NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
// This guru handles only Guest Isolated network that supports Source nat service // This guru handles only Guest Isolated network that supports Source nat service
if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == Network.GuestType.Isolated && if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == Network.GuestType.Isolated
isMyIsolationMethod(physicalNetwork) && ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(offering.getId(), Service.Connectivity)) { && isMyIsolationMethod(physicalNetwork) && ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(offering.getId(), Service.Connectivity)) {
return true; return true;
} else { } else {
s_logger.trace("We only take care of Guest networks of type " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced); s_logger.trace("We only take care of Guest networks of type " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced);
@ -116,14 +116,14 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru {
@Override @Override
public Network design(final NetworkOffering offering, final DeploymentPlan plan, final Network userSpecified, final Account owner) { public Network design(final NetworkOffering offering, final DeploymentPlan plan, final Network userSpecified, final Account owner) {
// Check of the isolation type of the related physical network is supported // Check of the isolation type of the related physical network is supported
PhysicalNetworkVO physnet = physicalNetworkDao.findById(plan.getPhysicalNetworkId()); final PhysicalNetworkVO physnet = physicalNetworkDao.findById(plan.getPhysicalNetworkId());
DataCenter dc = _dcDao.findById(plan.getDataCenterId()); final DataCenter dc = _dcDao.findById(plan.getDataCenterId());
if (!canHandle(offering, dc.getNetworkType(), physnet)) { if (!canHandle(offering, dc.getNetworkType(), physnet)) {
s_logger.debug("Refusing to design this network"); s_logger.debug("Refusing to design this network");
return null; return null;
} }
List<NiciraNvpDeviceVO> devices = niciraNvpDao.listByPhysicalNetwork(physnet.getId()); final List<NiciraNvpDeviceVO> devices = niciraNvpDao.listByPhysicalNetwork(physnet.getId());
if (devices.isEmpty()) { if (devices.isEmpty()) {
s_logger.error("No NiciraNvp Controller on physical network " + physnet.getName()); s_logger.error("No NiciraNvp Controller on physical network " + physnet.getName());
return null; return null;
@ -131,11 +131,10 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru {
s_logger.debug("Nicira Nvp " + devices.get(0).getUuid() + " found on physical network " + physnet.getId()); s_logger.debug("Nicira Nvp " + devices.get(0).getUuid() + " found on physical network " + physnet.getId());
s_logger.debug("Physical isolation type is supported, asking GuestNetworkGuru to design this network"); s_logger.debug("Physical isolation type is supported, asking GuestNetworkGuru to design this network");
NetworkVO networkObject = (NetworkVO)super.design(offering, plan, userSpecified, owner); final NetworkVO networkObject = (NetworkVO) super.design(offering, plan, userSpecified, owner);
if (networkObject == null) { if (networkObject == null) {
return null; return null;
} }
// Override the broadcast domain type
networkObject.setBroadcastDomainType(BroadcastDomainType.Lswitch); networkObject.setBroadcastDomainType(BroadcastDomainType.Lswitch);
return networkObject; return networkObject;
@ -143,12 +142,11 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru {
@Override @Override
public Network implement(final Network network, final NetworkOffering offering, final DeployDestination dest, final ReservationContext context) public Network implement(final Network network, final NetworkOffering offering, final DeployDestination dest, final ReservationContext context)
throws InsufficientVirtualNetworkCapacityException { throws InsufficientVirtualNetworkCapacityException {
assert (network.getState() == State.Implementing) : "Why are we implementing " + network; assert network.getState() == State.Implementing : "Why are we implementing " + network;
long dcId = dest.getDataCenter().getId(); final long dcId = dest.getDataCenter().getId();
//get physical network id
Long physicalNetworkId = network.getPhysicalNetworkId(); Long physicalNetworkId = network.getPhysicalNetworkId();
// physical network id can be null in Guest Network in Basic zone, so locate the physical network // physical network id can be null in Guest Network in Basic zone, so locate the physical network
@ -156,9 +154,8 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru {
physicalNetworkId = networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType()); physicalNetworkId = networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType());
} }
NetworkVO implemented = final NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(),
new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated, State.Allocated, network.getDataCenterId(), physicalNetworkId, offering.getRedundantRouter());
network.getDataCenterId(), physicalNetworkId, offering.getRedundantRouter());
if (network.getGateway() != null) { if (network.getGateway() != null) {
implemented.setGateway(network.getGateway()); implemented.setGateway(network.getGateway());
@ -171,26 +168,26 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru {
// Name is either the given name or the uuid // Name is either the given name or the uuid
String name = network.getName(); String name = network.getName();
if (name == null || name.isEmpty()) { if (name == null || name.isEmpty()) {
name = ((NetworkVO)network).getUuid(); name = ((NetworkVO) network).getUuid();
} }
if (name.length() > MAX_NAME_LENGTH) { if (name.length() > MAX_NAME_LENGTH) {
name = name.substring(0, MAX_NAME_LENGTH - 1); // max length 40 name = name.substring(0, MAX_NAME_LENGTH - 1);
} }
List<NiciraNvpDeviceVO> devices = niciraNvpDao.listByPhysicalNetwork(physicalNetworkId); final List<NiciraNvpDeviceVO> devices = niciraNvpDao.listByPhysicalNetwork(physicalNetworkId);
if (devices.isEmpty()) { if (devices.isEmpty()) {
s_logger.error("No NiciraNvp Controller on physical network " + physicalNetworkId); s_logger.error("No NiciraNvp Controller on physical network " + physicalNetworkId);
return null; return null;
} }
NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); final NiciraNvpDeviceVO niciraNvpDevice = devices.get(0);
HostVO niciraNvpHost = hostDao.findById(niciraNvpDevice.getHostId()); final HostVO niciraNvpHost = hostDao.findById(niciraNvpDevice.getHostId());
hostDao.loadDetails(niciraNvpHost); hostDao.loadDetails(niciraNvpHost);
String transportzoneuuid = niciraNvpHost.getDetail("transportzoneuuid"); final String transportzoneuuid = niciraNvpHost.getDetail("transportzoneuuid");
String transportzoneisotype = niciraNvpHost.getDetail("transportzoneisotype"); final String transportzoneisotype = niciraNvpHost.getDetail("transportzoneisotype");
CreateLogicalSwitchCommand cmd = final CreateLogicalSwitchCommand cmd = new CreateLogicalSwitchCommand(transportzoneuuid, transportzoneisotype, name, context.getDomain().getName() + "-"
new CreateLogicalSwitchCommand(transportzoneuuid, transportzoneisotype, name, context.getDomain().getName() + "-" + context.getAccount().getAccountName()); + context.getAccount().getAccountName());
CreateLogicalSwitchAnswer answer = (CreateLogicalSwitchAnswer)agentMgr.easySend(niciraNvpHost.getId(), cmd); final CreateLogicalSwitchAnswer answer = (CreateLogicalSwitchAnswer) agentMgr.easySend(niciraNvpHost.getId(), cmd);
if (answer == null || !answer.getResult()) { if (answer == null || !answer.getResult()) {
s_logger.error("CreateLogicalSwitchCommand failed"); s_logger.error("CreateLogicalSwitchCommand failed");
@ -201,7 +198,7 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru {
implemented.setBroadcastUri(new URI("lswitch", answer.getLogicalSwitchUuid(), null)); implemented.setBroadcastUri(new URI("lswitch", answer.getLogicalSwitchUuid(), null));
implemented.setBroadcastDomainType(BroadcastDomainType.Lswitch); implemented.setBroadcastDomainType(BroadcastDomainType.Lswitch);
s_logger.info("Implemented OK, network linked to = " + implemented.getBroadcastUri().toString()); s_logger.info("Implemented OK, network linked to = " + implemented.getBroadcastUri().toString());
} catch (URISyntaxException e) { } catch (final URISyntaxException e) {
s_logger.error("Unable to store logical switch id in broadcast uri, uuid = " + implemented.getUuid(), e); s_logger.error("Unable to store logical switch id in broadcast uri, uuid = " + implemented.getUuid(), e);
return null; return null;
} }
@ -211,35 +208,33 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru {
@Override @Override
public void reserve(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context) public void reserve(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context)
throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException { throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
// TODO Auto-generated method stub
super.reserve(nic, network, vm, dest, context); super.reserve(nic, network, vm, dest, context);
} }
@Override @Override
public boolean release(final NicProfile nic, final VirtualMachineProfile vm, final String reservationId) { public boolean release(final NicProfile nic, final VirtualMachineProfile vm, final String reservationId) {
// TODO Auto-generated method stub
return super.release(nic, vm, reservationId); return super.release(nic, vm, reservationId);
} }
@Override @Override
public void shutdown(final NetworkProfile profile, final NetworkOffering offering) { public void shutdown(final NetworkProfile profile, final NetworkOffering offering) {
NetworkVO networkObject = networkDao.findById(profile.getId()); final NetworkVO networkObject = networkDao.findById(profile.getId());
if (networkObject.getBroadcastDomainType() != BroadcastDomainType.Lswitch || networkObject.getBroadcastUri() == null) { if (networkObject.getBroadcastDomainType() != BroadcastDomainType.Lswitch || networkObject.getBroadcastUri() == null) {
s_logger.warn("BroadcastUri is empty or incorrect for guestnetwork " + networkObject.getDisplayText()); s_logger.warn("BroadcastUri is empty or incorrect for guestnetwork " + networkObject.getDisplayText());
return; return;
} }
List<NiciraNvpDeviceVO> devices = niciraNvpDao.listByPhysicalNetwork(networkObject.getPhysicalNetworkId()); final List<NiciraNvpDeviceVO> devices = niciraNvpDao.listByPhysicalNetwork(networkObject.getPhysicalNetworkId());
if (devices.isEmpty()) { if (devices.isEmpty()) {
s_logger.error("No NiciraNvp Controller on physical network " + networkObject.getPhysicalNetworkId()); s_logger.error("No NiciraNvp Controller on physical network " + networkObject.getPhysicalNetworkId());
return; return;
} }
NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); final NiciraNvpDeviceVO niciraNvpDevice = devices.get(0);
HostVO niciraNvpHost = hostDao.findById(niciraNvpDevice.getHostId()); final HostVO niciraNvpHost = hostDao.findById(niciraNvpDevice.getHostId());
DeleteLogicalSwitchCommand cmd = new DeleteLogicalSwitchCommand(BroadcastDomainType.getValue(networkObject.getBroadcastUri())); final DeleteLogicalSwitchCommand cmd = new DeleteLogicalSwitchCommand(BroadcastDomainType.getValue(networkObject.getBroadcastUri()));
DeleteLogicalSwitchAnswer answer = (DeleteLogicalSwitchAnswer)agentMgr.easySend(niciraNvpHost.getId(), cmd); final DeleteLogicalSwitchAnswer answer = (DeleteLogicalSwitchAnswer) agentMgr.easySend(niciraNvpHost.getId(), cmd);
if (answer == null || !answer.getResult()) { if (answer == null || !answer.getResult()) {
s_logger.error("DeleteLogicalSwitchCommand failed"); s_logger.error("DeleteLogicalSwitchCommand failed");

View File

@ -0,0 +1,50 @@
//
// 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.nicira;
import java.util.concurrent.atomic.AtomicInteger;
public class ExecutionCounter {
private final int executionLimit;
private final AtomicInteger executionCount = new AtomicInteger(0);
public ExecutionCounter(final int executionLimit) {
this.executionLimit = executionLimit;
}
public ExecutionCounter resetExecutionCounter() {
executionCount.set(0);
return this;
}
public boolean hasReachedExecutionLimit() {
return executionCount.get() >= executionLimit;
}
public ExecutionCounter incrementExecutionCounter() {
executionCount.incrementAndGet();
return this;
}
public int getValue() {
return executionCount.get();
}
}

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.nicira;
import java.lang.reflect.Type;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
public class NatRuleAdapter implements JsonDeserializer<NatRule> {
@Override
public NatRule deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = jsonElement.getAsJsonObject();
if (!jsonObject.has("type")) {
throw new JsonParseException("Deserializing as a NatRule, but no type present in the json object");
}
final String natRuleType = jsonObject.get("type").getAsString();
if ("SourceNatRule".equals(natRuleType)) {
return context.deserialize(jsonElement, SourceNatRule.class);
} else if ("DestinationNatRule".equals(natRuleType)) {
return context.deserialize(jsonElement, DestinationNatRule.class);
}
throw new JsonParseException("Failed to deserialize type \"" + natRuleType + "\"");
}
}

View File

@ -0,0 +1,42 @@
//
// 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.nicira;
public class NiciraConstants {
public static final String SEC_PROFILE_URI_PREFIX = "/ws.v1/security-profile";
public static final String ACL_URI_PREFIX = "/ws.v1/acl";
public static final String SWITCH_URI_PREFIX = "/ws.v1/lswitch";
public static final String ROUTER_URI_PREFIX = "/ws.v1/lrouter";
public static final String LOGIN_URL = "/ws.v1/login";
public static final String CONTROL_CLUSTER_STATUS_URL = "/ws.v1/control-cluster/status";
public static final String ATTACHMENT_PATH_SEGMENT = "/attachment";
public static final String NAT_PATH_SEGMENT = "/nat";
public static final String LPORT_PATH_SEGMENT = "/lport";
public static final String ATTACHMENT_VIF_UUID_QUERY_PARAMETER_NAME = "attachment_vif_uuid";
public static final String ATTACHMENT_VLAN_PARAMETER = "attachment_vlan";
public static final String ATTACHMENT_GWSVC_UUID_QUERY_PARAMETER = "attachment_gwsvc_uuid";
public static final String WILDCARD_QUERY_PARAMETER = "*";
public static final String UUID_QUERY_PARAMETER = "uuid";
public static final String FIELDS_QUERY_PARAMETER = "fields";
}

View File

@ -0,0 +1,627 @@
//
// 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.nicira;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;
import com.cloud.utils.rest.CloudstackRESTException;
import com.cloud.utils.rest.RESTServiceConnector;
import com.google.common.base.Optional;
import com.google.gson.JsonDeserializer;
import com.google.gson.reflect.TypeToken;
@SuppressWarnings("rawtypes")
public class NiciraNvpApi {
private static final Optional<String> ABSENT = Optional.absent();
private static final String SWITCH_URI_PREFIX = NiciraConstants.SWITCH_URI_PREFIX;
private static final String ROUTER_URI_PREFIX = NiciraConstants.ROUTER_URI_PREFIX;
private static final String ATTACHMENT_PATH_SEGMENT = NiciraConstants.ATTACHMENT_PATH_SEGMENT;
private static final String NAT_PATH_SEGMENT = NiciraConstants.NAT_PATH_SEGMENT;
private static final String LPORT_PATH_SEGMENT = NiciraConstants.LPORT_PATH_SEGMENT;
private static final String ATTACHMENT_GWSVC_UUID_QUERY_PARAMETER = NiciraConstants.ATTACHMENT_GWSVC_UUID_QUERY_PARAMETER;
private static final String WILDCARD_QUERY_PARAMETER = NiciraConstants.WILDCARD_QUERY_PARAMETER;
private static final String UUID_QUERY_PARAMETER = NiciraConstants.UUID_QUERY_PARAMETER;
private static final String FIELDS_QUERY_PARAMETER = NiciraConstants.FIELDS_QUERY_PARAMETER;
private static final int DEFAULT_MAX_RETRIES = 5;
private final RESTServiceConnector restConnector;
protected final static Map<Class, String> prefixMap;
protected final static Map<Class, Type> listTypeMap;
protected final static Map<String, String> defaultListParams;
static {
prefixMap = new HashMap<Class, String>();
prefixMap.put(SecurityProfile.class, NiciraConstants.SEC_PROFILE_URI_PREFIX);
prefixMap.put(Acl.class, NiciraConstants.ACL_URI_PREFIX);
prefixMap.put(LogicalSwitch.class, SWITCH_URI_PREFIX);
prefixMap.put(LogicalRouter.class, ROUTER_URI_PREFIX);
listTypeMap = new HashMap<Class, Type>();
listTypeMap.put(SecurityProfile.class, new TypeToken<NiciraNvpList<SecurityProfile>>() {
}.getType());
listTypeMap.put(Acl.class, new TypeToken<NiciraNvpList<Acl>>() {
}.getType());
listTypeMap.put(LogicalSwitch.class, new TypeToken<NiciraNvpList<LogicalSwitch>>() {
}.getType());
listTypeMap.put(LogicalRouter.class, new TypeToken<NiciraNvpList<LogicalRouter>>() {
}.getType());
defaultListParams = new HashMap<String, String>();
defaultListParams.put(FIELDS_QUERY_PARAMETER, WILDCARD_QUERY_PARAMETER);
}
private NiciraNvpApi(final Builder builder) {
final Map<Class<?>, JsonDeserializer<?>> classToDeserializerMap = new HashMap<>();
classToDeserializerMap.put(NatRule.class, new NatRuleAdapter());
classToDeserializerMap.put(RoutingConfig.class, new RoutingConfigAdapter());
final NiciraRestClient niciraRestClient = NiciraRestClient.create()
.client(builder.httpClient)
.clientContext(builder.httpClientContext)
.hostname(builder.host)
.username(builder.username)
.password(builder.password)
.loginUrl(NiciraConstants.LOGIN_URL)
.executionLimit(DEFAULT_MAX_RETRIES)
.build();
restConnector = RESTServiceConnector.create()
.classToDeserializerMap(classToDeserializerMap)
.client(niciraRestClient)
.build();
}
public static Builder create() {
return new Builder();
}
/**
* POST
*
* @param entity
* @return
* @throws NiciraNvpApiException
*/
private <T> T create(final T entity) throws NiciraNvpApiException {
final String uri = prefixMap.get(entity.getClass());
return createWithUri(entity, uri);
}
/**
* POST
*
* @param entity
* @return
* @throws NiciraNvpApiException
*/
private <T> T createWithUri(final T entity, final String uri) throws NiciraNvpApiException {
T createdEntity;
try {
createdEntity = restConnector.executeCreateObject(entity, uri, Collections.<String, String> emptyMap());
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
return createdEntity;
}
/**
* GET list of items
*
* @param uuid
*
* @return
* @throws NiciraNvpApiException
*/
private <T> List<T> find(final Optional<String> uuid, final Class<T> clazz) throws NiciraNvpApiException {
final String uri = prefixMap.get(clazz);
Map<String, String> params = defaultListParams;
if (uuid.isPresent()) {
params = new HashMap<String, String>(defaultListParams);
params.put(UUID_QUERY_PARAMETER, uuid.get());
}
NiciraNvpList<T> entities;
try {
entities = restConnector.executeRetrieveObject(listTypeMap.get(clazz), uri, params);
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
if (entities == null) {
throw new NiciraNvpApiException("Unexpected response from API");
}
return entities.getResults();
}
/**
* PUT item given a UUID as key and an item object with the new data
*
* @param item
* @param uuid
* @throws NiciraNvpApiException
*/
private <T> void update(final T item, final String uuid) throws NiciraNvpApiException {
final String uri = prefixMap.get(item.getClass()) + "/" + uuid;
updateWithUri(item, uri);
}
/**
* PUT item given a UUID as key and an item object with the new data
*
* @param item
* @param uuid
* @throws NiciraNvpApiException
*/
private <T> void updateWithUri(final T item, final String uri) throws NiciraNvpApiException {
try {
restConnector.executeUpdateObject(item, uri, Collections.<String, String> emptyMap());
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
}
/**
* DELETE Security Profile given a UUID as key
*
* @param securityProfileUuid
* @throws NiciraNvpApiException
*/
private <T> void delete(final String uuid, final Class<T> clazz) throws NiciraNvpApiException {
final String uri = prefixMap.get(clazz) + "/" + uuid;
deleteWithUri(uri);
}
/**
* DELETE Security Profile given a UUID as key
*
* @param securityProfileUuid
* @throws NiciraNvpApiException
*/
private void deleteWithUri(final String uri) throws NiciraNvpApiException {
try {
restConnector.executeDeleteObject(uri);
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
}
/**
* POST {@link SecurityProfile}
*
* @param securityProfile
* @return
* @throws NiciraNvpApiException
*/
public SecurityProfile createSecurityProfile(final SecurityProfile securityProfile) throws NiciraNvpApiException {
return create(securityProfile);
}
/**
* GET list of {@link SecurityProfile}
*
* @return
* @throws NiciraNvpApiException
*/
public List<SecurityProfile> findSecurityProfile() throws NiciraNvpApiException {
return find(ABSENT, SecurityProfile.class);
}
/**
* GET list of {@link SecurityProfile} filtered by UUID
*
* We could have invoked the service: SEC_PROFILE_URI_PREFIX + "/" + securityProfileUuid but it is not working currently
*
* @param uuid
* @return
* @throws NiciraNvpApiException
*/
public List<SecurityProfile> findSecurityProfile(final String uuid) throws NiciraNvpApiException {
return find(Optional.fromNullable(uuid), SecurityProfile.class);
}
/**
* PUT {@link SecurityProfile} given a UUID as key and a {@link SecurityProfile} with the new data
*
* @param securityProfile
* @param securityProfileUuid
* @throws NiciraNvpApiException
*/
public void updateSecurityProfile(final SecurityProfile securityProfile, final String securityProfileUuid) throws NiciraNvpApiException {
update(securityProfile, securityProfileUuid);
}
/**
* DELETE Security Profile given a UUID as key
*
* @param securityProfileUuid
* @throws NiciraNvpApiException
*/
public void deleteSecurityProfile(final String securityProfileUuid) throws NiciraNvpApiException {
delete(securityProfileUuid, SecurityProfile.class);
}
/**
* POST {@link Acl}
*
* @param acl
* @return
* @throws NiciraNvpApiException
*/
public Acl createAcl(final Acl acl) throws NiciraNvpApiException {
return create(acl);
}
/**
* GET list of {@link Acl}
*
* @return
* @throws NiciraNvpApiException
*/
public List<Acl> findAcl() throws NiciraNvpApiException {
return findAcl(null);
}
/**
* GET list of {@link Acl} filtered by UUID
*
* @param uuid
* @return
* @throws NiciraNvpApiException
*/
public List<Acl> findAcl(final String uuid) throws NiciraNvpApiException {
return find(Optional.fromNullable(uuid), Acl.class);
}
/**
* PUT {@link Acl} given a UUID as key and a {@link Acl} with the new data
*
* @param acl
* @param aclUuid
* @throws NiciraNvpApiException
*/
public void updateAcl(final Acl acl, final String aclUuid) throws NiciraNvpApiException {
update(acl, aclUuid);
}
/**
* DELETE Acl given a UUID as key
*
* @param acl
* @throws NiciraNvpApiException
*/
public void deleteAcl(final String aclUuid) throws NiciraNvpApiException {
delete(aclUuid, Acl.class);
}
public LogicalSwitch createLogicalSwitch(final LogicalSwitch logicalSwitch) throws NiciraNvpApiException {
return create(logicalSwitch);
}
/**
* GET list of {@link LogicalSwitch}
*
* @return
* @throws NiciraNvpApiException
*/
public List<LogicalSwitch> findLogicalSwitch() throws NiciraNvpApiException {
return findLogicalSwitch(null);
}
/**
* GET list of {@link LogicalSwitch} filtered by UUID
*
* @param uuid
* @return
* @throws NiciraNvpApiException
*/
public List<LogicalSwitch> findLogicalSwitch(final String uuid) throws NiciraNvpApiException {
return find(Optional.fromNullable(uuid), LogicalSwitch.class);
}
/**
* PUT {@link LogicalSwitch} given a UUID as key and a {@link LogicalSwitch} with the new data
*
* @param logicalSwitch
* @param logicalSwitchUuid
* @throws NiciraNvpApiException
*/
public void updateLogicalSwitch(final LogicalSwitch logicalSwitch, final String logicalSwitchUuid) throws NiciraNvpApiException {
update(logicalSwitch, logicalSwitchUuid);
}
public void deleteLogicalSwitch(final String uuid) throws NiciraNvpApiException {
delete(uuid, LogicalSwitch.class);
}
public LogicalSwitchPort createLogicalSwitchPort(final String logicalSwitchUuid, final LogicalSwitchPort logicalSwitchPort) throws NiciraNvpApiException {
return createWithUri(logicalSwitchPort, buildLogicalSwitchElementUri(logicalSwitchUuid, LPORT_PATH_SEGMENT));
}
public void updateLogicalSwitchPort(final String logicalSwitchUuid, final LogicalSwitchPort logicalSwitchPort) throws NiciraNvpApiException {
updateWithUri(logicalSwitchPort, buildLogicalSwitchElementUri(logicalSwitchUuid, LPORT_PATH_SEGMENT, logicalSwitchPort.getUuid().toString()));
}
public void updateLogicalSwitchPortAttachment(final String logicalSwitchUuid, final String logicalSwitchPortUuid, final Attachment attachment) throws NiciraNvpApiException {
updateWithUri(attachment, buildLogicalSwitchElementUri(logicalSwitchUuid, LPORT_PATH_SEGMENT, logicalSwitchPortUuid) + ATTACHMENT_PATH_SEGMENT);
}
public void deleteLogicalSwitchPort(final String logicalSwitchUuid, final String logicalSwitchPortUuid) throws NiciraNvpApiException {
deleteWithUri(buildLogicalSwitchElementUri(logicalSwitchUuid, LPORT_PATH_SEGMENT, logicalSwitchPortUuid));
}
public String findLogicalSwitchPortUuidByVifAttachmentUuid(final String logicalSwitchUuid, final String vifAttachmentUuid) throws NiciraNvpApiException {
final String uri = buildLogicalSwitchElementUri(logicalSwitchUuid, LPORT_PATH_SEGMENT);
final Map<String, String> params = buildBasicParametersMap(UUID_QUERY_PARAMETER);
params.put(NiciraConstants.ATTACHMENT_VIF_UUID_QUERY_PARAMETER_NAME, vifAttachmentUuid);
NiciraNvpList<LogicalSwitchPort> niciraList;
try {
final Type niciraListType = new TypeToken<NiciraNvpList<LogicalSwitchPort>>() {
}.getType();
niciraList = restConnector.executeRetrieveObject(niciraListType, uri, params);
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
final List<LogicalSwitchPort> lspl = niciraList.getResults();
final int listSize = lspl.size();
if (listSize != 1) {
throw new NiciraNvpApiException("Expected 1 LogicalSwitchPort, but got " + listSize);
}
final LogicalSwitchPort lsp = lspl.get(0);
return lsp.getUuid();
}
public ControlClusterStatus getControlClusterStatus() throws NiciraNvpApiException {
final String uri = NiciraConstants.CONTROL_CLUSTER_STATUS_URL;
try {
return restConnector.executeRetrieveObject(ControlClusterStatus.class, uri, new HashMap<String, String>());
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
}
public List<LogicalSwitchPort> findLogicalSwitchPortsByUuid(final String logicalSwitchUuid, final String logicalSwitchPortUuid) throws NiciraNvpApiException {
final String uri = buildLogicalSwitchElementUri(logicalSwitchUuid, LPORT_PATH_SEGMENT);
final Map<String, String> params = buildBasicParametersMap(UUID_QUERY_PARAMETER);
params.put(UUID_QUERY_PARAMETER, logicalSwitchPortUuid);
try {
final Type niciraListType = new TypeToken<NiciraNvpList<LogicalSwitchPort>>() {
}.getType();
return restConnector.<NiciraNvpList<LogicalSwitchPort>> executeRetrieveObject(niciraListType, uri, params).getResults();
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
}
public List<LogicalRouterPort> findLogicalRouterPortsByUuid(final String logicalRouterUuid, final String logicalRouterPortUuid) throws NiciraNvpApiException {
final String uri = buildLogicalRouterElementUri(logicalRouterUuid, LPORT_PATH_SEGMENT);
final Map<String, String> params = buildBasicParametersMap(UUID_QUERY_PARAMETER);
params.put(UUID_QUERY_PARAMETER, logicalRouterPortUuid);
try {
final Type niciraListType = new TypeToken<NiciraNvpList<LogicalRouterPort>>() {
}.getType();
return restConnector.<NiciraNvpList<LogicalRouterPort>> executeRetrieveObject(niciraListType, uri, params).getResults();
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
}
public LogicalRouter createLogicalRouter(final LogicalRouter logicalRouter) throws NiciraNvpApiException {
return create(logicalRouter);
}
/**
* GET list of {@link LogicalRouter}
*
* @return
* @throws NiciraNvpApiException
*/
public List<LogicalRouter> findLogicalRouter() throws NiciraNvpApiException {
return findLogicalRouter(null);
}
/**
* GET list of {@link LogicalRouter} filtered by UUID
*
* @param uuid
* @return
* @throws NiciraNvpApiException
*/
public List<LogicalRouter> findLogicalRouter(final String uuid) throws NiciraNvpApiException {
return find(Optional.fromNullable(uuid), LogicalRouter.class);
}
public LogicalRouter findOneLogicalRouterByUuid(final String logicalRouterUuid) throws NiciraNvpApiException {
return findLogicalRouter(logicalRouterUuid).get(0);
}
public void updateLogicalRouter(final LogicalRouter logicalRouter, final String logicalRouterUuid) throws NiciraNvpApiException {
update(logicalRouter, logicalRouterUuid);
}
public void deleteLogicalRouter(final String logicalRouterUuid) throws NiciraNvpApiException {
deleteWithUri(buildLogicalRouterUri(logicalRouterUuid));
}
public LogicalRouterPort createLogicalRouterPort(final String logicalRouterUuid, final LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException {
return createWithUri(logicalRouterPort, buildLogicalRouterElementUri(logicalRouterUuid, LPORT_PATH_SEGMENT));
}
public void deleteLogicalRouterPort(final String logicalRouterUuid, final String logicalRouterPortUuid) throws NiciraNvpApiException {
deleteWithUri(buildLogicalRouterElementUri(logicalRouterUuid, LPORT_PATH_SEGMENT, logicalRouterPortUuid));
}
public void updateLogicalRouterPort(final String logicalRouterUuid, final LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException {
updateWithUri(logicalRouterPort, buildLogicalRouterElementUri(logicalRouterUuid, LPORT_PATH_SEGMENT, logicalRouterPort.getUuid().toString()));
}
public void updateLogicalRouterPortAttachment(final String logicalRouterUuid, final String logicalRouterPortUuid, final Attachment attachment) throws NiciraNvpApiException {
updateWithUri(attachment, buildLogicalRouterElementUri(logicalRouterUuid, LPORT_PATH_SEGMENT, logicalRouterPortUuid) + ATTACHMENT_PATH_SEGMENT);
}
public NatRule createLogicalRouterNatRule(final String logicalRouterUuid, final NatRule natRule) throws NiciraNvpApiException {
return createWithUri(natRule, buildLogicalRouterElementUri(logicalRouterUuid, NAT_PATH_SEGMENT));
}
public void updateLogicalRouterNatRule(final String logicalRouterUuid, final NatRule natRule) throws NiciraNvpApiException {
updateWithUri(natRule, buildLogicalRouterElementUri(logicalRouterUuid, NAT_PATH_SEGMENT, natRule.getUuid().toString()));
}
public void deleteLogicalRouterNatRule(final String logicalRouterUuid, final UUID natRuleUuid) throws NiciraNvpApiException {
deleteWithUri(buildLogicalRouterElementUri(logicalRouterUuid, NAT_PATH_SEGMENT, natRuleUuid.toString()));
}
public List<LogicalRouterPort> findLogicalRouterPortByGatewayServiceAndVlanId(final String logicalRouterUuid, final String gatewayServiceUuid, final long vlanId)
throws NiciraNvpApiException {
final String uri = buildLogicalRouterElementUri(logicalRouterUuid, LPORT_PATH_SEGMENT);
final Map<String, String> params = buildBasicParametersMap(WILDCARD_QUERY_PARAMETER);
params.put(ATTACHMENT_GWSVC_UUID_QUERY_PARAMETER, gatewayServiceUuid);
params.put(NiciraConstants.ATTACHMENT_VLAN_PARAMETER, Long.toString(vlanId));
try {
final Type niciraListType = new TypeToken<NiciraNvpList<LogicalRouterPort>>() {
}.getType();
return restConnector.<NiciraNvpList<LogicalRouterPort>> executeRetrieveObject(niciraListType, uri, params).getResults();
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
}
public List<NatRule> findNatRulesByLogicalRouterUuid(final String logicalRouterUuid) throws NiciraNvpApiException {
final String uri = buildLogicalRouterElementUri(logicalRouterUuid, NAT_PATH_SEGMENT);
final Map<String, String> params = buildBasicParametersMap(WILDCARD_QUERY_PARAMETER);
try {
final Type niciraListType = new TypeToken<NiciraNvpList<NatRule>>() {
}.getType();
return restConnector.<NiciraNvpList<NatRule>> executeRetrieveObject(niciraListType, uri, params).getResults();
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
}
public List<LogicalRouterPort> findLogicalRouterPortByGatewayServiceUuid(final String logicalRouterUuid, final String l3GatewayServiceUuid)
throws NiciraNvpApiException {
final String uri = buildLogicalRouterElementUri(logicalRouterUuid, LPORT_PATH_SEGMENT);
final Map<String, String> params = buildBasicParametersMap(WILDCARD_QUERY_PARAMETER);
params.put(ATTACHMENT_GWSVC_UUID_QUERY_PARAMETER, l3GatewayServiceUuid);
try {
final Type niciraListType = new TypeToken<NiciraNvpList<LogicalRouterPort>>() {
}.getType();
return restConnector.<NiciraNvpList<LogicalRouterPort>> executeRetrieveObject(niciraListType, uri, params).getResults();
} catch (final CloudstackRESTException e) {
throw new NiciraNvpApiException(e);
}
}
private static Map<String, String> buildBasicParametersMap(final String fieldsQueryValue) {
final Map<String, String> params = new HashMap<String, String>();
params.put(FIELDS_QUERY_PARAMETER, fieldsQueryValue);
return params;
}
private static String buildUri(final String uriPrefix, final String uuid) {
return uriPrefix + "/" + uuid;
}
private static String buildLogicalSwitchUri(final String logicalSwitchUuid) {
return buildUri(SWITCH_URI_PREFIX, logicalSwitchUuid);
}
private static String buildLogicalSwitchElementUri(final String logicalSwitchUuid, final String logicalElementType) {
return buildLogicalSwitchUri(logicalSwitchUuid) + logicalElementType;
}
private static String buildLogicalSwitchElementUri(final String logicalSwitchUuid, final String logicalElementType, final String elementUuid) {
return buildLogicalSwitchElementUri(logicalSwitchUuid, logicalElementType) + "/" + elementUuid.toString();
}
private static String buildLogicalRouterUri(final String logicalRouterUuid) {
return buildUri(ROUTER_URI_PREFIX, logicalRouterUuid);
}
private static String buildLogicalRouterElementUri(final String logicalRouterUuid, final String logicalElementType) {
return buildLogicalRouterUri(logicalRouterUuid) + logicalElementType;
}
private static String buildLogicalRouterElementUri(final String logicalRouterUuid, final String logicalRouterElementType, final String elementUuid) {
return buildLogicalRouterElementUri(logicalRouterUuid, logicalRouterElementType) + "/" + elementUuid.toString();
}
public static class Builder {
private String host;
private String username;
private String password;
private CloseableHttpClient httpClient;
private HttpClientContext httpClientContext = HttpClientContext.create();
public Builder host(final String host) {
this.host = host;
return this;
}
public Builder username(final String username) {
this.username = username;
return this;
}
public Builder password(final String password) {
this.password = password;
return this;
}
public Builder httpClient(final CloseableHttpClient httpClient) {
this.httpClient = httpClient;
return this;
}
public Builder httpClientContext(final HttpClientContext httpClientContext) {
this.httpClientContext = httpClientContext;
return this;
}
public NiciraNvpApi build() {
return new NiciraNvpApi(this);
}
}
}

View File

@ -0,0 +1,202 @@
//
// 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.nicira;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import com.cloud.utils.rest.BasicRestClient;
import com.cloud.utils.rest.CloudstackRESTException;
import com.cloud.utils.rest.HttpConstants;
import com.cloud.utils.rest.HttpMethods;
import com.cloud.utils.rest.HttpStatusCodeHelper;
import com.cloud.utils.rest.HttpUriRequestBuilder;
public class NiciraRestClient extends BasicRestClient {
private static final Logger s_logger = Logger.getLogger(NiciraRestClient.class);
private static final String CONTENT_TYPE = HttpConstants.CONTENT_TYPE;
private static final String TEXT_HTML_CONTENT_TYPE = HttpConstants.TEXT_HTML_CONTENT_TYPE;
private static final int DEFAULT_BODY_RESP_MAX_LEN = 1024;
private static final int DEFAULT_EXECUTION_LIMIT = 5;
private final ExecutionCounter counter;
private final int maxResponseErrorMesageLength;
private final int executionLimit;
private final String username;
private final String password;
private final String loginUrl;
private NiciraRestClient(final Builder builder) {
super(builder.client, builder.clientContext, builder.hostname);
executionLimit = builder.executionLimit;
counter = new ExecutionCounter(executionLimit);
maxResponseErrorMesageLength = builder.maxResponseErrorMesageLength;
username = builder.username;
password = builder.password;
loginUrl = builder.loginUrl;
}
public static Builder create() {
return new Builder();
}
@Override
public CloseableHttpResponse execute(final HttpUriRequest request) throws CloudstackRESTException {
return execute(request, 0);
}
private CloseableHttpResponse execute(final HttpUriRequest request, final int previousStatusCode) throws CloudstackRESTException {
if (counter.hasReachedExecutionLimit()) {
throw new CloudstackRESTException("Reached max executions limit of " + executionLimit);
}
counter.incrementExecutionCounter();
s_logger.debug("Executing " + request.getMethod() + " request [execution count = " + counter.getValue() + "]");
final CloseableHttpResponse response = super.execute(request);
final StatusLine statusLine = response.getStatusLine();
final int statusCode = statusLine.getStatusCode();
s_logger.debug("Status of last request: " + statusLine.toString());
if (HttpStatusCodeHelper.isUnauthorized(statusCode)) {
return handleUnauthorizedResponse(request, previousStatusCode, response, statusCode);
} else if (HttpStatusCodeHelper.isSuccess(statusCode)) {
return handleSuccessResponse(response);
} else {
throw new CloudstackRESTException("Unexpecetd status code: " + statusCode);
}
}
private CloseableHttpResponse handleUnauthorizedResponse(final HttpUriRequest request, final int previousStatusCode, final CloseableHttpResponse response, final int statusCode)
throws CloudstackRESTException {
super.closeResponse(response);
if (HttpStatusCodeHelper.isUnauthorized(previousStatusCode)) {
s_logger.error(responseToErrorMessage(response));
throw new CloudstackRESTException("Two consecutive failed attempts to authenticate against REST server");
}
final HttpUriRequest authenticateRequest = createAuthenticationRequest();
final CloseableHttpResponse loginResponse = execute(authenticateRequest, statusCode);
final int loginStatusCode = loginResponse.getStatusLine().getStatusCode();
super.closeResponse(loginResponse);
return execute(request, loginStatusCode);
}
private CloseableHttpResponse handleSuccessResponse(final CloseableHttpResponse response) {
counter.resetExecutionCounter();
return response;
}
private HttpUriRequest createAuthenticationRequest() {
final Map<String, String> parameters = new HashMap<>();
parameters.put("username", username);
parameters.put("password", password);
return HttpUriRequestBuilder.create()
.method(HttpMethods.POST)
.methodParameters(parameters)
.path(loginUrl)
.build();
}
private String responseToErrorMessage(final CloseableHttpResponse response) {
String errorMessage = response.getStatusLine().toString();
if (response.containsHeader(CONTENT_TYPE) && TEXT_HTML_CONTENT_TYPE.equals(response.getFirstHeader(CONTENT_TYPE).getValue())) {
try {
final HttpEntity entity = response.getEntity();
final String respobnseBody = EntityUtils.toString(entity);
errorMessage = respobnseBody.subSequence(0, maxResponseErrorMesageLength).toString();
} catch (final IOException e) {
s_logger.debug("Could not read repsonse body. Response: " + response, e);
}
}
return errorMessage;
}
protected static class Builder extends BasicRestClient.Builder<Builder> {
private CloseableHttpClient client;
private HttpClientContext clientContext;
private String hostname;
private String username;
private String password;
private String loginUrl;
private int executionLimit = DEFAULT_EXECUTION_LIMIT;
private int maxResponseErrorMesageLength = DEFAULT_BODY_RESP_MAX_LEN;
public Builder hostname(final String hostname) {
this.hostname = hostname;
return this;
}
public Builder username(final String username) {
this.username = username;
return this;
}
public Builder password(final String password) {
this.password = password;
return this;
}
public Builder loginUrl(final String loginUrl) {
this.loginUrl = loginUrl;
return this;
}
@Override
public Builder client(final CloseableHttpClient client) {
this.client = client;
return this;
}
@Override
public Builder clientContext(final HttpClientContext clientContext) {
this.clientContext = clientContext;
return this;
}
public Builder executionLimit(final int executionLimit) {
this.executionLimit = executionLimit;
return this;
}
public Builder maxResponseErrorMesageLength(final int maxResponseErrorMesageLength) {
this.maxResponseErrorMesageLength = maxResponseErrorMesageLength;
return this;
}
@Override
public NiciraRestClient build() {
return new NiciraRestClient(this);
}
}
}

View File

@ -0,0 +1,52 @@
//
// 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.nicira;
import java.lang.reflect.Type;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
public class RoutingConfigAdapter implements JsonDeserializer<RoutingConfig> {
private static final String ROUTING_TABLE_ROUTING_CONFIG = "RoutingTableRoutingConfig";
private static final String SINGLE_DEFAULT_ROUTE_IMPLICIT_ROUTING_CONFIG = "SingleDefaultRouteImplicitRoutingConfig";
@Override
public RoutingConfig deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = jsonElement.getAsJsonObject();
if (!jsonObject.has("type")) {
throw new JsonParseException("Deserializing as a RoutingConfig, but no type present in the json object");
}
final String routingConfigType = jsonObject.get("type").getAsString();
if (SINGLE_DEFAULT_ROUTE_IMPLICIT_ROUTING_CONFIG.equals(routingConfigType)) {
return context.deserialize(jsonElement, SingleDefaultRouteImplicitRoutingConfig.class);
} else if (ROUTING_TABLE_ROUTING_CONFIG.equals(routingConfigType)) {
return context.deserialize(jsonElement, RoutingTableRoutingConfig.class);
}
throw new JsonParseException("Failed to deserialize type \"" + routingConfigType + "\"");
}
}

View File

@ -19,6 +19,9 @@
package com.cloud.network.resource; package com.cloud.network.resource;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Map; import java.util.Map;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
@ -42,6 +45,8 @@ import com.cloud.network.nicira.NiciraNvpApiException;
import com.cloud.network.nicira.SourceNatRule; import com.cloud.network.nicira.SourceNatRule;
import com.cloud.network.utils.CommandRetryUtility; import com.cloud.network.utils.CommandRetryUtility;
import com.cloud.resource.ServerResource; import com.cloud.resource.ServerResource;
import com.cloud.utils.rest.CloudstackRESTException;
import com.cloud.utils.rest.HttpClientHelper;
public class NiciraNvpResource implements ServerResource { public class NiciraNvpResource implements ServerResource {
@ -49,6 +54,7 @@ public class NiciraNvpResource implements ServerResource {
public static final int NAME_MAX_LEN = 40; public static final int NAME_MAX_LEN = 40;
public static final int NUM_RETRIES = 2; public static final int NUM_RETRIES = 2;
private static final int MAX_REDIRECTS = 5;
private String name; private String name;
private String guid; private String guid;
@ -58,39 +64,47 @@ public class NiciraNvpResource implements ServerResource {
private NiciraNvpUtilities niciraNvpUtilities; private NiciraNvpUtilities niciraNvpUtilities;
private CommandRetryUtility retryUtility; private CommandRetryUtility retryUtility;
protected NiciraNvpApi createNiciraNvpApi() { protected NiciraNvpApi createNiciraNvpApi(final String host, final String username, final String password) throws CloudstackRESTException {
return new NiciraNvpApi(); try {
return NiciraNvpApi.create().host(host).username(username).password(password).httpClient(HttpClientHelper.createHttpClient(MAX_REDIRECTS)).build();
} catch (final KeyManagementException e) {
throw new CloudstackRESTException("Could not create HTTP client", e);
} catch (final NoSuchAlgorithmException e) {
throw new CloudstackRESTException("Could not create HTTP client", e);
} catch (final KeyStoreException e) {
throw new CloudstackRESTException("Could not create HTTP client", e);
}
} }
@Override @Override
public boolean configure(final String ignoredName, final Map<String, Object> params) throws ConfigurationException { public boolean configure(final String ignoredName, final Map<String, Object> params) throws ConfigurationException {
name = (String)params.get("name"); name = (String) params.get("name");
if (name == null) { if (name == null) {
throw new ConfigurationException("Unable to find name"); throw new ConfigurationException("Unable to find name");
} }
guid = (String)params.get("guid"); guid = (String) params.get("guid");
if (guid == null) { if (guid == null) {
throw new ConfigurationException("Unable to find the guid"); throw new ConfigurationException("Unable to find the guid");
} }
zoneId = (String)params.get("zoneId"); zoneId = (String) params.get("zoneId");
if (zoneId == null) { if (zoneId == null) {
throw new ConfigurationException("Unable to find zone"); throw new ConfigurationException("Unable to find zone");
} }
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");
} }
final String adminuser = (String)params.get("adminuser"); final String adminuser = (String) params.get("adminuser");
if (adminuser == null) { if (adminuser == null) {
throw new ConfigurationException("Unable to find admin username"); throw new ConfigurationException("Unable to find admin username");
} }
final String adminpass = (String)params.get("adminpass"); final String adminpass = (String) params.get("adminpass");
if (adminpass == null) { if (adminpass == null) {
throw new ConfigurationException("Unable to find admin password"); throw new ConfigurationException("Unable to find admin password");
} }
@ -99,9 +113,11 @@ public class NiciraNvpResource implements ServerResource {
retryUtility = CommandRetryUtility.getInstance(); retryUtility = CommandRetryUtility.getInstance();
retryUtility.setServerResource(this); retryUtility.setServerResource(this);
niciraNvpApi = createNiciraNvpApi(); try {
niciraNvpApi.setControllerAddress(ip); niciraNvpApi = createNiciraNvpApi(ip, adminuser, adminpass);
niciraNvpApi.setAdminCredentials(adminuser, adminpass); } catch (final CloudstackRESTException e) {
throw new ConfigurationException("Could not create a Nicira Nvp API client: " + e.getMessage());
}
return true; return true;
} }
@ -149,7 +165,7 @@ public class NiciraNvpResource implements ServerResource {
sc.setPrivateIpAddress(""); sc.setPrivateIpAddress("");
sc.setStorageIpAddress(""); sc.setStorageIpAddress("");
sc.setVersion(NiciraNvpResource.class.getPackage().getImplementationVersion()); sc.setVersion(NiciraNvpResource.class.getPackage().getImplementationVersion());
return new StartupCommand[] {sc}; return new StartupCommand[] { sc };
} }
@Override @Override
@ -212,16 +228,16 @@ public class NiciraNvpResource implements ServerResource {
natRuleStr.append(m.getDestinationPort()); natRuleStr.append(m.getDestinationPort());
natRuleStr.append(" ]) -->"); natRuleStr.append(" ]) -->");
if ("SourceNatRule".equals(rule.getType())) { if ("SourceNatRule".equals(rule.getType())) {
natRuleStr.append(((SourceNatRule)rule).getToSourceIpAddressMin()); natRuleStr.append(((SourceNatRule) rule).getToSourceIpAddressMin());
natRuleStr.append("-"); natRuleStr.append("-");
natRuleStr.append(((SourceNatRule)rule).getToSourceIpAddressMax()); natRuleStr.append(((SourceNatRule) rule).getToSourceIpAddressMax());
natRuleStr.append(" ["); natRuleStr.append(" [");
natRuleStr.append(((SourceNatRule)rule).getToSourcePort()); natRuleStr.append(((SourceNatRule) rule).getToSourcePort());
natRuleStr.append(" ])"); natRuleStr.append(" ])");
} else { } else {
natRuleStr.append(((DestinationNatRule)rule).getToDestinationIpAddress()); natRuleStr.append(((DestinationNatRule) rule).getToDestinationIpAddress());
natRuleStr.append(" ["); natRuleStr.append(" [");
natRuleStr.append(((DestinationNatRule)rule).getToDestinationPort()); natRuleStr.append(((DestinationNatRule) rule).getToDestinationPort());
natRuleStr.append(" ])"); natRuleStr.append(" ])");
} }
return natRuleStr.toString(); return natRuleStr.toString();
@ -247,25 +263,25 @@ public class NiciraNvpResource implements ServerResource {
Match m = new Match(); Match m = new Match();
m.setDestinationIpAddresses(outsideIp); m.setDestinationIpAddresses(outsideIp);
rulepair[0].setMatch(m); rulepair[0].setMatch(m);
((DestinationNatRule)rulepair[0]).setToDestinationIpAddress(insideIp); ((DestinationNatRule) rulepair[0]).setToDestinationIpAddress(insideIp);
// create matching snat rule // create matching snat rule
m = new Match(); m = new Match();
m.setSourceIpAddresses(insideIp); m.setSourceIpAddresses(insideIp);
rulepair[1].setMatch(m); rulepair[1].setMatch(m);
((SourceNatRule)rulepair[1]).setToSourceIpAddressMin(outsideIp); ((SourceNatRule) rulepair[1]).setToSourceIpAddressMin(outsideIp);
((SourceNatRule)rulepair[1]).setToSourceIpAddressMax(outsideIp); ((SourceNatRule) rulepair[1]).setToSourceIpAddressMax(outsideIp);
return rulepair; return rulepair;
} }
public NatRule[] generatePortForwardingRulePair(final String insideIp, final int[] insidePorts, final String outsideIp, final int[] outsidePorts, public NatRule[] generatePortForwardingRulePair(final String insideIp, final int[] insidePorts, final String outsideIp, final int[] outsidePorts,
final String protocol) { final String protocol) {
// Start with a basic static nat rule, then add port and protocol details // Start with a basic static nat rule, then add port and protocol details
final NatRule[] rulepair = generateStaticNatRulePair(insideIp, outsideIp); final NatRule[] rulepair = generateStaticNatRulePair(insideIp, outsideIp);
((DestinationNatRule)rulepair[0]).setToDestinationPort(insidePorts[0]); ((DestinationNatRule) rulepair[0]).setToDestinationPort(insidePorts[0]);
rulepair[0].getMatch().setDestinationPort(outsidePorts[0]); rulepair[0].getMatch().setDestinationPort(outsidePorts[0]);
rulepair[0].setOrder(50); rulepair[0].setOrder(50);
rulepair[0].getMatch().setEthertype("IPv4"); rulepair[0].getMatch().setEthertype("IPv4");
@ -275,7 +291,7 @@ public class NiciraNvpResource implements ServerResource {
rulepair[0].getMatch().setProtocol(17); rulepair[0].getMatch().setProtocol(17);
} }
((SourceNatRule)rulepair[1]).setToSourcePort(outsidePorts[0]); ((SourceNatRule) rulepair[1]).setToSourcePort(outsidePorts[0]);
rulepair[1].getMatch().setSourcePort(insidePorts[0]); rulepair[1].getMatch().setSourcePort(insidePorts[0]);
rulepair[1].setOrder(50); rulepair[1].setOrder(50);
rulepair[1].getMatch().setEthertype("IPv4"); rulepair[1].getMatch().setEthertype("IPv4");

View File

@ -21,6 +21,8 @@ package com.cloud.network.resource.wrapper;
import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES; import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES;
import java.util.List;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
@ -30,13 +32,12 @@ import com.cloud.agent.api.to.PortForwardingRuleTO;
import com.cloud.network.nicira.NatRule; import com.cloud.network.nicira.NatRule;
import com.cloud.network.nicira.NiciraNvpApi; 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.resource.NiciraNvpResource; import com.cloud.network.resource.NiciraNvpResource;
import com.cloud.network.utils.CommandRetryUtility; 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;
@ResourceWrapper(handles = ConfigurePortForwardingRulesOnLogicalRouterCommand.class) @ResourceWrapper(handles = ConfigurePortForwardingRulesOnLogicalRouterCommand.class)
public final class NiciraNvpConfigurePortForwardingRulesCommandWrapper extends CommandWrapper<ConfigurePortForwardingRulesOnLogicalRouterCommand, Answer, NiciraNvpResource> { public final class NiciraNvpConfigurePortForwardingRulesCommandWrapper extends CommandWrapper<ConfigurePortForwardingRulesOnLogicalRouterCommand, Answer, NiciraNvpResource> {
private static final Logger s_logger = Logger.getLogger(NiciraNvpConfigurePortForwardingRulesCommandWrapper.class); private static final Logger s_logger = Logger.getLogger(NiciraNvpConfigurePortForwardingRulesCommandWrapper.class);
@ -45,7 +46,7 @@ public final class NiciraNvpConfigurePortForwardingRulesCommandWrapper extends C
public Answer execute(final ConfigurePortForwardingRulesOnLogicalRouterCommand command, final NiciraNvpResource niciraNvpResource) { public Answer execute(final ConfigurePortForwardingRulesOnLogicalRouterCommand command, final NiciraNvpResource niciraNvpResource) {
final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi(); final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi();
try { try {
final NiciraNvpList<NatRule> existingRules = niciraNvpApi.findNatRulesByLogicalRouterUuid(command.getLogicalRouterUuid()); final List<NatRule> existingRules = niciraNvpApi.findNatRulesByLogicalRouterUuid(command.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)
// A SourceNat rule with a match other than a /32 cidr is assumed to be the "main" SourceNat rule // A SourceNat rule with a match other than a /32 cidr is assumed to be the "main" SourceNat rule
// Any other SourceNat rule should have a corresponding DestinationNat rule // Any other SourceNat rule should have a corresponding DestinationNat rule
@ -60,12 +61,13 @@ public final class NiciraNvpConfigurePortForwardingRulesCommandWrapper extends C
return new ConfigurePortForwardingRulesOnLogicalRouterAnswer(command, false, "Nicira NVP doesn't support port ranges for port forwarding"); return new ConfigurePortForwardingRulesOnLogicalRouterAnswer(command, false, "Nicira NVP doesn't support port ranges for port forwarding");
} }
final NatRule[] rulepair = niciraNvpResource.generatePortForwardingRulePair(rule.getDstIp(), rule.getDstPortRange(), rule.getSrcIp(), rule.getSrcPortRange(), rule.getProtocol()); final NatRule[] rulepair = niciraNvpResource.generatePortForwardingRulePair(rule.getDstIp(), rule.getDstPortRange(), rule.getSrcIp(), rule.getSrcPortRange(),
rule.getProtocol());
NatRule incoming = null; NatRule incoming = null;
NatRule outgoing = null; NatRule outgoing = null;
for (final NatRule storedRule : existingRules.getResults()) { for (final NatRule storedRule : existingRules) {
if (storedRule.equalsIgnoreUuid(rulepair[1])) { if (storedRule.equalsIgnoreUuid(rulepair[1])) {
// The outgoing rule exists // The outgoing rule exists
outgoing = storedRule; outgoing = storedRule;

View File

@ -21,19 +21,20 @@ package com.cloud.network.resource.wrapper;
import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES; import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES;
import java.util.List;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterAnswer; import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterAnswer;
import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterCommand; import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterCommand;
import com.cloud.network.nicira.LogicalRouterPort; import com.cloud.network.nicira.LogicalRouterPort;
import com.cloud.network.nicira.NiciraNvpApi; 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.resource.NiciraNvpResource; import com.cloud.network.resource.NiciraNvpResource;
import com.cloud.network.utils.CommandRetryUtility; 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;
@ResourceWrapper(handles = ConfigurePublicIpsOnLogicalRouterCommand.class) @ResourceWrapper(handles = ConfigurePublicIpsOnLogicalRouterCommand.class)
public final class NiciraNvpConfigurePublicIpsCommandWrapper extends CommandWrapper<ConfigurePublicIpsOnLogicalRouterCommand, Answer, NiciraNvpResource> { public final class NiciraNvpConfigurePublicIpsCommandWrapper extends CommandWrapper<ConfigurePublicIpsOnLogicalRouterCommand, Answer, NiciraNvpResource> {
@Override @Override
@ -41,16 +42,16 @@ public final class NiciraNvpConfigurePublicIpsCommandWrapper extends CommandWrap
final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi(); final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi();
try { try {
final NiciraNvpList<LogicalRouterPort> ports = niciraNvpApi.findLogicalRouterPortByGatewayServiceUuid(command.getLogicalRouterUuid(), command.getL3GatewayServiceUuid()); final List<LogicalRouterPort> ports = niciraNvpApi.findLogicalRouterPortByGatewayServiceUuid(command.getLogicalRouterUuid(), command.getL3GatewayServiceUuid());
if (ports.getResultCount() != 1) { if (ports.size() != 1) {
return new ConfigurePublicIpsOnLogicalRouterAnswer(command, false, "No logical router ports found, unable to set ip addresses"); return new ConfigurePublicIpsOnLogicalRouterAnswer(command, false, "No logical router ports found, unable to set ip addresses");
} }
final LogicalRouterPort lrp = ports.getResults().get(0); final LogicalRouterPort lrp = ports.get(0);
lrp.setIpAddresses(command.getPublicCidrs()); lrp.setIpAddresses(command.getPublicCidrs());
niciraNvpApi.updateLogicalRouterPort(command.getLogicalRouterUuid(), lrp); niciraNvpApi.updateLogicalRouterPort(command.getLogicalRouterUuid(), lrp);
return new ConfigurePublicIpsOnLogicalRouterAnswer(command, true, "Configured " + command.getPublicCidrs().size() + " ip addresses on logical router uuid " + return new ConfigurePublicIpsOnLogicalRouterAnswer(command, true, "Configured " + command.getPublicCidrs().size() + " ip addresses on logical router uuid " +
command.getLogicalRouterUuid()); command.getLogicalRouterUuid());
} catch (final NiciraNvpApiException e) { } catch (final NiciraNvpApiException e) {
final CommandRetryUtility retryUtility = niciraNvpResource.getRetryUtility(); final CommandRetryUtility retryUtility = niciraNvpResource.getRetryUtility();
retryUtility.addRetry(command, NUM_RETRIES); retryUtility.addRetry(command, NUM_RETRIES);

View File

@ -21,6 +21,8 @@ package com.cloud.network.resource.wrapper;
import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES; import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES;
import java.util.List;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
@ -30,13 +32,12 @@ import com.cloud.agent.api.to.StaticNatRuleTO;
import com.cloud.network.nicira.NatRule; import com.cloud.network.nicira.NatRule;
import com.cloud.network.nicira.NiciraNvpApi; 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.resource.NiciraNvpResource; import com.cloud.network.resource.NiciraNvpResource;
import com.cloud.network.utils.CommandRetryUtility; 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;
@ResourceWrapper(handles = ConfigureStaticNatRulesOnLogicalRouterCommand.class) @ResourceWrapper(handles = ConfigureStaticNatRulesOnLogicalRouterCommand.class)
public final class NiciraNvpConfigureStaticNatRulesCommandWrapper extends CommandWrapper<ConfigureStaticNatRulesOnLogicalRouterCommand, Answer, NiciraNvpResource> { public final class NiciraNvpConfigureStaticNatRulesCommandWrapper extends CommandWrapper<ConfigureStaticNatRulesOnLogicalRouterCommand, Answer, NiciraNvpResource> {
private static final Logger s_logger = Logger.getLogger(NiciraNvpConfigureStaticNatRulesCommandWrapper.class); private static final Logger s_logger = Logger.getLogger(NiciraNvpConfigureStaticNatRulesCommandWrapper.class);
@ -46,7 +47,7 @@ public final class NiciraNvpConfigureStaticNatRulesCommandWrapper extends Comman
final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi(); final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi();
try { try {
final NiciraNvpList<NatRule> existingRules = niciraNvpApi.findNatRulesByLogicalRouterUuid(command.getLogicalRouterUuid()); final List<NatRule> existingRules = niciraNvpApi.findNatRulesByLogicalRouterUuid(command.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)
// A SourceNat rule with a match other than a /32 cidr is assumed to be the "main" SourceNat rule // A SourceNat rule with a match other than a /32 cidr is assumed to be the "main" SourceNat rule
// Any other SourceNat rule should have a corresponding DestinationNat rule // Any other SourceNat rule should have a corresponding DestinationNat rule
@ -58,7 +59,7 @@ public final class NiciraNvpConfigureStaticNatRulesCommandWrapper extends Comman
NatRule incoming = null; NatRule incoming = null;
NatRule outgoing = null; NatRule outgoing = null;
for (final NatRule storedRule : existingRules.getResults()) { for (final NatRule storedRule : existingRules) {
if (storedRule.equalsIgnoreUuid(rulepair[1])) { if (storedRule.equalsIgnoreUuid(rulepair[1])) {
// The outgoing rule exists // The outgoing rule exists
outgoing = storedRule; outgoing = storedRule;

View File

@ -21,19 +21,20 @@ package com.cloud.network.resource.wrapper;
import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES; import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES;
import java.util.List;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
import com.cloud.agent.api.FindLogicalSwitchPortAnswer; import com.cloud.agent.api.FindLogicalSwitchPortAnswer;
import com.cloud.agent.api.FindLogicalSwitchPortCommand; import com.cloud.agent.api.FindLogicalSwitchPortCommand;
import com.cloud.network.nicira.LogicalSwitchPort; import com.cloud.network.nicira.LogicalSwitchPort;
import com.cloud.network.nicira.NiciraNvpApi; 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.resource.NiciraNvpResource; import com.cloud.network.resource.NiciraNvpResource;
import com.cloud.network.utils.CommandRetryUtility; 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;
@ResourceWrapper(handles = FindLogicalSwitchPortCommand.class) @ResourceWrapper(handles = FindLogicalSwitchPortCommand.class)
public final class NiciraNvpFindLogicalSwitchPortCommandWrapper extends CommandWrapper<FindLogicalSwitchPortCommand, Answer, NiciraNvpResource> { public final class NiciraNvpFindLogicalSwitchPortCommandWrapper extends CommandWrapper<FindLogicalSwitchPortCommand, Answer, NiciraNvpResource> {
@Override @Override
@ -44,8 +45,8 @@ public final class NiciraNvpFindLogicalSwitchPortCommandWrapper extends CommandW
final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi(); final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi();
try { try {
final NiciraNvpList<LogicalSwitchPort> ports = niciraNvpApi.findLogicalSwitchPortsByUuid(logicalSwitchUuid, logicalSwitchPortUuid); final List<LogicalSwitchPort> ports = niciraNvpApi.findLogicalSwitchPortsByUuid(logicalSwitchUuid, logicalSwitchPortUuid);
if (ports.getResultCount() == 0) { if (ports.size() == 0) {
return new FindLogicalSwitchPortAnswer(command, false, "Logical switchport " + logicalSwitchPortUuid + " not found", null); return new FindLogicalSwitchPortAnswer(command, false, "Logical switchport " + logicalSwitchPortUuid + " not found", null);
} else { } else {
return new FindLogicalSwitchPortAnswer(command, true, "Logical switchport " + logicalSwitchPortUuid + " found", logicalSwitchPortUuid); return new FindLogicalSwitchPortAnswer(command, true, "Logical switchport " + logicalSwitchPortUuid + " found", logicalSwitchPortUuid);

View File

@ -0,0 +1,55 @@
//
// 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.nicira;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import org.junit.Test;
public class ExecutionCounterTest {
@Test
public void testIncrementCounter() throws Exception {
final ExecutionCounter executionCounter = new ExecutionCounter(-1);
executionCounter.incrementExecutionCounter().incrementExecutionCounter();
assertThat(executionCounter.getValue(), equalTo(2));
}
@Test
public void testHasNotYetReachedTheExecutuionLimit() throws Exception {
final ExecutionCounter executionCounter = new ExecutionCounter(2);
executionCounter.incrementExecutionCounter();
assertThat(executionCounter.hasReachedExecutionLimit(), equalTo(false));
}
@Test
public void testHasAlreadyReachedTheExecutuionLimit() throws Exception {
final ExecutionCounter executionCounter = new ExecutionCounter(2);
executionCounter.incrementExecutionCounter().incrementExecutionCounter();
assertThat(executionCounter.hasReachedExecutionLimit(), equalTo(true));
}
}

View File

@ -0,0 +1,60 @@
//
// 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.nicira;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import org.junit.Test;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
public class NatRuleAdapterTest {
private final Gson gson = new GsonBuilder()
.registerTypeAdapter(NatRule.class, new NatRuleAdapter())
.create();
@Test(expected = JsonParseException.class)
public void testNatRuleAdapterNoType() {
gson.fromJson("{}", NatRule.class);
}
@Test(expected = JsonParseException.class)
public void testNatRuleAdapterWrongType() {
gson.fromJson("{type : \"WrongType\"}", NatRule.class);
}
@Test()
public void testNatRuleAdapterWithSourceNatRule() {
final SourceNatRule sourceNatRule = (SourceNatRule) gson.fromJson("{type : \"SourceNatRule\"}", NatRule.class);
assertThat(sourceNatRule, instanceOf(SourceNatRule.class));
}
@Test()
public void testNatRuleAdapterWithDestinationNatRule() {
final DestinationNatRule destinationNatRule = (DestinationNatRule) gson.fromJson("{type : \"DestinationNatRule\"}", NatRule.class);
assertThat(destinationNatRule, instanceOf(DestinationNatRule.class));
}
}

Some files were not shown because too many files have changed in this diff Show More