CORD-628 Refactored VTN service network and port API
- Removed direct use of Neutron data model and Neutron API
- Extended service network and service port API to have all network
information required for VTN
- Removed unnecessary dependency manager and store
- Removed network state sync method with Neutron and XOS
- Removed Neutron and XOS access information from the network config
- Re-organized API packages
Change-Id: I18f49ec733309315f683dfb2e6be6526056118f1
diff --git a/src/main/java/org/opencord/cordvtn/api/config/CordVtnConfig.java b/src/main/java/org/opencord/cordvtn/api/CordVtnConfig.java
similarity index 81%
rename from src/main/java/org/opencord/cordvtn/api/config/CordVtnConfig.java
rename to src/main/java/org/opencord/cordvtn/api/CordVtnConfig.java
index 7f5a102..aa90093 100644
--- a/src/main/java/org/opencord/cordvtn/api/config/CordVtnConfig.java
+++ b/src/main/java/org/opencord/cordvtn/api/CordVtnConfig.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.opencord.cordvtn.api.config;
+package org.opencord.cordvtn.api;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -31,8 +31,8 @@
import org.onosproject.net.behaviour.ControllerInfo;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.InvalidFieldException;
+import org.opencord.cordvtn.api.net.CidrAddr;
import org.opencord.cordvtn.api.node.CordVtnNode;
-import org.opencord.cordvtn.api.node.NetworkAddress;
import org.opencord.cordvtn.api.node.SshAccessInfo;
import org.slf4j.Logger;
@@ -74,12 +74,10 @@
private static final String SSH_USER = "sshUser";
private static final String SSH_KEY_FILE = "sshKeyFile";
+ @Deprecated
private static final String OPENSTACK = "openstack";
+ @Deprecated
private static final String XOS = "xos";
- private static final String ENDPOINT = "endpoint";
- private static final String TENANT = "tenant";
- private static final String USER = "user";
- private static final String PASSWORD = "password";
private static final String CONTROLLERS = "controllers";
private static final int INDEX_IP = 0;
@@ -108,23 +106,23 @@
}
// check all mandatory fields are present and valid
- result &= isMacAddress(PRIVATE_GATEWAY_MAC, MANDATORY);
- result &= isIpPrefix(LOCAL_MANAGEMENT_IP, MANDATORY);
+ result = result && isMacAddress(PRIVATE_GATEWAY_MAC, MANDATORY);
+ result = result && isIpPrefix(LOCAL_MANAGEMENT_IP, MANDATORY);
for (JsonNode node : object.get(CORDVTN_NODES)) {
ObjectNode vtnNode = (ObjectNode) node;
- result &= hasFields(
+ result = result && hasFields(
vtnNode,
HOSTNAME,
HOST_MANAGEMENT_IP,
DATA_IP,
DATA_IFACE,
INTEGRATION_BRIDGE_ID);
- result &= isIpPrefix(vtnNode, HOST_MANAGEMENT_IP, MANDATORY);
- result &= isIpPrefix(vtnNode, DATA_IP, MANDATORY);
+ result = result && isIpPrefix(vtnNode, HOST_MANAGEMENT_IP, MANDATORY);
+ result = result && isIpPrefix(vtnNode, DATA_IP, MANDATORY);
- NetworkAddress localMgmt = NetworkAddress.valueOf(get(LOCAL_MANAGEMENT_IP, ""));
- NetworkAddress hostsMgmt = NetworkAddress.valueOf(getConfig(vtnNode, HOST_MANAGEMENT_IP));
+ CidrAddr localMgmt = CidrAddr.valueOf(get(LOCAL_MANAGEMENT_IP, ""));
+ CidrAddr hostsMgmt = CidrAddr.valueOf(getConfig(vtnNode, HOST_MANAGEMENT_IP));
if (hostsMgmt.prefix().contains(localMgmt.prefix()) ||
localMgmt.prefix().contains(hostsMgmt.prefix())) {
final String msg = "Host and local management network IP conflict";
@@ -132,43 +130,30 @@
}
}
- result &= hasFields(
+ result = result && hasFields(
(ObjectNode) object.get(SSH),
SSH_PORT,
SSH_USER,
SSH_KEY_FILE);
- result &= isTpPort(
+ result = result && isTpPort(
(ObjectNode) object.get(SSH),
SSH_PORT,
MANDATORY);
- result &= hasFields(
- (ObjectNode) object.get(OPENSTACK),
- ENDPOINT,
- TENANT,
- USER,
- PASSWORD);
-
- result &= hasFields(
- (ObjectNode) object.get(XOS),
- ENDPOINT,
- USER,
- PASSWORD);
-
// check all optional fields are valid
- result &= isTpPort(OVSDB_PORT, OPTIONAL);
+ result = result && isTpPort(OVSDB_PORT, OPTIONAL);
if (object.get(PUBLIC_GATEWAYS) != null && object.get(PUBLIC_GATEWAYS).isArray()) {
for (JsonNode node : object.get(PUBLIC_GATEWAYS)) {
ObjectNode gateway = (ObjectNode) node;
- result &= isIpAddress(gateway, GATEWAY_IP, MANDATORY);
- result &= isMacAddress(gateway, GATEWAY_MAC, MANDATORY);
+ result = result && isIpAddress(gateway, GATEWAY_IP, MANDATORY);
+ result = result && isMacAddress(gateway, GATEWAY_MAC, MANDATORY);
}
}
if (object.get(CONTROLLERS) != null) {
for (JsonNode jsonNode : object.get(CONTROLLERS)) {
- result &= isController(jsonNode);
+ result = result && isController(jsonNode);
}
}
return result;
@@ -211,8 +196,8 @@
String ovsdbPort = getConfig(object, OVSDB_PORT);
object.get(CORDVTN_NODES).forEach(vtnNode -> {
- NetworkAddress localMgmt = NetworkAddress.valueOf(get(LOCAL_MANAGEMENT_IP, ""));
- NetworkAddress hostsMgmt = NetworkAddress.valueOf(getConfig(vtnNode, HOST_MANAGEMENT_IP));
+ CidrAddr localMgmt = CidrAddr.valueOf(get(LOCAL_MANAGEMENT_IP, ""));
+ CidrAddr hostsMgmt = CidrAddr.valueOf(getConfig(vtnNode, HOST_MANAGEMENT_IP));
SshAccessInfo sshInfo = new SshAccessInfo(
hostsMgmt.ip().getIp4Address(),
@@ -286,31 +271,6 @@
}
/**
- * Returns XOS API endpoint and credential configuration.
- *
- * @return xos api configuration
- */
- public XosConfig xosConfig() {
- JsonNode jsonNode = object.get(XOS);
- return new XosConfig(getConfig(jsonNode, ENDPOINT),
- getConfig(jsonNode, USER),
- getConfig(jsonNode, PASSWORD));
- }
-
- /**
- * Returns OpenStack API endpoint and credential configuration.
- *
- * @return openstack api configuration
- */
- public OpenStackConfig openStackConfig() {
- JsonNode jsonNode = object.get(OPENSTACK);
- return new OpenStackConfig(jsonNode.path(ENDPOINT).asText(),
- jsonNode.path(TENANT).asText(),
- jsonNode.path(USER).asText(),
- jsonNode.path(PASSWORD).asText());
- }
-
- /**
* Returns controllers for the integration bridge.
* It returns the information taken from cluster service with the default OF
* port if no controller is specified in the network config.
diff --git a/src/main/java/org/opencord/cordvtn/api/config/AbstractApiConfig.java b/src/main/java/org/opencord/cordvtn/api/config/AbstractApiConfig.java
deleted file mode 100644
index ffac44f..0000000
--- a/src/main/java/org/opencord/cordvtn/api/config/AbstractApiConfig.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.api.config;
-
-import com.google.common.base.MoreObjects;
-
-import java.util.Objects;
-
-/**
- * Representation of external API access configuration.
- */
-public abstract class AbstractApiConfig {
-
- protected final String endpoint;
- protected final String user;
- protected final String password;
-
- /**
- * Default constructor.
- *
- * @param endpoint api endpoint
- * @param user user name
- * @param password password of the user
- */
- protected AbstractApiConfig(String endpoint, String user, String password) {
- this.endpoint = endpoint;
- this.user = user;
- this.password = password;
- }
-
- /**
- * Returns the endpoint.
- *
- * @return endpoint
- */
- public String endpoint() {
- return endpoint;
- }
-
- /**
- * Returns the user.
- *
- * @return user
- */
- public String user() {
- return user;
- }
-
- /**
- * Returns the password.
- *
- * @return password
- */
- public String password() {
- return password;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(endpoint, user, password);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if ((obj instanceof AbstractApiConfig)) {
- AbstractApiConfig that = (AbstractApiConfig) obj;
- if (Objects.equals(endpoint, that.endpoint) &&
- Objects.equals(user, that.user) &&
- Objects.equals(password, that.password)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(getClass())
- .add("endpoint", endpoint)
- .add("user", user)
- .add("password", password)
- .toString();
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/api/config/OpenStackConfig.java b/src/main/java/org/opencord/cordvtn/api/config/OpenStackConfig.java
deleted file mode 100644
index 913b5e8..0000000
--- a/src/main/java/org/opencord/cordvtn/api/config/OpenStackConfig.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.api.config;
-
-import com.google.common.base.MoreObjects;
-
-import java.util.Objects;
-
-/**
- * Representation of OpenStack API access configuration.
- */
-public final class OpenStackConfig extends AbstractApiConfig {
-
- private final String tenant;
-
- /**
- * Default constructor.
- *
- * @param endpoint api endpoint
- * @param tenant tenant name
- * @param user user name
- * @param password password of the user
- */
- public OpenStackConfig(String endpoint, String tenant, String user,
- String password) {
- super(endpoint, user, password);
- this.tenant = tenant;
- }
-
- /**
- * Returns the tenant name.
- *
- * @return tenant name
- */
- public String tenant() {
- return tenant;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(endpoint, tenant, user, password);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if ((obj instanceof OpenStackConfig)) {
- OpenStackConfig that = (OpenStackConfig) obj;
- if (Objects.equals(endpoint, that.endpoint) &&
- Objects.equals(tenant, that.tenant) &&
- Objects.equals(user, that.user) &&
- Objects.equals(password, that.password)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(getClass())
- .add("endpoint", endpoint)
- .add("tenant", tenant)
- .add("user", user)
- .add("password", password)
- .toString();
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/api/config/XosConfig.java b/src/main/java/org/opencord/cordvtn/api/config/XosConfig.java
deleted file mode 100644
index b2387a6..0000000
--- a/src/main/java/org/opencord/cordvtn/api/config/XosConfig.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.api.config;
-
-/**
- * Representation of XOS API access configuration.
- */
-public final class XosConfig extends AbstractApiConfig {
-
- /**
- * Default constructor.
- *
- * @param endpoint api endpoint
- * @param user user name
- * @param password password of the user
- */
- public XosConfig(String endpoint, String user, String password) {
- super(endpoint, user, password);
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/api/config/package-info.java b/src/main/java/org/opencord/cordvtn/api/config/package-info.java
deleted file mode 100644
index b4fa066..0000000
--- a/src/main/java/org/opencord/cordvtn/api/config/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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.
- */
-
-/**
- * CORD VTN configuration API definitions.
- */
-package org.opencord.cordvtn.api.config;
\ No newline at end of file
diff --git a/src/main/java/org/opencord/cordvtn/api/core/CordVtnAdminService.java b/src/main/java/org/opencord/cordvtn/api/core/CordVtnAdminService.java
deleted file mode 100644
index 2411628..0000000
--- a/src/main/java/org/opencord/cordvtn/api/core/CordVtnAdminService.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.api.core;
-
-import org.opencord.cordvtn.api.net.NetworkId;
-import org.opencord.cordvtn.api.net.NetworkService;
-import org.opencord.cordvtn.api.net.PortId;
-import org.opencord.cordvtn.api.net.ServiceNetwork;
-import org.opencord.cordvtn.api.net.ServiceNetworkService;
-import org.opencord.cordvtn.api.net.ServicePort;
-import org.opencord.cordvtn.api.net.SubnetId;
-import org.openstack4j.model.network.Network;
-import org.openstack4j.model.network.Port;
-import org.openstack4j.model.network.Subnet;
-
-/**
- * Service for administering the inventory of {@link Network} and
- * {@link ServiceNetwork}.
- */
-public interface CordVtnAdminService extends CordVtnService, NetworkService,
- ServiceNetworkService {
-
- /**
- * Purges internal network states.
- */
- void purgeStates();
-
- /**
- * Synchronizes internal network states with external services.
- */
- void syncStates();
-
- /**
- * Creates a service port with the given information.
- *
- * @param servicePort the new service port
- */
- void createServicePort(ServicePort servicePort);
-
- /**
- * Updates a service port with the given information.
- *
- * @param servicePort the updated service port
- */
- void updateServicePort(ServicePort servicePort);
-
- /**
- * Removes a service port with the given port id.
- *
- * @param portId port id
- */
- void removeServicePort(PortId portId);
-
- /**
- * Creates a service network with the given information.
- *
- * @param serviceNet the new service network
- */
- void createServiceNetwork(ServiceNetwork serviceNet);
-
- /**
- * Updates a service network with the given information.
- *
- * @param serviceNet the updated service network
- */
- void updateServiceNetwork(ServiceNetwork serviceNet);
-
- /**
- * Removes a service network with the given network id.
- *
- * @param netId network id
- */
- void removeServiceNetwork(NetworkId netId);
-
- /**
- * Creates a port.
- *
- * @param port port
- */
- void createPort(Port port);
-
- /**
- * Updates the port.
- *
- * @param port the updated port
- */
- void updatePort(Port port);
-
- /**
- * Removes the port with the given port id.
- *
- * @param portId port id
- */
- void removePort(PortId portId);
-
- /**
- * Creates a network.
- *
- * @param network network
- */
- void createNetwork(Network network);
-
- /**
- * Updates the network.
- *
- * @param network the updated network
- */
- void updateNetwork(Network network);
-
- /**
- * Removes the network with the given network id.
- *
- * @param netId network id
- */
- void removeNetwork(NetworkId netId);
-
- /**
- * Creates a subnet.
- *
- * @param subnet subnet id
- */
- void createSubnet(Subnet subnet);
-
- /**
- * Updates the subnet.
- *
- * @param subnet the updated subnet
- */
- void updateSubnet(Subnet subnet);
-
- /**
- * Removes the subnet with the given subnet id.
- *
- * @param subnetId subnet id
- */
- void removeSubnet(SubnetId subnetId);
-}
diff --git a/src/main/java/org/opencord/cordvtn/api/core/CordVtnService.java b/src/main/java/org/opencord/cordvtn/api/core/CordVtnService.java
deleted file mode 100644
index 6f5e55e..0000000
--- a/src/main/java/org/opencord/cordvtn/api/core/CordVtnService.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.api.core;
-
-import org.onosproject.event.ListenerService;
-import org.opencord.cordvtn.api.net.NetworkId;
-import org.opencord.cordvtn.api.net.PortId;
-import org.opencord.cordvtn.api.net.VtnNetwork;
-import org.opencord.cordvtn.api.net.VtnNetworkEvent;
-import org.opencord.cordvtn.api.net.VtnNetworkListener;
-import org.opencord.cordvtn.api.net.VtnPort;
-
-import java.util.Set;
-
-/**
- * Service for interacting with the inventory of {@link VtnNetwork} and
- * {@link VtnPort}.
- */
-public interface CordVtnService
- extends ListenerService<VtnNetworkEvent, VtnNetworkListener> {
-
- /**
- * Returns the VTN port with the given port id.
- *
- * @param portId port id
- * @return service port
- */
- VtnPort vtnPort(PortId portId);
-
- /**
- * Returns the VTN port with the given port name.
- *
- * @param portName port name
- * @return vtn port
- */
- VtnPort vtnPort(String portName);
-
- /**
- * Returns all VTN ports.
- *
- * @return set of service ports
- */
- Set<VtnPort> vtnPorts();
-
- /**
- * Returns the VTN network with the given network id.
- *
- * @param netId network id
- * @return service network
- */
- VtnNetwork vtnNetwork(NetworkId netId);
-
- /**
- * Returns all VTN networks.
- *
- * @return set of service networks
- */
- Set<VtnNetwork> vtnNetworks();
-}
diff --git a/src/main/java/org/opencord/cordvtn/api/core/CordVtnStore.java b/src/main/java/org/opencord/cordvtn/api/core/CordVtnStore.java
deleted file mode 100644
index 78a60a4..0000000
--- a/src/main/java/org/opencord/cordvtn/api/core/CordVtnStore.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.api.core;
-
-import org.onosproject.store.Store;
-import org.opencord.cordvtn.api.net.NetworkId;
-import org.opencord.cordvtn.api.net.PortId;
-import org.opencord.cordvtn.api.net.SubnetId;
-import org.opencord.cordvtn.api.net.VtnNetwork;
-import org.opencord.cordvtn.api.net.VtnNetworkEvent;
-import org.opencord.cordvtn.api.net.VtnPort;
-import org.openstack4j.model.network.Network;
-import org.openstack4j.model.network.Port;
-import org.openstack4j.model.network.Subnet;
-
-import java.util.Set;
-
-/**
- * Manages inventory of virtual and vtn networks; not intended for direct use.
- */
-public interface CordVtnStore extends Store<VtnNetworkEvent, CordVtnStoreDelegate> {
-
- /**
- * Purges vtn store.
- */
- void clear();
-
- /**
- * Creates vtn network.
- *
- * @param vtnNet vtn network
- */
- void createVtnNetwork(VtnNetwork vtnNet);
-
- /**
- * Updates the vtn network.
- *
- * @param vtnNet vtn network
- */
- void updateVtnNetwork(VtnNetwork vtnNet);
-
- /**
- * Returns the vtn network with the given network id.
- *
- * @param netId network id
- * @return vtn network
- */
- VtnNetwork vtnNetwork(NetworkId netId);
-
- /**
- * Returns all vtn networks.
- *
- * @return set of vtn networks
- */
- Set<VtnNetwork> vtnNetworks();
-
- /**
- * Removes the vtn network with the given network id.
- *
- * @param netId network id
- */
- void removeVtnNetwork(NetworkId netId);
-
- /**
- * Creates vtn port.
- *
- * @param vtnPort the new vtn port
- */
- void createVtnPort(VtnPort vtnPort);
-
- /**
- * Updates the vtn port.
- *
- * @param vtnPort vtn port
- */
- void updateVtnPort(VtnPort vtnPort);
-
- /**
- * Returns the vtn port with the given port id.
- *
- * @param portId port id
- * @return vtn port
- */
- VtnPort vtnPort(PortId portId);
-
- /**
- * Returns all vtn ports.
- *
- * @return set of vtn ports
- */
- Set<VtnPort> vtnPorts();
-
- /**
- * Removes vtn port.
- *
- * @param portId port id
- */
- void removeVtnPort(PortId portId);
-
- /**
- * Creates a network.
- *
- * @param net network
- */
- void createNetwork(Network net);
-
- /**
- * Updates the network.
- *
- * @param net the updated network
- */
- void updateNetwork(Network net);
-
- /**
- * Returns the network with the given network id.
- *
- * @param netId network id
- * @return network
- */
- Network network(NetworkId netId);
-
- /**
- * Returns all networks.
- *
- * @return set of networks
- */
- Set<Network> networks();
-
- /**
- * Removes the network with the given network id.
- *
- * @param netId network id
- */
- void removeNetwork(NetworkId netId);
-
- /**
- * Creates a port.
- *
- * @param port port
- */
- void createPort(Port port);
-
- /**
- * Updates the port.
- *
- * @param port the updated port
- */
- void updatePort(Port port);
-
- /**
- * Returns the port with the given port id.
- *
- * @param portId port id
- * @return port
- */
- Port port(PortId portId);
-
- /**
- * Returns all ports.
- *
- * @return set of ports
- */
- Set<Port> ports();
-
- /**
- * Removes the port with the given port id.
- *
- * @param portId port id
- */
- void removePort(PortId portId);
-
- /**
- * Creates a subnet.
- *
- * @param subnet subnet id
- */
- void createSubnet(Subnet subnet);
-
- /**
- * Updates the subnet.
- *
- * @param subnet the updated subnet
- */
- void updateSubnet(Subnet subnet);
-
- /**
- * Returns the subnet with the given subnet id.
- *
- * @param subnetId subnet id
- * @return subnet
- */
- Subnet subnet(SubnetId subnetId);
-
- /**
- * Returns all subnets.
- *
- * @return set of subnets
- */
- Set<Subnet> subnets();
-
- /**
- * Removes the subnet with the given subnet id.
- *
- * @param subnetId subnet id
- */
- void removeSubnet(SubnetId subnetId);
-}
diff --git a/src/main/java/org/opencord/cordvtn/api/instance/Instance.java b/src/main/java/org/opencord/cordvtn/api/core/Instance.java
similarity index 95%
rename from src/main/java/org/opencord/cordvtn/api/instance/Instance.java
rename to src/main/java/org/opencord/cordvtn/api/core/Instance.java
index 79e478f..24c81b5 100644
--- a/src/main/java/org/opencord/cordvtn/api/instance/Instance.java
+++ b/src/main/java/org/opencord/cordvtn/api/core/Instance.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.opencord.cordvtn.api.instance;
+package org.opencord.cordvtn.api.core;
import com.google.common.base.Strings;
import org.onlab.packet.Ip4Address;
@@ -23,7 +23,7 @@
import org.onosproject.net.PortNumber;
import org.opencord.cordvtn.api.net.NetworkId;
import org.opencord.cordvtn.api.net.PortId;
-import org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType;
+import org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -91,9 +91,9 @@
*
* @return network type
*/
- public ServiceNetworkType netType() {
+ public NetworkType netType() {
String netType = host.annotations().value(NETWORK_TYPE);
- return ServiceNetworkType.valueOf(netType);
+ return NetworkType.valueOf(netType);
}
/**
diff --git a/src/main/java/org/opencord/cordvtn/api/instance/InstanceHandler.java b/src/main/java/org/opencord/cordvtn/api/core/InstanceHandler.java
similarity index 96%
rename from src/main/java/org/opencord/cordvtn/api/instance/InstanceHandler.java
rename to src/main/java/org/opencord/cordvtn/api/core/InstanceHandler.java
index 6e1cdc9..bc06992 100644
--- a/src/main/java/org/opencord/cordvtn/api/instance/InstanceHandler.java
+++ b/src/main/java/org/opencord/cordvtn/api/core/InstanceHandler.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.opencord.cordvtn.api.instance;
+package org.opencord.cordvtn.api.core;
/**
* Handles service instance detection and removal.
diff --git a/src/main/java/org/opencord/cordvtn/api/instance/InstanceService.java b/src/main/java/org/opencord/cordvtn/api/core/InstanceService.java
similarity index 96%
rename from src/main/java/org/opencord/cordvtn/api/instance/InstanceService.java
rename to src/main/java/org/opencord/cordvtn/api/core/InstanceService.java
index 4d3ccca..c8eb5ef 100644
--- a/src/main/java/org/opencord/cordvtn/api/instance/InstanceService.java
+++ b/src/main/java/org/opencord/cordvtn/api/core/InstanceService.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.opencord.cordvtn.api.instance;
+package org.opencord.cordvtn.api.core;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.HostId;
@@ -24,6 +24,8 @@
*/
public interface InstanceService {
+ // TODO add get instance
+
/**
* Adds a service instance on a given connect point. Or updates if the
* instance already exists.
diff --git a/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkAdminService.java b/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkAdminService.java
new file mode 100644
index 0000000..55edc53
--- /dev/null
+++ b/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkAdminService.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed 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 org.opencord.cordvtn.api.core;
+
+import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.PortId;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
+import org.opencord.cordvtn.api.net.ServicePort;
+
+/**
+ * Service for administering the inventory of {@link ServiceNetwork}.
+ */
+public interface ServiceNetworkAdminService extends ServiceNetworkService {
+
+ /**
+ * Purges internal network states.
+ */
+ void purgeStates();
+
+ /**
+ * Creates a service network with the given information.
+ *
+ * @param serviceNetwork the new service network
+ */
+ void createServiceNetwork(ServiceNetwork serviceNetwork);
+
+ /**
+ * Updates a service network with the given information.
+ *
+ * @param serviceNetwork the updated service network
+ */
+ void updateServiceNetwork(ServiceNetwork serviceNetwork);
+
+ /**
+ * Removes a service network with the given network id.
+ *
+ * @param networkId network id
+ */
+ void removeServiceNetwork(NetworkId networkId);
+
+ /**
+ * Creates a service port with the given information.
+ *
+ * @param servicePort the new service port
+ */
+ void createServicePort(ServicePort servicePort);
+
+ /**
+ * Updates a service port with the given information.
+ *
+ * @param servicePort the updated service port
+ */
+ void updateServicePort(ServicePort servicePort);
+
+ /**
+ * Removes a service port with the given port id.
+ *
+ * @param portId port id
+ */
+ void removeServicePort(PortId portId);
+}
diff --git a/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkEvent.java b/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkEvent.java
new file mode 100644
index 0000000..5392ba0
--- /dev/null
+++ b/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkEvent.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed 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 org.opencord.cordvtn.api.core;
+
+import org.joda.time.LocalDateTime;
+import org.onosproject.event.AbstractEvent;
+import org.opencord.cordvtn.api.net.Provider;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
+import org.opencord.cordvtn.api.net.ServicePort;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Describes service network event.
+ */
+public class ServiceNetworkEvent extends AbstractEvent<ServiceNetworkEvent.Type, ServiceNetwork> {
+
+ private final ServicePort servicePort;
+ private final Provider provider;
+
+ /**
+ * Type of service network event.
+ */
+ public enum Type {
+ /**
+ * Signifies that a new service network has been created.
+ */
+ SERVICE_NETWORK_CREATED,
+
+ /**
+ * Signifies that some service network attributes have changed.
+ */
+ SERVICE_NETWORK_UPDATED,
+
+ /**
+ * Signifies that provider network was added.
+ */
+ SERVICE_NETWORK_PROVIDER_ADDED,
+
+ /**
+ * Signifies that provider network was removed.
+ */
+ SERVICE_NETWORK_PROVIDER_REMOVED,
+
+ /**
+ * Signifies that a service network has been removed.
+ */
+ SERVICE_NETWORK_REMOVED,
+
+ /**
+ * Signifies that a new service port has been created.
+ */
+ SERVICE_PORT_CREATED,
+
+ /**
+ * Signifies that some service port attributes have changed.
+ */
+ SERVICE_PORT_UPDATED,
+
+ /**
+ * Signifies that a service port has been removed.
+ */
+ SERVICE_PORT_REMOVED
+ }
+
+ /**
+ * Creates an event of a given type and for the specified service network and
+ * the current time.
+ *
+ * @param type service network event type
+ * @param serviceNetwork service network subject
+ */
+ public ServiceNetworkEvent(Type type, ServiceNetwork serviceNetwork) {
+ super(type, serviceNetwork);
+ this.servicePort = null;
+ this.provider = null;
+ }
+
+ /**
+ * Creates an event of a given type and for the specified service network,
+ * port and the current time.
+ *
+ * @param type service network event type
+ * @param serviceNetwork service network subject
+ * @param servicePort optional service port subject
+ */
+ public ServiceNetworkEvent(Type type, ServiceNetwork serviceNetwork, ServicePort servicePort) {
+ super(type, serviceNetwork);
+ this.servicePort = servicePort;
+ this.provider = null;
+ }
+
+ /**
+ * Creates an event of a given type and for the specified service network,
+ * provider, dependency type with the provider, and the current time.
+ *
+ * @param type service network event type
+ * @param serviceNetwork service network subject
+ * @param provider optional provider network
+ */
+ public ServiceNetworkEvent(Type type, ServiceNetwork serviceNetwork, Provider provider) {
+ super(type, serviceNetwork);
+ this.servicePort = null;
+ this.provider = provider;
+ }
+
+ /**
+ * Returns the service port subject.
+ * It returns valid value only with the service port events.
+ *
+ * @return service port; null if the event is not service port specific
+ */
+ public ServicePort servicePort() {
+ return servicePort;
+ }
+
+ /**
+ * Returns the provider of the service network.
+ *
+ * @return provider network; null if the event is not provider specific
+ */
+ public Provider provider() {
+ return provider;
+ }
+
+ @Override
+ public String toString() {
+ if (servicePort == null) {
+ return super.toString();
+ }
+ return toStringHelper(this)
+ .add("time", new LocalDateTime(time()))
+ .add("type", type())
+ .add("serviceNetwork", subject())
+ .add("servicePort", servicePort)
+ .add("provider", provider)
+ .toString();
+ }
+}
diff --git a/src/main/java/org/opencord/cordvtn/api/net/VtnNetworkListener.java b/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkListener.java
similarity index 80%
rename from src/main/java/org/opencord/cordvtn/api/net/VtnNetworkListener.java
rename to src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkListener.java
index 62cf834..dc8782c 100644
--- a/src/main/java/org/opencord/cordvtn/api/net/VtnNetworkListener.java
+++ b/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkListener.java
@@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.opencord.cordvtn.api.net;
+package org.opencord.cordvtn.api.core;
import org.onosproject.event.EventListener;
/**
- * Listener for vtn network event.
+ * Listener for service network event.
*/
-public interface VtnNetworkListener extends EventListener<VtnNetworkEvent> {
+public interface ServiceNetworkListener extends EventListener<ServiceNetworkEvent> {
}
diff --git a/src/main/java/org/opencord/cordvtn/api/net/ServiceNetworkService.java b/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkService.java
similarity index 66%
rename from src/main/java/org/opencord/cordvtn/api/net/ServiceNetworkService.java
rename to src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkService.java
index 173f723..4217df0 100644
--- a/src/main/java/org/opencord/cordvtn/api/net/ServiceNetworkService.java
+++ b/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkService.java
@@ -13,7 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.opencord.cordvtn.api.net;
+package org.opencord.cordvtn.api.core;
+
+import org.onosproject.event.ListenerService;
+import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.PortId;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
+import org.opencord.cordvtn.api.net.ServicePort;
import java.util.Set;
@@ -21,15 +27,16 @@
* Service for interacting with the inventory of {@link ServiceNetwork} and
* {@link ServicePort}.
*/
-public interface ServiceNetworkService {
+public interface ServiceNetworkService
+ extends ListenerService<ServiceNetworkEvent, ServiceNetworkListener> {
/**
* Returns the service network with the supplied network ID.
*
- * @param netId network id
+ * @param networkId network id
* @return service network
*/
- ServiceNetwork serviceNetwork(NetworkId netId);
+ ServiceNetwork serviceNetwork(NetworkId networkId);
/**
* Returns all service networks registered in the service.
@@ -52,4 +59,11 @@
* @return set of service ports
*/
Set<ServicePort> servicePorts();
+
+ /**
+ * Returns all service ports associated with the supplied network.
+ * @param networkId network id
+ * @return set of service ports
+ */
+ Set<ServicePort> servicePorts(NetworkId networkId);
}
diff --git a/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkStore.java b/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkStore.java
new file mode 100644
index 0000000..536a9c5
--- /dev/null
+++ b/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkStore.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed 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 org.opencord.cordvtn.api.core;
+
+import org.onosproject.store.Store;
+import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.PortId;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
+import org.opencord.cordvtn.api.net.ServicePort;
+
+import java.util.Set;
+
+/**
+ * Manages inventory of service networks; not intended for direct use.
+ */
+public interface ServiceNetworkStore extends Store<ServiceNetworkEvent, ServiceNetworkStoreDelegate> {
+
+ /**
+ * Purges the service network store.
+ */
+ void clear();
+
+ /**
+ * Creates new service network.
+ *
+ * @param serviceNetwork service network
+ */
+ void createServiceNetwork(ServiceNetwork serviceNetwork);
+
+ /**
+ * Updates the service network.
+ *
+ * @param serviceNetwork service network
+ */
+ void updateServiceNetwork(ServiceNetwork serviceNetwork);
+
+ /**
+ * Returns the service network with the given network id.
+ *
+ * @param networkId network id
+ * @return service network
+ */
+ ServiceNetwork serviceNetwork(NetworkId networkId);
+
+ /**
+ * Returns all service networks.
+ *
+ * @return set of service networks
+ */
+ Set<ServiceNetwork> serviceNetworks();
+
+ /**
+ * Removes the service network with the given network id.
+ *
+ * @param networkId network id
+ * @return service network removed; null if failed
+ */
+ ServiceNetwork removeServiceNetwork(NetworkId networkId);
+
+ /**
+ * Creates service port.
+ *
+ * @param servicePort the new service port
+ */
+ void createServicePort(ServicePort servicePort);
+
+ /**
+ * Updates the service port.
+ *
+ * @param servicePort service port
+ */
+ void updateServicePort(ServicePort servicePort);
+
+ /**
+ * Returns the service port with the given port id.
+ *
+ * @param portId port id
+ * @return service port
+ */
+ ServicePort servicePort(PortId portId);
+
+ /**
+ * Returns all service ports.
+ *
+ * @return set of service ports
+ */
+ Set<ServicePort> servicePorts();
+
+ /**
+ * Removes service port.
+ *
+ * @param portId port id
+ */
+ ServicePort removeServicePort(PortId portId);
+}
diff --git a/src/main/java/org/opencord/cordvtn/api/core/CordVtnStoreDelegate.java b/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkStoreDelegate.java
similarity index 84%
rename from src/main/java/org/opencord/cordvtn/api/core/CordVtnStoreDelegate.java
rename to src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkStoreDelegate.java
index d5d7b91..c1ff606 100644
--- a/src/main/java/org/opencord/cordvtn/api/core/CordVtnStoreDelegate.java
+++ b/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkStoreDelegate.java
@@ -16,10 +16,9 @@
package org.opencord.cordvtn.api.core;
import org.onosproject.store.StoreDelegate;
-import org.opencord.cordvtn.api.net.VtnNetworkEvent;
/**
* VTN store delegate abstraction.
*/
-public interface CordVtnStoreDelegate extends StoreDelegate<VtnNetworkEvent> {
+public interface ServiceNetworkStoreDelegate extends StoreDelegate<ServiceNetworkEvent> {
}
diff --git a/src/main/java/org/opencord/cordvtn/api/dependency/Dependency.java b/src/main/java/org/opencord/cordvtn/api/dependency/Dependency.java
deleted file mode 100644
index 775fb16..0000000
--- a/src/main/java/org/opencord/cordvtn/api/dependency/Dependency.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.api.dependency;
-
-import com.google.common.base.MoreObjects;
-import org.opencord.cordvtn.api.net.VtnNetwork;
-
-import java.util.Objects;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Representation of a dependency between two networks, subscriber and provider.
- */
-public final class Dependency {
-
- public enum Type {
- BIDIRECTIONAL,
- UNIDIRECTIONAL
- }
-
- private final VtnNetwork subscriber;
- private final VtnNetwork provider;
- private final Type type;
-
- private Dependency(VtnNetwork subscriber, VtnNetwork provider, Type type) {
- this.subscriber = subscriber;
- this.provider = provider;
- this.type = type;
- }
-
- /**
- * Returns subscriber network.
- *
- * @return vtn network
- */
- public VtnNetwork subscriber() {
- return subscriber;
- }
-
- /**
- * Returns provider network.
- *
- * @return vtn network
- */
- public VtnNetwork provider() {
- return provider;
- }
-
- /**
- * Returns direct access type between subscriber and provider networks.
- *
- * @return type
- */
- public Type type() {
- return type;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (obj instanceof Dependency) {
- Dependency that = (Dependency) obj;
- if (Objects.equals(subscriber, that.subscriber) &&
- Objects.equals(provider, that.provider) &&
- Objects.equals(type, that.type)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(subscriber, provider, type);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(getClass())
- .add("subscriber", subscriber.id())
- .add("provider", provider.id())
- .add("type", type)
- .toString();
- }
-
- /**
- * Returns new dependency builder instance.
- *
- * @return dependency
- */
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * Builder of the dependency entities.
- */
- public static final class Builder {
- private VtnNetwork subscriber;
- private VtnNetwork provider;
- private Type type;
-
- private Builder() {
- }
-
- /**
- * Builds an immutable dependency.
- *
- * @return dependency instance
- */
- public Dependency build() {
- checkNotNull(subscriber);
- checkNotNull(provider);
- checkNotNull(type);
-
- return new Dependency(subscriber, provider, type);
- }
-
- /**
- * Returns dependency with the supplied subscriber.
- *
- * @param subscriber subscriber network
- * @return dependency builder
- */
- public Builder subscriber(VtnNetwork subscriber) {
- this.subscriber = subscriber;
- return this;
- }
-
- /**
- * Returns dependency with the supplied provider.
- *
- * @param provider provider network
- * @return dependency builder
- */
- public Builder provider(VtnNetwork provider) {
- this.provider = provider;
- return this;
- }
-
- /**
- * Returns dependency with the supplied type.
- *
- * @param type type
- * @return dependency builder
- */
- public Builder type(Type type) {
- this.type = type;
- return this;
- }
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/api/dependency/DependencyService.java b/src/main/java/org/opencord/cordvtn/api/dependency/DependencyService.java
deleted file mode 100644
index 3323d66..0000000
--- a/src/main/java/org/opencord/cordvtn/api/dependency/DependencyService.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.api.dependency;
-
-import org.opencord.cordvtn.api.dependency.Dependency.Type;
-import org.opencord.cordvtn.api.net.NetworkId;
-
-/**
- * Provides dependency services.
- */
-public interface DependencyService {
-
- /**
- * Creates dependencies for a given tenant service.
- *
- * @param subscriber subscriber network id
- * @param provider provider network id
- * @param type bidirectional access type
- */
- void createDependency(NetworkId subscriber, NetworkId provider, Type type);
-
- /**
- * Removes all dependencies from a given tenant service.
- *
- * @param subscriber subscriber network id
- * @param provider provider network id
- */
- void removeDependency(NetworkId subscriber, NetworkId provider);
-}
diff --git a/src/main/java/org/opencord/cordvtn/api/dependency/package-info.java b/src/main/java/org/opencord/cordvtn/api/dependency/package-info.java
deleted file mode 100644
index 7e6589f..0000000
--- a/src/main/java/org/opencord/cordvtn/api/dependency/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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.
- */
-
-/**
- * CORD VTN service dependency API definitions.
- */
-package org.opencord.cordvtn.api.dependency;
\ No newline at end of file
diff --git a/src/main/java/org/opencord/cordvtn/api/instance/package-info.java b/src/main/java/org/opencord/cordvtn/api/instance/package-info.java
deleted file mode 100644
index bdb3900..0000000
--- a/src/main/java/org/opencord/cordvtn/api/instance/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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.
- */
-
-/**
- * CORD VTN service instance API definitions.
- */
-package org.opencord.cordvtn.api.instance;
\ No newline at end of file
diff --git a/src/main/java/org/opencord/cordvtn/api/node/NetworkAddress.java b/src/main/java/org/opencord/cordvtn/api/net/CidrAddr.java
similarity index 84%
rename from src/main/java/org/opencord/cordvtn/api/node/NetworkAddress.java
rename to src/main/java/org/opencord/cordvtn/api/net/CidrAddr.java
index 93bcb7a..5cd1d7e 100644
--- a/src/main/java/org/opencord/cordvtn/api/node/NetworkAddress.java
+++ b/src/main/java/org/opencord/cordvtn/api/net/CidrAddr.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.opencord.cordvtn.api.node;
+package org.opencord.cordvtn.api.net;
import com.google.common.base.MoreObjects;
import org.onlab.packet.IpAddress;
@@ -24,19 +24,19 @@
import static com.google.common.base.Preconditions.checkArgument;
/**
- * Representation of a network address, which consists of IP address and prefix.
+ * Representation of a network address with CIDR notation.
*/
-public final class NetworkAddress {
+public final class CidrAddr {
private final IpAddress ip;
private final IpPrefix prefix;
/**
* Constructor for a given IP address and prefix.
*
- * @param ip ip address
+ * @param ip ip address
* @param prefix ip prefix
*/
- public NetworkAddress(IpAddress ip, IpPrefix prefix) {
+ public CidrAddr(IpAddress ip, IpPrefix prefix) {
this.ip = ip;
this.prefix = prefix;
}
@@ -48,13 +48,13 @@
* @return network address
* @throws IllegalArgumentException if the cidr is not valid
*/
- public static NetworkAddress valueOf(String cidr) {
+ public static CidrAddr valueOf(String cidr) {
checkArgument(cidr.contains("/"));
IpAddress ipAddress = IpAddress.valueOf(cidr.split("/")[0]);
IpPrefix ipPrefix = IpPrefix.valueOf(cidr);
- return new NetworkAddress(ipAddress, ipPrefix);
+ return new CidrAddr(ipAddress, ipPrefix);
}
/**
@@ -90,8 +90,8 @@
return true;
}
- if (obj instanceof NetworkAddress) {
- NetworkAddress that = (NetworkAddress) obj;
+ if (obj instanceof CidrAddr) {
+ CidrAddr that = (CidrAddr) obj;
if (Objects.equals(ip, that.ip) && Objects.equals(prefix, that.prefix)) {
return true;
}
diff --git a/src/main/java/org/opencord/cordvtn/api/net/NetworkService.java b/src/main/java/org/opencord/cordvtn/api/net/NetworkService.java
deleted file mode 100644
index ac505e2..0000000
--- a/src/main/java/org/opencord/cordvtn/api/net/NetworkService.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.api.net;
-
-import org.openstack4j.model.network.Network;
-import org.openstack4j.model.network.Port;
-import org.openstack4j.model.network.Subnet;
-
-import java.util.Set;
-
-/**
- * Service for interacting with the inventory of {@link Network}, {@link Port},
- * and {@link Subnet}.
- */
-public interface NetworkService {
-
- /**
- * Returns the network with the supplied network ID.
- *
- * @param netId network id
- * @return network
- */
- Network network(NetworkId netId);
-
- /**
- * Returns all networks registered in the service.
- *
- * @return set of networks
- */
- Set<Network> networks();
-
- /**
- * Returns the port with the supplied port ID.
- *
- * @param portId port id
- * @return port
- */
- Port port(PortId portId);
-
- /**
- * Returns all ports registered in the service.
- *
- * @return set of ports
- */
- Set<Port> ports();
-
- /**
- * Returns the subnet with the supplied subnet ID.
- *
- * @param subnetId subnet id
- * @return subnet
- */
- Subnet subnet(SubnetId subnetId);
-
- /**
- * Returns all subnets registered in the service.
- *
- * @return set of subnets
- */
- Set<Subnet> subnets();
-}
diff --git a/src/main/java/org/opencord/cordvtn/api/net/Provider.java b/src/main/java/org/opencord/cordvtn/api/net/Provider.java
new file mode 100644
index 0000000..e093137
--- /dev/null
+++ b/src/main/java/org/opencord/cordvtn/api/net/Provider.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed 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 org.opencord.cordvtn.api.net;
+
+import com.google.common.base.MoreObjects;
+import org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Representation of a provider network.
+ */
+public final class Provider {
+
+ private final ServiceNetwork provider;
+ private final DependencyType type;
+
+ private Provider(ServiceNetwork provider, DependencyType type) {
+ this.provider = provider;
+ this.type = type;
+ }
+
+ /**
+ * Returns provider network.
+ *
+ * @return service network
+ */
+ public ServiceNetwork provider() {
+ return provider;
+ }
+
+ /**
+ * Returns direct access type between subscriber and provider networks.
+ *
+ * @return type
+ */
+ public DependencyType type() {
+ return type;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof Provider) {
+ Provider that = (Provider) obj;
+ if (Objects.equals(provider, that.provider) &&
+ Objects.equals(type, that.type)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(provider, type);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("provider", provider.id())
+ .add("type", type)
+ .toString();
+ }
+
+ /**
+ * Returns new provider network builder instance.
+ *
+ * @return provider network
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder of the provider network entities.
+ */
+ public static final class Builder {
+ private ServiceNetwork provider;
+ private DependencyType type;
+
+ private Builder() {
+ }
+
+ /**
+ * Builds an immutable provider network.
+ *
+ * @return provider network instance
+ */
+ public Provider build() {
+ checkNotNull(provider);
+ checkNotNull(type);
+
+ return new Provider(provider, type);
+ }
+
+ /**
+ * Returns provider network with the supplied provider.
+ *
+ * @param provider provider network
+ * @return provider network builder
+ */
+ public Builder provider(ServiceNetwork provider) {
+ this.provider = provider;
+ return this;
+ }
+
+ /**
+ * Returns provider network with the supplied type.
+ *
+ * @param type type
+ * @return provider network builder
+ */
+ public Builder type(DependencyType type) {
+ this.type = type;
+ return this;
+ }
+ }
+}
diff --git a/src/main/java/org/opencord/cordvtn/api/net/ProviderNetwork.java b/src/main/java/org/opencord/cordvtn/api/net/ProviderNetwork.java
deleted file mode 100644
index 37fce8c..0000000
--- a/src/main/java/org/opencord/cordvtn/api/net/ProviderNetwork.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.api.net;
-
-import com.google.common.base.MoreObjects;
-import org.opencord.cordvtn.api.dependency.Dependency.Type;
-
-import java.util.Objects;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Representation of a provider network.
- */
-public final class ProviderNetwork {
-
- private final NetworkId id;
- private final Type type;
-
- private ProviderNetwork(NetworkId id, Type type) {
- this.id = id;
- this.type = type;
- }
-
- /**
- * Returns network id.
- *
- * @return network id
- */
- public NetworkId id() {
- return id;
- }
-
- /**
- * Returns the direct access type with this provider network.
- *
- * @return direct access type
- */
- public Type type() {
- return type;
- }
-
- /**
- * Returns immutable provider network with the supplied network id and type.
- *
- * @param id network id
- * @param type direct access type
- * @return provider network
- */
- public static ProviderNetwork of(NetworkId id, Type type) {
- checkNotNull(id);
- checkNotNull(type);
- return new ProviderNetwork(id, type);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (obj instanceof ProviderNetwork) {
- ProviderNetwork that = (ProviderNetwork) obj;
- if (Objects.equals(id, that.id) &&
- Objects.equals(type, that.type)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(id, type);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(getClass())
- .add("id", id)
- .add("type", type)
- .toString();
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/api/net/ServiceNetwork.java b/src/main/java/org/opencord/cordvtn/api/net/ServiceNetwork.java
index 6b26daf..849a6ea 100644
--- a/src/main/java/org/opencord/cordvtn/api/net/ServiceNetwork.java
+++ b/src/main/java/org/opencord/cordvtn/api/net/ServiceNetwork.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-present Open Networking Laboratory
+ * Copyright 2017-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,25 +15,19 @@
*/
package org.opencord.cordvtn.api.net;
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
-import java.util.Objects;
-import java.util.Set;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.opencord.cordvtn.api.dependency.Dependency.Type.BIDIRECTIONAL;
+import java.util.Comparator;
+import java.util.Map;
/**
* Representation of a service network which holds service specific information,
* like service type or dependency, in addition to the common network.
*/
-public class ServiceNetwork {
+public interface ServiceNetwork {
- private static final String ERR_ID = "Service network ID cannot be null";
- private static final String ERR_TYPE = "Service network type cannot be null";
-
- public enum ServiceNetworkType {
+ enum NetworkType {
PRIVATE,
PUBLIC,
MANAGEMENT_HOST,
@@ -42,97 +36,129 @@
ACCESS_AGENT
}
- protected final NetworkId id;
- protected final ServiceNetworkType type;
- protected final Set<ProviderNetwork> providers;
-
- public ServiceNetwork(NetworkId id,
- ServiceNetworkType type,
- Set<ProviderNetwork> providers) {
- this.id = checkNotNull(id, ERR_ID);
- this.type = checkNotNull(type, ERR_TYPE);
- this.providers = providers == null ? ImmutableSet.of() : providers;
+ enum DependencyType {
+ BIDIRECTIONAL,
+ UNIDIRECTIONAL
}
+ Comparator<ServiceNetwork> SERVICE_NETWORK_COMPARATOR =
+ (net1, net2) -> net1.id().id().compareTo(net2.id().id());
+
/**
- * Returns the network id of the service network.
+ * Returns the service network identifier.
*
- * @return network id
+ * @return service network identifier
*/
- public NetworkId id() {
- return id;
- }
+ NetworkId id();
+
+ /**
+ * Returns the service network name.
+ *
+ * @return service network name.
+ */
+ String name();
/**
* Returns the type of the service network.
*
- * @return service network type
+ * @return service network type; empty value if type is not set
*/
- public ServiceNetworkType type() {
- return type;
- }
+ NetworkType type();
/**
- * Returns the provider networks of this service network if exists.
+ * Returns the service network segmentation identifier.
*
- * @return provider networks
+ * @return segmentation id; empty value if segment id is not set
*/
- public Set<ProviderNetwork> providers() {
- return providers;
- }
+ SegmentId segmentId();
/**
- * Returns if the given network is the provider of this network or not.
+ * Returns the subnet of the service network.
*
- * @param netId network id
- * @return true if the given network is the provider of this network
+ * @return subnet ip prefix; empty value if subnet is not set
*/
- public boolean isProvider(NetworkId netId) {
- return providers.stream().filter(p -> Objects.equals(p.id(), netId))
- .findAny().isPresent();
- }
+ IpPrefix subnet();
/**
- * Returns if the given network is the provider of this network with
- * bidirectional access type.
+ * Returns the service IP address of the service network.
*
- * @param netId network id
- * @return true if the given network is a bidrectional provider
+ * @return service ip; empty value if service ip is not set
*/
- public boolean isBidirectionalProvider(NetworkId netId) {
- return providers.stream().filter(p -> Objects.equals(p.id(), netId))
- .filter(p -> p.type() == BIDIRECTIONAL)
- .findAny().isPresent();
- }
+ IpAddress serviceIp();
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
+ /**
+ * Returns the providers of the service network.
+ *
+ * @return set of provider networks; empty map if no providers exist
+ */
+ Map<NetworkId, DependencyType> providers();
- if (obj instanceof ServiceNetwork) {
- ServiceNetwork that = (ServiceNetwork) obj;
- if (Objects.equals(id, that.id) &&
- Objects.equals(type, that.type) &&
- Objects.equals(providers, that.providers)) {
- return true;
- }
- }
- return false;
- }
+ /**
+ * Builder of new service network entities.
+ */
+ interface Builder {
- @Override
- public int hashCode() {
- return Objects.hash(id, type, providers);
- }
+ /**
+ * Builds an immutable service network instance.
+ *
+ * @return service network instance
+ */
+ ServiceNetwork build();
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(getClass())
- .add("networkId", id)
- .add("type", type)
- .add("providers", providers)
- .toString();
+ /**
+ * Returns service network builder with the supplied identifier.
+ *
+ * @param networkId network id
+ * @return service network builder
+ */
+ Builder id(NetworkId networkId);
+
+ /**
+ * Returns service network builder with the supplied name.
+ *
+ * @param name network name
+ * @return service network builder
+ */
+ Builder name(String name);
+
+ /**
+ * Returns service network builder with the supplied type.
+ *
+ * @param type service network type
+ * @return service network builder
+ */
+ Builder type(NetworkType type);
+
+ /**
+ * Returns service network builder with the supplied segmentation id.
+ *
+ * @param segmentId segmentation id
+ * @return service network builder
+ */
+ Builder segmentId(SegmentId segmentId);
+
+ /**
+ * Returns service network builder with the supplied subnet.
+ *
+ * @param subnet subnet
+ * @return service network builder
+ */
+ Builder subnet(IpPrefix subnet);
+
+ /**
+ * Returns service network builder with the supplied service IP address.
+ *
+ * @param serviceIp service ip address
+ * @return service network builder
+ */
+ Builder serviceIp(IpAddress serviceIp);
+
+ /**
+ * Returns service network builder with the supplied providers.
+ *
+ * @param providers set of provider network
+ * @return service network builder
+ */
+ Builder providers(Map<NetworkId, DependencyType> providers);
}
}
diff --git a/src/main/java/org/opencord/cordvtn/api/net/ServicePort.java b/src/main/java/org/opencord/cordvtn/api/net/ServicePort.java
index 99a79ff..83117ee 100644
--- a/src/main/java/org/opencord/cordvtn/api/net/ServicePort.java
+++ b/src/main/java/org/opencord/cordvtn/api/net/ServicePort.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-present Open Networking Laboratory
+ * Copyright 2017-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,91 +15,137 @@
*/
package org.opencord.cordvtn.api.net;
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
-import java.util.Objects;
-import java.util.Optional;
+import java.util.Comparator;
import java.util.Set;
-import static com.google.common.base.Preconditions.checkNotNull;
-
/**
* Representation of a service port which holds service specific port information,
* like vlan tag or additional addresses, to the common network port.
*/
-public class ServicePort {
+public interface ServicePort {
- private static final String ERR_ID = "Service port ID cannot be null";
-
- protected final PortId id;
- protected final VlanId vlanId;
- protected final Set<AddressPair> addressPairs;
-
- public ServicePort(PortId id,
- VlanId vlanId,
- Set<AddressPair> addressPairs) {
- this.id = checkNotNull(id, ERR_ID);
- this.vlanId = vlanId;
- this.addressPairs = addressPairs == null ? ImmutableSet.of() : addressPairs;
- }
+ Comparator<ServicePort> SERVICE_PORT_COMPARATOR =
+ (port1, port2) -> port1.networkId().id().compareTo(port2.networkId().id());
/**
- * Returns the port id of the service port.
+ * Returns the port identifier.
*
* @return port id
*/
- public PortId id() {
- return id;
- }
+ PortId id();
/**
- * Returns the vlan id of the the service port if exists.
+ * Returns the port name.
+ *
+ * @return port name
+ */
+ String name();
+
+ /**
+ * Returns associated network identifier of the service port.
+ *
+ * @return network id
+ */
+ NetworkId networkId();
+
+ /**
+ * Returns the MAC address of the service port.
+ *
+ * @return mac address
+ */
+ MacAddress mac();
+
+ /**
+ * Returns the fixed IP address of the service port.
+ *
+ * @return ip address
+ */
+ IpAddress ip();
+
+ /**
+ * Returns VLAN of service the port.
*
* @return vlan id
*/
- public Optional<VlanId> vlanId() {
- return Optional.ofNullable(vlanId);
- }
+ VlanId vlanId();
/**
- * Returns the additional address pairs used in this port.
+ * Returns additional floating address pairs of the service port.
*
- * @return set of ip and mac address pairs
+ * @return set of mac and ip address pair
*/
- public Set<AddressPair> addressPairs() {
- return addressPairs;
- }
+ Set<AddressPair> addressPairs();
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
+ /**
+ * Builder of new service port entities.
+ */
+ interface Builder {
- if (obj instanceof ServicePort) {
- ServicePort that = (ServicePort) obj;
- if (Objects.equals(id, that.id) &&
- Objects.equals(vlanId, that.vlanId) &&
- Objects.equals(addressPairs, that.addressPairs)) {
- return true;
- }
- }
- return false;
- }
+ /**
+ * Builds an immutable service port instance.
+ *
+ * @return service port
+ */
+ ServicePort build();
- @Override
- public int hashCode() {
- return Objects.hash(id, vlanId, addressPairs);
- }
+ /**
+ * Returns service port builder with the supplied identifier.
+ *
+ * @param id port id
+ * @return service port builder
+ */
+ Builder id(PortId id);
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(getClass())
- .add("portId", id)
- .add("vlanId", vlanId)
- .add("addressPairs", addressPairs)
- .toString();
+ /**
+ * Returns service port builder with the supplied name.
+ *
+ * @param name port name
+ * @return service port builder
+ */
+ Builder name(String name);
+
+ /**
+ * Returns service port builder with the supplied network identifier.
+ *
+ * @param networkId network id
+ * @return service port builder
+ */
+ Builder networkId(NetworkId networkId);
+
+ /**
+ * Returns service port builder with the supplied MAC address.
+ *
+ * @param mac mac address
+ * @return service port builder
+ */
+ Builder mac(MacAddress mac);
+
+ /**
+ * Returns service port builder with the supplied IP address.
+ *
+ * @param ip ip address
+ * @return service port builder
+ */
+ Builder ip(IpAddress ip);
+
+ /**
+ * Returns service port builder with the supplied VLAN.
+ *
+ * @param vlanId vlan id
+ * @return service port builder
+ */
+ Builder vlanId(VlanId vlanId);
+
+ /**
+ * Returns service port builder with the supplied address pairs.
+ *
+ * @param addressPairs set of address pair
+ * @return service port builder
+ */
+ Builder addressPairs(Set<AddressPair> addressPairs);
}
}
diff --git a/src/main/java/org/opencord/cordvtn/api/net/SubnetId.java b/src/main/java/org/opencord/cordvtn/api/net/SubnetId.java
deleted file mode 100644
index b7c49bd..0000000
--- a/src/main/java/org/opencord/cordvtn/api/net/SubnetId.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.api.net;
-
-import org.onlab.util.Identifier;
-
-/**
- * Representation of the subnet identifier.
- */
-public final class SubnetId extends Identifier<String> {
-
- /**
- * Default constructor.
- *
- * @param id string subnet identifier
- */
- private SubnetId(String id) {
- super(id);
- }
-
- /**
- * Returns the subnet identifier with the supplied value.
- *
- * @param id string subnet identifier
- * @return subnet identifier
- */
- public static SubnetId of(String id) {
- return new SubnetId(id);
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/api/net/VtnNetwork.java b/src/main/java/org/opencord/cordvtn/api/net/VtnNetwork.java
deleted file mode 100644
index c4ae68e..0000000
--- a/src/main/java/org/opencord/cordvtn/api/net/VtnNetwork.java
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.api.net;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.opencord.cordvtn.api.dependency.Dependency;
-import org.openstack4j.model.network.Network;
-import org.openstack4j.model.network.Subnet;
-
-import java.util.Comparator;
-import java.util.Objects;
-import java.util.Set;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.PRIVATE;
-
-/**
- * Representation of a network holding the basic virtual network and additional
- * service network specific information.
- * All the services making use of CordVtnService are intended to interface
- * with this VtnNetwork, and not allowed to directly access {@link Network} or
- * {@link ServiceNetwork}.
- */
-public final class VtnNetwork extends ServiceNetwork {
-
- private static final String ERR_SEGMENT_ID_MISSING = "VTN network segment ID is missing";
- private static final String ERR_GATEWAY_IP_MISSING = "VTN subnet gateway IP is missing";
-
- private final SegmentId segmentId;
- private final IpPrefix subnet;
- private final IpAddress serviceIp;
-
- private VtnNetwork(NetworkId id,
- SegmentId segmentId,
- IpPrefix subnet,
- IpAddress serviceIp,
- ServiceNetworkType type,
- Set<ProviderNetwork> providers) {
- super(id, type, providers);
- this.segmentId = segmentId;
- this.subnet = subnet;
- this.serviceIp = serviceIp;
- }
-
- public static final Comparator<VtnNetwork> VTN_NETWORK_COMPARATOR =
- (net1, net2) -> net1.serviceIp().compareTo(net2.serviceIp());
-
- /**
- * Returns the network ID.
- *
- * @return network id
- */
- public NetworkId id() {
- return id;
- }
-
- /**
- * Returns the segment ID of this network.
- *
- * @return segment id
- */
- public SegmentId segmentId() {
- return segmentId;
- }
-
- /**
- * Returns the subnet used in this network.
- *
- * @return subnet
- */
- public IpPrefix subnet() {
- return subnet;
- }
-
- /**
- * Returns the service IP address of this network.
- *
- * @return ip address
- */
- public IpAddress serviceIp() {
- return serviceIp;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (obj instanceof VtnNetwork) {
- VtnNetwork that = (VtnNetwork) obj;
- if (Objects.equals(id, that.id) &&
- Objects.equals(segmentId, that.segmentId) &&
- Objects.equals(subnet, that.subnet) &&
- Objects.equals(serviceIp, that.serviceIp) &&
- Objects.equals(type, that.type) &&
- Objects.equals(providers, that.providers)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(id, segmentId, subnet, serviceIp, type, providers);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(getClass())
- .add("id", id)
- .add("segmentId", segmentId)
- .add("subnet", subnet)
- .add("serviceIp", serviceIp)
- .add("type", type)
- .add("providers", providers)
- .toString();
- }
-
- /**
- * Returns immutable VTN network with the supplied Neutron network, subnet,
- * and additional service network information.
- *
- * @param network neutron network
- * @param subnet neutron subnet
- * @param serviceNet service network
- * @return vtn network
- */
- public static VtnNetwork of(Network network, Subnet subnet, ServiceNetwork serviceNet) {
- validateNeutronNetwork(network, subnet);
- if (serviceNet != null) {
- checkArgument(Objects.equals(network.getId(), serviceNet.id().id()));
- }
-
- return builder().id(NetworkId.of(network.getId()))
- .segmentId(SegmentId.of(Long.valueOf(network.getProviderSegID())))
- .subnet(IpPrefix.valueOf(subnet.getCidr()))
- .serviceIp(IpAddress.valueOf(subnet.getGateway()))
- .type(serviceNet == null ? PRIVATE : serviceNet.type())
- .providers(serviceNet == null ? ImmutableSet.of() : serviceNet.providers())
- .build();
- }
-
- private static void validateNeutronNetwork(Network network, Subnet subnet) {
- checkNotNull(network);
- checkNotNull(subnet);
- checkArgument(Objects.equals(network.getId(), subnet.getNetworkId()));
- checkArgument(!Strings.isNullOrEmpty(network.getProviderSegID()), ERR_SEGMENT_ID_MISSING);
- checkArgument(!Strings.isNullOrEmpty(subnet.getGateway()), ERR_GATEWAY_IP_MISSING);
- }
-
- /**
- * Returns new vtn network builder instance.
- *
- * @return vtn network builder
- */
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * Returns new vtn network builder instance with copy of the given vtn network.
- *
- * @param vtnNet vtn network
- * @return vtn network builder
- */
- public static Builder builder(VtnNetwork vtnNet) {
- return new Builder()
- .id(vtnNet.id())
- .segmentId(vtnNet.segmentId())
- .subnet(vtnNet.subnet())
- .serviceIp(vtnNet.serviceIp())
- .type(vtnNet.type())
- .providers(vtnNet.providers());
- }
-
- /**
- * Builder of the vtn network entities.
- */
- public static final class Builder {
- private NetworkId id;
- private SegmentId segmentId;
- private IpPrefix subnet;
- private IpAddress serviceIp;
- private ServiceNetworkType type;
- private Set<ProviderNetwork> providers = ImmutableSet.of();
-
- private Builder() {
- }
-
- /**
- * Builds an immutable vtn network.
- *
- * @return vtn network instance
- */
- public VtnNetwork build() {
- checkNotNull(id, "VTN network id cannot be null");
- checkNotNull(segmentId, "VTN network segment id cannot be null");
- checkNotNull(subnet, "VTN network subnet cannot be null");
- checkNotNull(serviceIp, "VTN network service IP cannot be null");
- checkNotNull(type, "VTN network type cannot be null");
- providers = providers == null ? ImmutableSet.of() : providers;
-
- return new VtnNetwork(id, segmentId, subnet, serviceIp, type, providers);
- }
-
- /**
- * Returns vtn network builder with the supplied network ID.
- *
- * @param id network id
- * @return vtn network builder
- */
- public Builder id(NetworkId id) {
- this.id = id;
- return this;
- }
-
- /**
- * Returns vtn network builder with the supplied segment ID.
- *
- * @param segmentId segment id
- * @return vtn network builder
- */
- public Builder segmentId(SegmentId segmentId) {
- this.segmentId = segmentId;
- return this;
- }
-
- /**
- * Returns vtn network builder with the supplied subnet.
- *
- * @param subnet subnet
- * @return vtn network builder
- */
- public Builder subnet(IpPrefix subnet) {
- this.subnet = subnet;
- return this;
- }
-
- /**
- * Returns vtn network service IP address.
- *
- * @param serviceIp service ip address
- * @return vtn network builder
- */
- public Builder serviceIp(IpAddress serviceIp) {
- this.serviceIp = serviceIp;
- return this;
- }
-
- /**
- * Returns vtn network builder with the supplied service network type.
- *
- * @param type service network type
- * @return vtn network builder
- */
- public Builder type(ServiceNetworkType type) {
- this.type = type;
- return this;
- }
-
- /**
- * Returns vtn network builder with the supplied provider service networks.
- *
- * @param providers provider service networks
- * @return vtn network builder
- */
- public Builder providers(Set<ProviderNetwork> providers) {
- this.providers = providers;
- return this;
- }
-
- /**
- * Returns vtn network builder with the given additional provider network.
- *
- * @param providerId provider network id
- * @param type direct access type to the provider network
- * @return vtn network builder
- */
- public Builder addProvider(NetworkId providerId, Dependency.Type type) {
- checkNotNull(providerId, "Provider network ID cannot be null");
- checkNotNull(type, "Provider network type cannot be null");
-
- Set<ProviderNetwork> updated = Sets.newHashSet(this.providers);
- updated.add(ProviderNetwork.of(providerId, type));
- this.providers = ImmutableSet.copyOf(updated);
- return this;
- }
-
- /**
- * Returns vtn network builder without the given provider network.
- *
- * @param providerId provider network id
- * @return vtn network builder
- */
- public Builder delProvider(NetworkId providerId) {
- checkNotNull(providerId, "Provider network ID cannot be null");
-
- ProviderNetwork provider = this.providers.stream()
- .filter(p -> Objects.equals(p.id(), providerId))
- .findAny().orElse(null);
- if (provider != null) {
- Set<ProviderNetwork> updated = Sets.newHashSet(this.providers);
- updated.remove(provider);
- this.providers = ImmutableSet.copyOf(updated);
- }
- return this;
- }
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/api/net/VtnNetworkEvent.java b/src/main/java/org/opencord/cordvtn/api/net/VtnNetworkEvent.java
deleted file mode 100644
index c6f187f..0000000
--- a/src/main/java/org/opencord/cordvtn/api/net/VtnNetworkEvent.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.api.net;
-
-import org.joda.time.LocalDateTime;
-import org.onosproject.event.AbstractEvent;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-/**
- * Describes vtn network event.
- */
-public class VtnNetworkEvent extends AbstractEvent<VtnNetworkEvent.Type, VtnNetwork> {
-
- private final VtnPort vtnPort;
-
- /**
- * Type of vtn network event.
- */
- public enum Type {
- /**
- * Signifies that a new vtn network has been created.
- */
- VTN_NETWORK_CREATED,
-
- /**
- * Signifies that some vtn network attributes have changed.
- */
- VTN_NETWORK_UPDATED,
-
- /**
- * Signifies that a vtn network has been removed.
- */
- VTN_NETWORK_REMOVED,
-
- /**
- * Signifies that a new vtn port has been created.
- */
- VTN_PORT_CREATED,
-
- /**
- * Signifies that some vtn port attributes have changed.
- */
- VTN_PORT_UPDATED,
-
- /**
- * Signifies that a vtn port has been removed.
- */
- VTN_PORT_REMOVED
- }
-
- /**
- * Creates an event of a given type and for the specified vtn network and
- * the current time.
- *
- * @param type vtn network event type
- * @param vtnNet vtn network subject
- */
- public VtnNetworkEvent(Type type, VtnNetwork vtnNet) {
- super(type, vtnNet);
- this.vtnPort = null;
- }
-
- /**
- * Creates an event of a given type and for the specified vtn network,
- * port and the current time.
- *
- * @param type vtn network event type
- * @param vtnNet vtn network subject
- * @param vtnPort optional vtn port subject
- */
- public VtnNetworkEvent(Type type, VtnNetwork vtnNet, VtnPort vtnPort) {
- super(type, vtnNet);
- this.vtnPort = vtnPort;
- }
-
- /**
- * Returns the vtn port subject.
- * It returns valid value only with the vtn port events.
- *
- * @return vtn port or null if the event is not vtn port specific
- */
- public VtnPort vtnPort() {
- return vtnPort;
- }
-
- @Override
- public String toString() {
- if (vtnPort == null) {
- return super.toString();
- }
- return toStringHelper(this)
- .add("time", new LocalDateTime(time()))
- .add("type", type())
- .add("vtnNet", subject())
- .add("vtnPort", vtnPort)
- .toString();
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/api/net/VtnPort.java b/src/main/java/org/opencord/cordvtn/api/net/VtnPort.java
deleted file mode 100644
index 1f07218..0000000
--- a/src/main/java/org/opencord/cordvtn/api/net/VtnPort.java
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.api.net;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.openstack4j.model.network.Port;
-
-import java.util.Comparator;
-import java.util.Objects;
-import java.util.Set;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Representation of a port holding the basic virtual port and additional service
- * port specific information.
- * All the services making use of CordVtnService are intended to interface
- * with this VtnPort, and not allowed to directly access {@link Port} or
- * {@link ServicePort}.
- */
-public final class VtnPort extends ServicePort {
-
- private static final String ERR_IP_MISSING = "VTN port IP address is missing";
-
- private final NetworkId netId;
- private final MacAddress mac;
- private final IpAddress ip;
-
- private VtnPort(PortId id,
- NetworkId netId,
- MacAddress mac,
- IpAddress ip,
- VlanId vlanId,
- Set<AddressPair> addressPairs) {
- super(id, vlanId, addressPairs);
- this.netId = netId;
- this.mac = mac;
- this.ip = ip;
- }
-
- public static final Comparator<VtnPort> VTN_PORT_COMPARATOR =
- (port1, port2) -> port1.ip().compareTo(port2.ip());
-
- /**
- * Returns the network ID of this port.
- *
- * @return network id
- */
- public NetworkId netId() {
- return netId;
- }
-
- /**
- * Returns the MAC address of this port.
- *
- * @return mac address
- */
- public MacAddress mac() {
- return mac;
- }
-
- /**
- * Returns the IP address of this port.
- *
- * @return ip address
- */
- public IpAddress ip() {
- return ip;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (obj instanceof VtnPort) {
- VtnPort that = (VtnPort) obj;
- if (Objects.equals(id, that.id) &&
- Objects.equals(netId, that.netId) &&
- Objects.equals(mac, that.mac) &&
- Objects.equals(ip, that.ip) &&
- Objects.equals(vlanId, that.vlanId) &&
- Objects.equals(addressPairs, that.addressPairs)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(id, netId, mac, ip, vlanId, addressPairs);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(getClass())
- .add("id", id)
- .add("netId", netId)
- .add("mac", mac)
- .add("ip", ip)
- .add("vlanId", vlanId)
- .add("addressPairs", addressPairs)
- .toString();
- }
-
- /**
- * Returns the immutable VTN port with the supplied Neutron port with additional
- * vtn port information.
- *
- * @param port neutron port
- * @param servicePort vtn port
- * @return vtn port
- */
- public static VtnPort of(Port port, ServicePort servicePort) {
- validateNeutronPort(port);
- if (servicePort != null) {
- checkArgument(Objects.equals(port.getId(), servicePort.id().id()));
- }
-
- return builder().id(PortId.of(port.getId()))
- .netId(NetworkId.of(port.getNetworkId()))
- .mac(MacAddress.valueOf(port.getMacAddress()))
- .ip(IpAddress.valueOf(port.getFixedIps().iterator().next().getIpAddress()))
- .vlanId(servicePort == null ? null : servicePort.vlanId().orElse(null))
- .addressPairs(servicePort == null ? ImmutableSet.of() : servicePort.addressPairs())
- .build();
- }
-
- private static void validateNeutronPort(Port port) {
- checkNotNull(port);
- checkArgument(port.getFixedIps().size() > 0, ERR_IP_MISSING);
- }
-
- /**
- * Returns the immutable VTN port with the supplied VTN port with additional
- * vtn port information.
- *
- * @param vtnPort vtn port
- * @param servicePort vtn port
- * @return vtn port
- */
- public static VtnPort of(VtnPort vtnPort, ServicePort servicePort) {
- return builder(vtnPort)
- .vlanId(servicePort.vlanId().orElse(null))
- .addressPairs(servicePort.addressPairs())
- .build();
- }
-
- /**
- * Returns new vtn port builder instance.
- *
- * @return vtn port builder
- */
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * Returns new vtn port builder instance with copy of the supplied vtn port.
- *
- * @param vtnPort vtn port
- * @return vtn port builder
- */
- public static Builder builder(VtnPort vtnPort) {
- return new Builder().id(vtnPort.id())
- .netId(vtnPort.netId())
- .mac(vtnPort.mac())
- .ip(vtnPort.ip())
- .vlanId(vtnPort.vlanId().orElse(null))
- .addressPairs(vtnPort.addressPairs());
- }
-
- /**
- * Builder of the vtn port entities.
- */
- public static final class Builder {
- private PortId id;
- private NetworkId netId;
- private MacAddress mac;
- private IpAddress ip;
- private VlanId vlanId;
- private Set<AddressPair> addressPairs = ImmutableSet.of();
-
- private Builder() {
- }
-
- /**
- * Builds an immutable vtn port.
- *
- * @return vtn port instance
- */
- public VtnPort build() {
- checkNotNull(id, "VtnPort port id cannot be null");
- checkNotNull(netId, "VtnPort network id cannot be null");
- checkNotNull(mac, "VtnPort mac address cannot be null");
- checkNotNull(ip, "VtnPort ip address cannot be null");
- addressPairs = addressPairs == null ? ImmutableSet.of() : addressPairs;
-
- return new VtnPort(id, netId, mac, ip, vlanId, addressPairs);
- }
-
- /**
- * Returns vtn port builder with the supplied port id.
- *
- * @param id port id
- * @return vtn port builder
- */
- public Builder id(PortId id) {
- this.id = id;
- return this;
- }
-
- /**
- * Returns vtn port builder with the supplied network id.
- *
- * @param netId network id
- * @return vtn port builder
- */
- public Builder netId(NetworkId netId) {
- this.netId = netId;
- return this;
- }
-
- /**
- * Returns vtn port builder with the supplied mac address.
- *
- * @param mac mac address
- * @return vtn port builder
- */
- public Builder mac(MacAddress mac) {
- this.mac = mac;
- return this;
- }
-
- /**
- * Returns vtn port builder with the supplied ip address.
- *
- * @param ip ip address
- * @return vtn port builder
- */
- public Builder ip(IpAddress ip) {
- this.ip = ip;
- return this;
- }
-
- /**
- * Returns vtn port builder with the supplied VLAN ID.
- *
- * @param vlanId vlan id
- * @return vtn port builder
- */
- public Builder vlanId(VlanId vlanId) {
- this.vlanId = vlanId;
- return this;
- }
-
- /**
- * Returns vtn port builder with the supplied address pairs.
- *
- * @param addressPairs set of address pairs
- * @return vtn port builder
- */
- public Builder addressPairs(Set<AddressPair> addressPairs) {
- this.addressPairs = addressPairs;
- return this;
- }
-
- /**
- * Returns vtn port builder with the given additional address pair.
- *
- * @param addressPair address pair to add
- * @return vtn port builder
- */
- public Builder addAddressPair(AddressPair addressPair) {
- checkNotNull(addressPair, "VtnPort address pair cannot be null");
-
- Set<AddressPair> updated = Sets.newHashSet(this.addressPairs);
- updated.add(addressPair);
- this.addressPairs = ImmutableSet.copyOf(updated);
- return this;
- }
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/api/node/CordVtnNode.java b/src/main/java/org/opencord/cordvtn/api/node/CordVtnNode.java
index d4339df..153eed3 100644
--- a/src/main/java/org/opencord/cordvtn/api/node/CordVtnNode.java
+++ b/src/main/java/org/opencord/cordvtn/api/node/CordVtnNode.java
@@ -20,6 +20,7 @@
import com.google.common.collect.Sets;
import org.onlab.packet.TpPort;
import org.onosproject.net.DeviceId;
+import org.opencord.cordvtn.api.net.CidrAddr;
import java.util.Comparator;
import java.util.Objects;
@@ -37,9 +38,9 @@
public final class CordVtnNode {
private final String hostname;
- private final NetworkAddress hostMgmtIp;
- private final NetworkAddress localMgmtIp;
- private final NetworkAddress dataIp;
+ private final CidrAddr hostMgmtIp;
+ private final CidrAddr localMgmtIp;
+ private final CidrAddr dataIp;
private final Optional<TpPort> ovsdbPort;
private final SshAccessInfo sshInfo;
private final DeviceId integrationBridgeId;
@@ -65,9 +66,9 @@
* @param state cordvtn node state
*/
private CordVtnNode(String hostname,
- NetworkAddress hostMgmtIp,
- NetworkAddress localMgmtIp,
- NetworkAddress dataIp,
+ CidrAddr hostMgmtIp,
+ CidrAddr localMgmtIp,
+ CidrAddr dataIp,
Optional<TpPort> ovsdbPort,
SshAccessInfo sshInfo,
DeviceId integrationBridgeId,
@@ -117,7 +118,7 @@
*
* @return network address
*/
- public NetworkAddress hostMgmtIp() {
+ public CidrAddr hostMgmtIp() {
return this.hostMgmtIp;
}
@@ -126,7 +127,7 @@
*
* @return network address
*/
- public NetworkAddress localMgmtIp() {
+ public CidrAddr localMgmtIp() {
return this.localMgmtIp;
}
@@ -135,7 +136,7 @@
*
* @return network address
*/
- public NetworkAddress dataIp() {
+ public CidrAddr dataIp() {
return this.dataIp;
}
@@ -286,9 +287,9 @@
*/
public static final class Builder {
private String hostname;
- private NetworkAddress hostMgmtIp;
- private NetworkAddress localMgmtIp;
- private NetworkAddress dataIp;
+ private CidrAddr hostMgmtIp;
+ private CidrAddr localMgmtIp;
+ private CidrAddr dataIp;
private Optional<TpPort> ovsdbPort =
Optional.of(TpPort.tpPort(DEFAULT_OVSDB_PORT));
private SshAccessInfo sshInfo;
@@ -344,7 +345,7 @@
* @param hostMgmtIp host management netework ip address
* @return cordvtn node builder
*/
- public Builder hostMgmtIp(NetworkAddress hostMgmtIp) {
+ public Builder hostMgmtIp(CidrAddr hostMgmtIp) {
checkNotNull(hostMgmtIp);
this.hostMgmtIp = hostMgmtIp;
return this;
@@ -357,7 +358,7 @@
* @return cordvtn node builder
*/
public Builder hostMgmtIp(String cidr) {
- this.hostMgmtIp = NetworkAddress.valueOf(cidr);
+ this.hostMgmtIp = CidrAddr.valueOf(cidr);
return this;
}
@@ -367,7 +368,7 @@
* @param localMgmtIp local management network ip address
* @return cordvtn node builder
*/
- public Builder localMgmtIp(NetworkAddress localMgmtIp) {
+ public Builder localMgmtIp(CidrAddr localMgmtIp) {
checkNotNull(localMgmtIp);
this.localMgmtIp = localMgmtIp;
return this;
@@ -380,7 +381,7 @@
* @return cordvtn node builder
*/
public Builder localMgmtIp(String cidr) {
- this.localMgmtIp = NetworkAddress.valueOf(cidr);
+ this.localMgmtIp = CidrAddr.valueOf(cidr);
return this;
}
@@ -390,7 +391,7 @@
* @param dataIp data network ip address
* @return cordvtn node builder
*/
- public Builder dataIp(NetworkAddress dataIp) {
+ public Builder dataIp(CidrAddr dataIp) {
checkNotNull(dataIp);
this.dataIp = dataIp;
return this;
@@ -403,7 +404,7 @@
* @return cordvtn node builder
*/
public Builder dataIp(String cidr) {
- this.dataIp = NetworkAddress.valueOf(cidr);
+ this.dataIp = CidrAddr.valueOf(cidr);
return this;
}
diff --git a/src/main/java/org/opencord/cordvtn/cli/CordVtnNetworkListCommand.java b/src/main/java/org/opencord/cordvtn/cli/CordVtnNetworkListCommand.java
index fac50f8..7f42dc2 100644
--- a/src/main/java/org/opencord/cordvtn/cli/CordVtnNetworkListCommand.java
+++ b/src/main/java/org/opencord/cordvtn/cli/CordVtnNetworkListCommand.java
@@ -21,8 +21,8 @@
import com.google.common.collect.Lists;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
-import org.opencord.cordvtn.api.core.CordVtnService;
-import org.opencord.cordvtn.api.net.VtnNetwork;
+import org.opencord.cordvtn.api.core.ServiceNetworkService;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
import java.util.Collections;
import java.util.List;
@@ -36,13 +36,13 @@
description = "Lists all VTN networks")
public class CordVtnNetworkListCommand extends AbstractShellCommand {
- private static final String FORMAT = "%-40s%-20s%-8s%-20s%s";
+ private static final String FORMAT = "%-40s%-20s%-20s%-8s%-20s%s";
@Override
protected void execute() {
- CordVtnService service = AbstractShellCommand.get(CordVtnService.class);
- List<VtnNetwork> networks = Lists.newArrayList(service.vtnNetworks());
- Collections.sort(networks, VtnNetwork.VTN_NETWORK_COMPARATOR);
+ ServiceNetworkService service = AbstractShellCommand.get(ServiceNetworkService.class);
+ List<ServiceNetwork> networks = Lists.newArrayList(service.serviceNetworks());
+ Collections.sort(networks, ServiceNetwork.SERVICE_NETWORK_COMPARATOR);
if (outputJson()) {
try {
@@ -51,9 +51,10 @@
print("Failed to list networks in JSON format");
}
} else {
- print(FORMAT, "ID", "Type", "VNI", "Subnet", "Service IP");
- for (VtnNetwork net: networks) {
+ print(FORMAT, "ID", "Name", "Type", "VNI", "Subnet", "Service IP");
+ for (ServiceNetwork net: networks) {
print(FORMAT, net.id(),
+ net.name(),
net.type(),
net.segmentId(),
net.subnet(),
@@ -62,17 +63,18 @@
}
}
- private JsonNode json(List<VtnNetwork> networks) {
+ private JsonNode json(List<ServiceNetwork> networks) {
ArrayNode result = mapper().enable(INDENT_OUTPUT).createArrayNode();
- for (VtnNetwork net: networks) {
+ for (ServiceNetwork net: networks) {
ArrayNode providers = mapper().createArrayNode();
- net.providers().forEach(provider -> providers.add(
+ net.providers().entrySet().forEach(provider -> providers.add(
mapper().createObjectNode()
- .put("networkId", provider.id().id())
- .put("type", provider.type().name())));
+ .put("networkId", provider.getKey().id())
+ .put("type", provider.getValue().name())));
result.add(mapper().createObjectNode()
.put("id", net.id().id())
+ .put("name", net.name())
.put("type", net.type().name())
.put("vni", net.segmentId().id())
.put("subnet", net.subnet().toString())
diff --git a/src/main/java/org/opencord/cordvtn/cli/CordVtnPortListCommand.java b/src/main/java/org/opencord/cordvtn/cli/CordVtnPortListCommand.java
index 32eaa22..6a7618d 100644
--- a/src/main/java/org/opencord/cordvtn/cli/CordVtnPortListCommand.java
+++ b/src/main/java/org/opencord/cordvtn/cli/CordVtnPortListCommand.java
@@ -23,8 +23,8 @@
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
-import org.opencord.cordvtn.api.core.CordVtnService;
-import org.opencord.cordvtn.api.net.VtnPort;
+import org.opencord.cordvtn.api.core.ServiceNetworkService;
+import org.opencord.cordvtn.api.net.ServicePort;
import java.util.Collections;
import java.util.List;
@@ -46,12 +46,12 @@
@Override
protected void execute() {
- CordVtnService service = AbstractShellCommand.get(CordVtnService.class);
+ ServiceNetworkService service = AbstractShellCommand.get(ServiceNetworkService.class);
- List<VtnPort> ports = Lists.newArrayList(service.vtnPorts());
- Collections.sort(ports, VtnPort.VTN_PORT_COMPARATOR);
+ List<ServicePort> ports = Lists.newArrayList(service.servicePorts());
+ Collections.sort(ports, ServicePort.SERVICE_PORT_COMPARATOR);
if (!Strings.isNullOrEmpty(networkId)) {
- ports.removeIf(port -> !port.netId().id().equals(networkId));
+ ports.removeIf(port -> !port.networkId().id().equals(networkId));
}
if (outputJson()) {
@@ -62,22 +62,22 @@
}
} else {
print(FORMAT, "ID", "MAC", "IP", "VLAN", "WAN IPs");
- for (VtnPort port: ports) {
+ for (ServicePort port: ports) {
List<String> floatingIps = port.addressPairs().stream()
.map(ip -> ip.ip().toString())
.collect(Collectors.toList());
print(FORMAT, port.id(),
port.mac(),
port.ip(),
- port.vlanId().isPresent() ? port.vlanId().get() : "",
+ port.vlanId() != null ? port.vlanId() : "",
floatingIps.isEmpty() ? "" : floatingIps);
}
}
}
- private JsonNode json(List<VtnPort> ports) {
+ private JsonNode json(List<ServicePort> ports) {
ArrayNode result = mapper().enable(INDENT_OUTPUT).createArrayNode();
- for (VtnPort port: ports) {
+ for (ServicePort port: ports) {
ArrayNode addrPairs = mapper().createArrayNode();
port.addressPairs().forEach(pair -> addrPairs.add(
mapper().createObjectNode()
@@ -86,11 +86,11 @@
result.add(mapper().createObjectNode()
.put("id", port.id().id())
- .put("networkId", port.netId().id())
+ .put("networkId", port.networkId().id())
.put("mac", port.mac().toString())
.put("ip", port.ip().toString())
- .put("vlan", port.vlanId().isPresent() ?
- port.vlanId().get().toString() : null)
+ .put("vlan", port.vlanId() != null ?
+ port.vlanId().toString() : null)
.set("addressPairs", addrPairs));
}
return result;
diff --git a/src/main/java/org/opencord/cordvtn/cli/CordVtnPurgeStatesCommand.java b/src/main/java/org/opencord/cordvtn/cli/CordVtnPurgeStatesCommand.java
index b26ec66..a6f63b7 100644
--- a/src/main/java/org/opencord/cordvtn/cli/CordVtnPurgeStatesCommand.java
+++ b/src/main/java/org/opencord/cordvtn/cli/CordVtnPurgeStatesCommand.java
@@ -17,7 +17,7 @@
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
-import org.opencord.cordvtn.api.core.CordVtnAdminService;
+import org.opencord.cordvtn.api.core.ServiceNetworkAdminService;
/**
* Purges internal network states.
@@ -28,8 +28,8 @@
@Override
protected void execute() {
- CordVtnAdminService adminService =
- AbstractShellCommand.get(CordVtnAdminService.class);
+ ServiceNetworkAdminService adminService =
+ AbstractShellCommand.get(ServiceNetworkAdminService.class);
adminService.purgeStates();
}
}
diff --git a/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncNeutronStatesCommand.java b/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncNeutronStatesCommand.java
new file mode 100644
index 0000000..c7dcdeb
--- /dev/null
+++ b/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncNeutronStatesCommand.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed 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 org.opencord.cordvtn.cli;
+
+import com.google.common.base.Strings;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.cli.AbstractShellCommand;
+import org.opencord.cordvtn.api.core.ServiceNetworkAdminService;
+import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.PortId;
+import org.opencord.cordvtn.api.net.SegmentId;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
+import org.opencord.cordvtn.api.net.ServicePort;
+import org.opencord.cordvtn.impl.DefaultServiceNetwork;
+import org.opencord.cordvtn.impl.DefaultServicePort;
+import org.openstack4j.api.OSClient;
+import org.openstack4j.api.exceptions.AuthenticationException;
+import org.openstack4j.model.identity.Access;
+import org.openstack4j.openstack.OSFactory;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Synchronizes network states with OpenStack Neutron.
+ * This command can be used to actively synchronize Neutron network with VTN
+ * service network.
+ */
+@Command(scope = "onos", name = "cordvtn-sync-neutron-states",
+ description = "Synchronizes network states with Neutron")
+public class CordVtnSyncNeutronStatesCommand extends AbstractShellCommand {
+
+ @Argument(index = 0, name = "endpoint", description = "OpenStack service endpoint",
+ required = true, multiValued = false)
+ private String endpoint = null;
+
+ @Argument(index = 1, name = "tenant", description = "OpenStack admin tenant name",
+ required = true, multiValued = false)
+ private String tenant = null;
+
+ @Argument(index = 2, name = "user", description = "OpenStack admin user name",
+ required = true, multiValued = false)
+ private String user = null;
+
+ @Argument(index = 3, name = "password", description = "OpenStack admin user password",
+ required = true, multiValued = false)
+ private String password = null;
+
+ private static final String NET_FORMAT = "%-40s%-20s%-20s%-8s%-20s%s";
+ private static final String PORT_FORMAT = "%-40s%-20s%-18s%-8s%s";
+
+ @Override
+ protected void execute() {
+ ServiceNetworkAdminService snetService =
+ AbstractShellCommand.get(ServiceNetworkAdminService.class);
+ Access osAccess;
+ try {
+ osAccess = OSFactory.builder()
+ .endpoint(this.endpoint)
+ .tenantName(this.tenant)
+ .credentials(this.user, this.password)
+ .authenticate()
+ .getAccess();
+ } catch (AuthenticationException e) {
+ print("Authentication failed");
+ return;
+ } catch (Exception e) {
+ print("OpenStack service endpoint is unreachable");
+ return;
+ }
+
+ print("Synchronizing service networks...");
+ print(NET_FORMAT, "ID", "Name", "Type", "VNI", "Subnet", "Service IP");
+ OSClient osClient = OSFactory.clientFromAccess(osAccess);
+ osClient.networking().network().list().forEach(osNet -> {
+ ServiceNetwork snet = DefaultServiceNetwork.builder()
+ .id(NetworkId.of(osNet.getId()))
+ .name(osNet.getName())
+ .type(ServiceNetwork.NetworkType.PRIVATE)
+ .segmentId(SegmentId.of(Long.valueOf(osNet.getProviderSegID())))
+ .build();
+ try {
+ if (snetService.serviceNetwork(snet.id()) != null) {
+ snetService.updateServiceNetwork(snet);
+ } else {
+ snetService.createServiceNetwork(snet);
+ }
+ } catch (Exception ignore) {
+ }
+ });
+
+ osClient.networking().subnet().list().forEach(osSubnet -> {
+ try {
+ ServiceNetwork snet = DefaultServiceNetwork.builder()
+ .id(NetworkId.of(osSubnet.getNetworkId()))
+ .subnet(IpPrefix.valueOf(osSubnet.getCidr()))
+ .serviceIp(IpAddress.valueOf(osSubnet.getGateway()))
+ .build();
+ snetService.updateServiceNetwork(snet);
+ ServiceNetwork updated = snetService.serviceNetwork(snet.id());
+ print(NET_FORMAT, updated.id(),
+ updated.name(),
+ updated.type(),
+ updated.segmentId(),
+ updated.subnet(),
+ updated.serviceIp());
+ } catch (Exception e) {
+ print(e.getMessage());
+ }
+ });
+
+ print("\nSynchronizing service ports...");
+ print(PORT_FORMAT, "ID", "MAC", "IP", "VLAN", "WAN IPs");
+ osClient.networking().port().list().forEach(osPort -> {
+ ServicePort.Builder sportBuilder = DefaultServicePort.builder()
+ .id(PortId.of(osPort.getId()))
+ .networkId(NetworkId.of(osPort.getNetworkId()));
+
+ if (!Strings.isNullOrEmpty(osPort.getName())) {
+ sportBuilder.name(osPort.getName());
+ }
+ if (osPort.getMacAddress() != null) {
+ sportBuilder.mac(MacAddress.valueOf(osPort.getMacAddress()));
+ }
+ if (!osPort.getFixedIps().isEmpty()) {
+ sportBuilder.ip(IpAddress.valueOf(
+ osPort.getFixedIps().iterator().next().getIpAddress()));
+ }
+ ServicePort sport = sportBuilder.build();
+ if (snetService.servicePort(sport.id()) != null) {
+ snetService.updateServicePort(sport);
+ } else {
+ snetService.createServicePort(sport);
+ }
+ ServicePort updated = snetService.servicePort(sport.id());
+ List<String> floatingIps = updated.addressPairs().stream()
+ .map(ip -> ip.ip().toString())
+ .collect(Collectors.toList());
+ print(PORT_FORMAT, updated.id(),
+ updated.mac(),
+ updated.ip(),
+ updated.vlanId() != null ? updated.vlanId() : "",
+ floatingIps.isEmpty() ? "" : floatingIps);
+ });
+ }
+}
diff --git a/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncStatesCommand.java b/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncStatesCommand.java
deleted file mode 100644
index 5540391..0000000
--- a/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncStatesCommand.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.cli;
-
-import org.apache.karaf.shell.commands.Command;
-import org.onosproject.cli.AbstractShellCommand;
-import org.opencord.cordvtn.api.core.CordVtnAdminService;
-
-/**
- * Synchronizes network states with external services.
- */
-@Command(scope = "onos", name = "cordvtn-sync-states",
- description = "Synchronizes network states with external services")
-public class CordVtnSyncStatesCommand extends AbstractShellCommand {
-
- @Override
- protected void execute() {
- CordVtnAdminService adminService =
- AbstractShellCommand.get(CordVtnAdminService.class);
- adminService.syncStates();
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncXosStatesCommand.java b/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncXosStatesCommand.java
new file mode 100644
index 0000000..b3fc988
--- /dev/null
+++ b/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncXosStatesCommand.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed 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 org.opencord.cordvtn.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.opencord.cordvtn.api.core.ServiceNetworkAdminService;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
+import org.opencord.cordvtn.api.net.ServicePort;
+import org.opencord.cordvtn.rest.XosVtnNetworkingClient;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Synchronizes network states with XOS VTN service.
+ * This command can be used to actively synchronize XOS network with VTN
+ * service network.
+ */
+@Command(scope = "onos", name = "cordvtn-sync-xos-states",
+ description = "Synchronizes network states with Neutron")
+public class CordVtnSyncXosStatesCommand extends AbstractShellCommand {
+
+ @Argument(index = 0, name = "endpoint", description = "XOS VTN service endpoint",
+ required = true, multiValued = false)
+ private String endpoint = null;
+
+ @Argument(index = 1, name = "user", description = "XOS admin user name",
+ required = true, multiValued = false)
+ private String user = null;
+
+ @Argument(index = 2, name = "password", description = "XOS admin user password",
+ required = true, multiValued = false)
+ private String password = null;
+
+ private static final String NET_FORMAT = "%-40s%-20s%-20s%-8s%-20s%s";
+ private static final String PORT_FORMAT = "%-40s%-20s%-18s%-8s%s";
+
+ @Override
+ protected void execute() {
+ ServiceNetworkAdminService snetService =
+ AbstractShellCommand.get(ServiceNetworkAdminService.class);
+
+ XosVtnNetworkingClient client = XosVtnNetworkingClient.builder()
+ .endpoint(endpoint)
+ .user(user)
+ .password(password)
+ .build();
+
+ print("Synchronizing service networks...");
+ print(NET_FORMAT, "ID", "Name", "Type", "VNI", "Subnet", "Service IP");
+ client.serviceNetworks().forEach(snet -> {
+ if (snetService.serviceNetwork(snet.id()) != null) {
+ snetService.updateServiceNetwork(snet);
+ } else {
+ snetService.createServiceNetwork(snet);
+ }
+ ServiceNetwork updated = snetService.serviceNetwork(snet.id());
+ print(NET_FORMAT, updated.id(),
+ updated.name(),
+ updated.type(),
+ updated.segmentId(),
+ updated.subnet(),
+ updated.serviceIp());
+ });
+
+ // FIXME creating a port fails until XOS service API provides network ID
+ print("\nSynchronizing service ports...");
+ print(PORT_FORMAT, "ID", "MAC", "IP", "VLAN", "WAN IPs");
+ client.servicePorts().forEach(sport -> {
+ if (snetService.servicePort(sport.id()) != null) {
+ snetService.updateServicePort(sport);
+ } else {
+ snetService.createServicePort(sport);
+ }
+ ServicePort updated = snetService.servicePort(sport.id());
+ List<String> floatingIps = updated.addressPairs().stream()
+ .map(ip -> ip.ip().toString())
+ .collect(Collectors.toList());
+ print(PORT_FORMAT, updated.id(),
+ updated.mac(),
+ updated.ip(),
+ updated.vlanId() != null ? updated.vlanId() : "",
+ floatingIps.isEmpty() ? "" : floatingIps);
+ });
+ }
+}
diff --git a/src/main/java/org/opencord/cordvtn/codec/ServiceNetworkCodec.java b/src/main/java/org/opencord/cordvtn/codec/ServiceNetworkCodec.java
index 84226b9..331bffe 100644
--- a/src/main/java/org/opencord/cordvtn/codec/ServiceNetworkCodec.java
+++ b/src/main/java/org/opencord/cordvtn/codec/ServiceNetworkCodec.java
@@ -16,25 +16,28 @@
package org.opencord.cordvtn.codec;
import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.Sets;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
-import org.opencord.cordvtn.api.dependency.Dependency;
import org.opencord.cordvtn.api.net.NetworkId;
-import org.opencord.cordvtn.api.net.ProviderNetwork;
+import org.opencord.cordvtn.api.net.SegmentId;
import org.opencord.cordvtn.api.net.ServiceNetwork;
-import org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType;
+import org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType;
+import org.opencord.cordvtn.impl.DefaultServiceNetwork;
-import java.util.Set;
+import java.util.Map;
import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
-import static org.opencord.cordvtn.api.dependency.Dependency.Type.BIDIRECTIONAL;
-import static org.opencord.cordvtn.api.dependency.Dependency.Type.UNIDIRECTIONAL;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.valueOf;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType.BIDIRECTIONAL;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType.UNIDIRECTIONAL;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.valueOf;
/**
* Service network JSON codec.
@@ -42,53 +45,176 @@
public final class ServiceNetworkCodec extends JsonCodec<ServiceNetwork> {
private static final String ID = "id";
+ private static final String NAME = "name";
private static final String TYPE = "type";
+ private static final String SEGMENT_ID = "segment_id";
+ private static final String SUBNET = "subnet";
+ private static final String SERVICE_IP = "service_ip";
+ @Deprecated
private static final String PROVIDER_NETWORKS = "providerNetworks";
- private static final String BIDIRECT = "bidirectional";
+ private static final String PROVIDERS = "providers";
+ private static final String DEP_TYPE = "bidirectional";
private static final String ERR_JSON = "Invalid ServiceNetwork received";
- private static final String ERR_ID = ": network ID cannot be null";
- private static final String ERR_TYPE = ": type cannot be null";
+ private static final String ERR_ID = "Service network ID cannot be null";
@Override
public ObjectNode encode(ServiceNetwork snet, CodecContext context) {
- ObjectNode result = context.mapper().createObjectNode()
- .put(ID, snet.id().id())
- .put(TYPE, snet.type().name().toLowerCase());
-
+ ObjectNode result = context.mapper().createObjectNode().put(ID, snet.id().id());
+ if (!Strings.isNullOrEmpty(snet.name())) {
+ result.put(NAME, snet.name());
+ }
+ if (snet.type() != null) {
+ result.put(TYPE, snet.type().name());
+ }
+ if (snet.segmentId() != null) {
+ result.put(SEGMENT_ID, snet.segmentId().id());
+ }
+ if (snet.subnet() != null) {
+ result.put(SUBNET, snet.subnet().toString());
+ }
+ if (snet.serviceIp() != null) {
+ result.put(SERVICE_IP, snet.serviceIp().toString());
+ }
ArrayNode providers = context.mapper().createArrayNode();
- snet.providers().forEach(provider -> {
+ snet.providers().entrySet().forEach(provider -> {
ObjectNode providerJson = context.mapper().createObjectNode()
- .put(ID, provider.id().id())
- .put(BIDIRECT, provider.type() == BIDIRECTIONAL ? TRUE : FALSE);
+ .put(ID, provider.getKey().id())
+ .put(DEP_TYPE, provider.getValue() == BIDIRECTIONAL ? TRUE : FALSE);
providers.add(providerJson);
});
-
- result.set(PROVIDER_NETWORKS, providers);
+ result.set(PROVIDERS, providers);
return result;
}
@Override
public ServiceNetwork decode(ObjectNode json, CodecContext context) {
- checkArgument(json != null && json.isObject(), ERR_JSON);
- checkArgument(json.get(ID) != null &&
- json.get(ID) != NullNode.getInstance(),
- ERR_JSON + ERR_ID);
- checkArgument(json.get(TYPE) != null &&
- json.get(TYPE) != NullNode.getInstance(),
- ERR_JSON + ERR_TYPE);
+ validateJson(json);
+ ServiceNetwork.Builder snetBuilder = DefaultServiceNetwork.builder()
+ .id(NetworkId.of(json.get(ID).asText()));
- NetworkId netId = NetworkId.of(json.get(ID).asText());
- ServiceNetworkType netType = valueOf(json.get(TYPE).asText().toUpperCase());
- Set<ProviderNetwork> providers = Sets.newHashSet();
+ // TODO remove existing values when explicit null received
+ if (json.get(NAME) != null && !json.get(NAME).isNull()) {
+ snetBuilder.name(json.get(NAME).asText());
+ }
+ if (json.get(TYPE) != null && !json.get(TYPE).isNull()) {
+ snetBuilder.type(valueOf(json.get(TYPE).asText().toUpperCase()));
+ }
+ if (json.get(SEGMENT_ID) != null && !json.get(SEGMENT_ID).isNull()) {
+ snetBuilder.segmentId(SegmentId.of(json.get(SEGMENT_ID).asLong()));
+ }
+ if (json.get(SUBNET) != null && !json.get(SUBNET).isNull()) {
+ snetBuilder.subnet(IpPrefix.valueOf(json.get(SUBNET).asText()));
+ }
+ if (json.get(SERVICE_IP) != null && !json.get(SERVICE_IP).isNull()) {
+ snetBuilder.serviceIp(IpAddress.valueOf(json.get(SERVICE_IP).asText()));
+ }
+ if (json.get(PROVIDERS) != null) {
+ if (json.get(PROVIDERS).isNull()) {
+ snetBuilder.providers(ImmutableMap.of());
+ } else {
+ Map<NetworkId, DependencyType> providers = Maps.newHashMap();
+ json.get(PROVIDERS).forEach(provider -> {
+ DependencyType type = provider.get(DEP_TYPE).asBoolean() ?
+ BIDIRECTIONAL : UNIDIRECTIONAL;
+ providers.put(NetworkId.of(provider.get(ID).asText()), type);
+ });
+ snetBuilder.providers(providers);
+ }
+ }
if (json.get(PROVIDER_NETWORKS) != null) {
- json.get(PROVIDER_NETWORKS).forEach(provider -> {
- NetworkId providerId = NetworkId.of(provider.get(ID).asText());
- Dependency.Type type = provider.get(BIDIRECT).asBoolean() ?
- BIDIRECTIONAL : UNIDIRECTIONAL;
- providers.add(ProviderNetwork.of(providerId, type));
+ if (json.get(PROVIDER_NETWORKS).isNull()) {
+ snetBuilder.providers(ImmutableMap.of());
+ } else {
+ Map<NetworkId, DependencyType> providers = Maps.newHashMap();
+ json.get(PROVIDER_NETWORKS).forEach(provider -> {
+ DependencyType type = provider.get(DEP_TYPE).asBoolean() ?
+ BIDIRECTIONAL : UNIDIRECTIONAL;
+ providers.put(NetworkId.of(provider.get(ID).asText()), type);
+ });
+ snetBuilder.providers(providers);
+ }
+ }
+ return snetBuilder.build();
+ }
+
+ private void validateJson(ObjectNode json) {
+ checkArgument(json != null && json.isObject(), ERR_JSON);
+ checkArgument(json.get(ID) != null && !json.get(ID).isNull(), ERR_ID);
+ checkArgument(!Strings.isNullOrEmpty(json.get(ID).asText()), ERR_ID);
+
+ // allow explicit null for removing the existing value
+ if (json.get(NAME) != null && !json.get(NAME).isNull()) {
+ if (Strings.isNullOrEmpty(json.get(NAME).asText())) {
+ final String error = "Null or empty ServiceNetwork name received";
+ throw new IllegalArgumentException(error);
+ }
+ }
+
+ if (json.get(TYPE) != null && !json.get(TYPE).isNull()) {
+ try {
+ valueOf(json.get(TYPE).asText().toUpperCase());
+ } catch (IllegalArgumentException e) {
+ final String error = "Invalid ServiceNetwork type received: ";
+ throw new IllegalArgumentException(error + json.get(TYPE).asText());
+ }
+ }
+
+ if (json.get(SEGMENT_ID) != null && !json.get(SEGMENT_ID).isNull()) {
+ if (json.get(SEGMENT_ID).asLong() == 0) {
+ final String error = "Invalid ServiecNetwork segment ID received: ";
+ throw new IllegalArgumentException(error + json.get(SEGMENT_ID).asText());
+ }
+ }
+
+ if (json.get(SUBNET) != null && !json.get(SUBNET).isNull()) {
+ try {
+ IpPrefix.valueOf(json.get(SUBNET).asText());
+ } catch (IllegalArgumentException e) {
+ final String error = "Invalid ServiceNetwork subnet received: ";
+ throw new IllegalArgumentException(error + json.get(SUBNET).asText());
+ }
+ }
+
+ if (json.get(SERVICE_IP) != null && !json.get(SERVICE_IP).isNull()) {
+ try {
+ IpAddress.valueOf(json.get(SERVICE_IP).asText());
+ } catch (IllegalArgumentException e) {
+ final String error = "Invalid ServiceNetwork service IP address received: ";
+ throw new IllegalArgumentException(error + json.get(SERVICE_IP).asText());
+ }
+ }
+
+ if (json.get(PROVIDERS) != null && !json.get(PROVIDERS).isNull()) {
+ json.get(PROVIDERS).forEach(provider -> {
+ if (provider.get(ID) == null || provider.get(ID).isNull() ||
+ Strings.isNullOrEmpty(provider.get(ID).asText())) {
+ final String error = "Null or empty provider network ID received";
+ throw new IllegalArgumentException(error);
+ }
+
+ if (provider.get(DEP_TYPE) == null || provider.get(DEP_TYPE).isNull()
+ || !provider.get(DEP_TYPE).isBoolean()) {
+ final String error = "Non-boolean bidirectional received";
+ throw new IllegalArgumentException(error);
+ }
});
}
- return new ServiceNetwork(netId, netType, providers);
+
+ if (json.get(PROVIDER_NETWORKS) != null && !json.get(PROVIDER_NETWORKS).isNull()) {
+ json.get(PROVIDER_NETWORKS).forEach(provider -> {
+ if (provider.get(ID) == null || provider.get(ID).isNull() ||
+ Strings.isNullOrEmpty(provider.get(ID).asText())) {
+ final String error = "Null or empty provider network ID received";
+ throw new IllegalArgumentException(error);
+ }
+
+ if (provider.get(DEP_TYPE) == null || provider.get(DEP_TYPE).isNull()
+ || !provider.get(DEP_TYPE).isBoolean()) {
+ final String error = "Non-boolean bidirectional received";
+ throw new IllegalArgumentException(error);
+ }
+ });
+ }
}
}
diff --git a/src/main/java/org/opencord/cordvtn/codec/ServicePortCodec.java b/src/main/java/org/opencord/cordvtn/codec/ServicePortCodec.java
index bb4a82b..5292604 100644
--- a/src/main/java/org/opencord/cordvtn/codec/ServicePortCodec.java
+++ b/src/main/java/org/opencord/cordvtn/codec/ServicePortCodec.java
@@ -16,8 +16,9 @@
package org.opencord.cordvtn.codec;
import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
@@ -27,6 +28,7 @@
import org.opencord.cordvtn.api.net.AddressPair;
import org.opencord.cordvtn.api.net.PortId;
import org.opencord.cordvtn.api.net.ServicePort;
+import org.opencord.cordvtn.impl.DefaultServicePort;
import java.util.Set;
@@ -38,22 +40,36 @@
public final class ServicePortCodec extends JsonCodec<ServicePort> {
private static final String ID = "id";
+ private static final String NAME = "name";
+ private static final String NETWORK_ID = "network_id";
+ private static final String MAC_ADDRESS = "mac_address";
+ private static final String IP_ADDRESS = "ip_address";
private static final String VLAN_ID = "vlan_id";
private static final String FLOATING_ADDRESS_PAIRS = "floating_address_pairs";
- private static final String IP_ADDRESS = "ip_address";
- private static final String MAC_ADDRESS = "mac_address";
private static final String ERR_JSON = "Invalid ServicePort received";
- private static final String ERR_ID = ": port ID cannot be null";
+ private static final String ERR_ID = "Service port ID cannot be null";
@Override
public ObjectNode encode(ServicePort sport, CodecContext context) {
ObjectNode result = context.mapper().createObjectNode()
.put(ID, sport.id().id());
- if (sport.vlanId().isPresent()) {
- result.put(VLAN_ID, sport.vlanId().get().id());
- }
+ if (sport.networkId() != null) {
+ result.put(NETWORK_ID, sport.networkId().id());
+ }
+ if (!Strings.isNullOrEmpty(sport.name())) {
+ result.put(NAME, sport.name());
+ }
+ if (sport.vlanId() != null) {
+ result.put(VLAN_ID, sport.vlanId().id());
+ }
+ if (sport.mac() != null) {
+ result.put(MAC_ADDRESS, sport.mac().toString());
+ }
+ if (sport.ip() != null) {
+ result.put(IP_ADDRESS, sport.ip().toString());
+ }
ArrayNode addressPairs = context.mapper().createArrayNode();
sport.addressPairs().forEach(pair -> {
ObjectNode pairJson = context.mapper().createObjectNode()
@@ -62,34 +78,107 @@
addressPairs.add(pairJson);
});
result.set(FLOATING_ADDRESS_PAIRS, addressPairs);
+
return result;
}
@Override
public ServicePort decode(ObjectNode json, CodecContext context) {
- checkArgument(json != null && json.isObject(), ERR_JSON);
- checkArgument(json.get(ID) != null &&
- json.get(ID) != NullNode.getInstance(),
- ERR_JSON + ERR_ID);
+ validateJson(json);
+ ServicePort.Builder sportBuilder = DefaultServicePort.builder()
+ .id(PortId.of(json.get(ID).asText()));
- PortId portId = PortId.of(json.get(ID).asText());
- VlanId vlanId = null;
- if (json.get(VLAN_ID) != NullNode.getInstance()) {
- try {
- vlanId = VlanId.vlanId(json.get(VLAN_ID).asText());
- } catch (Exception ignore) {
- }
+ // TODO allow removing existing value when explicit null received
+ if (json.get(NAME) != null && !json.get(NAME).isNull()) {
+ sportBuilder.name(json.get(NAME).asText());
}
-
- Set<AddressPair> addressPairs = Sets.newHashSet();
- if (json.get(FLOATING_ADDRESS_PAIRS) != null) {
+ if (json.get(MAC_ADDRESS) != null && !json.get(MAC_ADDRESS).isNull()) {
+ sportBuilder.mac(MacAddress.valueOf(json.get(MAC_ADDRESS).asText()));
+ }
+ if (json.get(IP_ADDRESS) != null && !json.get(IP_ADDRESS).isNull()) {
+ sportBuilder.ip(IpAddress.valueOf(json.get(IP_ADDRESS).asText()));
+ }
+ if (json.get(VLAN_ID) != null && !json.get(VLAN_ID).isNull()) {
+ sportBuilder.vlanId(VlanId.vlanId(json.get(VLAN_ID).asText()));
+ }
+ if (json.get(FLOATING_ADDRESS_PAIRS).isNull()) {
+ sportBuilder.addressPairs(ImmutableSet.of());
+ } else if (json.get(FLOATING_ADDRESS_PAIRS) != null) {
+ Set<AddressPair> addressPairs = Sets.newHashSet();
json.get(FLOATING_ADDRESS_PAIRS).forEach(pair -> {
AddressPair addrPair = AddressPair.of(
IpAddress.valueOf(pair.get(IP_ADDRESS).asText()),
MacAddress.valueOf(pair.get(MAC_ADDRESS).asText()));
addressPairs.add(addrPair);
});
+ sportBuilder.addressPairs(addressPairs);
}
- return new ServicePort(portId, vlanId, addressPairs);
+ return sportBuilder.build();
+ }
+
+ private void validateJson(ObjectNode json) {
+ checkArgument(json != null && json.isObject(), ERR_JSON);
+ checkArgument(json.get(ID) != null && !json.get(ID).isNull(), ERR_ID);
+
+ // allow explicit null for removing the existing value
+ if (json.get(NAME) != null && !json.get(NAME).isNull()) {
+ if (Strings.isNullOrEmpty(json.get(NAME).asText())) {
+ final String error = "Null or empty ServiceNetwork name received";
+ throw new IllegalArgumentException(error);
+ }
+ }
+
+ if (json.get(MAC_ADDRESS) != null && !json.get(MAC_ADDRESS).isNull()) {
+ try {
+ MacAddress.valueOf(json.get(MAC_ADDRESS).asText());
+ } catch (IllegalArgumentException e) {
+ final String error = "Invalid ServicePort MAC address received: ";
+ throw new IllegalArgumentException(error + json.get(MAC_ADDRESS).asText());
+ }
+ }
+
+ if (json.get(IP_ADDRESS) != null && !json.get(IP_ADDRESS).isNull()) {
+ try {
+ IpAddress.valueOf(json.get(IP_ADDRESS).asText());
+ } catch (IllegalArgumentException e) {
+ final String error = "Invalid ServicePort IP address received: ";
+ throw new IllegalArgumentException(error + json.get(IP_ADDRESS).asText());
+ }
+ }
+
+ if (json.get(VLAN_ID) != null && !json.get(VLAN_ID).isNull()) {
+ try {
+ VlanId.vlanId(json.get(VLAN_ID).asText());
+ } catch (IllegalArgumentException e) {
+ final String error = "Invalid VLAN ID is received: ";
+ throw new IllegalArgumentException(error + json.get(VLAN_ID).asText());
+ }
+ }
+
+ if (json.get(FLOATING_ADDRESS_PAIRS) != null &&
+ !json.get(FLOATING_ADDRESS_PAIRS).isNull()) {
+ json.get(FLOATING_ADDRESS_PAIRS).forEach(pair -> {
+ if (pair.get(IP_ADDRESS) == null ||
+ pair.get(IP_ADDRESS).isNull() ||
+ pair.get(MAC_ADDRESS) == null ||
+ pair.get(MAC_ADDRESS).isNull()) {
+ final String error = "Invalid floating address pair received";
+ throw new IllegalArgumentException(error);
+ }
+ try {
+ IpAddress.valueOf(pair.get(IP_ADDRESS).asText());
+ } catch (IllegalArgumentException e) {
+ final String error = "Invalid floating address pair IP: ";
+ throw new IllegalArgumentException(error + pair.get(IP_ADDRESS).asText());
+ }
+
+ try {
+ MacAddress.valueOf(pair.get(MAC_ADDRESS).asText());
+ } catch (IllegalArgumentException e) {
+ final String error = "Invalid floating address pair MAC: ";
+ throw new IllegalArgumentException(error + pair.get(MAC_ADDRESS).asText());
+ }
+ });
+ }
}
}
diff --git a/src/main/java/org/opencord/cordvtn/impl/CordVtnArpProxy.java b/src/main/java/org/opencord/cordvtn/impl/CordVtnArpProxy.java
index c2e2a62..7b906e9 100644
--- a/src/main/java/org/opencord/cordvtn/impl/CordVtnArpProxy.java
+++ b/src/main/java/org/opencord/cordvtn/impl/CordVtnArpProxy.java
@@ -29,14 +29,11 @@
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
import org.onosproject.net.PortNumber;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
-import org.onosproject.net.config.NetworkConfigRegistry;
-import org.onosproject.net.packet.PacketProcessor;
-import org.opencord.cordvtn.api.config.CordVtnConfig;
-import org.opencord.cordvtn.api.instance.Instance;
-import org.onosproject.net.Host;
+import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
@@ -44,8 +41,11 @@
import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
-import org.opencord.cordvtn.api.net.VtnNetwork;
+import org.opencord.cordvtn.api.CordVtnConfig;
+import org.opencord.cordvtn.api.core.Instance;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
import org.opencord.cordvtn.impl.handler.AbstractInstanceHandler;
import org.slf4j.Logger;
@@ -55,7 +55,7 @@
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.*;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.*;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -72,7 +72,7 @@
protected CordVtnNodeManager nodeManager;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected NetworkConfigRegistry configRegistry;
+ protected NetworkConfigService configService;
private final PacketProcessor packetProcessor = new InternalPacketProcessor();
private final Map<Ip4Address, MacAddress> gateways = Maps.newConcurrentMap();
@@ -83,7 +83,7 @@
@Activate
protected void activate() {
super.activate();
- configRegistry.addListener(configListener);
+ configService.addListener(configListener);
readConfiguration();
packetService.addProcessor(packetProcessor, PacketProcessor.director(0));
@@ -93,7 +93,7 @@
@Deactivate
protected void deactivate() {
packetService.removeProcessor(packetProcessor);
- configRegistry.removeListener(configListener);
+ configService.removeListener(configListener);
super.deactivate();
}
@@ -354,13 +354,13 @@
return;
}
- VtnNetwork vtnNet = getVtnNetwork(instance);
- if (vtnNet.type() != PUBLIC && vtnNet.type() != MANAGEMENT_HOST &&
- vtnNet.type() != MANAGEMENT_LOCAL) {
- log.trace("Added IP:{} MAC:{}", vtnNet.serviceIp(), privateGatewayMac);
- addGateway(vtnNet.serviceIp(), privateGatewayMac);
+ ServiceNetwork snet = getServiceNetwork(instance);
+ if (snet.type() != PUBLIC && snet.type() != MANAGEMENT_HOST &&
+ snet.type() != MANAGEMENT_LOCAL) {
+ log.trace("Added IP:{} MAC:{}", snet.serviceIp(), privateGatewayMac);
+ addGateway(snet.serviceIp(), privateGatewayMac);
// send gratuitous ARP for the existing VMs when ONOS is restarted
- sendGratuitousArp(vtnNet.serviceIp(), ImmutableSet.of(instance));
+ sendGratuitousArp(snet.serviceIp(), ImmutableSet.of(instance));
}
}
@@ -372,7 +372,7 @@
return;
}
- VtnNetwork vtnNet = getVtnNetwork(instance);
+ ServiceNetwork vtnNet = getServiceNetwork(instance);
// remove this network gateway from proxy ARP if no instance presents
if (vtnNet.type() == PRIVATE &&
getInstances(vtnNet.id()).isEmpty()) {
@@ -381,7 +381,7 @@
}
private void readConfiguration() {
- CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class);
+ CordVtnConfig config = configService.getConfig(appId, CordVtnConfig.class);
if (config == null) {
log.debug("No configuration found");
return;
diff --git a/src/main/java/org/opencord/cordvtn/impl/CordVtnDhcpProxy.java b/src/main/java/org/opencord/cordvtn/impl/CordVtnDhcpProxy.java
index 607e3b0..e1f8fbf 100644
--- a/src/main/java/org/opencord/cordvtn/impl/CordVtnDhcpProxy.java
+++ b/src/main/java/org/opencord/cordvtn/impl/CordVtnDhcpProxy.java
@@ -39,7 +39,7 @@
import org.onosproject.net.HostId;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
-import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
@@ -51,10 +51,11 @@
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.opencord.cordvtn.api.Constants;
-import org.opencord.cordvtn.api.config.CordVtnConfig;
-import org.opencord.cordvtn.api.core.CordVtnService;
-import org.opencord.cordvtn.api.instance.Instance;
-import org.opencord.cordvtn.api.net.VtnNetwork;
+import org.opencord.cordvtn.api.CordVtnConfig;
+import org.opencord.cordvtn.api.core.Instance;
+import org.opencord.cordvtn.api.core.ServiceNetworkService;
+import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
import org.slf4j.Logger;
import java.nio.ByteBuffer;
@@ -68,8 +69,9 @@
import static org.onlab.packet.DHCP.DHCPOptionCode.*;
import static org.onlab.packet.DHCPPacketType.DHCPACK;
import static org.onlab.packet.DHCPPacketType.DHCPOFFER;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.MANAGEMENT_HOST;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.MANAGEMENT_LOCAL;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType.BIDIRECTIONAL;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.MANAGEMENT_HOST;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.MANAGEMENT_LOCAL;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -94,7 +96,7 @@
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected NetworkConfigRegistry configRegistry;
+ protected NetworkConfigService configService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PacketService packetService;
@@ -103,7 +105,7 @@
protected HostService hostService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected CordVtnService cordVtnService;
+ protected ServiceNetworkService snetService;
private final PacketProcessor packetProcessor = new InternalPacketProcessor();
private final NetworkConfigListener configListener = new InternalConfigListener();
@@ -114,7 +116,7 @@
@Activate
protected void activate() {
appId = coreService.registerApplication(Constants.CORDVTN_APP_ID);
- configRegistry.addListener(configListener);
+ configService.addListener(configListener);
readConfiguration();
packetService.addProcessor(packetProcessor, PacketProcessor.director(0));
@@ -124,7 +126,7 @@
@Deactivate
protected void deactivate() {
- configRegistry.removeListener(configListener);
+ configService.removeListener(configListener);
packetService.removeProcessor(packetProcessor);
cancelPackets();
log.info("Stopped");
@@ -246,8 +248,8 @@
checkArgument(!dhcpServerMac.equals(MacAddress.NONE),
"DHCP server MAC is not set");
- VtnNetwork vtnNet = cordVtnService.vtnNetwork(reqInstance.netId());
- Ip4Address serverIp = vtnNet.serviceIp().getIp4Address();
+ ServiceNetwork snet = snetService.serviceNetwork(reqInstance.netId());
+ Ip4Address serverIp = snet.serviceIp().getIp4Address();
Ethernet ethReply = new Ethernet();
ethReply.setSourceMACAddress(dhcpServerMac);
@@ -267,7 +269,7 @@
DHCP dhcpRequest = (DHCP) udpRequest.getPayload();
DHCP dhcpReply = buildDhcpReply(
- dhcpRequest, packetType, reqInstance.ipAddress(), vtnNet);
+ dhcpRequest, packetType, reqInstance.ipAddress(), snet);
udpReply.setPayload(dhcpReply);
ipv4Reply.setPayload(udpReply);
@@ -294,9 +296,9 @@
}
private DHCP buildDhcpReply(DHCP request, byte msgType, Ip4Address yourIp,
- VtnNetwork vtnNet) {
- Ip4Address serverIp = vtnNet.serviceIp().getIp4Address();
- int subnetPrefixLen = vtnNet.subnet().prefixLength();
+ ServiceNetwork snet) {
+ Ip4Address serverIp = snet.serviceIp().getIp4Address();
+ int subnetPrefixLen = snet.subnet().prefixLength();
DHCP dhcpReply = new DHCP();
dhcpReply.setOpCode(DHCP.OPCODE_REPLY);
@@ -362,7 +364,7 @@
options.add(option);
// router address
- if (vtnNet.type() != MANAGEMENT_LOCAL && vtnNet.type() != MANAGEMENT_HOST) {
+ if (snet.type() != MANAGEMENT_LOCAL && snet.type() != MANAGEMENT_HOST) {
option = new DHCPOption();
option.setCode(OptionCode_RouterAddress.getValue());
option.setLength((byte) 4);
@@ -371,7 +373,7 @@
}
// classless static routes
- byte[] data = getClasslessStaticRoutesData(vtnNet);
+ byte[] data = getClasslessStaticRoutesData(snet);
if (data.length >= 5) {
option = new DHCPOption();
option.setCode(DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
@@ -390,13 +392,13 @@
return dhcpReply;
}
- private byte[] getClasslessStaticRoutesData(VtnNetwork vtnNet) {
+ private byte[] getClasslessStaticRoutesData(ServiceNetwork snet) {
List<Byte> result = Lists.newArrayList();
- List<Byte> router = Bytes.asList(vtnNet.serviceIp().toOctets());
+ List<Byte> router = Bytes.asList(snet.serviceIp().toOctets());
// static routes for the providers
- Set<VtnNetwork> providers = vtnNet.providers().stream()
- .map(provider -> cordVtnService.vtnNetwork(provider.id()))
+ Set<ServiceNetwork> providers = snet.providers().keySet().stream()
+ .map(provider -> snetService.serviceNetwork(provider))
.filter(Objects::nonNull)
.collect(Collectors.toSet());
@@ -407,8 +409,8 @@
});
// static routes for the bidirectional subscribers
- Set<VtnNetwork> subscribers = cordVtnService.vtnNetworks().stream()
- .filter(net -> net.isBidirectionalProvider(vtnNet.id()))
+ Set<ServiceNetwork> subscribers = snetService.serviceNetworks().stream()
+ .filter(net -> isBidirectionalProvider(net, snet.id()))
.collect(Collectors.toSet());
subscribers.stream().forEach(subscriber -> {
@@ -420,6 +422,13 @@
return Bytes.toArray(result);
}
+ private boolean isBidirectionalProvider(ServiceNetwork snet, NetworkId targetNetId) {
+ return snet.providers().entrySet().stream()
+ .filter(p -> Objects.equals(p.getKey(), targetNetId))
+ .filter(p -> p.getValue() == BIDIRECTIONAL)
+ .findAny().isPresent();
+ }
+
private List<Byte> getSignificantOctets(IpPrefix ipPrefix) {
int numOfOctets = ipPrefix.prefixLength() / 8;
if (ipPrefix.prefixLength() % 8 != 0) {
@@ -431,7 +440,7 @@
}
private void readConfiguration() {
- CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class);
+ CordVtnConfig config = configService.getConfig(appId, CordVtnConfig.class);
if (config == null) {
log.debug("No configuration found");
return;
diff --git a/src/main/java/org/opencord/cordvtn/impl/CordVtnManager.java b/src/main/java/org/opencord/cordvtn/impl/CordVtnManager.java
deleted file mode 100644
index f3dd1f4..0000000
--- a/src/main/java/org/opencord/cordvtn/impl/CordVtnManager.java
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.impl;
-
-import com.google.common.collect.ImmutableSet;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.Service;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.event.ListenerRegistry;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.config.ConfigFactory;
-import org.onosproject.net.config.NetworkConfigRegistry;
-import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.config.basics.SubjectFactories;
-import org.onosproject.net.host.HostService;
-import org.opencord.cordvtn.api.Constants;
-import org.opencord.cordvtn.api.config.CordVtnConfig;
-import org.opencord.cordvtn.api.config.OpenStackConfig;
-import org.opencord.cordvtn.api.config.XosConfig;
-import org.opencord.cordvtn.api.core.CordVtnAdminService;
-import org.opencord.cordvtn.api.core.CordVtnService;
-import org.opencord.cordvtn.api.core.CordVtnStore;
-import org.opencord.cordvtn.api.core.CordVtnStoreDelegate;
-import org.opencord.cordvtn.api.instance.Instance;
-import org.opencord.cordvtn.api.net.NetworkId;
-import org.opencord.cordvtn.api.net.NetworkService;
-import org.opencord.cordvtn.api.net.PortId;
-import org.opencord.cordvtn.api.net.ServiceNetwork;
-import org.opencord.cordvtn.api.net.ServiceNetworkService;
-import org.opencord.cordvtn.api.net.ServicePort;
-import org.opencord.cordvtn.api.net.SubnetId;
-import org.opencord.cordvtn.api.net.VtnNetwork;
-import org.opencord.cordvtn.api.net.VtnNetworkEvent;
-import org.opencord.cordvtn.api.net.VtnNetworkListener;
-import org.opencord.cordvtn.api.net.VtnPort;
-import org.opencord.cordvtn.impl.external.OpenStackNetworking;
-import org.opencord.cordvtn.impl.external.XosServiceNetworking;
-import org.openstack4j.model.network.Network;
-import org.openstack4j.model.network.Port;
-import org.openstack4j.model.network.Subnet;
-import org.slf4j.Logger;
-
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Provides implementation of administering and interfacing VTN networks.
- */
-@Component(immediate = true)
-@Service
-public class CordVtnManager extends ListenerRegistry<VtnNetworkEvent, VtnNetworkListener>
- implements CordVtnAdminService, CordVtnService, NetworkService,
- ServiceNetworkService {
-
- protected final Logger log = getLogger(getClass());
-
- private static final String MSG_SERVICE_NET = "VTN network %s %s";
- private static final String MSG_SERVICE_PORT = "VTN port %s %s";
- private static final String MSG_NET = "Network %s %s";
- private static final String MSG_PORT = "Port %s %s";
- private static final String MSG_SUBNET = "Subnet %s %s";
-
- private static final String CREATED = "created";
- private static final String UPDATED = "updated";
- private static final String REMOVED = "removed";
-
- private static final String ERR_NULL_SERVICE_PORT = "Service port cannot be null";
- private static final String ERR_NULL_SERVICE_NET = "Service network cannot be null";
- private static final String ERR_NULL_PORT = "Port cannot be null";
- private static final String ERR_NULL_NET = "Network cannot be null";
- private static final String ERR_NULL_SUBNET = "Subnet cannot be null";
- private static final String ERR_NULL_PORT_ID = "Port ID cannot be null";
- private static final String ERR_NULL_NET_ID = "Network ID cannot be null";
- private static final String ERR_NULL_SUBNET_ID = "Subnet ID cannot be null";
-
- private static final String ERR_SYNC = "VTN store is out of sync: ";
- private static final String ERR_NOT_FOUND = " does not exist";
- private static final String ERR_IN_USE_PORT = "There are ports still in use on the network %s";
- private static final String ERR_SUBNET_DUPLICATE = "Subnet already exists for network %s";
-
- private static final String PORT = "port ";
- private static final String NETWORK = "network ";
- private static final String SUBNET = "subnet for ";
- private static final String PROVIDER = "provider ";
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected NetworkConfigService configService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected NetworkConfigRegistry configRegistry;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected CoreService coreService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected HostService hostService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected CordVtnStore store;
-
- // TODO add cordvtn config service and move this
- private static final Class<CordVtnConfig> CONFIG_CLASS = CordVtnConfig.class;
- private final ConfigFactory configFactory =
- new ConfigFactory<ApplicationId, CordVtnConfig>(
- SubjectFactories.APP_SUBJECT_FACTORY, CONFIG_CLASS, "cordvtn") {
- @Override
- public CordVtnConfig createConfig() {
- return new CordVtnConfig();
- }
- };
-
- private final CordVtnStoreDelegate delegate = new InternalCordVtnStoreDelegate();
- private ApplicationId appId;
-
- @Activate
- protected void activate() {
- appId = coreService.registerApplication(Constants.CORDVTN_APP_ID);
- configRegistry.registerConfigFactory(configFactory);
- store.setDelegate(delegate);
- log.info("Started");
- }
-
- @Deactivate
- protected void deactivate() {
- configRegistry.unregisterConfigFactory(configFactory);
- store.unsetDelegate(delegate);
- log.info("Stopped");
- }
-
- @Override
- public void purgeStates() {
- store.clear();
- }
-
- @Override
- public void syncStates() {
- syncNetwork();
- syncServiceNetwork();
- }
-
- @Override
- public void createServiceNetwork(ServiceNetwork serviceNet) {
- checkNotNull(serviceNet, ERR_NULL_SERVICE_NET);
- synchronized (this) {
- Network network = store.network(serviceNet.id());
- if (network == null) {
- final String error = ERR_SYNC + NETWORK + serviceNet.id() + ERR_NOT_FOUND;
- throw new IllegalStateException(error);
- }
-
- Subnet subnet = getSubnet(serviceNet.id());
- if (subnet == null) {
- final String error = ERR_SYNC + SUBNET + serviceNet.id() + ERR_NOT_FOUND;
- throw new IllegalStateException(error);
- }
-
- // TODO check VTN network instead of network
- serviceNet.providers().stream().forEach(provider -> {
- if (store.network(provider.id()) == null) {
- final String error = ERR_SYNC + PROVIDER + provider.id() + ERR_NOT_FOUND;
- throw new IllegalStateException(error);
- }
- });
-
- store.createVtnNetwork(VtnNetwork.of(network, subnet, serviceNet));
- log.info(String.format(MSG_SERVICE_NET, CREATED, serviceNet.id()));
- }
- }
-
- @Override
- public void updateServiceNetwork(ServiceNetwork serviceNet) {
- checkNotNull(serviceNet, ERR_NULL_SERVICE_NET);
- synchronized (this) {
- VtnNetwork existing = store.vtnNetwork(serviceNet.id());
- if (existing == null) {
- final String error = ERR_SYNC + NETWORK + serviceNet.id() + ERR_NOT_FOUND;
- throw new IllegalStateException(error);
- }
- // only providers update is allowed
- VtnNetwork updated = VtnNetwork.builder(existing)
- .providers(serviceNet.providers())
- .build();
- store.updateVtnNetwork(updated);
- log.info(String.format(MSG_SERVICE_NET, UPDATED, serviceNet.id()));
- }
- }
-
- @Override
- public void removeServiceNetwork(NetworkId netId) {
- checkNotNull(netId, ERR_NULL_NET_ID);
- // TODO check if the network still exists?
- store.removeVtnNetwork(netId);
- log.info(String.format(MSG_SERVICE_NET, REMOVED, netId));
- }
-
- @Override
- public void createServicePort(ServicePort servicePort) {
- checkNotNull(servicePort, ERR_NULL_SERVICE_PORT);
- synchronized (this) {
- Port port = store.port(servicePort.id());
- if (port == null) {
- final String error = ERR_SYNC + PORT + servicePort.id() + ERR_NOT_FOUND;
- throw new IllegalStateException(error);
- }
- store.createVtnPort(VtnPort.of(port, servicePort));
- log.info(String.format(MSG_SERVICE_PORT, CREATED, servicePort.id()));
- }
- }
-
- @Override
- public void updateServicePort(ServicePort servicePort) {
- checkNotNull(servicePort, ERR_NULL_SERVICE_PORT);
- synchronized (this) {
- VtnPort vtnPort = store.vtnPort(servicePort.id());
- if (vtnPort == null) {
- final String error = ERR_SYNC + PORT + servicePort.id() + ERR_NOT_FOUND;
- throw new IllegalStateException(error);
- }
- store.updateVtnPort(VtnPort.of(vtnPort, servicePort));
- log.info(String.format(MSG_SERVICE_PORT, UPDATED, servicePort.id()));
- }
- }
-
- @Override
- public void removeServicePort(PortId portId) {
- checkNotNull(portId, ERR_NULL_PORT_ID);
- store.removeVtnPort(portId);
- log.info(String.format(MSG_SERVICE_PORT, REMOVED, portId));
- }
-
- @Override
- public void createNetwork(Network network) {
- checkNotNull(network, ERR_NULL_NET);
- store.createNetwork(network);
- log.info(String.format(MSG_NET, CREATED, network.getId()));
- }
-
- @Override
- public void updateNetwork(Network network) {
- checkNotNull(network, ERR_NULL_NET);
- store.updateNetwork(network);
- log.info(String.format(MSG_NET, UPDATED, network.getId()));
- }
-
- @Override
- public void removeNetwork(NetworkId netId) {
- checkNotNull(netId, ERR_NULL_NET_ID);
- // FIXME Neutron removes network anyway even if there's an exception here
- store.removeNetwork(netId);
- log.info(String.format(MSG_NET, REMOVED, netId));
- }
-
- @Override
- public void createPort(Port port) {
- checkNotNull(port, ERR_NULL_PORT);
- synchronized (this) {
- if (store.network(NetworkId.of(port.getNetworkId())) == null) {
- final String error = ERR_SYNC + port.getNetworkId() + ERR_NOT_FOUND;
- throw new IllegalStateException(error);
- }
- store.createPort(port);
- log.info(String.format(MSG_PORT, CREATED, port.getId()));
- }
- }
-
- @Override
- public void updatePort(Port port) {
- checkNotNull(port, ERR_NULL_PORT);
- synchronized (this) {
- if (store.network(NetworkId.of(port.getNetworkId())) == null) {
- final String error = ERR_SYNC + port.getNetworkId() + ERR_NOT_FOUND;
- throw new IllegalStateException(error);
- }
- store.updatePort(port);
- log.info(String.format(MSG_PORT, UPDATED, port.getId()));
- }
- }
-
- @Override
- public void removePort(PortId portId) {
- checkNotNull(portId, ERR_NULL_PORT_ID);
- synchronized (this) {
- if (getInstance(portId) != null) {
- final String error = String.format(ERR_IN_USE_PORT, portId);
- throw new IllegalStateException(error);
- }
- removeServicePort(portId);
- store.removePort(portId);
- log.info(String.format(MSG_PORT, REMOVED, portId));
- }
- }
-
- @Override
- public void createSubnet(Subnet subnet) {
- checkNotNull(subnet, ERR_NULL_SUBNET);
- synchronized (this) {
- if (store.network(NetworkId.of(subnet.getNetworkId())) == null) {
- final String error = ERR_SYNC + subnet.getNetworkId() + ERR_NOT_FOUND;
- throw new IllegalStateException(error);
- }
-
- Subnet existing = getSubnet(NetworkId.of(subnet.getNetworkId()));
- if (existing != null && !Objects.equals(existing.getId(), subnet.getId())) {
- // CORD does not allow multiple subnets for a network
- final String error = String.format(ERR_SUBNET_DUPLICATE, subnet.getNetworkId());
- throw new IllegalStateException(error);
- }
- store.createSubnet(subnet);
- // FIXME update the network as well with the new subnet
- log.info(String.format(MSG_SUBNET, CREATED, subnet.getId()));
- }
- }
-
- @Override
- public void updateSubnet(Subnet subnet) {
- checkNotNull(subnet, ERR_NULL_SUBNET);
- synchronized (this) {
- if (store.network(NetworkId.of(subnet.getNetworkId())) == null) {
- final String error = ERR_SYNC + subnet.getNetworkId() + ERR_NOT_FOUND;
- throw new IllegalStateException(error);
- }
- store.updateSubnet(subnet);
- log.info(String.format(MSG_SUBNET, UPDATED, subnet.getId()));
- }
- }
-
- @Override
- public void removeSubnet(SubnetId subnetId) {
- checkNotNull(subnetId, ERR_NULL_SUBNET_ID);
- // FIXME Neutron removes network anyway even if there's an exception here
- synchronized (this) {
- removeServiceNetwork(NetworkId.of(store.subnet(subnetId).getNetworkId()));
- store.removeSubnet(subnetId);
- log.info(String.format(MSG_SUBNET, REMOVED, subnetId));
- }
- }
-
- @Override
- public VtnNetwork vtnNetwork(NetworkId netId) {
- checkNotNull(netId, ERR_NULL_NET_ID);
-
- // return default VTN network if the network and subnet exist
- VtnNetwork vtnNet = store.vtnNetwork(netId);
- return vtnNet == null ? getDefaultVtnNetwork(netId) : vtnNet;
- }
-
- @Override
- public Set<VtnNetwork> vtnNetworks() {
- Set<VtnNetwork> vtnNetworks = networks().stream()
- .filter(net -> vtnNetwork(NetworkId.of(net.getId())) != null)
- .map(net -> vtnNetwork(NetworkId.of(net.getId())))
- .collect(Collectors.toSet());
- return ImmutableSet.copyOf(vtnNetworks);
- }
-
- @Override
- public VtnPort vtnPort(PortId portId) {
- checkNotNull(portId, ERR_NULL_PORT_ID);
-
- // return default VTN port if the port exists
- VtnPort vtnPort = store.vtnPort(portId);
- return vtnPort == null ? getDefaultPort(portId) : vtnPort;
- }
-
- @Override
- public VtnPort vtnPort(String portName) {
- Optional<Port> port = store.ports()
- .stream()
- .filter(p -> p.getId().contains(portName.substring(3)))
- .findFirst();
- if (!port.isPresent()) {
- return null;
- }
- return vtnPort(PortId.of(port.get().getId()));
- }
-
- @Override
- public Set<VtnPort> vtnPorts() {
- Set<VtnPort> vtnPorts = ports().stream()
- .filter(port -> vtnPort(PortId.of(port.getId())) != null)
- .map(port -> vtnPort(PortId.of(port.getId())))
- .collect(Collectors.toSet());
- return ImmutableSet.copyOf(vtnPorts);
- }
-
- @Override
- public ServiceNetwork serviceNetwork(NetworkId netId) {
- checkNotNull(netId, ERR_NULL_NET_ID);
- return store.vtnNetwork(netId);
- }
-
- @Override
- public Set<ServiceNetwork> serviceNetworks() {
- return ImmutableSet.copyOf(store.vtnNetworks());
- }
-
- @Override
- public ServicePort servicePort(PortId portId) {
- checkNotNull(portId, ERR_NULL_PORT_ID);
- return store.vtnPort(portId);
- }
-
- @Override
- public Set<ServicePort> servicePorts() {
- return ImmutableSet.copyOf(store.vtnPorts());
- }
-
- @Override
- public Network network(NetworkId netId) {
- checkNotNull(netId, ERR_NULL_NET_ID);
- return store.network(netId);
- }
-
- @Override
- public Set<Network> networks() {
- return ImmutableSet.copyOf(store.networks());
- }
-
- @Override
- public Port port(PortId portId) {
- checkNotNull(portId, ERR_NULL_PORT_ID);
- return store.port(portId);
- }
-
- @Override
- public Set<Port> ports() {
- return ImmutableSet.copyOf(store.ports());
- }
-
- @Override
- public Subnet subnet(SubnetId subnetId) {
- checkNotNull(subnetId, ERR_NULL_SUBNET_ID);
- return store.subnet(subnetId);
- }
-
- @Override
- public Set<Subnet> subnets() {
- return ImmutableSet.copyOf(store.subnets());
- }
-
- private void syncNetwork() {
- CordVtnConfig config = configService.getConfig(appId, CordVtnConfig.class);
- if (config == null) {
- final String error = "Failed to read network configurations";
- throw new IllegalArgumentException(error);
- }
-
- OpenStackConfig osConfig = config.openStackConfig();
- NetworkService netService = OpenStackNetworking.builder()
- .endpoint(osConfig.endpoint())
- .tenant(osConfig.tenant())
- .user(osConfig.user())
- .password(osConfig.password())
- .build();
-
- netService.networks().forEach(this::createNetwork);
- netService.subnets().forEach(this::createSubnet);
- netService.ports().forEach(this::createPort);
- }
-
- private void syncServiceNetwork() {
- CordVtnConfig config = configService.getConfig(appId, CordVtnConfig.class);
- if (config == null) {
- final String error = "Failed to read network configurations";
- throw new IllegalArgumentException(error);
- }
-
- XosConfig xosConfig = config.xosConfig();
- ServiceNetworkService snetService = XosServiceNetworking.builder()
- .endpoint(xosConfig.endpoint())
- .user(xosConfig.user())
- .password(xosConfig.password())
- .build();
-
- snetService.serviceNetworks().forEach(this::createServiceNetwork);
- snetService.servicePorts().forEach(this::createServicePort);
- }
-
- private Instance getInstance(PortId portId) {
- VtnPort vtnPort = vtnPort(portId);
- if (vtnPort == null) {
- final String error = "Failed to build VTN port for " + portId.id();
- throw new IllegalStateException(error);
- }
- Host host = hostService.getHost(HostId.hostId(vtnPort.mac()));
- if (host == null) {
- return null;
- }
- return Instance.of(host);
- }
-
- private VtnNetwork getDefaultVtnNetwork(NetworkId netId) {
- Network network = network(netId);
- Subnet subnet = getSubnet(netId);
- if (network == null || subnet == null) {
- return null;
- }
- return VtnNetwork.of(network, subnet, null);
- }
-
- private VtnPort getDefaultPort(PortId portId) {
- Port port = port(portId);
- if (port == null) {
- return null;
- }
- return VtnPort.of(port, null);
- }
-
- private Subnet getSubnet(NetworkId netId) {
- Optional<Subnet> subnet = subnets().stream()
- .filter(s -> Objects.equals(s.getNetworkId(), netId.id()))
- .findFirst();
- return subnet.orElse(null);
- }
-
- private class InternalCordVtnStoreDelegate implements CordVtnStoreDelegate {
-
- @Override
- public void notify(VtnNetworkEvent event) {
- if (event != null) {
- log.trace("send service network event {}", event);
- process(event);
- }
- }
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/impl/CordVtnNodeManager.java b/src/main/java/org/opencord/cordvtn/impl/CordVtnNodeManager.java
index f7f9c2d..44b70ac 100644
--- a/src/main/java/org/opencord/cordvtn/impl/CordVtnNodeManager.java
+++ b/src/main/java/org/opencord/cordvtn/impl/CordVtnNodeManager.java
@@ -65,12 +65,12 @@
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.Versioned;
-import org.opencord.cordvtn.api.config.CordVtnConfig;
-import org.opencord.cordvtn.api.instance.InstanceService;
+import org.opencord.cordvtn.api.CordVtnConfig;
+import org.opencord.cordvtn.api.core.InstanceService;
+import org.opencord.cordvtn.api.net.CidrAddr;
import org.opencord.cordvtn.api.node.ConnectionHandler;
import org.opencord.cordvtn.api.node.CordVtnNode;
import org.opencord.cordvtn.api.node.CordVtnNodeState;
-import org.opencord.cordvtn.api.node.NetworkAddress;
import org.opencord.cordvtn.api.node.SshAccessInfo;
import org.slf4j.Logger;
@@ -107,7 +107,7 @@
.register(CordVtnNode.class)
.register(NodeState.class)
.register(SshAccessInfo.class)
- .register(NetworkAddress.class);
+ .register(CidrAddr.class);
private static final int DPID_BEGIN = 3;
@@ -751,6 +751,7 @@
if (node.systemIfaces().contains(portName)) {
setNodeState(node, getNodeState(node));
} else if (isNodeStateComplete(node)) {
+ // TODO move this logic to InstanceManager
instanceService.addInstance(connectPoint(port));
} else {
log.warn("Instance is detected on incomplete node, ignore it.", portName);
@@ -777,6 +778,7 @@
if (node.systemIfaces().contains(portName)) {
setNodeState(node, NodeState.INCOMPLETE);
} else if (isNodeStateComplete(node)) {
+ // TODO move this logic to InstanceManager
instanceService.removeInstance(connectPoint(port));
} else {
log.warn("VM is vanished from incomplete node, ignore it.", portName);
diff --git a/src/main/java/org/opencord/cordvtn/impl/DefaultServiceNetwork.java b/src/main/java/org/opencord/cordvtn/impl/DefaultServiceNetwork.java
new file mode 100644
index 0000000..68a8d4a
--- /dev/null
+++ b/src/main/java/org/opencord/cordvtn/impl/DefaultServiceNetwork.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed 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 org.opencord.cordvtn.impl;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.SegmentId;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
+
+import java.util.Map;
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Collections.EMPTY_MAP;
+
+/**
+ * Implementation of {@link ServiceNetwork}.
+ */
+public final class DefaultServiceNetwork implements ServiceNetwork {
+
+ private static final String ERR_ID_MISSING = "Service network ID cannot be null";
+
+ private final NetworkId id;
+ private final String name;
+ private final NetworkType type;
+ private final SegmentId segmentId;
+ private final IpPrefix subnet;
+ private final IpAddress serviceIp;
+ private final Map<NetworkId, DependencyType> providers;
+
+ private DefaultServiceNetwork(NetworkId id,
+ String name,
+ NetworkType type,
+ SegmentId segmentId,
+ IpPrefix subnet,
+ IpAddress serviceIp,
+ Map<NetworkId, DependencyType> providers) {
+ this.id = id;
+ this.name = name;
+ this.type = type;
+ this.segmentId = segmentId;
+ this.subnet = subnet;
+ this.serviceIp = serviceIp;
+ this.providers = providers;
+ }
+
+ @Override
+ public NetworkId id() {
+ return id;
+ }
+
+ @Override
+ public String name() {
+ return name;
+ }
+
+ @Override
+ public NetworkType type() {
+ return type;
+ }
+
+ @Override
+ public SegmentId segmentId() {
+ return segmentId;
+ }
+
+ @Override
+ public IpPrefix subnet() {
+ return subnet;
+ }
+
+ @Override
+ public IpAddress serviceIp() {
+ return serviceIp;
+ }
+
+ @Override
+ public Map<NetworkId, DependencyType> providers() {
+ return providers;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof DefaultServiceNetwork) {
+ DefaultServiceNetwork that = (DefaultServiceNetwork) obj;
+ if (Objects.equals(id, that.id) &&
+ Objects.equals(name, that.name) &&
+ Objects.equals(type, that.type) &&
+ Objects.equals(segmentId, that.segmentId) &&
+ Objects.equals(subnet, that.subnet) &&
+ Objects.equals(serviceIp, that.serviceIp) &&
+ Objects.equals(providers, that.providers)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name, segmentId, subnet, serviceIp, type, providers);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("id", id)
+ .add("name", name)
+ .add("type", type)
+ .add("segmentId", segmentId)
+ .add("subnet", subnet)
+ .add("serviceIp", serviceIp)
+ .add("providers", providers)
+ .toString();
+ }
+
+ /**
+ * Returns new service network builder instance.
+ *
+ * @return service network builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns new service network builder instance with copy of the given service network.
+ *
+ * @param snet service network
+ * @return service network builder
+ */
+ public static Builder builder(ServiceNetwork snet) {
+ return new Builder()
+ .id(snet.id())
+ .name(snet.name())
+ .type(snet.type())
+ .segmentId(snet.segmentId())
+ .subnet(snet.subnet())
+ .serviceIp(snet.serviceIp())
+ .providers(snet.providers());
+ }
+
+ /**
+ * Returns service network builder instance with updated values. Any value
+ * not specified in the updated but in the existing remains in the updated
+ * builder.
+ *
+ * @param existing existing service network
+ * @param updated updated service network
+ * @return service network builder
+ */
+ public static Builder builder(ServiceNetwork existing, ServiceNetwork updated) {
+ checkArgument(Objects.equals(existing.id(), updated.id()));
+ // FIXME allow removing existing values
+ return new Builder()
+ .id(existing.id())
+ .name(updated.name() != null ? updated.name() : existing.name())
+ .type(updated.type() != null ? updated.type() : existing.type())
+ .segmentId(updated.segmentId() != null ?
+ updated.segmentId() : existing.segmentId())
+ .subnet(updated.subnet() != null ? updated.subnet() : existing.subnet())
+ .serviceIp(updated.serviceIp() != null ?
+ updated.serviceIp() : existing.serviceIp())
+ .providers(updated.providers() != EMPTY_MAP ?
+ updated.providers() : existing.providers());
+ }
+
+ public static final class Builder implements ServiceNetwork.Builder {
+
+ private NetworkId id;
+ private String name;
+ private NetworkType type;
+ private SegmentId segmentId;
+ private IpPrefix subnet;
+ private IpAddress serviceIp;
+ private Map<NetworkId, DependencyType> providers;
+
+ private Builder() {
+ }
+
+ @Override
+ public ServiceNetwork build() {
+ checkNotNull(id, ERR_ID_MISSING);
+ providers = providers != null ? providers : EMPTY_MAP;
+ return new DefaultServiceNetwork(
+ id, name, type,
+ segmentId,
+ subnet, serviceIp,
+ providers);
+ }
+
+ @Override
+ public Builder id(NetworkId id) {
+ this.id = id;
+ return this;
+ }
+
+ @Override
+ public Builder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ @Override
+ public Builder type(NetworkType type) {
+ this.type = type;
+ return this;
+ }
+
+ @Override
+ public Builder segmentId(SegmentId segmentId) {
+ this.segmentId = segmentId;
+ return this;
+ }
+
+ @Override
+ public Builder subnet(IpPrefix subnet) {
+ this.subnet = subnet;
+ return this;
+ }
+
+ @Override
+ public Builder serviceIp(IpAddress serviceIp) {
+ this.serviceIp = serviceIp;
+ return this;
+ }
+
+ @Override
+ public Builder providers(Map<NetworkId, DependencyType> providers) {
+ this.providers = providers;
+ return this;
+ }
+ }
+}
diff --git a/src/main/java/org/opencord/cordvtn/impl/DefaultServicePort.java b/src/main/java/org/opencord/cordvtn/impl/DefaultServicePort.java
new file mode 100644
index 0000000..3ce8b78
--- /dev/null
+++ b/src/main/java/org/opencord/cordvtn/impl/DefaultServicePort.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed 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 org.opencord.cordvtn.impl;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.opencord.cordvtn.api.net.AddressPair;
+import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.PortId;
+import org.opencord.cordvtn.api.net.ServicePort;
+
+import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Collections.EMPTY_SET;
+
+/**
+ * Implementation of {@link ServicePort}.
+ */
+public final class DefaultServicePort implements ServicePort {
+
+ private static final String ERR_ID_MISSING = "Service port ID is missing";
+
+ private final PortId id;
+ private final String name;
+ private final NetworkId networkId;
+ private final MacAddress mac;
+ private final IpAddress ip;
+ private final VlanId vlanId;
+ private final Set<AddressPair> addressPairs;
+
+ private DefaultServicePort(PortId id,
+ String name,
+ NetworkId networkId,
+ MacAddress mac,
+ IpAddress ip,
+ VlanId vlanId,
+ Set<AddressPair> addressPairs) {
+ this.id = id;
+ this.name = name;
+ this.networkId = networkId;
+ this.mac = mac;
+ this.ip = ip;
+ this.vlanId = vlanId;
+ this.addressPairs = addressPairs;
+ }
+
+ @Override
+ public PortId id() {
+ return id;
+ }
+
+ @Override
+ public String name() {
+ return name;
+ }
+
+ @Override
+ public NetworkId networkId() {
+ return networkId;
+ }
+
+ @Override
+ public MacAddress mac() {
+ return mac;
+ }
+
+ @Override
+ public IpAddress ip() {
+ return ip;
+ }
+
+ @Override
+ public VlanId vlanId() {
+ return vlanId;
+ }
+
+ @Override
+ public Set<AddressPair> addressPairs() {
+ return addressPairs;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof DefaultServicePort) {
+ DefaultServicePort that = (DefaultServicePort) obj;
+ if (Objects.equals(id, that.id) &&
+ Objects.equals(name, that.name) &&
+ Objects.equals(networkId, that.networkId) &&
+ Objects.equals(mac, that.mac) &&
+ Objects.equals(ip, that.ip) &&
+ Objects.equals(vlanId, that.vlanId) &&
+ Objects.equals(addressPairs, that.addressPairs)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name, networkId, mac, ip, vlanId, addressPairs);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("id", id)
+ .add("name", name)
+ .add("networkId", networkId)
+ .add("mac", mac)
+ .add("ip", ip)
+ .add("vlanId", vlanId)
+ .add("addressPairs", addressPairs)
+ .toString();
+ }
+
+ /**
+ * Returns new service port builder instance.
+ *
+ * @return vtn port builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns new builder instance with copy of the supplied service port.
+ *
+ * @param sport vtn port
+ * @return vtn port builder
+ */
+ public static Builder builder(ServicePort sport) {
+ return new Builder()
+ .id(sport.id())
+ .name(sport.name())
+ .networkId(sport.networkId())
+ .mac(sport.mac())
+ .ip(sport.ip())
+ .vlanId(sport.vlanId())
+ .addressPairs(sport.addressPairs());
+ }
+
+ /**
+ * Returns service port builder instance with updated values. Any value
+ * not specified in the updated but in the existing remains in the updated
+ * builder.
+ *
+ * @param existing existing service port
+ * @param updated updated service port
+ * @return service network builder
+ */
+ public static Builder builder(ServicePort existing, ServicePort updated) {
+ checkArgument(Objects.equals(existing.id(), updated.id()));
+ // FIXME allow removing existing values
+ return new Builder()
+ .id(existing.id())
+ .name(updated.name() != null ? updated.name() : existing.name())
+ .networkId(updated.networkId() != null ?
+ updated.networkId() : existing.networkId())
+ .mac(updated.mac() != null ? updated.mac() : existing.mac())
+ .ip(updated.ip() != null ? updated.ip() : existing.ip())
+ .vlanId(updated.vlanId() != null ? updated.vlanId() : existing.vlanId())
+ .addressPairs(updated.addressPairs() != EMPTY_SET ?
+ updated.addressPairs() : existing.addressPairs());
+ }
+
+ public static final class Builder implements ServicePort.Builder {
+
+ private PortId id;
+ private String name;
+ private NetworkId networkId;
+ private MacAddress mac;
+ private IpAddress ip;
+ private VlanId vlanId;
+ private Set<AddressPair> addressPairs;
+
+ private Builder() {
+ }
+
+ @Override
+ public ServicePort build() {
+ checkNotNull(id, ERR_ID_MISSING);
+ addressPairs = addressPairs != null ? addressPairs : EMPTY_SET;
+ return new DefaultServicePort(
+ id, name,
+ networkId, mac, ip, vlanId,
+ addressPairs);
+ }
+
+ @Override
+ public Builder id(PortId id) {
+ this.id = id;
+ return this;
+ }
+
+ @Override
+ public Builder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ @Override
+ public Builder networkId(NetworkId networkId) {
+ this.networkId = networkId;
+ return this;
+ }
+
+ @Override
+ public Builder mac(MacAddress mac) {
+ this.mac = mac;
+ return this;
+ }
+
+ @Override
+ public Builder ip(IpAddress ip) {
+ this.ip = ip;
+ return this;
+ }
+
+ @Override
+ public Builder vlanId(VlanId vlanId) {
+ this.vlanId = vlanId;
+ return this;
+ }
+
+ @Override
+ public Builder addressPairs(Set<AddressPair> addressPairs) {
+ this.addressPairs = addressPairs;
+ return this;
+ }
+ }
+}
diff --git a/src/main/java/org/opencord/cordvtn/impl/DependencyManager.java b/src/main/java/org/opencord/cordvtn/impl/DependencyManager.java
deleted file mode 100644
index fa9c36a..0000000
--- a/src/main/java/org/opencord/cordvtn/impl/DependencyManager.java
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.impl;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.Service;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.util.KryoNamespace;
-import org.onosproject.cluster.ClusterService;
-import org.onosproject.cluster.LeadershipService;
-import org.onosproject.cluster.NodeId;
-import org.onosproject.store.serializers.KryoNamespaces;
-import org.onosproject.store.service.ConsistentMap;
-import org.onosproject.store.service.MapEvent;
-import org.onosproject.store.service.MapEventListener;
-import org.onosproject.store.service.Serializer;
-import org.onosproject.store.service.StorageService;
-import org.onosproject.store.service.Versioned;
-import org.opencord.cordvtn.api.core.CordVtnAdminService;
-import org.opencord.cordvtn.api.node.CordVtnNode;
-import org.opencord.cordvtn.api.dependency.Dependency;
-import org.opencord.cordvtn.api.dependency.Dependency.Type;
-import org.opencord.cordvtn.api.dependency.DependencyService;
-import org.opencord.cordvtn.api.instance.Instance;
-import org.onosproject.core.DefaultGroupId;
-import org.onosproject.core.GroupId;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.instructions.ExtensionTreatment;
-import org.onosproject.net.group.DefaultGroupDescription;
-import org.onosproject.net.group.DefaultGroupKey;
-import org.onosproject.net.group.Group;
-import org.onosproject.net.group.GroupBucket;
-import org.onosproject.net.group.GroupBuckets;
-import org.onosproject.net.group.GroupDescription;
-import org.onosproject.net.group.GroupKey;
-import org.onosproject.net.group.GroupService;
-import org.opencord.cordvtn.api.net.NetworkId;
-import org.opencord.cordvtn.api.net.ProviderNetwork;
-import org.opencord.cordvtn.api.net.SegmentId;
-import org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType;
-import org.opencord.cordvtn.api.net.VtnNetwork;
-import org.opencord.cordvtn.api.net.VtnNetworkEvent;
-import org.opencord.cordvtn.api.net.VtnNetworkListener;
-import org.opencord.cordvtn.impl.handler.AbstractInstanceHandler;
-import org.slf4j.Logger;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static org.opencord.cordvtn.api.dependency.Dependency.Type.BIDIRECTIONAL;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.ACCESS_AGENT;
-import static org.opencord.cordvtn.impl.CordVtnPipeline.*;
-import static org.onosproject.net.group.DefaultGroupBucket.createSelectGroupBucket;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Provisions service dependency capabilities between network services.
- */
-@Component(immediate = true)
-@Service
-public class DependencyManager extends AbstractInstanceHandler implements DependencyService {
-
- protected final Logger log = getLogger(getClass());
-
- private static final String ERR_NET_FAIL = "Failed to get VTN network ";
- private static final String MSG_CREATE = "Created dependency %s";
- private static final String MSG_REMOVE = "Removed dependency %s";
- private static final String ADDED = "Added ";
- private static final String REMOVED = "Removed ";
-
- private static final KryoNamespace SERIALIZER_DEPENDENCY = KryoNamespace.newBuilder()
- .register(KryoNamespaces.API)
- .register(VtnNetwork.class)
- .register(NetworkId.class)
- .register(SegmentId.class)
- .register(ServiceNetworkType.class)
- .register(ProviderNetwork.class)
- .register(Dependency.class)
- .register(Type.class)
- .build();
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected GroupService groupService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected LeadershipService leadershipService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected ClusterService clusterService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected StorageService storageService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected CordVtnPipeline pipeline;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected CordVtnNodeManager nodeManager;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected CordVtnAdminService vtnService;
-
- private final VtnNetworkListener vtnNetListener = new InternalVtnNetListener();
- private final MapEventListener<NetworkId, Set<Dependency>> dependencyListener =
- new DependencyMapListener();
-
- private ConsistentMap<NetworkId, Set<Dependency>> dependencyStore;
- private NodeId localNodeId;
-
- @Activate
- protected void activate() {
- super.activate();
-
- dependencyStore = storageService.<NetworkId, Set<Dependency>>consistentMapBuilder()
- .withSerializer(Serializer.using(SERIALIZER_DEPENDENCY))
- .withName("cordvtn-dependencymap")
- .withApplicationId(appId)
- .build();
- dependencyStore.addListener(dependencyListener);
-
- localNodeId = clusterService.getLocalNode().id();
- leadershipService.runForLeadership(appId.name());
- vtnService.addListener(vtnNetListener);
- }
-
- @Deactivate
- protected void deactivate() {
- super.deactivate();
- dependencyStore.removeListener(dependencyListener);
- vtnService.removeListener(vtnNetListener);
- leadershipService.withdraw(appId.name());
- }
-
- @Override
- public void createDependency(NetworkId subNetId, NetworkId proNetId, Type type) {
- // FIXME this is not safe
- VtnNetwork existing = vtnService.vtnNetwork(subNetId);
- if (existing == null) {
- log.warn("Failed to create dependency between {} and {}", subNetId, proNetId);
- return;
- }
- vtnService.createServiceNetwork(existing);
- VtnNetwork updated = VtnNetwork.builder(existing)
- .addProvider(proNetId, type)
- .build();
- vtnService.updateServiceNetwork(updated);
- }
-
- @Override
- public void removeDependency(NetworkId subNetId, NetworkId proNetId) {
- // FIXME this is not safe
- VtnNetwork subNet = vtnService.vtnNetwork(subNetId);
- if (subNet == null) {
- log.warn("No dependency exists between {} and {}", subNetId, proNetId);
- return;
- }
- VtnNetwork updated = VtnNetwork.builder(subNet)
- .delProvider(proNetId)
- .build();
- vtnService.updateServiceNetwork(updated);
- }
-
- @Override
- public void instanceDetected(Instance instance) {
- // TODO remove this when XOS provides access agent information
- // and handle it the same way wit the other instances
- if (instance.netType() == ACCESS_AGENT) {
- return;
- }
-
- VtnNetwork vtnNet = vtnService.vtnNetwork(instance.netId());
- if (vtnNet == null) {
- final String error = ERR_NET_FAIL + instance.netId();
- throw new IllegalStateException(error);
- }
-
- if (!vtnNet.providers().isEmpty()) {
- updateSubscriberInstances(vtnNet, instance, true);
- }
- // TODO check if subscribers on this network
- updateProviderInstances(vtnNet);
- }
-
- @Override
- public void instanceRemoved(Instance instance) {
- // TODO remove this when XOS provides access agent information
- // and handle it the same way wit the other instances
- if (instance.netType() == ACCESS_AGENT) {
- return;
- }
-
- VtnNetwork vtnNet = vtnService.vtnNetwork(instance.netId());
- if (vtnNet == null) {
- final String error = ERR_NET_FAIL + instance.netId();
- throw new IllegalStateException(error);
- }
-
- if (!vtnNet.providers().isEmpty()) {
- updateSubscriberInstances(vtnNet, instance, false);
- }
- // TODO check if subscribers on this network
- updateProviderInstances(vtnNet);
- }
-
- private void dependencyCreated(Dependency dependency) {
- populateDependencyRules(dependency.subscriber(), dependency.provider(),
- dependency.type(), true);
- log.info(String.format(MSG_CREATE, dependency));
- }
-
- private void dependencyRemoved(Dependency dependency) {
- populateDependencyRules(dependency.subscriber(), dependency.provider(),
- dependency.type(), false);
- if (getSubscribers(dependency.provider().id()).isEmpty()) {
- removeProviderGroup(dependency.provider().id());
- }
- log.info(String.format(MSG_REMOVE, dependency));
- }
-
- private void updateProviderInstances(VtnNetwork provider) {
- Set<DeviceId> devices = nodeManager.completeNodes().stream()
- .map(CordVtnNode::integrationBridgeId)
- .collect(Collectors.toSet());
-
- GroupKey groupKey = getGroupKey(provider.id());
- for (DeviceId deviceId : devices) {
- Group group = groupService.getGroup(deviceId, groupKey);
- if (group == null) {
- continue;
- }
-
- List<GroupBucket> oldBuckets = group.buckets().buckets();
- List<GroupBucket> newBuckets = getProviderGroupBuckets(
- deviceId,
- provider.segmentId().id(),
- getInstances(provider.id())).buckets();
-
- if (oldBuckets.equals(newBuckets)) {
- continue;
- }
-
- List<GroupBucket> bucketsToRemove = Lists.newArrayList(oldBuckets);
- bucketsToRemove.removeAll(newBuckets);
- if (!bucketsToRemove.isEmpty()) {
- groupService.removeBucketsFromGroup(
- deviceId,
- groupKey,
- new GroupBuckets(bucketsToRemove),
- groupKey, appId);
- log.debug("Removed buckets from provider({}) group on {}: {}",
- provider.id(), deviceId, bucketsToRemove);
- }
-
- List<GroupBucket> bucketsToAdd = Lists.newArrayList(newBuckets);
- bucketsToAdd.removeAll(oldBuckets);
- if (!bucketsToAdd.isEmpty()) {
- groupService.addBucketsToGroup(
- deviceId,
- groupKey,
- new GroupBuckets(bucketsToAdd),
- groupKey, appId);
- log.debug("Added buckets to provider({}) group on {}: {}",
- provider.id(), deviceId, bucketsToAdd);
- }
- }
- }
-
- private void updateSubscriberInstances(VtnNetwork subscriber, Instance instance,
- boolean isDetected) {
- DeviceId deviceId = instance.deviceId();
- final String isAdded = isDetected ? ADDED : REMOVED;
- subscriber.providers().stream().forEach(provider -> {
- populateInPortRule(
- ImmutableMap.of(deviceId, ImmutableSet.of(instance.portNumber())),
- ImmutableMap.of(deviceId, getGroupId(provider.id(), deviceId)),
- isDetected);
-
- log.info(isAdded + "subscriber instance({}) for provider({})",
- instance.host().id(), provider.id());
- });
- }
-
- private void populateDependencyRules(VtnNetwork subscriber,
- VtnNetwork provider,
- Type type, boolean install) {
- Map<DeviceId, GroupId> providerGroups = Maps.newHashMap();
- Map<DeviceId, Set<PortNumber>> subscriberPorts = Maps.newHashMap();
-
- nodeManager.completeNodes().stream().forEach(node -> {
- DeviceId deviceId = node.integrationBridgeId();
- GroupId groupId = getProviderGroup(provider, deviceId);
- providerGroups.put(deviceId, groupId);
-
- Set<PortNumber> ports = getInstances(subscriber.id())
- .stream()
- .filter(instance -> instance.deviceId().equals(deviceId))
- .map(Instance::portNumber)
- .collect(Collectors.toSet());
- subscriberPorts.put(deviceId, ports);
- });
-
- Ip4Prefix subscriberIp = subscriber.subnet().getIp4Prefix();
- Ip4Prefix providerIp = provider.subnet().getIp4Prefix();
-
- populateInPortRule(subscriberPorts, providerGroups, install);
- populateIndirectAccessRule(
- subscriberIp,
- provider.serviceIp().getIp4Address(),
- providerGroups,
- install);
- populateDirectAccessRule(subscriberIp, providerIp, install);
- if (type == BIDIRECTIONAL) {
- populateDirectAccessRule(providerIp, subscriberIp, install);
- }
- }
-
- private void populateIndirectAccessRule(Ip4Prefix srcIp, Ip4Address serviceIp,
- Map<DeviceId, GroupId> outGroups,
- boolean install) {
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_IPV4)
- .matchIPSrc(srcIp)
- .matchIPDst(serviceIp.toIpPrefix())
- .build();
-
- for (Map.Entry<DeviceId, GroupId> outGroup : outGroups.entrySet()) {
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .group(outGroup.getValue())
- .build();
-
- FlowRule flowRule = DefaultFlowRule.builder()
- .fromApp(appId)
- .withSelector(selector)
- .withTreatment(treatment)
- .withPriority(PRIORITY_HIGH)
- .forDevice(outGroup.getKey())
- .forTable(TABLE_ACCESS)
- .makePermanent()
- .build();
-
- pipeline.processFlowRule(install, flowRule);
- }
- }
-
- private void populateDirectAccessRule(Ip4Prefix srcIp, Ip4Prefix dstIp, boolean install) {
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_IPV4)
- .matchIPSrc(srcIp)
- .matchIPDst(dstIp)
- .build();
-
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .transition(TABLE_DST)
- .build();
-
- nodeManager.completeNodes().stream().forEach(node -> {
- DeviceId deviceId = node.integrationBridgeId();
- FlowRule flowRuleDirect = DefaultFlowRule.builder()
- .fromApp(appId)
- .withSelector(selector)
- .withTreatment(treatment)
- .withPriority(PRIORITY_DEFAULT)
- .forDevice(deviceId)
- .forTable(TABLE_ACCESS)
- .makePermanent()
- .build();
-
- pipeline.processFlowRule(install, flowRuleDirect);
- });
- }
-
- private void populateInPortRule(Map<DeviceId, Set<PortNumber>> subscriberPorts,
- Map<DeviceId, GroupId> providerGroups,
- boolean install) {
- for (Map.Entry<DeviceId, Set<PortNumber>> entry : subscriberPorts.entrySet()) {
- Set<PortNumber> ports = entry.getValue();
- DeviceId deviceId = entry.getKey();
-
- GroupId groupId = providerGroups.get(deviceId);
- if (groupId == null) {
- continue;
- }
-
- ports.stream().forEach(port -> {
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchInPort(port)
- .build();
-
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .group(groupId)
- .build();
-
- FlowRule flowRule = DefaultFlowRule.builder()
- .fromApp(appId)
- .withSelector(selector)
- .withTreatment(treatment)
- .withPriority(PRIORITY_DEFAULT)
- .forDevice(deviceId)
- .forTable(TABLE_IN_SERVICE)
- .makePermanent()
- .build();
-
- pipeline.processFlowRule(install, flowRule);
- });
- }
- }
-
- private GroupId getGroupId(NetworkId netId, DeviceId deviceId) {
- return new DefaultGroupId(Objects.hash(netId, deviceId));
- }
-
- private GroupKey getGroupKey(NetworkId netId) {
- return new DefaultGroupKey(netId.id().getBytes());
- }
-
- private GroupId getProviderGroup(VtnNetwork provider, DeviceId deviceId) {
- GroupKey groupKey = getGroupKey(provider.id());
- Group group = groupService.getGroup(deviceId, groupKey);
- GroupId groupId = getGroupId(provider.id(), deviceId);
-
- if (group != null) {
- return groupId;
- }
-
- GroupBuckets buckets = getProviderGroupBuckets(
- deviceId, provider.segmentId().id(), getInstances(provider.id()));
- GroupDescription groupDescription = new DefaultGroupDescription(
- deviceId,
- GroupDescription.Type.SELECT,
- buckets,
- groupKey,
- groupId.id(),
- appId);
-
- groupService.addGroup(groupDescription);
- return groupId;
- }
-
- private Set<Dependency> getSubscribers(NetworkId netId) {
- return dependencyStore.values().stream().map(Versioned::value)
- .flatMap(Collection::stream)
- .filter(dependency -> dependency.provider().id().equals(netId))
- .collect(Collectors.toSet());
- }
-
- private void removeProviderGroup(NetworkId netId) {
- GroupKey groupKey = getGroupKey(netId);
- nodeManager.completeNodes().stream()
- .forEach(node -> {
- DeviceId deviceId = node.integrationBridgeId();
- Group group = groupService.getGroup(deviceId, groupKey);
- if (group != null) {
- groupService.removeGroup(deviceId, groupKey, appId);
- }
- });
- log.debug("Removed group for network {}", netId);
- }
-
- private GroupBuckets getProviderGroupBuckets(DeviceId deviceId,
- long tunnelId,
- Set<Instance> instances) {
- List<GroupBucket> buckets = Lists.newArrayList();
- instances.stream().forEach(instance -> {
- Ip4Address tunnelIp = nodeManager.dataIp(instance.deviceId()).getIp4Address();
-
- if (deviceId.equals(instance.deviceId())) {
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setEthDst(instance.mac())
- .setOutput(instance.portNumber())
- .build();
- buckets.add(createSelectGroupBucket(treatment));
- } else {
- ExtensionTreatment tunnelDst =
- pipeline.tunnelDstTreatment(deviceId, tunnelIp);
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setEthDst(instance.mac())
- .extension(tunnelDst, deviceId)
- .setTunnelId(tunnelId)
- .setOutput(nodeManager.tunnelPort(instance.deviceId()))
- .build();
- buckets.add(createSelectGroupBucket(treatment));
- }
- });
- return new GroupBuckets(buckets);
- }
-
- private class InternalVtnNetListener implements VtnNetworkListener {
-
- @Override
- public void event(VtnNetworkEvent event) {
- NodeId leader = leadershipService.getLeader(appId.name());
- if (!Objects.equals(localNodeId, leader)) {
- // do not allow to proceed without leadership
- return;
- }
-
- switch (event.type()) {
- case VTN_NETWORK_CREATED:
- case VTN_NETWORK_UPDATED:
- log.debug("Processing dependency for {}", event.subject());
- eventExecutor.execute(() -> updateDependency(event.subject()));
- break;
- case VTN_NETWORK_REMOVED:
- log.debug("Removing dependency for {}", event.subject());
- NetworkId netId = event.subject().id();
- eventExecutor.execute(() -> dependencyStore.remove(netId));
- break;
- case VTN_PORT_CREATED:
- case VTN_PORT_UPDATED:
- case VTN_PORT_REMOVED:
- default:
- // do nothing for the other events
- break;
- }
- }
-
- private void updateDependency(VtnNetwork subscriber) {
- Set<Dependency> dependencies = subscriber.providers().stream()
- .map(provider -> Dependency.builder()
- .subscriber(subscriber)
- .provider(vtnService.vtnNetwork(provider.id()))
- .type(provider.type())
- .build())
- .collect(Collectors.toSet());
- dependencyStore.put(subscriber.id(), dependencies);
- }
- }
-
- private class DependencyMapListener implements MapEventListener<NetworkId, Set<Dependency>> {
-
- @Override
- public void event(MapEvent<NetworkId, Set<Dependency>> event) {
- NodeId leader = leadershipService.getLeader(appId.name());
- if (!Objects.equals(localNodeId, leader)) {
- // do not allow to proceed without leadership
- return;
- }
-
- switch (event.type()) {
- case UPDATE:
- log.debug("Subscriber {} updated", event.key());
- eventExecutor.execute(() -> dependencyUpdated(
- event.oldValue().value(),
- event.newValue().value()
- ));
- break;
- case INSERT:
- log.debug("Subscriber {} inserted", event.key());
- eventExecutor.execute(() -> dependencyUpdated(
- ImmutableSet.of(),
- event.newValue().value()
- ));
- break;
- case REMOVE:
- log.debug("Subscriber {} removed", event.key());
- eventExecutor.execute(() -> dependencyUpdated(
- event.oldValue().value(),
- ImmutableSet.of()
- ));
- break;
- default:
- log.error("Unsupported event type");
- break;
- }
- }
-
- private void dependencyUpdated(Set<Dependency> oldDeps, Set<Dependency> newDeps) {
- oldDeps.stream().filter(oldDep -> !newDeps.contains(oldDep))
- .forEach(DependencyManager.this::dependencyRemoved);
-
- newDeps.stream().filter(newDep -> !oldDeps.contains(newDep))
- .forEach(DependencyManager.this::dependencyCreated);
- }
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/impl/DistributedCordVtnStore.java b/src/main/java/org/opencord/cordvtn/impl/DistributedCordVtnStore.java
deleted file mode 100644
index beb6475..0000000
--- a/src/main/java/org/opencord/cordvtn/impl/DistributedCordVtnStore.java
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.impl;
-
-import com.google.common.collect.ImmutableSet;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.Service;
-import org.onlab.util.Tools;
-import org.onosproject.store.AbstractStore;
-import org.onosproject.store.service.MapEvent;
-import org.onosproject.store.service.MapEventListener;
-import org.onosproject.store.service.Versioned;
-import org.opencord.cordvtn.api.core.CordVtnStore;
-import org.onlab.util.KryoNamespace;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.store.serializers.KryoNamespaces;
-import org.onosproject.store.service.ConsistentMap;
-import org.onosproject.store.service.Serializer;
-import org.onosproject.store.service.StorageService;
-import org.opencord.cordvtn.api.net.AddressPair;
-import org.opencord.cordvtn.api.core.CordVtnStoreDelegate;
-import org.opencord.cordvtn.api.dependency.Dependency;
-import org.opencord.cordvtn.api.net.NetworkId;
-import org.opencord.cordvtn.api.net.PortId;
-import org.opencord.cordvtn.api.net.ProviderNetwork;
-import org.opencord.cordvtn.api.net.SegmentId;
-import org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType;
-import org.opencord.cordvtn.api.net.SubnetId;
-import org.opencord.cordvtn.api.net.VtnNetwork;
-import org.opencord.cordvtn.api.net.VtnNetworkEvent;
-import org.opencord.cordvtn.api.net.VtnPort;
-import org.openstack4j.model.network.IP;
-import org.openstack4j.model.network.IPVersionType;
-import org.openstack4j.model.network.Network;
-import org.openstack4j.model.network.NetworkType;
-import org.openstack4j.model.network.Port;
-import org.openstack4j.model.network.State;
-import org.openstack4j.model.network.Subnet;
-import org.openstack4j.openstack.networking.domain.NeutronAllowedAddressPair;
-import org.openstack4j.openstack.networking.domain.NeutronExtraDhcpOptCreate;
-import org.openstack4j.openstack.networking.domain.NeutronHostRoute;
-import org.openstack4j.openstack.networking.domain.NeutronIP;
-import org.openstack4j.openstack.networking.domain.NeutronNetwork;
-import org.openstack4j.openstack.networking.domain.NeutronPool;
-import org.openstack4j.openstack.networking.domain.NeutronPort;
-import org.openstack4j.openstack.networking.domain.NeutronSubnet;
-import org.slf4j.Logger;
-
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.stream.Collectors;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.concurrent.Executors.newSingleThreadExecutor;
-import static org.onlab.util.Tools.groupedThreads;
-import static org.opencord.cordvtn.api.Constants.CORDVTN_APP_ID;
-import static org.opencord.cordvtn.api.net.VtnNetworkEvent.Type.*;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Manages the inventory of VTN networks using a {@code ConsistentMap}.
- */
-@Component(immediate = true)
-@Service
-public class DistributedCordVtnStore extends AbstractStore<VtnNetworkEvent, CordVtnStoreDelegate>
- implements CordVtnStore {
-
- protected final Logger log = getLogger(getClass());
-
- private static final String ERR_SYNC = "VTN store is out of sync: ";
- private static final String ERR_NOT_FOUND = " does not exist";
- private static final String ERR_DUPLICATE = " already exists with different properties";
-
- private static final KryoNamespace SERIALIZER_SERVICE = KryoNamespace.newBuilder()
- .register(KryoNamespaces.API)
- .register(VtnNetwork.class)
- .register(NetworkId.class)
- .register(SegmentId.class)
- .register(ServiceNetworkType.class)
- .register(ProviderNetwork.class)
- .register(Dependency.Type.class)
- .register(VtnPort.class)
- .register(PortId.class)
- .register(AddressPair.class)
- .build();
-
- // Use Neutron data model until we need our own abstraction of virtual networks
- private static final KryoNamespace SERIALIZER_NEUTRON = KryoNamespace.newBuilder()
- .register(KryoNamespaces.API)
- .register(Network.class)
- .register(NetworkId.class)
- .register(NeutronNetwork.class)
- .register(State.class)
- .register(NetworkType.class)
- .register(Port.class)
- .register(PortId.class)
- .register(NeutronPort.class)
- .register(NeutronIP.class)
- .register(NeutronAllowedAddressPair.class)
- .register(NeutronExtraDhcpOptCreate.class)
- .register(Subnet.class)
- .register(SubnetId.class)
- .register(NeutronSubnet.class)
- .register(NeutronPool.class)
- .register(NeutronHostRoute.class)
- .register(IPVersionType.class)
- .build();
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected CoreService coreService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected StorageService storageService;
-
- private final MapEventListener<PortId, VtnPort> vtnPortListener = new VtnPortMapListener();
- private final MapEventListener<NetworkId, VtnNetwork> vtnNetworkListener = new VtnNetworkMapListener();
- private final ExecutorService eventExecutor = newSingleThreadExecutor(
- groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
-
- private ConsistentMap<NetworkId, VtnNetwork> vtnNetworkStore;
- private ConsistentMap<PortId, VtnPort> vtnPortStore;
- private ConsistentMap<NetworkId, Network> networkStore;
- private ConsistentMap<SubnetId, Subnet> subnetStore;
- private ConsistentMap<PortId, Port> portStore;
-
- @Activate
- protected void activate() {
- ApplicationId appId = coreService.registerApplication(CORDVTN_APP_ID);
-
- vtnNetworkStore = storageService.<NetworkId, VtnNetwork>consistentMapBuilder()
- .withSerializer(Serializer.using(SERIALIZER_SERVICE))
- .withName("cordvtn-vtnnetstore")
- .withApplicationId(appId)
- .build();
- vtnNetworkStore.addListener(vtnNetworkListener);
-
- vtnPortStore = storageService.<PortId, VtnPort>consistentMapBuilder()
- .withSerializer(Serializer.using(SERIALIZER_SERVICE))
- .withName("cordvtn-vtnportstore")
- .withApplicationId(appId)
- .build();
- vtnPortStore.addListener(vtnPortListener);
-
- networkStore = storageService.<NetworkId, Network>consistentMapBuilder()
- .withSerializer(Serializer.using(SERIALIZER_NEUTRON))
- .withName("cordvtn-networkstore")
- .withApplicationId(appId)
- .build();
-
- portStore = storageService.<PortId, Port>consistentMapBuilder()
- .withSerializer(Serializer.using(SERIALIZER_NEUTRON))
- .withName("cordvtn-portstore")
- .withApplicationId(appId)
- .build();
-
- subnetStore = storageService.<SubnetId, Subnet>consistentMapBuilder()
- .withSerializer(Serializer.using(SERIALIZER_NEUTRON))
- .withName("cordvtn-subnetstore")
- .withApplicationId(appId)
- .build();
-
- log.info("Started");
- }
-
- @Deactivate
- protected void deactivate() {
- vtnNetworkStore.removeListener(vtnNetworkListener);
- vtnPortStore.removeListener(vtnPortListener);
-
- log.info("Stopped");
- }
-
- @Override
- public void clear() {
- synchronized (this) {
- vtnNetworkStore.clear();
- vtnPortStore.clear();
- networkStore.clear();
- portStore.clear();
- subnetStore.clear();
- }
- }
-
- @Override
- public void createVtnNetwork(VtnNetwork vtnNet) {
- vtnNetworkStore.compute(vtnNet.id(), (id, existing) -> {
- final String error = ERR_SYNC + vtnNet.id().id() + ERR_DUPLICATE;
- checkArgument(existing == null || existing.equals(vtnNet), error);
- return vtnNet;
- });
- }
-
- @Override
- public void updateVtnNetwork(VtnNetwork vtnNet) {
- vtnNetworkStore.compute(vtnNet.id(), (id, existing) -> {
- final String error = ERR_SYNC + vtnNet.id().id() + ERR_NOT_FOUND;
- checkArgument(existing != null, ERR_SYNC + error);
- return vtnNet;
- });
- }
-
- @Override
- public void removeVtnNetwork(NetworkId netId) {
- synchronized (this) {
- // remove any dependencies that this network involved in
- vtnNetworkStore.computeIfPresent(netId, (id, existing) ->
- VtnNetwork.builder(existing)
- .providers(ImmutableSet.of()).build()
- );
- getSubscribers(netId).stream().forEach(subs ->
- vtnNetworkStore.computeIfPresent(subs.id(), (id, existing) ->
- VtnNetwork.builder(existing)
- .delProvider(netId).build())
- );
- vtnNetworkStore.remove(netId);
- }
- }
-
- @Override
- public VtnNetwork vtnNetwork(NetworkId netId) {
- Versioned<VtnNetwork> versioned = vtnNetworkStore.get(netId);
- return versioned == null ? null : versioned.value();
- }
-
- @Override
- public Set<VtnNetwork> vtnNetworks() {
- Set<VtnNetwork> vtnNetworks = vtnNetworkStore.values().stream()
- .map(Versioned::value)
- .collect(Collectors.toSet());
- return ImmutableSet.copyOf(vtnNetworks);
- }
-
- @Override
- public void createVtnPort(VtnPort vtnPort) {
- vtnPortStore.compute(vtnPort.id(), (id, existing) -> {
- final String error = ERR_SYNC + vtnPort.id().id() + ERR_DUPLICATE;
- checkArgument(existing == null || existing.equals(vtnPort), error);
- return vtnPort;
- });
- }
-
- @Override
- public void updateVtnPort(VtnPort vtnPort) {
- vtnPortStore.compute(vtnPort.id(), (id, existing) -> {
- final String error = ERR_SYNC + vtnPort.id().id() + ERR_NOT_FOUND;
- checkArgument(existing != null, ERR_SYNC + error);
- return vtnPort;
- });
- }
-
- @Override
- public void removeVtnPort(PortId portId) {
- vtnPortStore.remove(portId);
- }
-
- @Override
- public VtnPort vtnPort(PortId portId) {
- Versioned<VtnPort> versioned = vtnPortStore.get(portId);
- return versioned == null ? null : versioned.value();
- }
-
- @Override
- public Set<VtnPort> vtnPorts() {
- Set<VtnPort> vtnPorts = vtnPortStore.values().stream()
- .map(Versioned::value)
- .collect(Collectors.toSet());
- return ImmutableSet.copyOf(vtnPorts);
- }
-
- @Override
- public void createNetwork(Network net) {
- networkStore.compute(NetworkId.of(net.getId()), (id, existing) -> {
- final String error = ERR_SYNC + net.getId() + ERR_DUPLICATE;
- checkArgument(existing == null || equalNetworks(net, existing), error);
- return net;
- });
- }
-
- @Override
- public void updateNetwork(Network net) {
- networkStore.compute(NetworkId.of(net.getId()), (id, existing) -> {
- final String error = ERR_SYNC + net.getId() + ERR_NOT_FOUND;
- checkArgument(existing != null, ERR_SYNC + error);
- return net;
- });
- }
-
- @Override
- public void removeNetwork(NetworkId netId) {
- networkStore.remove(netId);
- }
-
- @Override
- public Network network(NetworkId netId) {
- Versioned<Network> versioned = networkStore.get(netId);
- return versioned == null ? null : versioned.value();
- }
-
- @Override
- public Set<Network> networks() {
- Set<Network> networks = networkStore.values().stream()
- .map(Versioned::value)
- .collect(Collectors.toSet());
- return ImmutableSet.copyOf(networks);
- }
-
- @Override
- public void createPort(Port port) {
- portStore.compute(PortId.of(port.getId()), (id, existing) -> {
- final String error = ERR_SYNC + port.getId() + ERR_DUPLICATE;
- checkArgument(existing == null || equalPorts(port, existing), error);
- return port;
- });
- }
-
- @Override
- public void updatePort(Port port) {
- portStore.compute(PortId.of(port.getId()), (id, existing) -> {
- final String error = ERR_SYNC + port.getId() + ERR_NOT_FOUND;
- checkArgument(existing != null, ERR_SYNC + error);
- return port;
- });
- }
-
- @Override
- public void removePort(PortId portId) {
- portStore.remove(portId);
- }
-
- @Override
- public Port port(PortId portId) {
- Versioned<Port> versioned = portStore.get(portId);
- return versioned == null ? null : versioned.value();
- }
-
- @Override
- public Set<Port> ports() {
- Set<Port> ports = portStore.values().stream()
- .map(Versioned::value)
- .collect(Collectors.toSet());
- return ImmutableSet.copyOf(ports);
- }
-
- @Override
- public void createSubnet(Subnet subnet) {
- subnetStore.compute(SubnetId.of(subnet.getId()), (id, existing) -> {
- final String error = ERR_SYNC + subnet.getId() + ERR_DUPLICATE;
- checkArgument(existing == null || equalSubnets(subnet, existing), error);
- return subnet;
- });
- }
-
- @Override
- public void updateSubnet(Subnet subnet) {
- subnetStore.compute(SubnetId.of(subnet.getId()), (id, existing) -> {
- final String error = ERR_SYNC + subnet.getId() + ERR_NOT_FOUND;
- checkArgument(existing != null, ERR_SYNC + error);
- return subnet;
- });
- }
-
- @Override
- public void removeSubnet(SubnetId subnetId) {
- subnetStore.remove(subnetId);
- }
-
- @Override
- public Subnet subnet(SubnetId subnetId) {
- Versioned<Subnet> versioned = subnetStore.get(subnetId);
- return versioned == null ? null : versioned.value();
- }
-
- @Override
- public Set<Subnet> subnets() {
- Set<Subnet> subnets = subnetStore.values().stream()
- .map(Versioned::value)
- .collect(Collectors.toSet());
- return ImmutableSet.copyOf(subnets);
- }
-
- private Set<VtnNetwork> getSubscribers(NetworkId netId) {
- Set<VtnNetwork> subscribers = vtnNetworks().stream()
- .filter(net -> net.isProvider(netId))
- .collect(Collectors.toSet());
- return ImmutableSet.copyOf(subscribers);
- }
-
- private boolean equalNetworks(Network netA, Network netB) {
- if (netA == netB) {
- return true;
- }
- // FIXME compare subnet here when CordVtnManager.createSubnet is fixed
- if (Objects.equals(netA.getId(), netB.getId()) &&
- Objects.equals(netA.getProviderSegID(), netB.getProviderSegID())) {
- return true;
- }
- return false;
- }
-
- private boolean equalSubnets(Subnet subnetA, Subnet subnetB) {
- if (subnetA == subnetB) {
- return true;
- }
- if (Objects.equals(subnetA.getId(), subnetB.getId()) &&
- Objects.equals(subnetA.getNetworkId(), subnetB.getNetworkId()) &&
- Objects.equals(subnetA.getCidr(), subnetB.getCidr()) &&
- Objects.equals(subnetA.getGateway(), subnetB.getGateway())) {
- return true;
- }
- return false;
- }
-
- private boolean equalPorts(Port portA, Port portB) {
- if (portA == portB) {
- return true;
- }
-
- List<String> portAIps = Tools.stream(portA.getFixedIps())
- .map(IP::getIpAddress)
- .collect(Collectors.toList());
- List<String> portBIps = Tools.stream(portB.getFixedIps())
- .map(IP::getIpAddress)
- .collect(Collectors.toList());
-
- if (Objects.equals(portA.getId(), portB.getId()) &&
- Objects.equals(portA.getNetworkId(), portB.getNetworkId()) &&
- Objects.equals(portA.getMacAddress(), portB.getMacAddress()) &&
- Objects.equals(portAIps, portBIps)) {
- return true;
- }
- return false;
- }
-
- private class VtnNetworkMapListener implements MapEventListener<NetworkId, VtnNetwork> {
-
- @Override
- public void event(MapEvent<NetworkId, VtnNetwork> event) {
- switch (event.type()) {
- case UPDATE:
- log.debug("VTN network updated {}", event.newValue());
- eventExecutor.execute(() -> {
- notifyDelegate(new VtnNetworkEvent(
- VTN_NETWORK_UPDATED,
- event.newValue().value()));
- });
- break;
- case INSERT:
- log.debug("VTN network created {}", event.newValue());
- eventExecutor.execute(() -> {
- notifyDelegate(new VtnNetworkEvent(
- VTN_NETWORK_CREATED,
- event.newValue().value()));
- });
- break;
- case REMOVE:
- log.debug("VTN network removed {}", event.oldValue());
- eventExecutor.execute(() -> {
- notifyDelegate(new VtnNetworkEvent(
- VTN_NETWORK_REMOVED,
- event.oldValue().value()));
- });
- break;
- default:
- log.error("Unsupported event type");
- break;
- }
- }
- }
-
- private class VtnPortMapListener implements MapEventListener<PortId, VtnPort> {
-
- @Override
- public void event(MapEvent<PortId, VtnPort> event) {
- switch (event.type()) {
- case UPDATE:
- log.debug("VTN port updated {}", event.newValue());
- eventExecutor.execute(() -> {
- notifyDelegate(new VtnNetworkEvent(
- VTN_PORT_UPDATED,
- vtnNetwork(event.newValue().value().netId()),
- event.newValue().value()));
- });
- break;
- case INSERT:
- log.debug("VTN port created {}", event.newValue());
- eventExecutor.execute(() -> {
- notifyDelegate(new VtnNetworkEvent(
- VTN_PORT_CREATED,
- vtnNetwork(event.newValue().value().netId()),
- event.newValue().value()));
- });
- break;
- case REMOVE:
- log.debug("VTN port removed {}", event.oldValue());
- eventExecutor.execute(() -> {
- notifyDelegate(new VtnNetworkEvent(
- VTN_PORT_REMOVED,
- vtnNetwork(event.oldValue().value().netId()),
- event.oldValue().value()));
- });
- break;
- default:
- log.error("Unsupported event type");
- break;
- }
- }
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/impl/DistributedServiceNetworkStore.java b/src/main/java/org/opencord/cordvtn/impl/DistributedServiceNetworkStore.java
new file mode 100644
index 0000000..dc98ced
--- /dev/null
+++ b/src/main/java/org/opencord/cordvtn/impl/DistributedServiceNetworkStore.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed 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 org.opencord.cordvtn.impl;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.store.AbstractStore;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.MapEvent;
+import org.onosproject.store.service.MapEventListener;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.Versioned;
+import org.opencord.cordvtn.api.core.ServiceNetworkEvent;
+import org.opencord.cordvtn.api.core.ServiceNetworkStore;
+import org.opencord.cordvtn.api.core.ServiceNetworkStoreDelegate;
+import org.opencord.cordvtn.api.net.AddressPair;
+import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.PortId;
+import org.opencord.cordvtn.api.net.Provider;
+import org.opencord.cordvtn.api.net.SegmentId;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
+import org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType;
+import org.opencord.cordvtn.api.net.ServicePort;
+import org.slf4j.Logger;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.opencord.cordvtn.api.Constants.CORDVTN_APP_ID;
+import static org.opencord.cordvtn.api.core.ServiceNetworkEvent.Type.*;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Manages the inventory of VTN networks using a {@code ConsistentMap}.
+ */
+@Component(immediate = true)
+@Service
+public class DistributedServiceNetworkStore extends AbstractStore<ServiceNetworkEvent, ServiceNetworkStoreDelegate>
+ implements ServiceNetworkStore {
+
+ protected final Logger log = getLogger(getClass());
+
+ private static final String ERR_NOT_FOUND = " does not exist";
+ private static final String ERR_DUPLICATE = " already exists";
+
+ private static final KryoNamespace SERIALIZER_SERVICE = KryoNamespace.newBuilder()
+ .register(KryoNamespaces.API)
+ .register(ServiceNetwork.class)
+ .register(DefaultServiceNetwork.class)
+ .register(NetworkId.class)
+ .register(SegmentId.class)
+ .register(ServiceNetwork.NetworkType.class)
+ .register(DependencyType.class)
+ .register(ServicePort.class)
+ .register(DefaultServicePort.class)
+ .register(PortId.class)
+ .register(AddressPair.class)
+ .register(Collections.EMPTY_MAP.getClass())
+ .register(Collections.EMPTY_SET.getClass())
+ .build();
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected StorageService storageService;
+
+ private final ExecutorService eventExecutor = newSingleThreadExecutor(
+ groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
+ private final MapEventListener<PortId, ServicePort> servicePortListener =
+ new ServicePortMapListener();
+ private final MapEventListener<NetworkId, ServiceNetwork> serviceNetworkListener =
+ new ServiceNetworkMapListener();
+
+ private ConsistentMap<NetworkId, ServiceNetwork> serviceNetworkStore;
+ private ConsistentMap<PortId, ServicePort> servicePortStore;
+
+ @Activate
+ protected void activate() {
+ ApplicationId appId = coreService.registerApplication(CORDVTN_APP_ID);
+
+ serviceNetworkStore = storageService.<NetworkId, ServiceNetwork>consistentMapBuilder()
+ .withSerializer(Serializer.using(SERIALIZER_SERVICE))
+ .withName("cordvtn-servicenetstore")
+ .withApplicationId(appId)
+ .build();
+ serviceNetworkStore.addListener(serviceNetworkListener);
+
+ servicePortStore = storageService.<PortId, ServicePort>consistentMapBuilder()
+ .withSerializer(Serializer.using(SERIALIZER_SERVICE))
+ .withName("cordvtn-serviceportstore")
+ .withApplicationId(appId)
+ .build();
+ servicePortStore.addListener(servicePortListener);
+
+ log.info("Started");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ serviceNetworkStore.removeListener(serviceNetworkListener);
+ servicePortStore.removeListener(servicePortListener);
+
+ log.info("Stopped");
+ }
+
+ @Override
+ public void clear() {
+ synchronized (this) {
+ serviceNetworkStore.clear();
+ servicePortStore.clear();
+ }
+ }
+
+ @Override
+ public void createServiceNetwork(ServiceNetwork snet) {
+ serviceNetworkStore.compute(snet.id(), (id, existing) -> {
+ final String error = snet.name() + ERR_DUPLICATE;
+ checkArgument(existing == null || existing.equals(snet), error);
+ return snet;
+ });
+ }
+
+ @Override
+ public void updateServiceNetwork(ServiceNetwork snet) {
+ serviceNetworkStore.compute(snet.id(), (id, existing) -> {
+ final String error = snet.name() + ERR_NOT_FOUND;
+ checkArgument(existing != null, error);
+ return snet;
+ });
+ }
+
+ @Override
+ public ServiceNetwork removeServiceNetwork(NetworkId netId) {
+ synchronized (this) {
+ Versioned<ServiceNetwork> snet = serviceNetworkStore.remove(netId);
+ return snet == null ? null : snet.value();
+ }
+ }
+
+ @Override
+ public ServiceNetwork serviceNetwork(NetworkId netId) {
+ Versioned<ServiceNetwork> versioned = serviceNetworkStore.get(netId);
+ return versioned == null ? null : versioned.value();
+ }
+
+ @Override
+ public Set<ServiceNetwork> serviceNetworks() {
+ Set<ServiceNetwork> snets = serviceNetworkStore.values().stream()
+ .map(Versioned::value)
+ .collect(Collectors.toSet());
+ return ImmutableSet.copyOf(snets);
+ }
+
+ @Override
+ public void createServicePort(ServicePort sport) {
+ servicePortStore.compute(sport.id(), (id, existing) -> {
+ final String error = sport.id().id() + ERR_DUPLICATE;
+ checkArgument(existing == null || existing.equals(sport), error);
+ return sport;
+ });
+ }
+
+ @Override
+ public void updateServicePort(ServicePort sport) {
+ servicePortStore.compute(sport.id(), (id, existing) -> {
+ final String error = sport.id().id() + ERR_NOT_FOUND;
+ checkArgument(existing != null, error);
+ return sport;
+ });
+ }
+
+ @Override
+ public ServicePort removeServicePort(PortId portId) {
+ Versioned<ServicePort> sport = servicePortStore.remove(portId);
+ return sport.value();
+ }
+
+ @Override
+ public ServicePort servicePort(PortId portId) {
+ Versioned<ServicePort> versioned = servicePortStore.get(portId);
+ return versioned == null ? null : versioned.value();
+ }
+
+ @Override
+ public Set<ServicePort> servicePorts() {
+ Set<ServicePort> sports = servicePortStore.values().stream()
+ .map(Versioned::value)
+ .collect(Collectors.toSet());
+ return ImmutableSet.copyOf(sports);
+ }
+
+ private class ServiceNetworkMapListener implements MapEventListener<NetworkId, ServiceNetwork> {
+
+ @Override
+ public void event(MapEvent<NetworkId, ServiceNetwork> event) {
+ switch (event.type()) {
+ case UPDATE:
+ log.debug("Service network updated {}", event.newValue());
+ eventExecutor.execute(() -> {
+ notifyDelegate(new ServiceNetworkEvent(
+ SERVICE_NETWORK_UPDATED,
+ event.newValue().value()));
+ notifyProviderUpdate(
+ event.oldValue().value(),
+ event.newValue().value());
+ });
+ break;
+ case INSERT:
+ log.debug("Service network created {}", event.newValue());
+ eventExecutor.execute(() -> {
+ notifyDelegate(new ServiceNetworkEvent(
+ SERVICE_NETWORK_CREATED,
+ event.newValue().value()));
+ notifyProviderUpdate(null, event.newValue().value());
+ });
+ break;
+ case REMOVE:
+ log.debug("Service network removed {}", event.oldValue());
+ eventExecutor.execute(() -> {
+ notifyProviderUpdate(event.oldValue().value(), null);
+ notifyDelegate(new ServiceNetworkEvent(
+ SERVICE_NETWORK_REMOVED,
+ event.oldValue().value()));
+ });
+ break;
+ default:
+ log.error("Unsupported event type");
+ break;
+ }
+ }
+
+ private void notifyProviderUpdate(ServiceNetwork oldValue, ServiceNetwork newValue) {
+ Map<NetworkId, DependencyType> oldp =
+ oldValue != null ? oldValue.providers() : ImmutableMap.of();
+ Map<NetworkId, DependencyType> newp =
+ newValue != null ? newValue.providers() : ImmutableMap.of();
+
+ oldp.entrySet().stream().filter(p -> !newp.keySet().contains(p.getKey()))
+ .forEach(p -> {
+ Provider providerNet = Provider.builder()
+ .provider(serviceNetwork(p.getKey()))
+ .type(p.getValue())
+ .build();
+ notifyDelegate(new ServiceNetworkEvent(
+ SERVICE_NETWORK_PROVIDER_REMOVED,
+ oldValue,
+ providerNet
+ ));
+ });
+
+ newp.entrySet().stream().filter(p -> !oldp.keySet().contains(p.getKey()))
+ .forEach(p -> {
+ Provider providerNet = Provider.builder()
+ .provider(serviceNetwork(p.getKey()))
+ .type(p.getValue())
+ .build();
+ notifyDelegate(new ServiceNetworkEvent(
+ SERVICE_NETWORK_PROVIDER_ADDED,
+ newValue,
+ providerNet));
+ });
+ }
+ }
+
+ private class ServicePortMapListener implements MapEventListener<PortId, ServicePort> {
+
+ @Override
+ public void event(MapEvent<PortId, ServicePort> event) {
+ switch (event.type()) {
+ case UPDATE:
+ log.debug("Service port updated {}", event.newValue());
+ eventExecutor.execute(() -> {
+ notifyDelegate(new ServiceNetworkEvent(
+ SERVICE_PORT_UPDATED,
+ serviceNetwork(event.newValue().value().networkId()),
+ event.newValue().value()));
+ });
+ break;
+ case INSERT:
+ log.debug("Service port created {}", event.newValue());
+ eventExecutor.execute(() -> {
+ notifyDelegate(new ServiceNetworkEvent(
+ SERVICE_PORT_CREATED,
+ serviceNetwork(event.newValue().value().networkId()),
+ event.newValue().value()));
+ });
+ break;
+ case REMOVE:
+ log.debug("Service port removed {}", event.oldValue());
+ eventExecutor.execute(() -> {
+ notifyDelegate(new ServiceNetworkEvent(
+ SERVICE_PORT_REMOVED,
+ serviceNetwork(event.oldValue().value().networkId()),
+ event.oldValue().value()));
+ });
+ break;
+ default:
+ log.error("Unsupported event type");
+ break;
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/opencord/cordvtn/impl/InstanceManager.java b/src/main/java/org/opencord/cordvtn/impl/InstanceManager.java
index 4d68b8d..2011342 100644
--- a/src/main/java/org/opencord/cordvtn/impl/InstanceManager.java
+++ b/src/main/java/org/opencord/cordvtn/impl/InstanceManager.java
@@ -45,14 +45,14 @@
import org.onosproject.net.provider.ProviderId;
import org.opencord.cordconfig.CordConfigService;
import org.opencord.cordconfig.access.AccessAgentData;
-import org.opencord.cordvtn.api.core.CordVtnService;
-import org.opencord.cordvtn.api.instance.Instance;
-import org.opencord.cordvtn.api.instance.InstanceService;
+import org.opencord.cordvtn.api.core.Instance;
+import org.opencord.cordvtn.api.core.InstanceService;
+import org.opencord.cordvtn.api.core.ServiceNetworkEvent;
+import org.opencord.cordvtn.api.core.ServiceNetworkListener;
+import org.opencord.cordvtn.api.core.ServiceNetworkService;
import org.opencord.cordvtn.api.net.PortId;
-import org.opencord.cordvtn.api.net.VtnNetwork;
-import org.opencord.cordvtn.api.net.VtnNetworkEvent;
-import org.opencord.cordvtn.api.net.VtnNetworkListener;
-import org.opencord.cordvtn.api.net.VtnPort;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
+import org.opencord.cordvtn.api.net.ServicePort;
import org.slf4j.Logger;
import java.util.Objects;
@@ -64,7 +64,7 @@
import static org.onosproject.net.AnnotationKeys.PORT_NAME;
import static org.opencord.cordvtn.api.Constants.CORDVTN_APP_ID;
import static org.opencord.cordvtn.api.Constants.NOT_APPLICABLE;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.ACCESS_AGENT;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.ACCESS_AGENT;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -76,8 +76,8 @@
InstanceService {
protected final Logger log = getLogger(getClass());
- private static final String ERR_VTN_NETWORK = "Faild to get VTN network for %s";
- private static final String ERR_VTN_PORT = "Faild to get VTN port for %s";
+ private static final String ERR_SERVICE_NETWORK = "Failed to get service network for %s";
+ private static final String ERR_SERVICE_PORT = "Failed to get service port for %s";
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@@ -102,11 +102,11 @@
protected CordConfigService cordConfig;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected CordVtnService vtnService;
+ protected ServiceNetworkService snetService;
private final ExecutorService eventExecutor =
newSingleThreadExecutor(groupedThreads(this.getClass().getSimpleName(), "event-handler"));
- private final VtnNetworkListener vtnNetListener = new InternalVtnNetworkListener();
+ private final ServiceNetworkListener snetListener = new InternalServiceNetworkListener();
private ApplicationId appId;
private NodeId localNodeId;
@@ -126,14 +126,14 @@
leadershipService.runForLeadership(appId.name());
hostProvider = hostProviderRegistry.register(this);
- vtnService.addListener(vtnNetListener);
+ snetService.addListener(snetListener);
log.info("Started");
}
@Deactivate
protected void deactivate() {
- vtnService.removeListener(vtnNetListener);
+ snetService.removeListener(snetListener);
hostProviderRegistry.unregister(this);
eventExecutor.shutdown();
leadershipService.withdraw(appId.name());
@@ -164,34 +164,35 @@
return;
}
- VtnPort vtnPort = vtnService.vtnPort(port.annotations().value(PORT_NAME));
- if (vtnPort == null) {
- log.warn(String.format(ERR_VTN_PORT, port));
+ ServicePort sport = getServicePortByPortName(port.annotations().value(PORT_NAME));
+ if (sport == null) {
+ log.warn(String.format(ERR_SERVICE_PORT, port));
return;
}
- VtnNetwork vtnNet = vtnService.vtnNetwork(vtnPort.netId());
- if (vtnNet == null) {
- log.warn(String.format(ERR_VTN_NETWORK, vtnPort));
- return;
+ ServiceNetwork snet = snetService.serviceNetwork(sport.networkId());
+ if (snet == null) {
+ final String error = String.format(ERR_SERVICE_NETWORK, sport);
+ throw new IllegalStateException(error);
}
// Added CREATE_TIME intentionally to trigger HOST_UPDATED event for the
- // existing instances.
+ // existing instances. Fix this after adding a method to update/reinstall
+ // flow rules for the existing service instances.
DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
- .set(Instance.NETWORK_TYPE, vtnNet.type().name())
- .set(Instance.NETWORK_ID, vtnNet.id().id())
- .set(Instance.PORT_ID, vtnPort.id().id())
+ .set(Instance.NETWORK_TYPE, snet.type().name())
+ .set(Instance.NETWORK_ID, snet.id().id())
+ .set(Instance.PORT_ID, sport.id().id())
.set(Instance.CREATE_TIME, String.valueOf(System.currentTimeMillis()));
HostDescription hostDesc = new DefaultHostDescription(
- vtnPort.mac(),
+ sport.mac(),
VlanId.NONE,
new HostLocation(connectPoint, System.currentTimeMillis()),
- Sets.newHashSet(vtnPort.ip()),
+ Sets.newHashSet(sport.ip()),
annotations.build());
- HostId hostId = HostId.hostId(vtnPort.mac());
+ HostId hostId = HostId.hostId(sport.mac());
hostProvider.hostDetected(hostId, hostDesc, false);
}
@@ -225,6 +226,14 @@
hostProvider.hostVanished(hostId);
}
+ private ServicePort getServicePortByPortName(String portName) {
+ Optional<ServicePort> sport = snetService.servicePorts()
+ .stream()
+ .filter(p -> p.id().id().contains(portName.substring(3)))
+ .findFirst();
+ return sport.isPresent() ? sport.get() : null;
+ }
+
// TODO remove this when XOS provides access agent information
private boolean isAccessAgent(ConnectPoint connectPoint) {
Optional<AccessAgentData> agent = cordConfig.getAccessAgent(connectPoint.deviceId());
@@ -255,22 +264,23 @@
}
private Instance getInstance(PortId portId) {
- VtnPort vtnPort = vtnService.vtnPort(portId);
- if (vtnPort == null) {
- final String error = "Failed to build VTN port for " + portId.id();
+ // TODO use instance service instead
+ ServicePort sport = snetService.servicePort(portId);
+ if (sport == null) {
+ final String error = String.format(ERR_SERVICE_PORT, portId);
throw new IllegalStateException(error);
}
- Host host = hostService.getHost(HostId.hostId(vtnPort.mac()));
+ Host host = hostService.getHost(HostId.hostId(sport.mac()));
if (host == null) {
return null;
}
return Instance.of(host);
}
- private class InternalVtnNetworkListener implements VtnNetworkListener {
+ private class InternalServiceNetworkListener implements ServiceNetworkListener {
@Override
- public void event(VtnNetworkEvent event) {
+ public void event(ServiceNetworkEvent event) {
NodeId leader = leadershipService.getLeader(appId.name());
if (!Objects.equals(localNodeId, leader)) {
// do not allow to proceed without leadership
@@ -278,10 +288,10 @@
}
switch (event.type()) {
- case VTN_PORT_CREATED:
- case VTN_PORT_UPDATED:
- log.debug("Processing service port {}", event.vtnPort());
- PortId portId = event.vtnPort().id();
+ case SERVICE_PORT_CREATED:
+ case SERVICE_PORT_UPDATED:
+ log.debug("Processing service port {}", event.servicePort());
+ PortId portId = event.servicePort().id();
eventExecutor.execute(() -> {
Instance instance = getInstance(portId);
if (instance != null) {
@@ -289,10 +299,10 @@
}
});
break;
- case VTN_PORT_REMOVED:
- case VTN_NETWORK_CREATED:
- case VTN_NETWORK_UPDATED:
- case VTN_NETWORK_REMOVED:
+ case SERVICE_PORT_REMOVED:
+ case SERVICE_NETWORK_CREATED:
+ case SERVICE_NETWORK_UPDATED:
+ case SERVICE_NETWORK_REMOVED:
default:
// do nothing for the other events
break;
diff --git a/src/main/java/org/opencord/cordvtn/impl/RemoteIpCommandUtil.java b/src/main/java/org/opencord/cordvtn/impl/RemoteIpCommandUtil.java
index e357a27..0821e83 100644
--- a/src/main/java/org/opencord/cordvtn/impl/RemoteIpCommandUtil.java
+++ b/src/main/java/org/opencord/cordvtn/impl/RemoteIpCommandUtil.java
@@ -23,7 +23,7 @@
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.onlab.packet.IpAddress;
-import org.opencord.cordvtn.api.node.NetworkAddress;
+import org.opencord.cordvtn.api.net.CidrAddr;
import org.opencord.cordvtn.api.node.SshAccessInfo;
import org.slf4j.Logger;
@@ -76,7 +76,7 @@
* @param device device name to assign the ip address
* @return true if the command succeeds, or false
*/
- public static boolean addIp(Session session, NetworkAddress ip, String device) {
+ public static boolean addIp(Session session, CidrAddr ip, String device) {
if (session == null || !session.isConnected()) {
return false;
}
diff --git a/src/main/java/org/opencord/cordvtn/impl/ServiceNetworkManager.java b/src/main/java/org/opencord/cordvtn/impl/ServiceNetworkManager.java
new file mode 100644
index 0000000..aaa74e5
--- /dev/null
+++ b/src/main/java/org/opencord/cordvtn/impl/ServiceNetworkManager.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed 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 org.opencord.cordvtn.impl;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.ListenerRegistry;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.net.host.HostService;
+import org.opencord.cordvtn.api.Constants;
+import org.opencord.cordvtn.api.CordVtnConfig;
+import org.opencord.cordvtn.api.core.ServiceNetworkAdminService;
+import org.opencord.cordvtn.api.core.ServiceNetworkEvent;
+import org.opencord.cordvtn.api.core.ServiceNetworkListener;
+import org.opencord.cordvtn.api.core.ServiceNetworkService;
+import org.opencord.cordvtn.api.core.ServiceNetworkStore;
+import org.opencord.cordvtn.api.core.ServiceNetworkStoreDelegate;
+import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.PortId;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
+import org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType;
+import org.opencord.cordvtn.api.net.ServicePort;
+import org.slf4j.Logger;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Provides implementation of administering and interfacing service network and port.
+ */
+@Component(immediate = true)
+@Service
+public class ServiceNetworkManager extends ListenerRegistry<ServiceNetworkEvent, ServiceNetworkListener>
+ implements ServiceNetworkAdminService, ServiceNetworkService {
+
+ protected final Logger log = getLogger(getClass());
+
+ private static final String MSG_SERVICE_NET = "Service network %s %s";
+ private static final String MSG_SERVICE_PORT = "Service port %s %s";
+ private static final String MSG_PROVIDER_NET = "Provider network %s %s";
+ private static final String MSG_CREATED = "created";
+ private static final String MSG_UPDATED = "updated";
+ private static final String MSG_REMOVED = "removed";
+
+ private static final String ERR_NULL_SERVICE_NET = "Service network cannot be null";
+ private static final String ERR_NULL_SERVICE_NET_ID = "Service network ID cannot be null";
+ private static final String ERR_NULL_SERVICE_NET_TYPE = "Service network type cannot be null";
+ private static final String ERR_NULL_SERVICE_PORT = "Service port cannot be null";
+ private static final String ERR_NULL_SERVICE_PORT_ID = "Service port ID cannot be null";
+ private static final String ERR_NULL_SERVICE_PORT_NET_ID = "Service port network ID cannot be null";
+
+ private static final String ERR_NOT_FOUND = " does not exist";
+ private static final String ERR_IN_USE = " still in use";
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetworkConfigRegistry configRegistry;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected HostService hostService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ServiceNetworkStore snetStore;
+
+ // TODO add cordvtn config service and move this
+ private static final Class<CordVtnConfig> CONFIG_CLASS = CordVtnConfig.class;
+ private final ConfigFactory configFactory =
+ new ConfigFactory<ApplicationId, CordVtnConfig>(
+ SubjectFactories.APP_SUBJECT_FACTORY, CONFIG_CLASS, "cordvtn") {
+ @Override
+ public CordVtnConfig createConfig() {
+ return new CordVtnConfig();
+ }
+ };
+
+ private final ServiceNetworkStoreDelegate delegate = new InternalServiceNetworkStoreDelegate();
+
+ @Activate
+ protected void activate() {
+ coreService.registerApplication(Constants.CORDVTN_APP_ID);
+ configRegistry.registerConfigFactory(configFactory);
+ snetStore.setDelegate(delegate);
+ log.info("Started");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ configRegistry.unregisterConfigFactory(configFactory);
+ snetStore.unsetDelegate(delegate);
+ log.info("Stopped");
+ }
+
+ @Override
+ public void purgeStates() {
+ snetStore.clear();
+ }
+
+ @Override
+ public ServiceNetwork serviceNetwork(NetworkId netId) {
+ checkNotNull(netId, ERR_NULL_SERVICE_NET_ID);
+ return snetStore.serviceNetwork(netId);
+ }
+
+ @Override
+ public Set<ServiceNetwork> serviceNetworks() {
+ return snetStore.serviceNetworks();
+ }
+
+ @Override
+ public void createServiceNetwork(ServiceNetwork snet) {
+ checkNotNull(snet, ERR_NULL_SERVICE_NET);
+ checkNotNull(snet.id(), ERR_NULL_SERVICE_NET_ID);
+ checkNotNull(snet.type(), ERR_NULL_SERVICE_NET_TYPE);
+ synchronized (this) {
+ snet.providers().keySet().forEach(provider -> {
+ if (snetStore.serviceNetwork(provider) == null) {
+ final String error = String.format(
+ MSG_PROVIDER_NET, provider.id(), ERR_NOT_FOUND);
+ throw new IllegalStateException(error);
+ }
+ });
+ snetStore.createServiceNetwork(snet);
+ log.info(String.format(MSG_SERVICE_NET, snet.name(), MSG_CREATED));
+ }
+ }
+
+ @Override
+ public void updateServiceNetwork(ServiceNetwork snet) {
+ checkNotNull(snet, ERR_NULL_SERVICE_NET);
+ checkNotNull(snet.id(), ERR_NULL_SERVICE_NET_ID);
+ synchronized (this) {
+ ServiceNetwork existing = snetStore.serviceNetwork(snet.id());
+ if (existing == null) {
+ final String error = String.format(
+ MSG_SERVICE_NET, snet.id(), ERR_NOT_FOUND);
+ throw new IllegalStateException(error);
+ }
+ // TODO do not allow service type update if the network in use
+ snetStore.updateServiceNetwork(DefaultServiceNetwork.builder(existing, snet).build());
+ log.info(String.format(MSG_SERVICE_NET, existing.name(), MSG_UPDATED));
+ }
+ }
+
+ @Override
+ public void removeServiceNetwork(NetworkId netId) {
+ checkNotNull(netId, ERR_NULL_SERVICE_NET_ID);
+ synchronized (this) {
+ if (isNetworkInUse(netId)) {
+ final String error = String.format(MSG_SERVICE_NET, netId, ERR_IN_USE);
+ throw new IllegalStateException(error);
+ }
+ // remove dependencies on this network first
+ serviceNetworks().stream().filter(n -> isProvider(n, netId)).forEach(n -> {
+ Map<NetworkId, DependencyType> newProviders = Maps.newHashMap(n.providers());
+ newProviders.remove(netId);
+ ServiceNetwork updated = DefaultServiceNetwork.builder(n)
+ .providers(newProviders)
+ .build();
+ snetStore.updateServiceNetwork(updated);
+ });
+ ServiceNetwork snet = snetStore.removeServiceNetwork(netId);
+ log.info(String.format(MSG_SERVICE_NET, snet.name(), MSG_REMOVED));
+ }
+ }
+
+ @Override
+ public ServicePort servicePort(PortId portId) {
+ checkNotNull(portId, ERR_NULL_SERVICE_PORT_ID);
+ return snetStore.servicePort(portId);
+ }
+
+ @Override
+ public Set<ServicePort> servicePorts() {
+ return snetStore.servicePorts();
+ }
+
+ @Override
+ public Set<ServicePort> servicePorts(NetworkId netId) {
+ Set<ServicePort> sports = snetStore.servicePorts().stream()
+ .filter(p -> Objects.equals(p.networkId(), netId))
+ .collect(Collectors.toSet());
+ return ImmutableSet.copyOf(sports);
+ }
+
+ @Override
+ public void createServicePort(ServicePort sport) {
+ checkNotNull(sport, ERR_NULL_SERVICE_PORT);
+ checkNotNull(sport.id(), ERR_NULL_SERVICE_PORT_ID);
+ checkNotNull(sport.networkId(), ERR_NULL_SERVICE_PORT_NET_ID);
+ synchronized (this) {
+ ServiceNetwork existing = snetStore.serviceNetwork(sport.networkId());
+ if (existing == null) {
+ final String error = String.format(
+ MSG_SERVICE_NET, sport.networkId(), ERR_NOT_FOUND);
+ throw new IllegalStateException(error);
+ }
+ snetStore.createServicePort(sport);
+ log.info(String.format(MSG_SERVICE_PORT, sport.id(), MSG_CREATED));
+ }
+ }
+
+ @Override
+ public void updateServicePort(ServicePort sport) {
+ checkNotNull(sport, ERR_NULL_SERVICE_PORT);
+ checkNotNull(sport.id(), ERR_NULL_SERVICE_PORT_ID);
+ synchronized (this) {
+ ServicePort existing = snetStore.servicePort(sport.id());
+ if (existing == null) {
+ final String error = String.format(
+ MSG_SERVICE_PORT, sport.id(), ERR_NOT_FOUND);
+ throw new IllegalStateException(error);
+ }
+ snetStore.updateServicePort(DefaultServicePort.builder(existing, sport).build());
+ log.info(String.format(MSG_SERVICE_PORT, sport.id(), MSG_UPDATED));
+ }
+ }
+
+ @Override
+ public void removeServicePort(PortId portId) {
+ checkNotNull(portId, ERR_NULL_SERVICE_PORT_ID);
+ synchronized (this) {
+ if (isPortInUse(portId)) {
+ final String error = String.format(MSG_SERVICE_PORT, portId, ERR_IN_USE);
+ throw new IllegalStateException(error);
+ }
+ snetStore.removeServicePort(portId);
+ log.info(String.format(MSG_SERVICE_PORT, portId, MSG_REMOVED));
+ }
+ }
+
+ /**
+ * Returns if the given target network is a provider of the given network.
+ *
+ * @param snet service network
+ * @param targetId target network
+ * @return true if the service network is a provider of the target network
+ */
+ private boolean isProvider(ServiceNetwork snet, NetworkId targetId) {
+ checkNotNull(snet);
+ return snet.providers().keySet().contains(targetId);
+ }
+
+ private boolean isNetworkInUse(NetworkId netId) {
+ // TODO use instance service to see if there's running instance for the network
+ return !servicePorts(netId).isEmpty();
+ }
+
+ private boolean isPortInUse(PortId portId) {
+ ServicePort sport = servicePort(portId);
+ if (sport == null) {
+ final String error = String.format(MSG_SERVICE_PORT, portId, ERR_NOT_FOUND);
+ throw new IllegalStateException(error);
+ }
+ // TODO use instance service to see if there's running instance for the port
+ Host host = hostService.getHost(HostId.hostId(sport.mac()));
+ return host != null;
+ }
+
+ private class InternalServiceNetworkStoreDelegate implements ServiceNetworkStoreDelegate {
+
+ @Override
+ public void notify(ServiceNetworkEvent event) {
+ if (event != null) {
+ log.trace("send service network event {}", event);
+ process(event);
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/opencord/cordvtn/impl/external/OpenStackNetworking.java b/src/main/java/org/opencord/cordvtn/impl/external/OpenStackNetworking.java
deleted file mode 100644
index 59a080d..0000000
--- a/src/main/java/org/opencord/cordvtn/impl/external/OpenStackNetworking.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.impl.external;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableSet;
-import org.opencord.cordvtn.api.net.NetworkId;
-import org.opencord.cordvtn.api.net.NetworkService;
-import org.opencord.cordvtn.api.net.PortId;
-import org.opencord.cordvtn.api.net.SubnetId;
-import org.openstack4j.api.OSClient;
-import org.openstack4j.api.exceptions.AuthenticationException;
-import org.openstack4j.model.identity.Access;
-import org.openstack4j.model.network.Network;
-import org.openstack4j.model.network.Port;
-import org.openstack4j.model.network.Subnet;
-import org.openstack4j.openstack.OSFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Set;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-/**
- * Implementation of {@link NetworkService} with OpenStack networking service.
- */
-public final class OpenStackNetworking implements NetworkService {
-
- protected final Logger log = LoggerFactory.getLogger(getClass());
-
- private static final String ERR_AUTH = "OpenStack authentication failure";
-
- private final String endpoint;
- private final String tenant;
- private final String user;
- private final String password;
- private final Access osAcess;
-
- private OpenStackNetworking(String endpoint,
- String tenant,
- String user,
- String password) {
- this.endpoint = endpoint;
- this.tenant = tenant;
- this.user = user;
- this.password = password;
-
- try {
- this.osAcess = OSFactory.builder()
- .endpoint(this.endpoint)
- .tenantName(this.tenant)
- .credentials(this.user, this.password)
- .authenticate()
- .getAccess();
- } catch (AuthenticationException e) {
- throw new IllegalArgumentException(ERR_AUTH);
- }
- }
-
- @Override
- public Network network(NetworkId netId) {
- OSClient osClient = OSFactory.clientFromAccess(osAcess);
- return osClient.networking().network().get(netId.id());
- }
-
- @Override
- public Set<Network> networks() {
- OSClient osClient = OSFactory.clientFromAccess(osAcess);
- return ImmutableSet.copyOf(osClient.networking().network().list());
- }
-
- @Override
- public Port port(PortId portId) {
- OSClient osClient = OSFactory.clientFromAccess(osAcess);
- return osClient.networking().port().get(portId.id());
- }
-
- @Override
- public Set<Port> ports() {
- OSClient osClient = OSFactory.clientFromAccess(osAcess);
- return ImmutableSet.copyOf(osClient.networking().port().list());
- }
-
- @Override
- public Subnet subnet(SubnetId subnetId) {
- OSClient osClient = OSFactory.clientFromAccess(osAcess);
- return osClient.networking().subnet().get(subnetId.id());
- }
-
- @Override
- public Set<Subnet> subnets() {
- OSClient osClient = OSFactory.clientFromAccess(osAcess);
- return ImmutableSet.copyOf(osClient.networking().subnet().list());
- }
-
- /**
- * Returns endpoint url for the OpenStack networking API access.
- *
- * @return endpoint url as a string
- */
- public String endpoint() {
- return endpoint;
- }
-
- /**
- * Returns tenant for the OpenStack networking API access.
- *
- * @return tenant name as a string
- */
- public String tenant() {
- return tenant;
- }
-
- /**
- * Returns user name for the OpenStack networking API access.
- *
- * @return user name as a string
- */
- public String user() {
- return this.user;
- }
-
- /**
- * Returns password for the OpenStack networking API access.
- *
- * @return password as a string
- */
- public String password() {
- return this.password;
- }
-
- /**
- * Returns new OpenStack networking builder instance.
- * @return openstack networking builder instance
- */
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * Builder of the OpenStack networking entities.
- */
- public static final class Builder {
-
- private String endpoint;
- private String tenant;
- private String user;
- private String password;
-
- private Builder() {
- }
-
- /**
- * Builds immutable OpenStack networking instance.
- *
- * @return openstack networking instance
- */
- public OpenStackNetworking build() {
- checkArgument(!Strings.isNullOrEmpty(endpoint));
- checkArgument(!Strings.isNullOrEmpty(tenant));
- checkArgument(!Strings.isNullOrEmpty(user));
- checkArgument(!Strings.isNullOrEmpty(password));
-
- return new OpenStackNetworking(endpoint, tenant, user, password);
- }
-
- /**
- * Returns OpenStack networking builder with the supplied endpoint.
- *
- * @param endpoint endpoint url as a string
- * @return openstack networking builder
- */
- public Builder endpoint(String endpoint) {
- this.endpoint = endpoint;
- return this;
- }
-
- /**
- * Returns OpenStack networking builder with the supplied tenant name.
- *
- * @param tenant tenant name as a string
- * @return openstack networking builder
- */
- public Builder tenant(String tenant) {
- this.tenant = tenant;
- return this;
- }
-
- /**
- * Returns OpenStack networking builder with the supplied user name.
- *
- * @param user user name as a string
- * @return openstack networking builder
- */
- public Builder user(String user) {
- this.user = user;
- return this;
- }
-
- /**
- * Returns OpenStack networking builder with the supplied password.
- *
- * @param password password as a string
- * @return openstack networking builder
- */
- public Builder password(String password) {
- this.password = password;
- return this;
- }
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/impl/external/package-info.java b/src/main/java/org/opencord/cordvtn/impl/external/package-info.java
deleted file mode 100644
index a096589..0000000
--- a/src/main/java/org/opencord/cordvtn/impl/external/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Laboratory
- *
- * Licensed 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.
- */
-
-/**
- * Implementation of NetworkService and ServiceNetworkService for external services.
- */
-package org.opencord.cordvtn.impl.external;
\ No newline at end of file
diff --git a/src/main/java/org/opencord/cordvtn/impl/handler/AbstractInstanceHandler.java b/src/main/java/org/opencord/cordvtn/impl/handler/AbstractInstanceHandler.java
index 01ccb91..0471ee6 100644
--- a/src/main/java/org/opencord/cordvtn/impl/handler/AbstractInstanceHandler.java
+++ b/src/main/java/org/opencord/cordvtn/impl/handler/AbstractInstanceHandler.java
@@ -18,6 +18,7 @@
import com.google.common.collect.ImmutableSet;
import org.onlab.osgi.DefaultServiceDirectory;
import org.onlab.osgi.ServiceDirectory;
+import org.onlab.util.Tools;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.mastership.MastershipService;
@@ -26,20 +27,18 @@
import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostService;
import org.opencord.cordvtn.api.Constants;
-import org.opencord.cordvtn.api.core.CordVtnService;
-import org.opencord.cordvtn.api.instance.Instance;
-import org.opencord.cordvtn.api.instance.InstanceHandler;
+import org.opencord.cordvtn.api.core.Instance;
+import org.opencord.cordvtn.api.core.InstanceHandler;
+import org.opencord.cordvtn.api.core.ServiceNetworkService;
import org.opencord.cordvtn.api.net.NetworkId;
-import org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType;
-import org.opencord.cordvtn.api.net.VtnNetwork;
-import org.opencord.cordvtn.api.net.VtnPort;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
+import org.opencord.cordvtn.api.net.ServicePort;
import org.slf4j.Logger;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.util.Tools.groupedThreads;
@@ -58,9 +57,9 @@
protected CoreService coreService;
protected MastershipService mastershipService;
protected HostService hostService;
- protected CordVtnService vtnService;
+ protected ServiceNetworkService snetService;
protected ApplicationId appId;
- protected Set<ServiceNetworkType> netTypes = ImmutableSet.of();
+ protected Set<ServiceNetwork.NetworkType> netTypes = ImmutableSet.of();
protected HostListener hostListener = new InternalHostListener();
@@ -72,7 +71,7 @@
coreService = services.get(CoreService.class);
mastershipService = services.get(MastershipService.class);
hostService = services.get(HostService.class);
- vtnService = services.get(CordVtnService.class);
+ snetService = services.get(ServiceNetworkService.class);
appId = coreService.registerApplication(Constants.CORDVTN_APP_ID);
hostService.addListener(hostListener);
@@ -93,7 +92,7 @@
}
protected Set<Instance> getInstances(NetworkId netId) {
- return StreamSupport.stream(hostService.getHosts().spliterator(), false)
+ return Tools.stream(hostService.getHosts())
.filter(host -> Objects.equals(
netId.id(),
host.annotations().value(Instance.NETWORK_ID)))
@@ -101,8 +100,8 @@
.collect(Collectors.toSet());
}
- protected VtnNetwork getVtnNetwork(Instance instance) {
- VtnNetwork vtnNet = vtnService.vtnNetwork(instance.netId());
+ protected ServiceNetwork getServiceNetwork(Instance instance) {
+ ServiceNetwork vtnNet = snetService.serviceNetwork(instance.netId());
if (vtnNet == null) {
final String error = String.format(ERR_VTN_NETWORK, instance);
throw new IllegalStateException(error);
@@ -110,8 +109,8 @@
return vtnNet;
}
- protected VtnPort getVtnPort(Instance instance) {
- VtnPort vtnPort = vtnService.vtnPort(instance.portId());
+ protected ServicePort getServicePort(Instance instance) {
+ ServicePort vtnPort = snetService.servicePort(instance.portId());
if (vtnPort == null) {
final String error = String.format(ERR_VTN_PORT, instance);
throw new IllegalStateException(error);
diff --git a/src/main/java/org/opencord/cordvtn/impl/handler/AccessAgentInstanceHandler.java b/src/main/java/org/opencord/cordvtn/impl/handler/AccessAgentInstanceHandler.java
index aee4d13..460ba25 100644
--- a/src/main/java/org/opencord/cordvtn/impl/handler/AccessAgentInstanceHandler.java
+++ b/src/main/java/org/opencord/cordvtn/impl/handler/AccessAgentInstanceHandler.java
@@ -28,12 +28,12 @@
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
-import org.opencord.cordvtn.api.instance.Instance;
-import org.opencord.cordvtn.api.instance.InstanceHandler;
+import org.opencord.cordvtn.api.core.Instance;
+import org.opencord.cordvtn.api.core.InstanceHandler;
import org.opencord.cordvtn.impl.CordVtnNodeManager;
import org.opencord.cordvtn.impl.CordVtnPipeline;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.ACCESS_AGENT;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.ACCESS_AGENT;
/**
* Provides network connectivity for access agent instances.
diff --git a/src/main/java/org/opencord/cordvtn/impl/handler/DefaultInstanceHandler.java b/src/main/java/org/opencord/cordvtn/impl/handler/DefaultInstanceHandler.java
index c33bb78..1684ce4 100644
--- a/src/main/java/org/opencord/cordvtn/impl/handler/DefaultInstanceHandler.java
+++ b/src/main/java/org/opencord/cordvtn/impl/handler/DefaultInstanceHandler.java
@@ -18,7 +18,6 @@
import com.google.common.collect.ImmutableSet;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
-
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
@@ -32,16 +31,14 @@
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
-import org.opencord.cordvtn.api.net.VtnNetwork;
+import org.opencord.cordvtn.api.core.Instance;
+import org.opencord.cordvtn.api.core.InstanceHandler;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
import org.opencord.cordvtn.api.node.CordVtnNode;
-import org.opencord.cordvtn.api.instance.Instance;
-import org.opencord.cordvtn.api.instance.InstanceHandler;
import org.opencord.cordvtn.impl.CordVtnNodeManager;
import org.opencord.cordvtn.impl.CordVtnPipeline;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.PRIVATE;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.PUBLIC;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.VSG;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.*;
/**
* Provides network connectivity for default service instances.
@@ -73,8 +70,8 @@
}
log.info("Instance is detected {}", instance);
- VtnNetwork vtnNet = getVtnNetwork(instance);
- populateDefaultRules(instance, vtnNet, true);
+ ServiceNetwork snet = getServiceNetwork(instance);
+ populateDefaultRules(instance, snet, true);
}
@Override
@@ -84,13 +81,13 @@
}
log.info("Instance is removed {}", instance);
- VtnNetwork vtnNet = getVtnNetwork(instance);
- populateDefaultRules(instance, vtnNet, false);
+ ServiceNetwork snet = getServiceNetwork(instance);
+ populateDefaultRules(instance, snet, false);
}
- private void populateDefaultRules(Instance instance, VtnNetwork vtnNet, boolean install) {
- long vni = vtnNet.segmentId().id();
- Ip4Prefix serviceIpRange = vtnNet.subnet().getIp4Prefix();
+ private void populateDefaultRules(Instance instance, ServiceNetwork snet, boolean install) {
+ long vni = snet.segmentId().id();
+ Ip4Prefix serviceIpRange = snet.subnet().getIp4Prefix();
populateInPortRule(instance, install);
populateDstIpRule(instance, vni, install);
@@ -99,7 +96,7 @@
if (install) {
populateDirectAccessRule(serviceIpRange, serviceIpRange, true);
populateServiceIsolationRule(serviceIpRange, true);
- } else if (getInstances(vtnNet.id()).isEmpty()) {
+ } else if (getInstances(snet.id()).isEmpty()) {
populateDirectAccessRule(serviceIpRange, serviceIpRange, false);
populateServiceIsolationRule(serviceIpRange, false);
}
diff --git a/src/main/java/org/opencord/cordvtn/impl/handler/DependencyHandler.java b/src/main/java/org/opencord/cordvtn/impl/handler/DependencyHandler.java
new file mode 100644
index 0000000..684bc6e
--- /dev/null
+++ b/src/main/java/org/opencord/cordvtn/impl/handler/DependencyHandler.java
@@ -0,0 +1,481 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed 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 org.opencord.cordvtn.impl.handler;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.GroupId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupService;
+import org.opencord.cordvtn.api.core.Instance;
+import org.opencord.cordvtn.api.core.ServiceNetworkAdminService;
+import org.opencord.cordvtn.api.core.ServiceNetworkEvent;
+import org.opencord.cordvtn.api.core.ServiceNetworkListener;
+import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
+import org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType;
+import org.opencord.cordvtn.api.node.CordVtnNode;
+import org.opencord.cordvtn.impl.CordVtnNodeManager;
+import org.opencord.cordvtn.impl.CordVtnPipeline;
+import org.slf4j.Logger;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.onosproject.net.group.DefaultGroupBucket.createSelectGroupBucket;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType.BIDIRECTIONAL;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.*;
+import static org.opencord.cordvtn.impl.CordVtnPipeline.*;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Provisions service dependencies between service networks.
+ */
+@Component(immediate = true)
+@Service
+public class DependencyHandler extends AbstractInstanceHandler {
+
+ protected final Logger log = getLogger(getClass());
+
+ private static final String ERR_NET_FAIL = "Failed to get VTN network ";
+ private static final String ADDED = "Added ";
+ private static final String REMOVED = "Removed ";
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected GroupService groupService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LeadershipService leadershipService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ClusterService clusterService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CordVtnPipeline pipeline;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CordVtnNodeManager nodeManager;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ServiceNetworkAdminService snetService;
+
+ private final ServiceNetworkListener snetListener = new InternalServiceNetworkListener();
+ private NodeId localNodeId;
+
+ @Activate
+ protected void activate() {
+ netTypes = ImmutableSet.of(PRIVATE, PUBLIC, VSG);
+ super.activate();
+ localNodeId = clusterService.getLocalNode().id();
+ leadershipService.runForLeadership(appId.name());
+ snetService.addListener(snetListener);
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ super.deactivate();
+ snetService.removeListener(snetListener);
+ leadershipService.withdraw(appId.name());
+ }
+
+ @Override
+ public void instanceDetected(Instance instance) {
+ ServiceNetwork snet = snetService.serviceNetwork(instance.netId());
+ if (snet == null) {
+ final String error = ERR_NET_FAIL + instance.netId();
+ throw new IllegalStateException(error);
+ }
+ if (!snet.providers().isEmpty()) {
+ updateSubscriberInstances(snet, instance, true);
+ }
+ // TODO check if subscribers on this network
+ updateProviderInstances(snet);
+ }
+
+ @Override
+ public void instanceRemoved(Instance instance) {
+ ServiceNetwork snet = snetService.serviceNetwork(instance.netId());
+ if (snet == null) {
+ final String error = ERR_NET_FAIL + instance.netId();
+ throw new IllegalStateException(error);
+ }
+ if (!snet.providers().isEmpty()) {
+ updateSubscriberInstances(snet, instance, false);
+ }
+ // TODO check if subscribers on this network and remove group if unused
+ updateProviderInstances(snet);
+ }
+
+ private void dependencyAdded(ServiceNetwork subscriber, ServiceNetwork provider,
+ DependencyType type) {
+ populateDependencyRules(subscriber, provider, type, true);
+ log.info("Dependency is created subscriber:{}, provider:{}, type: {}",
+ subscriber.name(),
+ provider.name(), type.name());
+ }
+
+ private void dependencyRemoved(ServiceNetwork subscriber, ServiceNetwork provider,
+ DependencyType type) {
+ populateDependencyRules(subscriber, provider, type, false);
+ if (!isProviderInUse(provider.id())) {
+ removeGroup(provider.id());
+ }
+ log.info("Dependency is removed subscriber:{}, provider:{}, type: {}",
+ subscriber.name(),
+ provider.name(), type.name());
+ }
+
+ private void updateProviderInstances(ServiceNetwork provider) {
+ Set<DeviceId> devices = nodeManager.completeNodes().stream()
+ .map(CordVtnNode::integrationBridgeId)
+ .collect(Collectors.toSet());
+
+ GroupKey groupKey = getGroupKey(provider.id());
+ for (DeviceId deviceId : devices) {
+ Group group = groupService.getGroup(deviceId, groupKey);
+ if (group == null) {
+ continue;
+ }
+ List<GroupBucket> oldBuckets = group.buckets().buckets();
+ List<GroupBucket> newBuckets = getProviderGroupBuckets(
+ deviceId,
+ provider.segmentId().id(),
+ getInstances(provider.id())).buckets();
+ if (oldBuckets.equals(newBuckets)) {
+ continue;
+ }
+
+ List<GroupBucket> bucketsToRemove = Lists.newArrayList(oldBuckets);
+ bucketsToRemove.removeAll(newBuckets);
+ if (!bucketsToRemove.isEmpty()) {
+ groupService.removeBucketsFromGroup(
+ deviceId,
+ groupKey,
+ new GroupBuckets(bucketsToRemove),
+ groupKey, appId);
+ log.debug("Removed buckets from provider({}) group on {}: {}",
+ provider.id(), deviceId, bucketsToRemove);
+ }
+
+ List<GroupBucket> bucketsToAdd = Lists.newArrayList(newBuckets);
+ bucketsToAdd.removeAll(oldBuckets);
+ if (!bucketsToAdd.isEmpty()) {
+ groupService.addBucketsToGroup(
+ deviceId,
+ groupKey,
+ new GroupBuckets(bucketsToAdd),
+ groupKey, appId);
+ log.debug("Added buckets to provider({}) group on {}: {}",
+ provider.id(), deviceId, bucketsToAdd);
+ }
+ }
+ }
+
+ private void updateSubscriberInstances(ServiceNetwork subscriber, Instance instance,
+ boolean isDetected) {
+ DeviceId deviceId = instance.deviceId();
+ final String isAdded = isDetected ? ADDED : REMOVED;
+ subscriber.providers().keySet().forEach(providerId -> {
+ populateInPortRule(
+ ImmutableMap.of(deviceId, ImmutableSet.of(instance.portNumber())),
+ ImmutableMap.of(deviceId, getGroupId(providerId, deviceId)),
+ isDetected);
+ log.info(isAdded + "subscriber instance({}) for provider({})",
+ instance.host().id(), providerId.id());
+ });
+ }
+
+ private boolean isProviderInUse(NetworkId providerId) {
+ return snetService.serviceNetworks().stream()
+ .flatMap(net -> net.providers().keySet().stream())
+ .filter(provider -> Objects.equals(provider, providerId))
+ .findAny().isPresent();
+ }
+
+ private void removeGroup(NetworkId netId) {
+ GroupKey groupKey = getGroupKey(netId);
+ nodeManager.completeNodes().stream()
+ .forEach(node -> {
+ DeviceId deviceId = node.integrationBridgeId();
+ Group group = groupService.getGroup(deviceId, groupKey);
+ if (group != null) {
+ groupService.removeGroup(deviceId, groupKey, appId);
+ }
+ });
+ log.debug("Removed group for network {}", netId);
+ }
+
+ private GroupId getGroupId(NetworkId netId, DeviceId deviceId) {
+ return new GroupId(Objects.hash(netId, deviceId));
+ }
+
+ private GroupKey getGroupKey(NetworkId netId) {
+ return new DefaultGroupKey(netId.id().getBytes());
+ }
+
+ private GroupId getProviderGroup(ServiceNetwork provider, DeviceId deviceId) {
+ GroupKey groupKey = getGroupKey(provider.id());
+ Group group = groupService.getGroup(deviceId, groupKey);
+ GroupId groupId = getGroupId(provider.id(), deviceId);
+
+ if (group != null) {
+ return groupId;
+ }
+
+ GroupBuckets buckets = getProviderGroupBuckets(
+ deviceId, provider.segmentId().id(), getInstances(provider.id()));
+ GroupDescription groupDescription = new DefaultGroupDescription(
+ deviceId,
+ GroupDescription.Type.SELECT,
+ buckets,
+ groupKey,
+ groupId.id(),
+ appId);
+
+ groupService.addGroup(groupDescription);
+ return groupId;
+ }
+
+ private void populateDependencyRules(ServiceNetwork subscriber, ServiceNetwork provider,
+ DependencyType type, boolean install) {
+ Map<DeviceId, GroupId> providerGroups = Maps.newHashMap();
+ Map<DeviceId, Set<PortNumber>> subscriberPorts = Maps.newHashMap();
+
+ nodeManager.completeNodes().stream().forEach(node -> {
+ DeviceId deviceId = node.integrationBridgeId();
+ GroupId groupId = getProviderGroup(provider, deviceId);
+ providerGroups.put(deviceId, groupId);
+
+ Set<PortNumber> ports = getInstances(subscriber.id())
+ .stream()
+ .filter(instance -> instance.deviceId().equals(deviceId))
+ .map(Instance::portNumber)
+ .collect(Collectors.toSet());
+ subscriberPorts.put(deviceId, ports);
+ });
+
+ // TODO support IPv6
+ IpPrefix sSubnet = subscriber.subnet().getIp4Prefix();
+ IpPrefix pSubnet = provider.subnet().getIp4Prefix();
+
+ populateInPortRule(subscriberPorts, providerGroups, install);
+ populateIndirectAccessRule(
+ sSubnet,
+ provider.serviceIp().getIp4Address(),
+ providerGroups,
+ install);
+ populateDirectAccessRule(sSubnet, pSubnet, install);
+ if (type == BIDIRECTIONAL) {
+ populateDirectAccessRule(pSubnet, sSubnet, install);
+ }
+ }
+
+ private void populateIndirectAccessRule(IpPrefix srcSubnet, IpAddress serviceIp,
+ Map<DeviceId, GroupId> outGroups,
+ boolean install) {
+ // TODO support IPv6
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPSrc(srcSubnet)
+ .matchIPDst(serviceIp.toIpPrefix())
+ .build();
+
+ for (Map.Entry<DeviceId, GroupId> outGroup : outGroups.entrySet()) {
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .group(outGroup.getValue())
+ .build();
+
+ FlowRule flowRule = DefaultFlowRule.builder()
+ .fromApp(appId)
+ .withSelector(selector)
+ .withTreatment(treatment)
+ .withPriority(PRIORITY_HIGH)
+ .forDevice(outGroup.getKey())
+ .forTable(TABLE_ACCESS)
+ .makePermanent()
+ .build();
+
+ pipeline.processFlowRule(install, flowRule);
+ }
+ }
+
+ private void populateDirectAccessRule(IpPrefix srcIp, IpPrefix dstIp, boolean install) {
+ // TODO support IPv6
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPSrc(srcIp)
+ .matchIPDst(dstIp)
+ .build();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .transition(TABLE_DST)
+ .build();
+
+ nodeManager.completeNodes().stream().forEach(node -> {
+ DeviceId deviceId = node.integrationBridgeId();
+ FlowRule flowRuleDirect = DefaultFlowRule.builder()
+ .fromApp(appId)
+ .withSelector(selector)
+ .withTreatment(treatment)
+ .withPriority(PRIORITY_DEFAULT)
+ .forDevice(deviceId)
+ .forTable(TABLE_ACCESS)
+ .makePermanent()
+ .build();
+
+ pipeline.processFlowRule(install, flowRuleDirect);
+ });
+ }
+
+ private void populateInPortRule(Map<DeviceId, Set<PortNumber>> subscriberPorts,
+ Map<DeviceId, GroupId> providerGroups,
+ boolean install) {
+ for (Map.Entry<DeviceId, Set<PortNumber>> entry : subscriberPorts.entrySet()) {
+ Set<PortNumber> ports = entry.getValue();
+ DeviceId deviceId = entry.getKey();
+ GroupId groupId = providerGroups.get(deviceId);
+ if (groupId == null) {
+ continue;
+ }
+ ports.stream().forEach(port -> {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchInPort(port)
+ .build();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .group(groupId)
+ .build();
+
+ FlowRule flowRule = DefaultFlowRule.builder()
+ .fromApp(appId)
+ .withSelector(selector)
+ .withTreatment(treatment)
+ .withPriority(PRIORITY_DEFAULT)
+ .forDevice(deviceId)
+ .forTable(TABLE_IN_SERVICE)
+ .makePermanent()
+ .build();
+
+ pipeline.processFlowRule(install, flowRule);
+ });
+ }
+ }
+
+ private GroupBuckets getProviderGroupBuckets(DeviceId deviceId, long tunnelId,
+ Set<Instance> instances) {
+ List<GroupBucket> buckets = Lists.newArrayList();
+ instances.stream().forEach(instance -> {
+ Ip4Address tunnelIp = nodeManager.dataIp(instance.deviceId()).getIp4Address();
+
+ if (deviceId.equals(instance.deviceId())) {
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setEthDst(instance.mac())
+ .setOutput(instance.portNumber())
+ .build();
+ buckets.add(createSelectGroupBucket(treatment));
+ } else {
+ ExtensionTreatment tunnelDst =
+ pipeline.tunnelDstTreatment(deviceId, tunnelIp);
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setEthDst(instance.mac())
+ .extension(tunnelDst, deviceId)
+ .setTunnelId(tunnelId)
+ .setOutput(nodeManager.tunnelPort(instance.deviceId()))
+ .build();
+ buckets.add(createSelectGroupBucket(treatment));
+ }
+ });
+ return new GroupBuckets(buckets);
+ }
+
+ private class InternalServiceNetworkListener implements ServiceNetworkListener {
+
+ @Override
+ public boolean isRelevant(ServiceNetworkEvent event) {
+ // do not allow to proceed without leadership
+ NodeId leader = leadershipService.getLeader(appId.name());
+ return Objects.equals(localNodeId, leader);
+ }
+
+ @Override
+ public void event(ServiceNetworkEvent event) {
+
+ switch (event.type()) {
+ case SERVICE_NETWORK_PROVIDER_ADDED:
+ log.debug("Dependency added: {}", event);
+ eventExecutor.execute(() -> {
+ dependencyAdded(
+ event.subject(),
+ event.provider().provider(),
+ event.provider().type());
+ });
+ break;
+ case SERVICE_NETWORK_PROVIDER_REMOVED:
+ log.debug("Dependency removed: {}", event);
+ eventExecutor.execute(() -> {
+ dependencyRemoved(
+ event.subject(),
+ event.provider().provider(),
+ event.provider().type());
+ });
+ break;
+ case SERVICE_NETWORK_CREATED:
+ case SERVICE_NETWORK_UPDATED:
+ // TODO handle dependency rule related element updates
+ case SERVICE_NETWORK_REMOVED:
+ case SERVICE_PORT_CREATED:
+ case SERVICE_PORT_UPDATED:
+ case SERVICE_PORT_REMOVED:
+ default:
+ // do nothing for the other events
+ break;
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/opencord/cordvtn/impl/handler/ManagementInstanceHandler.java b/src/main/java/org/opencord/cordvtn/impl/handler/ManagementInstanceHandler.java
index dd3eb81..0475f07 100644
--- a/src/main/java/org/opencord/cordvtn/impl/handler/ManagementInstanceHandler.java
+++ b/src/main/java/org/opencord/cordvtn/impl/handler/ManagementInstanceHandler.java
@@ -29,14 +29,14 @@
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
-import org.opencord.cordvtn.api.instance.Instance;
-import org.opencord.cordvtn.api.instance.InstanceHandler;
-import org.opencord.cordvtn.api.net.VtnNetwork;
+import org.opencord.cordvtn.api.core.Instance;
+import org.opencord.cordvtn.api.core.InstanceHandler;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
import org.opencord.cordvtn.impl.CordVtnNodeManager;
import org.opencord.cordvtn.impl.CordVtnPipeline;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.MANAGEMENT_HOST;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.MANAGEMENT_LOCAL;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.MANAGEMENT_HOST;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.MANAGEMENT_LOCAL;
/**
* Provides local management network connectivity to the instance. The instance
@@ -64,7 +64,7 @@
@Override
public void instanceDetected(Instance instance) {
- VtnNetwork vtnNet = getVtnNetwork(instance);
+ ServiceNetwork vtnNet = getServiceNetwork(instance);
switch (vtnNet.type()) {
case MANAGEMENT_LOCAL:
@@ -82,7 +82,7 @@
@Override
public void instanceRemoved(Instance instance) {
- VtnNetwork vtnNet = getVtnNetwork(instance);
+ ServiceNetwork vtnNet = getServiceNetwork(instance);
switch (vtnNet.type()) {
case MANAGEMENT_LOCAL:
diff --git a/src/main/java/org/opencord/cordvtn/impl/handler/VsgInstanceHandler.java b/src/main/java/org/opencord/cordvtn/impl/handler/VsgInstanceHandler.java
index 694d53a..f01b0e3 100644
--- a/src/main/java/org/opencord/cordvtn/impl/handler/VsgInstanceHandler.java
+++ b/src/main/java/org/opencord/cordvtn/impl/handler/VsgInstanceHandler.java
@@ -28,12 +28,8 @@
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
-import org.onosproject.net.Host;
-import org.opencord.cordvtn.api.net.AddressPair;
-import org.opencord.cordvtn.api.instance.InstanceService;
-import org.opencord.cordvtn.api.instance.Instance;
-import org.opencord.cordvtn.api.instance.InstanceHandler;
import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.DefaultFlowRule;
@@ -50,7 +46,11 @@
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
import org.onosproject.net.host.DefaultHostDescription;
import org.onosproject.net.host.HostDescription;
-import org.opencord.cordvtn.api.net.VtnPort;
+import org.opencord.cordvtn.api.core.Instance;
+import org.opencord.cordvtn.api.core.InstanceHandler;
+import org.opencord.cordvtn.api.core.InstanceService;
+import org.opencord.cordvtn.api.net.AddressPair;
+import org.opencord.cordvtn.api.net.ServicePort;
import org.opencord.cordvtn.impl.CordVtnNodeManager;
import org.opencord.cordvtn.impl.CordVtnPipeline;
@@ -59,7 +59,7 @@
import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_DST;
import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_PUSH;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.VSG;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.VSG;
/**
* Provides network connectivity for vSG instances.
@@ -108,34 +108,34 @@
throw new IllegalStateException(error);
}
- VtnPort vtnPort = getVtnPort(vsgVm);
- Set<IpAddress> wanIps = vtnPort.addressPairs().stream()
+ ServicePort sport = getServicePort(vsgVm);
+ Set<IpAddress> wanIps = sport.addressPairs().stream()
.map(AddressPair::ip).collect(Collectors.toSet());
populateVsgRules(
- vsgVm, vtnPort.vlanId().get(),
+ vsgVm, sport.vlanId(),
nodeManager.dataPort(vsgVm.deviceId()),
wanIps, true);
} else {
log.info(String.format(MSG_VSG_VM, MSG_DETECTED, instance));
- VtnPort vtnPort = vtnService.vtnPort(instance.portId());
- if (vtnPort == null || !vtnPort.vlanId().isPresent()) {
+ ServicePort sport = snetService.servicePort(instance.portId());
+ if (sport == null || sport.vlanId() == null) {
// service port can be updated after instance is created
return;
}
// insert vSG containers inside the vSG VM as a host
- vtnPort.addressPairs().stream().forEach(pair -> addVsgContainer(
+ sport.addressPairs().stream().forEach(pair -> addVsgContainer(
instance,
pair.ip(),
pair.mac(),
- vtnPort.vlanId().get()));
+ sport.vlanId()));
}
}
@Override
public void instanceUpdated(Instance instance) {
if (!isVsgContainer(instance)) {
- Set<MacAddress> vsgMacs = getVtnPort(instance).addressPairs().stream()
+ Set<MacAddress> vsgMacs = getServicePort(instance).addressPairs().stream()
.map(AddressPair::mac)
.collect(Collectors.toSet());
hostService.getConnectedHosts(instance.host().location()).stream()
@@ -159,24 +159,25 @@
return;
}
- VtnPort vtnPort = getVtnPort(instance);
- Set<IpAddress> wanIps = vtnPort.addressPairs().stream()
+ // FIXME service port can be removed already
+ ServicePort sport = getServicePort(instance);
+ Set<IpAddress> wanIps = sport.addressPairs().stream()
.map(AddressPair::ip).collect(Collectors.toSet());
populateVsgRules(
- vsgVm, vtnPort.vlanId().get(),
+ vsgVm, sport.vlanId(),
nodeManager.dataPort(vsgVm.deviceId()),
isVsgContainer ? wanIps : ImmutableSet.of(),
false);
}
@Override
- protected VtnPort getVtnPort(Instance instance) {
- VtnPort vtnPort = vtnService.vtnPort(instance.portId());
- if (vtnPort == null || !vtnPort.vlanId().isPresent()) {
+ protected ServicePort getServicePort(Instance instance) {
+ ServicePort sport = snetService.servicePort(instance.portId());
+ if (sport == null || sport.vlanId() == null) {
final String error = String.format(ERR_VTN_PORT, instance);
throw new IllegalStateException(error);
}
- return vtnPort;
+ return sport;
}
private boolean isVsgContainer(Instance instance) {
diff --git a/src/main/java/org/opencord/cordvtn/rest/CordVtnWebApplication.java b/src/main/java/org/opencord/cordvtn/rest/CordVtnWebApplication.java
index 1f282cb..8dbdbba 100644
--- a/src/main/java/org/opencord/cordvtn/rest/CordVtnWebApplication.java
+++ b/src/main/java/org/opencord/cordvtn/rest/CordVtnWebApplication.java
@@ -28,7 +28,6 @@
public Set<Class<?>> getClasses() {
return getClasses(ServiceNetworkWebResource.class,
ServicePortWebResource.class,
- ServiceDependencyWebResource.class,
NeutronMl2NetworksWebResource.class,
NeutronMl2SubnetsWebResource.class,
NeutronMl2PortsWebResource.class,
diff --git a/src/main/java/org/opencord/cordvtn/rest/NeutronMl2NetworksWebResource.java b/src/main/java/org/opencord/cordvtn/rest/NeutronMl2NetworksWebResource.java
index 5baf99b..939b373 100644
--- a/src/main/java/org/opencord/cordvtn/rest/NeutronMl2NetworksWebResource.java
+++ b/src/main/java/org/opencord/cordvtn/rest/NeutronMl2NetworksWebResource.java
@@ -16,21 +16,21 @@
package org.opencord.cordvtn.rest;
import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.osgi.DefaultServiceDirectory;
import org.onosproject.rest.AbstractWebResource;
-import org.opencord.cordvtn.api.core.CordVtnAdminService;
+import org.opencord.cordvtn.api.core.ServiceNetworkAdminService;
import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.SegmentId;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
+import org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType;
+import org.opencord.cordvtn.impl.DefaultServiceNetwork;
import org.openstack4j.core.transport.ObjectMapperSingleton;
-import org.openstack4j.model.network.Network;
import org.openstack4j.openstack.networking.domain.NeutronNetwork;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
@@ -42,11 +42,12 @@
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.io.InputStream;
-import java.util.Set;
import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
-import static javax.ws.rs.core.Response.*;
-import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static javax.ws.rs.core.Response.Status.OK;
+import static javax.ws.rs.core.Response.created;
+import static javax.ws.rs.core.Response.noContent;
+import static javax.ws.rs.core.Response.status;
/**
* Neutron ML2 mechanism driver implementation for the network resource.
@@ -56,11 +57,10 @@
protected final Logger log = LoggerFactory.getLogger(getClass());
private static final String MESSAGE = "Received networks %s request";
- private static final String NETWORK = "network";
private static final String NETWORKS = "networks";
- private final CordVtnAdminService adminService =
- DefaultServiceDirectory.getService(CordVtnAdminService.class);
+ private final ServiceNetworkAdminService adminService =
+ DefaultServiceDirectory.getService(ServiceNetworkAdminService.class);
@Context
private UriInfo uriInfo;
@@ -78,12 +78,12 @@
public Response createNetwork(InputStream input) {
log.trace(String.format(MESSAGE, "CREATE"));
- final NeutronNetwork net = readNetwork(input);
- adminService.createNetwork(net);
+ final ServiceNetwork snet = readNetwork(input);
+ adminService.createServiceNetwork(snet);
UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
.path(NETWORKS)
- .path(net.getId());
+ .path(snet.id().id());
return created(locationBuilder.build()).build();
}
@@ -103,54 +103,10 @@
public Response updateNetwork(@PathParam("id") String id, InputStream input) {
log.trace(String.format(MESSAGE, "UPDATE " + id));
- final NeutronNetwork net = readNetwork(input);
- adminService.updateNetwork(net);
+ final ServiceNetwork snet = readNetwork(input);
+ adminService.updateServiceNetwork(snet);
- ObjectNode result = this.mapper().createObjectNode();
- return ok(result.set(NETWORK, writeNetwork(net))).build();
- }
-
- /**
- * Returns all networks.
- *
- * @return 200 OK with set of networks
- */
- @GET
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response getNetworks() {
- log.trace(String.format(MESSAGE, "GET"));
-
- Set<Network> nets = adminService.networks();
- ArrayNode arrayNodes = mapper().createArrayNode();
- nets.stream().forEach(net -> {
- arrayNodes.add(writeNetwork(net));
- });
-
- ObjectNode result = this.mapper().createObjectNode();
- return ok(result.set(NETWORKS, arrayNodes)).build();
- }
-
- /**
- * Returns the network with the given network id.
- *
- * @param id network id
- * @return 200 OK with the network, 404 NOT_FOUND if the network does not exist
- */
- @GET
- @Path("{id}")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response getNetwork(@PathParam("id") String id) {
- log.trace(String.format(MESSAGE, "GET " + id));
-
- Network net = adminService.network(NetworkId.of(id));
- if (net == null) {
- return status(NOT_FOUND).build();
- }
-
- ObjectNode result = mapper().createObjectNode();
- return ok(result.set(NETWORK, writeNetwork(net))).build();
+ return status(OK).build();
}
/**
@@ -166,31 +122,26 @@
public Response deleteNetwork(@PathParam("id") String id) {
log.trace(String.format(MESSAGE, "DELETE " + id));
- adminService.removeNetwork(NetworkId.of(id));
+ adminService.removeServiceNetwork(NetworkId.of(id));
return noContent().build();
}
- private NeutronNetwork readNetwork(InputStream input) {
+ private ServiceNetwork readNetwork(InputStream input) {
try {
JsonNode jsonTree = mapper().enable(INDENT_OUTPUT).readTree(input);
log.trace(mapper().writeValueAsString(jsonTree));
- return ObjectMapperSingleton.getContext(NeutronNetwork.class)
+ NeutronNetwork osNet = ObjectMapperSingleton.getContext(NeutronNetwork.class)
.readerFor(NeutronNetwork.class)
.readValue(jsonTree);
+
+ return DefaultServiceNetwork.builder()
+ .id(NetworkId.of(osNet.getId()))
+ .name(osNet.getName())
+ .type(NetworkType.PRIVATE)
+ .segmentId(SegmentId.of(Long.valueOf(osNet.getProviderSegID())))
+ .build();
} catch (Exception e) {
throw new IllegalArgumentException();
}
}
-
- private ObjectNode writeNetwork(Network net) {
- try {
- String strNet = ObjectMapperSingleton.getContext(NeutronNetwork.class)
- .writerFor(NeutronNetwork.class)
- .writeValueAsString(net);
- log.trace(strNet);
- return (ObjectNode) mapper().readTree(strNet.getBytes());
- } catch (Exception e) {
- throw new IllegalStateException();
- }
- }
}
diff --git a/src/main/java/org/opencord/cordvtn/rest/NeutronMl2PortsWebResource.java b/src/main/java/org/opencord/cordvtn/rest/NeutronMl2PortsWebResource.java
index d1b52ce..8776e39 100644
--- a/src/main/java/org/opencord/cordvtn/rest/NeutronMl2PortsWebResource.java
+++ b/src/main/java/org/opencord/cordvtn/rest/NeutronMl2PortsWebResource.java
@@ -16,21 +16,23 @@
package org.opencord.cordvtn.rest;
import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.base.Strings;
import org.onlab.osgi.DefaultServiceDirectory;
-import org.opencord.cordvtn.api.core.CordVtnAdminService;
-import org.opencord.cordvtn.api.net.PortId;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
import org.onosproject.rest.AbstractWebResource;
+import org.opencord.cordvtn.api.core.ServiceNetworkAdminService;
+import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.PortId;
+import org.opencord.cordvtn.api.net.ServicePort;
+import org.opencord.cordvtn.impl.DefaultServicePort;
import org.openstack4j.core.transport.ObjectMapperSingleton;
-import org.openstack4j.model.network.Port;
import org.openstack4j.openstack.networking.domain.NeutronPort;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
@@ -42,10 +44,9 @@
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.io.InputStream;
-import java.util.Set;
import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
-import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static javax.ws.rs.core.Response.Status.OK;
import static javax.ws.rs.core.Response.created;
import static javax.ws.rs.core.Response.noContent;
import static javax.ws.rs.core.Response.status;
@@ -59,11 +60,10 @@
protected final Logger log = LoggerFactory.getLogger(getClass());
private static final String MESSAGE = "Received ports %s request";
- private static final String PORT = "port";
private static final String PORTS = "ports";
- private final CordVtnAdminService adminService =
- DefaultServiceDirectory.getService(CordVtnAdminService.class);
+ private final ServiceNetworkAdminService adminService =
+ DefaultServiceDirectory.getService(ServiceNetworkAdminService.class);
@Context
private UriInfo uriInfo;
@@ -81,11 +81,11 @@
public Response createPorts(InputStream input) {
log.trace(String.format(MESSAGE, "CREATE"));
- final NeutronPort port = readPort(input);
- adminService.createPort(port);
+ final ServicePort sport = readPort(input);
+ adminService.createServicePort(sport);
UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
.path(PORTS)
- .path(port.getId());
+ .path(sport.id().id());
return created(locationBuilder.build()).build();
}
@@ -105,54 +105,10 @@
public Response updatePort(@PathParam("id") String id, InputStream input) {
log.trace(String.format(MESSAGE, "UPDATE " + id));
- final NeutronPort port = readPort(input);
- adminService.updatePort(port);
+ final ServicePort port = readPort(input);
+ adminService.updateServicePort(port);
- ObjectNode result = this.mapper().createObjectNode();
- return ok(result.set(PORT, writePort(port))).build();
- }
-
- /**
- * Returns all ports.
- *
- * @return 200 OK with set of ports
- */
- @GET
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response getPorts() {
- log.trace(String.format(MESSAGE, "GET"));
-
- Set<Port> ports = adminService.ports();
- ArrayNode arrayNodes = mapper().createArrayNode();
- ports.stream().forEach(port -> {
- arrayNodes.add(writePort(port));
- });
-
- ObjectNode result = this.mapper().createObjectNode();
- return ok(result.set(PORTS, arrayNodes)).build();
- }
-
- /**
- * Returns the port with the given id.
- *
- * @param id port id
- * @return 200 OK with the port, 404 NOT_FOUND if the port does not exist
- */
- @GET
- @Path("{id}")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response getPort(@PathParam("id") String id) {
- log.trace(String.format(MESSAGE, "GET " + id));
-
- Port port = adminService.port(PortId.of(id));
- if (port == null) {
- return status(NOT_FOUND).build();
- }
-
- ObjectNode result = this.mapper().createObjectNode();
- return ok(result.set(PORT, writePort(port))).build();
+ return status(OK).build();
}
/**
@@ -168,31 +124,36 @@
public Response deletePorts(@PathParam("id") String id) {
log.trace(String.format(MESSAGE, "DELETE " + id));
- adminService.removePort(PortId.of(id));
+ adminService.removeServicePort(PortId.of(id));
return noContent().build();
}
- private NeutronPort readPort(InputStream input) {
+ private ServicePort readPort(InputStream input) {
try {
JsonNode jsonTree = mapper().enable(INDENT_OUTPUT).readTree(input);
log.trace(mapper().writeValueAsString(jsonTree));
- return ObjectMapperSingleton.getContext(NeutronPort.class)
+ NeutronPort osPort = ObjectMapperSingleton.getContext(NeutronPort.class)
.readerFor(NeutronPort.class)
.readValue(jsonTree);
+
+ ServicePort.Builder sportBuilder = DefaultServicePort.builder()
+ .id(PortId.of(osPort.getId()))
+ .networkId(NetworkId.of(osPort.getNetworkId()));
+
+ if (!Strings.isNullOrEmpty(osPort.getName())) {
+ sportBuilder.name(osPort.getName());
+ }
+ if (osPort.getMacAddress() != null) {
+ sportBuilder.mac(MacAddress.valueOf(osPort.getMacAddress()));
+ }
+ if (!osPort.getFixedIps().isEmpty()) {
+ sportBuilder.ip(IpAddress.valueOf(
+ osPort.getFixedIps().iterator().next().getIpAddress()));
+ }
+
+ return sportBuilder.build();
} catch (Exception e) {
throw new IllegalArgumentException();
}
}
-
- private ObjectNode writePort(Port port) {
- try {
- String strPort = ObjectMapperSingleton.getContext(NeutronPort.class)
- .writerFor(NeutronPort.class)
- .writeValueAsString(port);
- log.trace(strPort);
- return (ObjectNode) mapper().readTree(strPort.getBytes());
- } catch (Exception e) {
- throw new IllegalStateException();
- }
- }
}
diff --git a/src/main/java/org/opencord/cordvtn/rest/NeutronMl2SubnetsWebResource.java b/src/main/java/org/opencord/cordvtn/rest/NeutronMl2SubnetsWebResource.java
index aa374db..fc7ee65 100644
--- a/src/main/java/org/opencord/cordvtn/rest/NeutronMl2SubnetsWebResource.java
+++ b/src/main/java/org/opencord/cordvtn/rest/NeutronMl2SubnetsWebResource.java
@@ -16,21 +16,21 @@
package org.opencord.cordvtn.rest;
import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
import org.onosproject.rest.AbstractWebResource;
-import org.opencord.cordvtn.api.core.CordVtnAdminService;
-import org.opencord.cordvtn.api.net.SubnetId;
+import org.opencord.cordvtn.api.core.ServiceNetworkAdminService;
+import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.ServiceNetwork;
+import org.opencord.cordvtn.impl.DefaultServiceNetwork;
import org.openstack4j.core.transport.ObjectMapperSingleton;
-import org.openstack4j.model.network.Subnet;
import org.openstack4j.openstack.networking.domain.NeutronSubnet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
@@ -42,10 +42,9 @@
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.io.InputStream;
-import java.util.Set;
import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
-import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static javax.ws.rs.core.Response.Status.OK;
import static javax.ws.rs.core.Response.created;
import static javax.ws.rs.core.Response.noContent;
import static javax.ws.rs.core.Response.status;
@@ -58,11 +57,10 @@
protected final Logger log = LoggerFactory.getLogger(getClass());
private static final String MESSAGE = "Received subnets %s request";
- private static final String SUBNET = "subnet";
private static final String SUBNETS = "subnets";
- private final CordVtnAdminService adminService =
- DefaultServiceDirectory.getService(CordVtnAdminService.class);
+ private final ServiceNetworkAdminService adminService =
+ DefaultServiceDirectory.getService(ServiceNetworkAdminService.class);
@Context
private UriInfo uriInfo;
@@ -80,13 +78,14 @@
public Response createSubnet(InputStream input) {
log.trace(String.format(MESSAGE, "CREATE"));
- final NeutronSubnet subnet = readSubnet(input);
- adminService.createSubnet(subnet);
+ // FIXME do not allow more than one subnet per network
+ final ServiceNetwork snet = readSubnet(input);
+ adminService.updateServiceNetwork(snet);
UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
.path(SUBNETS)
- .path(subnet.getId());
+ .path(snet.id().id());
- // TODO fix networking-onos to send Network UPDATE when subnet created
+ // TODO fix Neutron networking-onos to send Network UPDATE when subnet created
return created(locationBuilder.build()).build();
}
@@ -105,54 +104,10 @@
public Response updateSubnet(@PathParam("id") String id, InputStream input) {
log.trace(String.format(MESSAGE, "UPDATE " + id));
- final NeutronSubnet subnet = readSubnet(input);
- adminService.updateSubnet(subnet);
+ final ServiceNetwork snet = readSubnet(input);
+ adminService.updateServiceNetwork(snet);
- ObjectNode result = this.mapper().createObjectNode();
- return ok(result.set(SUBNET, writeSubnet(subnet))).build();
- }
-
- /**
- * Returns all subnets.
- *
- * @return 200 OK with set of subnets
- */
- @GET
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response getSubnets() {
- log.trace(String.format(MESSAGE, "GET"));
-
- Set<Subnet> subnets = adminService.subnets();
- ArrayNode arrayNodes = mapper().createArrayNode();
- subnets.stream().forEach(subnet -> {
- arrayNodes.add(writeSubnet(subnet));
- });
-
- ObjectNode result = this.mapper().createObjectNode();
- return ok(result.set(SUBNETS, arrayNodes)).build();
- }
-
- /**
- * Returns the subnet with the given subnet id.
- *
- * @param id subnet id
- * @return 200 OK with the subnet, 404 NOT_FOUND if the subnet does not exist
- */
- @GET
- @Path("{id}")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response getSubnet(@PathParam("id") String id) {
- log.trace(String.format(MESSAGE, "GET " + id));
-
- Subnet subnet = adminService.subnet(SubnetId.of(id));
- if (subnet == null) {
- return status(NOT_FOUND).build();
- }
-
- ObjectNode result = this.mapper().createObjectNode();
- return ok(result.set(SUBNET, writeSubnet(subnet))).build();
+ return status(OK).build();
}
/**
@@ -167,32 +122,24 @@
@Produces(MediaType.APPLICATION_JSON)
public Response deleteSubnet(@PathParam("id") String id) {
log.trace(String.format(MESSAGE, "DELETE " + id));
-
- adminService.removeSubnet(SubnetId.of(id));
return noContent().build();
}
- private NeutronSubnet readSubnet(InputStream input) {
+ private ServiceNetwork readSubnet(InputStream input) {
try {
JsonNode jsonTree = mapper().enable(INDENT_OUTPUT).readTree(input);
log.trace(mapper().writeValueAsString(jsonTree));
- return ObjectMapperSingleton.getContext(NeutronSubnet.class)
+ NeutronSubnet osSubnet = ObjectMapperSingleton.getContext(NeutronSubnet.class)
.readerFor(NeutronSubnet.class)
.readValue(jsonTree);
- } catch (Exception e) {
- throw new IllegalArgumentException();
- }
- }
- private ObjectNode writeSubnet(Subnet subnet) {
- try {
- String strSubnet = ObjectMapperSingleton.getContext(NeutronSubnet.class)
- .writerFor(NeutronSubnet.class)
- .writeValueAsString(subnet);
- log.trace(strSubnet);
- return (ObjectNode) mapper().readTree(strSubnet.getBytes());
+ return DefaultServiceNetwork.builder()
+ .id(NetworkId.of(osSubnet.getNetworkId()))
+ .subnet(IpPrefix.valueOf(osSubnet.getCidr()))
+ .serviceIp(IpAddress.valueOf(osSubnet.getGateway()))
+ .build();
} catch (Exception e) {
- throw new IllegalStateException();
+ throw new IllegalArgumentException(e);
}
}
}
diff --git a/src/main/java/org/opencord/cordvtn/rest/ServiceDependencyWebResource.java b/src/main/java/org/opencord/cordvtn/rest/ServiceDependencyWebResource.java
deleted file mode 100644
index be4a94b..0000000
--- a/src/main/java/org/opencord/cordvtn/rest/ServiceDependencyWebResource.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Laboratory
- *
- * Licensed 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 org.opencord.cordvtn.rest;
-
-import org.onosproject.rest.AbstractWebResource;
-import org.opencord.cordvtn.api.dependency.Dependency.Type;
-import org.opencord.cordvtn.api.dependency.DependencyService;
-import org.opencord.cordvtn.api.net.NetworkId;
-
-import javax.ws.rs.DELETE;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.util.Objects;
-
-import static org.opencord.cordvtn.api.dependency.Dependency.Type.BIDIRECTIONAL;
-import static org.opencord.cordvtn.api.dependency.Dependency.Type.UNIDIRECTIONAL;
-
-/**
- * Manages service dependency.
- */
-@Deprecated
-@Path("service-dependency")
-public class ServiceDependencyWebResource extends AbstractWebResource {
-
- private final DependencyService service = get(DependencyService.class);
- private static final String BIDIRECTION = "b";
-
- /**
- * Creates service dependencies with unidirectional access between the services.
- *
- * @param tServiceId tenant service id
- * @param pServiceId provider service id
- * @return 200 OK
- */
- @POST
- @Path("{tenantServiceId}/{providerServiceId}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response createServiceDependency(@PathParam("tenantServiceId") String tServiceId,
- @PathParam("providerServiceId") String pServiceId) {
- service.createDependency(NetworkId.of(tServiceId),
- NetworkId.of(pServiceId),
- UNIDIRECTIONAL);
- return Response.status(Response.Status.OK).build();
- }
-
- /**
- * Creates service dependencies with an access type extension between the services.
- *
- * @param tServiceId tenant service id
- * @param pServiceId provider service id
- * @param direction b for bidirectional access, otherwise unidirectional access
- * @return 200 OK
- */
- @POST
- @Path("{tenantServiceId}/{providerServiceId}/{direction}")
- @Produces(MediaType.APPLICATION_JSON)
- public Response createServiceDependency(@PathParam("tenantServiceId") String tServiceId,
- @PathParam("providerServiceId") String pServiceId,
- @PathParam("direction") String direction) {
- Type type = Objects.equals(direction, BIDIRECTION) ? BIDIRECTIONAL : UNIDIRECTIONAL;
- service.createDependency(NetworkId.of(tServiceId),
- NetworkId.of(pServiceId),
- type);
- return Response.status(Response.Status.OK).build();
- }
-
- /**
- * Removes service dependencies.
- *
- * @param tServiceId tenant service id
- * @param pServiceId provider service id
- * @return 204 NO CONTENT
- */
- @DELETE
- @Path("{tenantServiceId}/{providerServiceId}")
- public Response removeServiceDependency(@PathParam("tenantServiceId") String tServiceId,
- @PathParam("providerServiceId") String pServiceId) {
- service.removeDependency(NetworkId.of(tServiceId), NetworkId.of(pServiceId));
- return Response.noContent().build();
- }
-}
diff --git a/src/main/java/org/opencord/cordvtn/rest/ServiceNetworkWebResource.java b/src/main/java/org/opencord/cordvtn/rest/ServiceNetworkWebResource.java
index 6a468a6..551d6af 100644
--- a/src/main/java/org/opencord/cordvtn/rest/ServiceNetworkWebResource.java
+++ b/src/main/java/org/opencord/cordvtn/rest/ServiceNetworkWebResource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-present Open Networking Laboratory
+ * Copyright 2017-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.osgi.DefaultServiceDirectory;
import org.onosproject.rest.AbstractWebResource;
-import org.opencord.cordvtn.api.core.CordVtnAdminService;
+import org.opencord.cordvtn.api.core.ServiceNetworkAdminService;
import org.opencord.cordvtn.api.net.NetworkId;
import org.opencord.cordvtn.api.net.ServiceNetwork;
import org.slf4j.Logger;
@@ -44,9 +44,7 @@
import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
-import static javax.ws.rs.core.Response.created;
-import static javax.ws.rs.core.Response.noContent;
-import static javax.ws.rs.core.Response.status;
+import static javax.ws.rs.core.Response.*;
/**
* Query and manage service networks.
@@ -59,8 +57,8 @@
private static final String SERVICE_NETWORK = "ServiceNetwork";
private static final String SERVICE_NETWORKS = "ServiceNetworks";
- private final CordVtnAdminService adminService =
- DefaultServiceDirectory.getService(CordVtnAdminService.class);
+ private final ServiceNetworkAdminService adminService =
+ DefaultServiceDirectory.getService(ServiceNetworkAdminService.class);
@Context
private UriInfo uriInfo;
diff --git a/src/main/java/org/opencord/cordvtn/rest/ServicePortWebResource.java b/src/main/java/org/opencord/cordvtn/rest/ServicePortWebResource.java
index b3a0580..88cc665 100644
--- a/src/main/java/org/opencord/cordvtn/rest/ServicePortWebResource.java
+++ b/src/main/java/org/opencord/cordvtn/rest/ServicePortWebResource.java
@@ -19,7 +19,7 @@
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.osgi.DefaultServiceDirectory;
import org.onosproject.rest.AbstractWebResource;
-import org.opencord.cordvtn.api.core.CordVtnAdminService;
+import org.opencord.cordvtn.api.core.ServiceNetworkAdminService;
import org.opencord.cordvtn.api.net.PortId;
import org.opencord.cordvtn.api.net.ServicePort;
import org.slf4j.Logger;
@@ -44,9 +44,7 @@
import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
-import static javax.ws.rs.core.Response.created;
-import static javax.ws.rs.core.Response.noContent;
-import static javax.ws.rs.core.Response.status;
+import static javax.ws.rs.core.Response.*;
/**
* Query and manage service ports.
@@ -59,8 +57,8 @@
private static final String SERVICE_PORT = "ServicePort";
private static final String SERVICE_PORTS = "ServicePorts";
- private final CordVtnAdminService adminService =
- DefaultServiceDirectory.getService(CordVtnAdminService.class);
+ private final ServiceNetworkAdminService adminService =
+ DefaultServiceDirectory.getService(ServiceNetworkAdminService.class);
@Context
private UriInfo uriInfo;
diff --git a/src/main/java/org/opencord/cordvtn/impl/external/XosServiceNetworking.java b/src/main/java/org/opencord/cordvtn/rest/XosVtnNetworkingClient.java
similarity index 93%
rename from src/main/java/org/opencord/cordvtn/impl/external/XosServiceNetworking.java
rename to src/main/java/org/opencord/cordvtn/rest/XosVtnNetworkingClient.java
index 1c232cf..fed5e91 100644
--- a/src/main/java/org/opencord/cordvtn/impl/external/XosServiceNetworking.java
+++ b/src/main/java/org/opencord/cordvtn/rest/XosVtnNetworkingClient.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.opencord.cordvtn.impl.external;
+package org.opencord.cordvtn.rest;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.SerializationFeature;
@@ -26,7 +26,6 @@
import org.opencord.cordvtn.api.net.NetworkId;
import org.opencord.cordvtn.api.net.PortId;
import org.opencord.cordvtn.api.net.ServiceNetwork;
-import org.opencord.cordvtn.api.net.ServiceNetworkService;
import org.opencord.cordvtn.api.net.ServicePort;
import org.slf4j.Logger;
@@ -45,10 +44,9 @@
import static org.slf4j.LoggerFactory.getLogger;
/**
- * Implementation of {@link ServiceNetworkService} with XOS VTN service.
+ * Implementation of REST client for XOS VTN networking service.
*/
-public final class XosServiceNetworking extends AbstractWebResource
- implements ServiceNetworkService {
+public final class XosVtnNetworkingClient extends AbstractWebResource {
protected final Logger log = getLogger(getClass());
@@ -72,7 +70,7 @@
private final String password;
private final Client client = ClientBuilder.newClient();
- private XosServiceNetworking(String endpoint, String user, String password) {
+ private XosVtnNetworkingClient(String endpoint, String user, String password) {
this.endpoint = endpoint;
this.user = user;
this.password = password;
@@ -82,7 +80,6 @@
mapper().enable(SerializationFeature.INDENT_OUTPUT);
}
- @Override
public Set<ServiceNetwork> serviceNetworks() {
String response = restGet(URL_SERVICE_NETWORKS);
final String error = String.format(ERR_LOG, SERVICE_NETWORKS, response);
@@ -101,7 +98,6 @@
}
}
- @Override
public ServiceNetwork serviceNetwork(NetworkId netId) {
String response = restGet(URL_SERVICE_NETWORKS + netId.id());
final String error = String.format(ERR_LOG, SERVICE_NETWORK, response);
@@ -118,7 +114,6 @@
}
}
- @Override
public Set<ServicePort> servicePorts() {
String response = restGet(URL_SERVICE_PORTS);
final String error = String.format(ERR_LOG, SERVICE_PORTS, response);
@@ -137,7 +132,6 @@
}
}
- @Override
public ServicePort servicePort(PortId portId) {
String response = restGet(URL_SERVICE_PORTS + portId.id());
final String error = String.format(ERR_LOG, SERVICE_PORT, response);
@@ -222,13 +216,13 @@
*
* @return xos service networking instance
*/
- public XosServiceNetworking build() {
+ public XosVtnNetworkingClient build() {
checkArgument(!Strings.isNullOrEmpty(endpoint));
checkArgument(!Strings.isNullOrEmpty(user));
checkArgument(!Strings.isNullOrEmpty(password));
// TODO perform authentication when XOS provides it
- return new XosServiceNetworking(endpoint, user, password);
+ return new XosVtnNetworkingClient(endpoint, user, password);
}
/**
diff --git a/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index bdb9335..ad95240 100644
--- a/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -35,7 +35,10 @@
<action class="org.opencord.cordvtn.cli.CordVtnPurgeStatesCommand"/>
</command>
<command>
- <action class="org.opencord.cordvtn.cli.CordVtnSyncStatesCommand"/>
+ <action class="org.opencord.cordvtn.cli.CordVtnSyncNeutronStatesCommand"/>
+ </command>
+ <command>
+ <action class="org.opencord.cordvtn.cli.CordVtnSyncXosStatesCommand"/>
</command>
<command>
<action class="org.opencord.cordvtn.cli.CordVtnNetworkListCommand"/>
diff --git a/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkCodecTest.java b/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkCodecTest.java
index 0886a4a..35d9a1b 100644
--- a/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkCodecTest.java
+++ b/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkCodecTest.java
@@ -18,25 +18,28 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableMap;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.onosproject.codec.JsonCodec;
import org.opencord.cordvtn.api.net.NetworkId;
-import org.opencord.cordvtn.api.net.ProviderNetwork;
import org.opencord.cordvtn.api.net.ServiceNetwork;
+import org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType;
+import org.opencord.cordvtn.impl.DefaultServiceNetwork;
import java.io.IOException;
import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
-import static org.opencord.cordvtn.api.dependency.Dependency.Type.BIDIRECTIONAL;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.MANAGEMENT_LOCAL;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.PRIVATE;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType.BIDIRECTIONAL;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.MANAGEMENT_LOCAL;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.PRIVATE;
import static org.opencord.cordvtn.codec.ServiceNetworkJsonMatcher.matchesServiceNetwork;
/**
@@ -45,21 +48,29 @@
public final class ServiceNetworkCodecTest {
private static final String SERVICE_NETWORK = "serviceNetwork";
private static final String ID = "id";
+ private static final String NAME = "name";
private static final String TYPE = "type";
- private static final String PROVIDER_NETWORKS = "providerNetworks";
+ private static final String PROVIDERS = "providers";
- private final ProviderNetwork providerA =
- ProviderNetwork.of(NetworkId.of("A"), BIDIRECTIONAL);
+ private final Map<NetworkId, DependencyType> providerA =
+ new HashMap<NetworkId, DependencyType>() {
+ {
+ put(NetworkId.of("A"), BIDIRECTIONAL);
+ }
+ };
- private final ServiceNetwork networkB = new ServiceNetwork(
- NetworkId.of("A"),
- MANAGEMENT_LOCAL,
- ImmutableSet.of());
+ private final ServiceNetwork networkA = DefaultServiceNetwork.builder()
+ .id(NetworkId.of("A"))
+ .name("A")
+ .type(MANAGEMENT_LOCAL)
+ .build();
- private final ServiceNetwork networkA = new ServiceNetwork(
- NetworkId.of("B"),
- PRIVATE,
- ImmutableSet.of(providerA));
+ private final ServiceNetwork networkB = DefaultServiceNetwork.builder()
+ .id(NetworkId.of("B"))
+ .name("B")
+ .type(PRIVATE)
+ .providers(providerA)
+ .build();
@Rule
public ExpectedException exception = ExpectedException.none();
@@ -93,20 +104,23 @@
public void testServiceNetworkDecode() throws IOException {
ServiceNetwork snet = getServiceNetwork("service-network.json");
assertThat(snet.id(), is(NetworkId.of("A")));
+ assertThat(snet.name(), is("A"));
assertThat(snet.type(), is(MANAGEMENT_LOCAL));
- assertThat(snet.providers(), is(ImmutableSet.of()));
+ assertThat(snet.providers(), is(ImmutableMap.of()));
snet = getServiceNetwork("service-network-with-provider.json");
assertThat(snet.id(), is(NetworkId.of("B")));
+ assertThat(snet.name(), is("B"));
assertThat(snet.type(), is(PRIVATE));
- assertThat(snet.providers(), is(ImmutableSet.of(providerA)));
+ assertThat(snet.providers(), is(providerA));
}
@Test
public void testServiceNetworkDecodeMissingId() throws IllegalArgumentException {
final JsonNode jsonMissingId = context.mapper().createObjectNode()
+ .put(NAME, "A")
.put(TYPE, PRIVATE.name())
- .put(PROVIDER_NETWORKS, "");
+ .put(PROVIDERS, "");
exception.expect(IllegalArgumentException.class);
codec.decode((ObjectNode) jsonMissingId, context);
}
@@ -115,8 +129,9 @@
public void testServiceNetworkDecodeEmptyId() throws IllegalArgumentException {
final JsonNode jsonEmptyId = context.mapper().createObjectNode()
.put(ID, "")
+ .put(NAME, "A")
.put(TYPE, PRIVATE.name())
- .put(PROVIDER_NETWORKS, "");
+ .put(PROVIDERS, "");
exception.expect(IllegalArgumentException.class);
codec.decode((ObjectNode) jsonEmptyId, context);
}
@@ -124,61 +139,24 @@
@Test
public void testServiceNetworkDecodeNullId() throws NullPointerException {
final JsonNode jsonNullId = context.mapper().createObjectNode()
+ .put(NAME, "A")
.put(TYPE, PRIVATE.name())
- .put(PROVIDER_NETWORKS, "")
+ .put(PROVIDERS, "")
.set(ID, NullNode.getInstance());
exception.expect(IllegalArgumentException.class);
codec.decode((ObjectNode) jsonNullId, context);
}
@Test
- public void testServiceNetworkDecodeMissingType() throws IllegalArgumentException {
- final JsonNode jsonMissingType = context.mapper().createObjectNode()
- .put(ID, "A")
- .put(PROVIDER_NETWORKS, "");
- exception.expect(IllegalArgumentException.class);
- codec.decode((ObjectNode) jsonMissingType, context);
- }
-
- @Test
- public void testServiceNetworkDecodeEmptyType() throws IllegalArgumentException {
- final JsonNode jsonEmptyType = context.mapper().createObjectNode()
- .put(ID, "A")
- .put(TYPE, "")
- .put(PROVIDER_NETWORKS, "");
- exception.expect(IllegalArgumentException.class);
- codec.decode((ObjectNode) jsonEmptyType, context);
- }
-
- @Test
- public void testServiceNetworkDecodeNullType() throws IllegalArgumentException {
- final JsonNode jsonNullType = context.mapper().createObjectNode()
- .put(ID, "A")
- .put(PROVIDER_NETWORKS, "")
- .set(TYPE, NullNode.getInstance());
- exception.expect(IllegalArgumentException.class);
- codec.decode((ObjectNode) jsonNullType, context);
- }
-
- @Test
- public void testServiceNetworkDecodeWrongType() throws IllegalArgumentException {
- final JsonNode jsonNoneType = context.mapper().createObjectNode()
- .put(ID, "A")
- .put(TYPE, "none")
- .put(PROVIDER_NETWORKS, "");
- exception.expect(IllegalArgumentException.class);
- codec.decode((ObjectNode) jsonNoneType, context);
- }
-
- @Test
public void testServiceNetworkDecodeWithMissingProviderId() throws NullPointerException {
final JsonNode jsonMissingProviderId = context.mapper().createObjectNode()
.put(TYPE, "B");
final JsonNode jsonWithProvider = context.mapper().createObjectNode()
.put(ID, "A")
+ .put(NAME, "A")
.put(TYPE, PRIVATE.name())
- .set(PROVIDER_NETWORKS, jsonMissingProviderId);
- exception.expect(NullPointerException.class);
+ .set(PROVIDERS, jsonMissingProviderId);
+ exception.expect(IllegalArgumentException.class);
codec.decode((ObjectNode) jsonWithProvider, context);
}
@@ -189,9 +167,10 @@
.put(TYPE, "none");
final JsonNode jsonWithProvider = context.mapper().createObjectNode()
.put(ID, "A")
+ .put(NAME, "A")
.put(TYPE, PRIVATE.name())
- .set(PROVIDER_NETWORKS, jsonWrongProviderType);
- exception.expect(NullPointerException.class);
+ .set(PROVIDERS, jsonWrongProviderType);
+ exception.expect(IllegalArgumentException.class);
codec.decode((ObjectNode) jsonWithProvider, context);
}
diff --git a/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkJsonMatcher.java b/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkJsonMatcher.java
index 0544a42..da321e3 100644
--- a/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkJsonMatcher.java
+++ b/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkJsonMatcher.java
@@ -19,12 +19,12 @@
import com.fasterxml.jackson.databind.node.NullNode;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeDiagnosingMatcher;
-import org.opencord.cordvtn.api.net.ProviderNetwork;
+import org.opencord.cordvtn.api.net.NetworkId;
import org.opencord.cordvtn.api.net.ServiceNetwork;
import java.util.Objects;
-import static org.opencord.cordvtn.api.dependency.Dependency.Type.BIDIRECTIONAL;
+import static org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType.BIDIRECTIONAL;
/**
* Json matcher for ServiceNetwork.
@@ -61,11 +61,11 @@
return false;
}
- if (network.providers().isEmpty()) {
+ if (network.providers() == null || network.providers().isEmpty()) {
return true;
}
- JsonNode jsonProviders = jsonNet.get("providerNetworks");
+ JsonNode jsonProviders = jsonNet.get("providers");
if (jsonProviders == null || jsonProviders == NullNode.getInstance()) {
description.appendText("provider networks were empty");
return false;
@@ -76,19 +76,16 @@
}
for (JsonNode provider : jsonProviders) {
- String id = provider.get("id").asText();
+ NetworkId id = NetworkId.of(provider.get("id").asText());
boolean bidirectional = provider.get("bidirectional").asBoolean();
- ProviderNetwork proNet = network.providers().stream()
- .filter(p -> p.id().id().equals(id))
- .findAny().orElse(null);
- if (proNet == null) {
+ if (!network.providers().containsKey(id)) {
final String msg = String.format("provider id:%s couldn't find", id);
description.appendText(msg);
return false;
}
- if (proNet.type().equals(BIDIRECTIONAL) != bidirectional) {
+ if (network.providers().get(id).equals(BIDIRECTIONAL) != bidirectional) {
final String msg = String.format(
"mismatch provider id:%s, bidirectional: %s",
id, bidirectional);
diff --git a/src/test/resources/org/opencord/cordvtn/codec/service-network-with-provider.json b/src/test/resources/org/opencord/cordvtn/codec/service-network-with-provider.json
index a5dbb88..b017c07 100644
--- a/src/test/resources/org/opencord/cordvtn/codec/service-network-with-provider.json
+++ b/src/test/resources/org/opencord/cordvtn/codec/service-network-with-provider.json
@@ -1,8 +1,9 @@
{
"serviceNetwork": {
"id": "B",
+ "name": "B",
"type": "private",
- "providerNetworks": [
+ "providers": [
{
"id": "A",
"bidirectional": true
diff --git a/src/test/resources/org/opencord/cordvtn/codec/service-network.json b/src/test/resources/org/opencord/cordvtn/codec/service-network.json
index 857cca6..9235f99 100644
--- a/src/test/resources/org/opencord/cordvtn/codec/service-network.json
+++ b/src/test/resources/org/opencord/cordvtn/codec/service-network.json
@@ -1,6 +1,7 @@
{
"serviceNetwork": {
"id": "A",
+ "name": "A",
"type": "management_local",
"providerNetworks": []
}