From 6a07d2d622eaa06953f3353e39c080984076e8de Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Fri, 9 Oct 2015 18:32:44 -0700 Subject: Updated master to commit id 6ee8aa3e67ce89908a8c93aa9445c6f71a18f986 Change-Id: I94b055ee2f298daf71e2ec794fd0f2495bd8081f --- .../net/config/basics/InterfaceConfig.java | 66 +++++- .../incubator/net/domain/DomainIntentResource.java | 84 ++++++++ .../incubator/net/domain/IntentDomainProvider.java | 26 +-- .../incubator/net/domain/IntentResource.java | 52 +++-- .../net/domain/NetworkIntentResource.java | 70 +++++++ .../incubator/net/intf/InterfaceAdminService.java | 40 ++++ .../incubator/net/tunnel/DomainTunnelId.java | 92 +++++++++ .../incubator/net/tunnel/NetworkTunnelId.java | 89 ++++++++ .../net/virtual/DefaultVirtualDevice.java | 75 +++++++ .../net/virtual/DefaultVirtualNetwork.java | 76 +++++++ .../incubator/net/virtual/VirtualElement.java | 7 - .../net/virtual/VirtualNetworkAdminService.java | 38 ++-- .../incubator/net/virtual/VirtualNetworkEvent.java | 72 +++++++ .../net/virtual/VirtualNetworkListener.java | 24 +++ .../net/virtual/VirtualNetworkProvider.java | 31 +++ .../virtual/VirtualNetworkProviderRegistry.java | 25 +++ .../net/virtual/VirtualNetworkProviderService.java | 11 + .../incubator/net/virtual/VirtualNetworkStore.java | 161 +++++++++++++++ .../net/virtual/VirtualNetworkStoreDelegate.java | 24 +++ .../incubator/net/intf/impl/InterfaceManager.java | 52 ++++- .../incubator/net/mcast/impl/MulticastData.java | 85 ++++++++ .../net/mcast/impl/MulticastRouteManager.java | 174 ++++++++++++++++ .../incubator/net/mcast/impl/package-info.java | 20 ++ .../incubator/net/meter/impl/MeterManager.java | 37 +++- .../net/virtual/impl/VirtualNetworkManager.java | 223 +++++++++++++++++++++ .../incubator/net/virtual/impl/package-info.java | 20 ++ .../net/mcast/impl/MulticastRouteManagerTest.java | 200 ++++++++++++++++++ .../incubator/net/meter/impl/MeterManagerTest.java | 15 +- .../store/meter/impl/DistributedMeterStore.java | 51 +++-- .../impl/DistributedVirtualNetworkStore.java | 147 ++++++++++++++ .../incubator/store/virtual/impl/package-info.java | 20 ++ 31 files changed, 2004 insertions(+), 103 deletions(-) create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/DomainIntentResource.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/NetworkIntentResource.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/intf/InterfaceAdminService.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DomainTunnelId.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/NetworkTunnelId.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualDevice.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetwork.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkEvent.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkListener.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProvider.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderRegistry.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderService.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkStore.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkStoreDelegate.java create mode 100644 framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/mcast/impl/MulticastData.java create mode 100644 framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/mcast/impl/MulticastRouteManager.java create mode 100644 framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/mcast/impl/package-info.java create mode 100644 framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java create mode 100644 framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/package-info.java create mode 100644 framework/src/onos/incubator/net/src/test/java/org/onosproject/incubator/net/mcast/impl/MulticastRouteManagerTest.java create mode 100644 framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/DistributedVirtualNetworkStore.java create mode 100644 framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/package-info.java (limited to 'framework/src/onos/incubator') diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/InterfaceConfig.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/InterfaceConfig.java index af2b47d8..592336c2 100644 --- a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/InterfaceConfig.java +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/InterfaceConfig.java @@ -17,13 +17,15 @@ package org.onosproject.incubator.net.config.basics; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.annotations.Beta; import com.google.common.collect.Sets; import org.onlab.packet.MacAddress; import org.onlab.packet.VlanId; -import org.onosproject.net.config.Config; import org.onosproject.incubator.net.intf.Interface; import org.onosproject.net.ConnectPoint; +import org.onosproject.net.config.Config; import org.onosproject.net.host.InterfaceIpAddress; import java.util.Set; @@ -37,7 +39,6 @@ public class InterfaceConfig extends Config { public static final String MAC = "mac"; public static final String VLAN = "vlan"; - public static final String IP_MISSING_ERROR = "Must have at least one IP address"; public static final String MAC_MISSING_ERROR = "Must have a MAC address for each interface"; public static final String CONFIG_VALUE_ERROR = "Error parsing config value"; @@ -53,9 +54,6 @@ public class InterfaceConfig extends Config { try { for (JsonNode intfNode : array) { Set ips = getIps(intfNode); - if (ips.isEmpty()) { - throw new ConfigException(IP_MISSING_ERROR); - } if (intfNode.path(MAC).isMissingNode()) { throw new ConfigException(MAC_MISSING_ERROR); @@ -63,10 +61,7 @@ public class InterfaceConfig extends Config { MacAddress mac = MacAddress.valueOf(intfNode.path(MAC).asText()); - VlanId vlan = VlanId.NONE; - if (!intfNode.path(VLAN).isMissingNode()) { - vlan = VlanId.vlanId(Short.valueOf(intfNode.path(VLAN).asText())); - } + VlanId vlan = getVlan(intfNode); interfaces.add(new Interface(subject, ips, mac, vlan)); } @@ -77,13 +72,64 @@ public class InterfaceConfig extends Config { return interfaces; } + /** + * Adds an interface to the config. + * + * @param intf interface to add + */ + public void addInterface(Interface intf) { + ObjectNode intfNode = array.addObject(); + intfNode.put(MAC, intf.mac().toString()); + + if (!intf.ipAddresses().isEmpty()) { + intfNode.set(IPS, putIps(intf.ipAddresses())); + } + + if (!intf.vlan().equals(VlanId.NONE)) { + intfNode.put(VLAN, intf.vlan().toString()); + } + } + + /** + * Removes an interface from the config. + * + * @param intf interface to remove + */ + public void removeInterface(Interface intf) { + for (int i = 0; i < array.size(); i++) { + if (intf.vlan().equals(getVlan(node))) { + array.remove(i); + break; + } + } + } + + private VlanId getVlan(JsonNode node) { + VlanId vlan = VlanId.NONE; + if (!node.path(VLAN).isMissingNode()) { + vlan = VlanId.vlanId(Short.valueOf(node.path(VLAN).asText())); + } + return vlan; + } + private Set getIps(JsonNode node) { Set ips = Sets.newHashSet(); JsonNode ipsNode = node.get(IPS); - ipsNode.forEach(jsonNode -> ips.add(InterfaceIpAddress.valueOf(jsonNode.asText()))); + if (ipsNode != null) { + ipsNode.forEach(jsonNode -> + ips.add(InterfaceIpAddress.valueOf(jsonNode.asText()))); + } return ips; } + private ArrayNode putIps(Set intfIpAddresses) { + ArrayNode ipArray = mapper.createArrayNode(); + + intfIpAddresses.forEach(i -> ipArray.add(i.toString())); + + return ipArray; + } + } diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/DomainIntentResource.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/DomainIntentResource.java new file mode 100644 index 00000000..ea1660e7 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/DomainIntentResource.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.domain; + +import org.onosproject.core.ApplicationId; +import org.onosproject.incubator.net.tunnel.DomainTunnelId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.Path; + +/** + * A variant of intent resource specialized for use on the intra-domain level. It contains a lower level path. + */ +public class DomainIntentResource extends IntentResource { + + private final Path domainPath; + + private final DomainTunnelId domainTunnelId; + + private final IntentDomainId intentDomainId; + + /** + * Constructor for a domain intent resource. + * + * @param primitive the primitive associated with this resource + * @param domainTunnelId the id of this tunnel (used as a sorting mechanism) + * @param domainId the ID of the intent domain containing this tunnel + * @param appId the id of the application which created this tunnel + * @param ingress the fist connect point associated with this tunnel (order is irrelevant as long as it is + * consistent with the path) + * @param egress the second connect point associated with this tunnel (order is irrelevant as long as it is + * consistent with the path) + * @param path the path followed through the domain + */ + public DomainIntentResource(IntentPrimitive primitive, DomainTunnelId domainTunnelId, IntentDomainId domainId, + ApplicationId appId, ConnectPoint ingress, ConnectPoint egress, Path path) { + super(primitive, appId, ingress, egress); + + this.domainPath = path; + this.domainTunnelId = domainTunnelId; + this.intentDomainId = domainId; + } + + /** + * Returns the domain path associated with this resource at creation. + * + * @return this resource's domain level path or if this resource backs a network tunnel then null. + */ + public Path path() { + return domainPath; + } + + /** + * Returns the tunnel ID associated with this domain at creation. + * + * @return this resource's tunnel ID. + */ + public DomainTunnelId tunnelId() { + return domainTunnelId; + } + + /** + * Returns the domain ID associated with this resource at creation. + * + * @return this resource's domain ID. + */ + public IntentDomainId domainId() { + return intentDomainId; + } + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainProvider.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainProvider.java index 51265f71..a19add60 100644 --- a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainProvider.java +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainProvider.java @@ -34,51 +34,51 @@ public interface IntentDomainProvider { * * @param domain intent domain for the request * @param primitive intent primitive - * @return request contexts that contain resources to satisfy the intent + * @return intent resources that specify paths that satisfy the request. */ //TODO Consider an iterable and/or holds (only hold one or two reservation(s) at a time) - List request(IntentDomain domain, IntentPrimitive primitive); + List request(IntentDomain domain, IntentPrimitive primitive); /** * Request that the provider attempt to modify an existing resource to satisfy * a new intent primitive. The application must apply the context before * the intent resource can be used. * - * @param resource existing resource - * @param newPrimitive intent primitive + * @param oldResource the resource to be replaced + * @param newResource the resource to be applied * @return request contexts that contain resources to satisfy the intent */ - List modify(IntentResource resource, IntentPrimitive newPrimitive); + DomainIntentResource modify(DomainIntentResource oldResource, DomainIntentResource newResource); /** * Requests that the provider release an intent resource. * * @param resource intent resource */ - void release(IntentResource resource); + void release(DomainIntentResource resource); /** - * Requests that the provider apply the intent resource in the request context. + * Requests that the provider apply the path from the intent resource. * - * @param context request context + * @param domainIntentResource request context * @return intent resource that satisfies the intent */ - IntentResource apply(RequestContext context); + DomainIntentResource apply(DomainIntentResource domainIntentResource); /** - * Requests that the provider cancel the request. Requests that are not applied + * Requests that the provider cancel the path. Requests that are not applied * will be eventually timed out by the provider. * - * @param context request context + * @param domainIntentResource the intent resource whose path should be cancelled. */ - void cancel(RequestContext context); + void cancel(DomainIntentResource domainIntentResource); /** * Returns all intent resources held by the provider. * * @return set of intent resources */ - Set getResources(); + Set getResources(); } diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentResource.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentResource.java index 9cd9aac0..627c863f 100644 --- a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentResource.java +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentResource.java @@ -16,53 +16,73 @@ package org.onosproject.incubator.net.domain; import com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.ConnectPoint; + /** * The abstract base class for the resource that satisfies an intent primitive. */ @Beta -public class IntentResource { +public abstract class IntentResource { private final IntentPrimitive primitive; - private final long tunnelId; - private final IntentDomainId domainId; + + private final ApplicationId appId; + private final ConnectPoint ingress; + private final ConnectPoint egress; + + //* QUESTIONABLE ADDITIONS *// // TODO add other common fields //String ingressTag; //String egressTag; //etc. - public IntentResource(IntentPrimitive primitive, long tunnelId, IntentDomainId domainId) { + public IntentResource(IntentPrimitive primitive, ApplicationId appId, + ConnectPoint ingress, ConnectPoint egress) { + this.appId = appId; + this.ingress = ingress; + this.egress = egress; this.primitive = primitive; - this.tunnelId = tunnelId; - this.domainId = domainId; } + //TODO when is same package tunnelID should be of type tunnelID and netTunnelId not long. + + /** - * Returns the intent primitive associated with this resource as creation. + * Returns the intent primitive associated with this resource at creation. * - * @return this resource's intent primitive + * @return this resource's intent primitive. */ public IntentPrimitive primitive() { return primitive; } /** - * Returns the tunnel ID associated with this resource as creation. + * Returns the application ID associated with this resource at creation. * - * @return this resource's tunnel ID + * @return this resource's application ID. */ - public long tunnelId() { - return tunnelId; + public ApplicationId appId() { + return appId; } /** - * Returns the domain ID associated with this resource as creation. + * Returns the ingress connect point associated with this resource at creation. * - * @return this resource's domain ID + * @return this resource's ingress connect point. */ - public IntentDomainId domainId() { - return domainId; + public ConnectPoint ingress() { + return ingress; } + /** + * Returns the egress connect point associated with this resource at creation. + * + * @return this resource's connect point. + */ + public ConnectPoint egress() { + return egress; + } } diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/NetworkIntentResource.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/NetworkIntentResource.java new file mode 100644 index 00000000..ac4445b4 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/NetworkIntentResource.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.domain; + +import org.onosproject.core.ApplicationId; +import org.onosproject.incubator.net.tunnel.NetworkTunnelId; +import org.onosproject.net.ConnectPoint; + +/** + * A variant of intent resource specialized for use on the inter-domain level. It contains a higher level path. + */ +public class NetworkIntentResource extends IntentResource { + + private final org.onlab.graph.Path netPath; + + private NetworkTunnelId networkTunnelId; + + /** + * Constructor for a network intent resource. + * + * @param primitive the primitive associated with this resource + * @param networkTunnelId the id of this tunnel (used as a sorting mechanism) + * @param appId the id of the application which created this tunnel + * @param ingress the fist connect point associated with this tunnel (order is irrelevant as long as it is + * consistent with the path) + * @param egress the second connect point associated with this tunnel (order is irrelevant as long as it is + * consistent with the path) + * @param path the path followed through the graph of domain vertices and domain edges + */ + public NetworkIntentResource(IntentPrimitive primitive, NetworkTunnelId networkTunnelId, ApplicationId appId, + ConnectPoint ingress, ConnectPoint egress, + org.onlab.graph.Path path) { + super(primitive, appId, ingress, egress); + + this.networkTunnelId = networkTunnelId; + this.netPath = path; + } + + /** + * Returns the network path associated with this resource at creation. + * + * @return this resource's network lever path or if this resource backs a domain level tunnel then null. + */ + public org.onlab.graph.Path path() { + return netPath; + } + + /** + * Returns ths network ID associated with this network tunnel at creation. + * + * @return thsi resource's tunnel ID. + */ + public NetworkTunnelId tunnelId() { + return this.networkTunnelId; + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/intf/InterfaceAdminService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/intf/InterfaceAdminService.java new file mode 100644 index 00000000..56d5aecc --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/intf/InterfaceAdminService.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.intf; + +import org.onlab.packet.VlanId; +import org.onosproject.net.ConnectPoint; + +/** + * Provides a means to modify the interfaces configuration. + */ +public interface InterfaceAdminService { + /** + * Adds a new interface configuration to the system. + * + * @param intf interface to add + */ + void add(Interface intf); + + /** + * Removes an interface configuration from the system. + * + * @param connectPoint connect point of the interface + * @param vlanId vlan id + */ + void remove(ConnectPoint connectPoint, VlanId vlanId); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DomainTunnelId.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DomainTunnelId.java new file mode 100644 index 00000000..430823ca --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DomainTunnelId.java @@ -0,0 +1,92 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.tunnel; + +/** + * A wrapper class for a long used to identify domain level tunnels. + */ +public final class DomainTunnelId { + + private final long value; + + /** + * Creates a tunnel identifier from the specified tunnel. + * + * @param value long value + * @return domain tunnel identifier + */ + public static DomainTunnelId valueOf(long value) { + return new DomainTunnelId(value); + } + + /** + * Creates a tunnel identifier from the specified tunnel. + * + * @param value long value as a string + * @return domain tunnel identifier + */ + public static DomainTunnelId valueOf(String value) { + return new DomainTunnelId(Long.parseLong(value)); + } + + /** + * Constructor for serializer. + */ + protected DomainTunnelId() { + this.value = 0; + } + + /** + * Constructs the Domain ID corresponding to a given long value. + * + * @param value the underlying value of this domain ID + */ + public DomainTunnelId(long value) { + this.value = value; + } + + /** + * Returns the backing value of this domain ID. + * + * @return the long value + */ + public long id() { + return value; + } + + @Override + public int hashCode() { + return Long.hashCode(value); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof DomainTunnelId)) { + return false; + } + DomainTunnelId that = (DomainTunnelId) obj; + return this.value == that.value; + } + + @Override + public String toString() { + return "0x" + Long.toHexString(value); + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/NetworkTunnelId.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/NetworkTunnelId.java new file mode 100644 index 00000000..a3de7883 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/NetworkTunnelId.java @@ -0,0 +1,89 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.tunnel; + +import com.google.common.annotations.Beta; + +/** + * Representation of a Network Tunnel Id. + */ +@Beta +public final class NetworkTunnelId { + private final long value; + + /** + * Creates an tunnel identifier from the specified tunnel. + * + * @param value long value + * @return tunnel identifier + */ + public static NetworkTunnelId valueOf(long value) { + return new NetworkTunnelId(value); + } + + public static NetworkTunnelId valueOf(String value) { + return new NetworkTunnelId(Long.parseLong(value)); + } + + /** + * Constructor for serializer. + */ + NetworkTunnelId() { + this.value = 0; + } + + /** + * Constructs the ID corresponding to a given long value. + * + * @param value the underlying value of this ID + */ + public NetworkTunnelId(long value) { + this.value = value; + } + + /** + * Returns the backing value. + * + * @return the value + */ + public long id() { + return value; + } + + @Override + public int hashCode() { + return Long.hashCode(value); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof NetworkTunnelId)) { + return false; + } + NetworkTunnelId that = (NetworkTunnelId) obj; + return this.value == that.value; + } + + @Override + public String toString() { + return "0x" + Long.toHexString(value); + } + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualDevice.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualDevice.java new file mode 100644 index 00000000..54a22a46 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualDevice.java @@ -0,0 +1,75 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.virtual; + +import org.onlab.packet.ChassisId; +import org.onosproject.net.DefaultDevice; +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.ProviderId; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.*; + +/** + * Default representation of a virtual device. + */ +public class DefaultVirtualDevice extends DefaultDevice implements VirtualDevice { + + private static final String VIRTUAL = "virtual"; + private static final ProviderId PID = new ProviderId(VIRTUAL, VIRTUAL); + + private final NetworkId networkId; + + /** + * Creates a network element attributed to the specified provider. + * + * @param networkId network identifier + * @param id device identifier + */ + public DefaultVirtualDevice(NetworkId networkId, DeviceId id) { + super(PID, id, Type.VIRTUAL, VIRTUAL, VIRTUAL, VIRTUAL, VIRTUAL, + new ChassisId(0)); + this.networkId = networkId; + } + + @Override + public NetworkId networkId() { + return networkId; + } + + @Override + public int hashCode() { + return 31 * super.hashCode() + Objects.hash(networkId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultVirtualDevice) { + DefaultVirtualDevice that = (DefaultVirtualDevice) obj; + return super.equals(that) && Objects.equals(this.networkId, that.networkId); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this).add("networkId", networkId).toString(); + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetwork.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetwork.java new file mode 100644 index 00000000..c1141912 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetwork.java @@ -0,0 +1,76 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.virtual; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Default implementation of the virtual network descriptor. + */ +public class DefaultVirtualNetwork implements VirtualNetwork { + + private final NetworkId id; + private final TenantId tenantId; + + /** + * Creates a new virtual network descriptor. + * + * @param id network identifier + * @param tenantId tenant identifier + */ + public DefaultVirtualNetwork(NetworkId id, TenantId tenantId) { + this.id = id; + this.tenantId = tenantId; + } + + @Override + public NetworkId id() { + return id; + } + + @Override + public TenantId tenantId() { + return tenantId; + } + + @Override + public int hashCode() { + return Objects.hash(id, tenantId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultVirtualNetwork) { + DefaultVirtualNetwork that = (DefaultVirtualNetwork) obj; + return Objects.equals(this.id, that.id) + && Objects.equals(this.tenantId, that.tenantId); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("id", id) + .add("tenantId", tenantId) + .toString(); + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualElement.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualElement.java index 1c74b92a..791b8e24 100644 --- a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualElement.java +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualElement.java @@ -23,13 +23,6 @@ import com.google.common.annotations.Beta; @Beta public interface VirtualElement { - /** - * Returns the identifier of the tenant to which this virtual element belongs. - * - * @return tenant identifier - */ - TenantId tenantId(); - /** * Returns the network identifier to which this virtual element belongs. * diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminService.java index 1e3648b5..07c399c0 100644 --- a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminService.java +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminService.java @@ -16,14 +16,11 @@ package org.onosproject.incubator.net.virtual; import com.google.common.annotations.Beta; -import org.onosproject.incubator.net.tunnel.Tunnel; +import org.onosproject.incubator.net.tunnel.TunnelId; import org.onosproject.net.ConnectPoint; import org.onosproject.net.DeviceId; import org.onosproject.net.Port; import org.onosproject.net.PortNumber; -import org.onosproject.net.device.DeviceDescription; -import org.onosproject.net.device.PortDescription; -import org.onosproject.net.link.LinkDescription; import java.util.Set; @@ -76,12 +73,12 @@ public interface VirtualNetworkAdminService extends VirtualNetworkService { * Creates a new virtual device within the specified network. The device id * must be unique within the bounds of the network. * - * @param networkId network identifier - * @param description device description + * @param networkId network identifier + * @param deviceId device identifier * @return newly created device * @throws org.onlab.util.ItemNotFoundException if no such network found */ - VirtualDevice createVirtualDevice(NetworkId networkId, DeviceDescription description); + VirtualDevice createVirtualDevice(NetworkId networkId, DeviceId deviceId); /** * Removes the specified virtual device and all its ports and affiliated links. @@ -96,14 +93,16 @@ public interface VirtualNetworkAdminService extends VirtualNetworkService { /** * Creates a new virtual link within the specified network. * - * @param networkId network identifier - * @param description link description - * @param realizedBy tunnel using which this link is realized + * @param networkId network identifier + * @param src source connection point + * @param dst destination connection point + * @param realizedBy identifier of the tunnel using which this link is realized * @return newly created virtual link * @throws org.onlab.util.ItemNotFoundException if no such network found */ - VirtualLink createVirtualLink(NetworkId networkId, LinkDescription description, - Tunnel realizedBy); + VirtualLink createVirtualLink(NetworkId networkId, + ConnectPoint src, ConnectPoint dst, + TunnelId realizedBy); // TODO: Discuss whether we should provide an alternate createVirtualLink // which is backed by a Path instead; I'm leaning towards not doing that. @@ -119,20 +118,17 @@ public interface VirtualNetworkAdminService extends VirtualNetworkService { void removeVirtualLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst); /** - * Creates a new virtual port on the specified device. Note that the port - * description can only request the resources which the underlying port - * port is capable of providing. It is, however, permissible to request - * only portion of those resources. + * Creates a new virtual port on the specified device. * - * @param networkId network identifier - * @param deviceId device identifier - * @param description port description - * @param realizedBy underlying port using which this virtual port is realized + * @param networkId network identifier + * @param deviceId device identifier + * @param portNumber port number + * @param realizedBy underlying port using which this virtual port is realized * @return newly created port * @throws org.onlab.util.ItemNotFoundException if no such network or device found */ VirtualPort createVirtualPort(NetworkId networkId, DeviceId deviceId, - PortDescription description, Port realizedBy); + PortNumber portNumber, Port realizedBy); /** * Removes the specified virtual port. diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkEvent.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkEvent.java new file mode 100644 index 00000000..7e076e09 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkEvent.java @@ -0,0 +1,72 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.virtual; + +import org.onosproject.event.AbstractEvent; + +/** + * Describes virtual network event. + */ +public class VirtualNetworkEvent extends AbstractEvent { + + /** + * Type of virtual network events. + */ + public enum Type { + /** + * Signifies that a new tenant identifier was registered. + */ + TENANT_REGISTERED, + /** + * Signifies that a tenant identifier was unregistered. + */ + TENANT_UNREGISTERED, + /** + * Signifies that a new virtual network was added. + */ + NETWORK_ADDED, + /** + * Signifies that a virtual network was updated. + */ + NETWORK_UPDATED, + /** + * Signifies that a virtual network was removed. + */ + NETWORK_REMOVED + } + + /** + * Creates an event of a given type and for the specified subject and the + * current time. + * + * @param type event type + * @param subject event subject + */ + public VirtualNetworkEvent(Type type, NetworkId subject) { + super(type, subject); + } + + /** + * Creates an event of a given type and for the specified subject and time. + * + * @param type device event type + * @param subject event subject + * @param time occurrence time + */ + public VirtualNetworkEvent(Type type, NetworkId subject, long time) { + super(type, subject, time); + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkListener.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkListener.java new file mode 100644 index 00000000..707ca8a7 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkListener.java @@ -0,0 +1,24 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.virtual; + +import org.onosproject.event.EventListener; + +/** + * Represents entity capable of receiving virtual network events. + */ +public interface VirtualNetworkListener extends EventListener { +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProvider.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProvider.java new file mode 100644 index 00000000..8e5b19a5 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProvider.java @@ -0,0 +1,31 @@ +package org.onosproject.incubator.net.virtual; + +import org.onosproject.incubator.net.tunnel.TunnelId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.provider.Provider; + +/** + * Entity capable of providing traffic isolation constructs for use in + * implementation of virtual devices and virtual links. + */ +public interface VirtualNetworkProvider extends Provider { + + /** + * Creates a network tunnel for all traffic from the specified source + * connection point to the indicated destination connection point. + * + * @param networkId virtual network identifier + * @param src source connection point + * @param dst destination connection point + */ + TunnelId createTunnel(NetworkId networkId, ConnectPoint src, ConnectPoint dst); + + /** + * Destroys the specified network tunnel. + * + * @param networkId virtual network identifier + * @param tunnelId tunnel identifier + */ + void destroyTunnel(NetworkId networkId, TunnelId tunnelId); + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderRegistry.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderRegistry.java new file mode 100644 index 00000000..4e893165 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderRegistry.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 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.onosproject.incubator.net.virtual; + +import org.onosproject.net.provider.ProviderRegistry; + +/** + * Abstraction of a virtual network provider registry. + */ +public interface VirtualNetworkProviderRegistry + extends ProviderRegistry { +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderService.java new file mode 100644 index 00000000..cba933c9 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderService.java @@ -0,0 +1,11 @@ +package org.onosproject.incubator.net.virtual; + +import org.onosproject.net.provider.ProviderService; + +/** + * Service through which virtual network providers can inject information into + * the core. + */ +public interface VirtualNetworkProviderService extends ProviderService { + // TODO: Add methods for notification of core about damaged tunnels, etc. +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkStore.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkStore.java new file mode 100644 index 00000000..49ad2f2b --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkStore.java @@ -0,0 +1,161 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.virtual; + +import org.onosproject.incubator.net.tunnel.TunnelId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; +import org.onosproject.store.Store; + +import java.util.Set; + +/** + * Mechanism for distributing and storing virtual network model information. + */ +public interface VirtualNetworkStore + extends Store { + + /** + * Adds a new tenant ID to the store. + * + * @param tenantId tenant identifier + */ + void addTenantId(TenantId tenantId); + + /** + * Removes the specified tenant ID from the store. + * + * @param tenantId tenant identifier + */ + void removeTenantId(TenantId tenantId); + + /** + * Returns set of registered tenant IDs. + * + * @return set of tenant identifiers + */ + Set getTenantIds(); + + /** + * Adds a new virtual network for the specified tenant to the store. + * + * @param tenantId tenant identifier + * @return the virtual network + */ + VirtualNetwork addNetwork(TenantId tenantId); + + /** + * Removes the specified virtual network from the store. + * + * @param networkId network identifier + */ + void removeNetwork(NetworkId networkId); + + /** + * Adds a new virtual device to the store. This device will have no ports. + * + * @param networkId network identifier + * @param deviceId device identifier + * @return the virtual device + */ + VirtualDevice addDevice(NetworkId networkId, DeviceId deviceId); + + /** + * Renmoves the specified virtual device from the given network. + * + * @param networkId network identifier + * @param deviceId device identifier + */ + void removeDevice(NetworkId networkId, DeviceId deviceId); + + /** + * Adds a new virtual link. + * + * @param networkId network identifier + * @param src source end-point of the link + * @param dst destination end-point of the link + * @param realizedBy underlying tunnel using which this link is realized + * @return the virtual link + */ + VirtualLink addLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst, + TunnelId realizedBy); + + /** + * Removes the specified link from the store. + * + * @param networkId network identifier + * @param src source connection point + * @param dst destination connection point + */ + void removeLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst); + + /** + * Adds a new virtual port to the network. + * + * @param networkId network identifier + * @param deviceId device identifier + * @param portNumber port number + * @param realizedBy underlying port which realizes the virtual port + * @return the virtual port + */ + VirtualPort addPort(NetworkId networkId, DeviceId deviceId, + PortNumber portNumber, Port realizedBy); + + /** + * Removes the specified port from the given device and network. + * + * @param networkId network identifier + * @param deviceId device identifier + * @param portNumber port number + */ + void removePort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber); + + /** + * Returns the list of networks. + * + * @param tenantId tenant identifier + * @return set of virtual networks + */ + Set getNetworks(TenantId tenantId); + + /** + * Returns the list of devices in the specified virtual network. + * + * @param networkId network identifier + * @return set of virtual devices + */ + Set getDevices(NetworkId networkId); + + /** + * Returns the list of virtual links in the specified virtual network. + * + * @param networkId network identifier + * @return set of virtual links + */ + Set getLinks(NetworkId networkId); + + /** + * Returns the list of ports of the specified virtual device. + * + * @param networkId network identifier + * @param deviceId device identifier + * @return set of virtual networks + */ + Set getPorts(NetworkId networkId, DeviceId deviceId); + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkStoreDelegate.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkStoreDelegate.java new file mode 100644 index 00000000..e57c3d3a --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.virtual; + +import org.onosproject.store.StoreDelegate; + +/** + * Network configuration store delegate abstraction. + */ +public interface VirtualNetworkStoreDelegate extends StoreDelegate { +} diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/intf/impl/InterfaceManager.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/intf/impl/InterfaceManager.java index f82cdbf2..0439d038 100644 --- a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/intf/impl/InterfaceManager.java +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/intf/impl/InterfaceManager.java @@ -29,6 +29,7 @@ import org.onlab.packet.VlanId; import org.onosproject.incubator.net.config.basics.ConfigException; import org.onosproject.incubator.net.config.basics.InterfaceConfig; import org.onosproject.incubator.net.intf.Interface; +import org.onosproject.incubator.net.intf.InterfaceAdminService; import org.onosproject.incubator.net.intf.InterfaceService; import org.onosproject.net.ConnectPoint; import org.onosproject.net.config.NetworkConfigEvent; @@ -50,7 +51,8 @@ import static java.util.stream.Collectors.toSet; */ @Service @Component(immediate = true) -public class InterfaceManager implements InterfaceService { +public class InterfaceManager implements InterfaceService, + InterfaceAdminService { private final Logger log = LoggerFactory.getLogger(getClass()); @@ -153,6 +155,54 @@ public class InterfaceManager implements InterfaceService { interfaces.remove(port); } + @Override + public void add(Interface intf) { + if (interfaces.containsKey(intf.connectPoint())) { + boolean conflict = interfaces.get(intf.connectPoint()).stream() + .filter(i -> i.connectPoint().equals(intf.connectPoint())) + .filter(i -> i.mac().equals(intf.mac())) + .filter(i -> i.vlan().equals(intf.vlan())) + .findAny().isPresent(); + + if (conflict) { + log.error("Can't add interface because it conflicts with existing config"); + return; + } + } + + InterfaceConfig config = + configService.addConfig(intf.connectPoint(), CONFIG_CLASS); + + config.addInterface(intf); + + configService.applyConfig(intf.connectPoint(), CONFIG_CLASS, config.node()); + } + + @Override + public void remove(ConnectPoint connectPoint, VlanId vlanId) { + Optional intf = interfaces.get(connectPoint).stream() + .filter(i -> i.vlan().equals(vlanId)) + .findAny(); + + if (!intf.isPresent()) { + log.error("Can't find interface {}/{} to remove", connectPoint, vlanId); + return; + } + + InterfaceConfig config = configService.addConfig(intf.get().connectPoint(), CONFIG_CLASS); + config.removeInterface(intf.get()); + + try { + if (config.getInterfaces().isEmpty()) { + configService.removeConfig(connectPoint, CONFIG_CLASS); + } else { + configService.applyConfig(intf.get().connectPoint(), CONFIG_CLASS, config.node()); + } + } catch (ConfigException e) { + log.error("Error reading interfaces JSON", e); + } + } + /** * Listener for network config events. */ diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/mcast/impl/MulticastData.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/mcast/impl/MulticastData.java new file mode 100644 index 00000000..946d8c6e --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/mcast/impl/MulticastData.java @@ -0,0 +1,85 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.mcast.impl; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import org.onosproject.net.ConnectPoint; + +import java.util.Collections; +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Simple entity maintaining a mapping between a source and a collection of sink + * connect points. + */ +public final class MulticastData { + + private final ConnectPoint source; + private final List sinks; + private final boolean isEmpty; + + private MulticastData() { + this.source = null; + this.sinks = Collections.EMPTY_LIST; + isEmpty = true; + } + + public MulticastData(ConnectPoint source, List sinks) { + this.source = checkNotNull(source, "Multicast source cannot be null."); + this.sinks = checkNotNull(sinks, "List of sinks cannot be null."); + isEmpty = false; + } + + public MulticastData(ConnectPoint source, ConnectPoint sink) { + this.source = checkNotNull(source, "Multicast source cannot be null."); + this.sinks = Lists.newArrayList(checkNotNull(sink, "Sink cannot be null.")); + isEmpty = false; + } + + public MulticastData(ConnectPoint source) { + this.source = checkNotNull(source, "Multicast source cannot be null."); + this.sinks = Lists.newArrayList(); + isEmpty = false; + } + + public ConnectPoint source() { + return source; + } + + public List sinks() { + return ImmutableList.copyOf(sinks); + } + + public void appendSink(ConnectPoint sink) { + sinks.add(sink); + } + + public boolean removeSink(ConnectPoint sink) { + return sinks.remove(sink); + } + + public boolean isEmpty() { + return isEmpty; + } + + public static MulticastData empty() { + return new MulticastData(); + } + +} diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/mcast/impl/MulticastRouteManager.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/mcast/impl/MulticastRouteManager.java new file mode 100644 index 00000000..f73dfe44 --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/mcast/impl/MulticastRouteManager.java @@ -0,0 +1,174 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.mcast.impl; + +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.IpPrefix; +import org.onlab.util.KryoNamespace; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.event.AbstractListenerManager; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.mcast.McastEvent; +import org.onosproject.net.mcast.McastListener; +import org.onosproject.net.mcast.McastRoute; +import org.onosproject.net.mcast.MulticastRouteService; +import org.onosproject.store.service.ConsistentMap; +import org.onosproject.store.service.Serializer; +import org.onosproject.store.service.StorageService; +import org.onosproject.store.service.Versioned; +import org.slf4j.Logger; + +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +import static org.slf4j.LoggerFactory.getLogger; + +/** + * An implementation of a multicast route table. + */ +@Component(immediate = true) +@Service +public class MulticastRouteManager + extends AbstractListenerManager + implements MulticastRouteService { + //TODO: add MulticastRouteAdminService + + private static final String MCASTRIB = "mcast-rib-table"; + + private Logger log = getLogger(getClass()); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + private StorageService storageService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + private CoreService coreService; + + + protected ApplicationId appId; + protected ConsistentMap mcastRoutes; + + @Activate + public void activate() { + + eventDispatcher.addSink(McastEvent.class, listenerRegistry); + + appId = coreService.registerApplication("org.onosproject.mcastrib"); + + mcastRoutes = storageService.consistentMapBuilder() + .withApplicationId(appId) + .withName(MCASTRIB) + .withSerializer(Serializer.using(KryoNamespace.newBuilder().register( + MulticastData.class, + McastRoute.class, + McastRoute.Type.class, + IpPrefix.class, + List.class, + ConnectPoint.class + ).build())).build(); + + log.info("Started"); + } + + @Deactivate + public void deactivate() { + log.info("Stopped"); + } + + @Override + public void add(McastRoute route) { + mcastRoutes.put(route, MulticastData.empty()); + post(new McastEvent(McastEvent.Type.ROUTE_ADDED, route, null, null)); + } + + @Override + public void remove(McastRoute route) { + mcastRoutes.remove(route); + post(new McastEvent(McastEvent.Type.ROUTE_REMOVED, route, null, null)); + } + + @Override + public void addSource(McastRoute route, ConnectPoint connectPoint) { + Versioned d = mcastRoutes.compute(route, (k, v) -> { + if (v.isEmpty()) { + return new MulticastData(connectPoint); + } else { + log.warn("Route {} is already in use.", route); + return v; + } + }); + + if (d != null) { + post(new McastEvent(McastEvent.Type.SOURCE_ADDED, + route, null, connectPoint)); + } + } + + @Override + public void addSink(McastRoute route, ConnectPoint connectPoint) { + AtomicReference source = new AtomicReference<>(); + mcastRoutes.compute(route, (k, v) -> { + if (!v.isEmpty()) { + v.appendSink(connectPoint); + source.set(v.source()); + } else { + log.warn("Route {} does not exist"); + } + return v; + }); + + if (source.get() != null) { + post(new McastEvent(McastEvent.Type.SINK_ADDED, route, + connectPoint, source.get())); + } + } + + + @Override + public void removeSink(McastRoute route, ConnectPoint connectPoint) { + AtomicReference source = new AtomicReference<>(); + mcastRoutes.compute(route, (k, v) -> { + if (v.removeSink(connectPoint)) { + source.set(v.source()); + } + return v; + }); + + if (source.get() != null) { + post(new McastEvent(McastEvent.Type.SINK_REMOVED, route, + connectPoint, source.get())); + } + } + + @Override + public ConnectPoint fetchSource(McastRoute route) { + MulticastData d = mcastRoutes.asJavaMap().getOrDefault(route, + MulticastData.empty()); + return d.source(); + } + + @Override + public List fetchSinks(McastRoute route) { + MulticastData d = mcastRoutes.asJavaMap().getOrDefault(route, + MulticastData.empty()); + return d.sinks(); + } +} diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/mcast/impl/package-info.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/mcast/impl/package-info.java new file mode 100644 index 00000000..464cf701 --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/mcast/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 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. + */ + +/** + * An implementation of a multicast RIB. + */ +package org.onosproject.incubator.net.mcast.impl; \ No newline at end of file diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java index 575a7153..5c5c11cd 100644 --- a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java @@ -15,6 +15,7 @@ */ package org.onosproject.incubator.net.meter.impl; +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; @@ -27,6 +28,7 @@ import org.onosproject.net.meter.Meter; import org.onosproject.net.meter.MeterEvent; import org.onosproject.net.meter.MeterFailReason; import org.onosproject.net.meter.MeterId; +import org.onosproject.net.meter.MeterKey; import org.onosproject.net.meter.MeterListener; import org.onosproject.net.meter.MeterOperation; import org.onosproject.net.meter.MeterProvider; @@ -61,7 +63,7 @@ public class MeterManager extends AbstractListenerProviderRegistry implements MeterService, MeterProviderRegistry { - private final String meterIdentifier = "meter-id-counter"; + private static final String METERCOUNTERIDENTIFIER = "meter-id-counter-%s"; private final Logger log = getLogger(getClass()); private final MeterStoreDelegate delegate = new InternalMeterStoreDelegate(); @@ -71,15 +73,13 @@ public class MeterManager extends AbstractListenerProviderRegistry meterIdCounters + = Maps.newConcurrentMap(); private TriConsumer onComplete; @Activate public void activate() { - meterIdCounter = storageService.atomicCounterBuilder() - .withName(meterIdentifier) - .build(); store.setDelegate(delegate); @@ -115,11 +115,13 @@ public class MeterManager extends AbstractListenerProviderRegistry { + if (v == null) { + return allocateCounter(k); + } + return v; + }).incrementAndGet(); + + return MeterId.meterId((int) id); + } + + private AtomicCounter allocateCounter(DeviceId deviceId) { + return storageService.atomicCounterBuilder() + .withName(String.format(METERCOUNTERIDENTIFIER, deviceId)) + .build(); } private class InternalMeterProviderService diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java new file mode 100644 index 00000000..fe9f8841 --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java @@ -0,0 +1,223 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.virtual.impl; + +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.incubator.net.tunnel.TunnelId; +import org.onosproject.incubator.net.virtual.NetworkId; +import org.onosproject.incubator.net.virtual.TenantId; +import org.onosproject.incubator.net.virtual.VirtualDevice; +import org.onosproject.incubator.net.virtual.VirtualLink; +import org.onosproject.incubator.net.virtual.VirtualNetwork; +import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService; +import org.onosproject.incubator.net.virtual.VirtualNetworkEvent; +import org.onosproject.incubator.net.virtual.VirtualNetworkListener; +import org.onosproject.incubator.net.virtual.VirtualNetworkProvider; +import org.onosproject.incubator.net.virtual.VirtualNetworkProviderRegistry; +import org.onosproject.incubator.net.virtual.VirtualNetworkProviderService; +import org.onosproject.incubator.net.virtual.VirtualNetworkService; +import org.onosproject.incubator.net.virtual.VirtualNetworkStore; +import org.onosproject.incubator.net.virtual.VirtualNetworkStoreDelegate; +import org.onosproject.incubator.net.virtual.VirtualPort; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; +import org.onosproject.net.provider.AbstractListenerProviderRegistry; +import org.onosproject.net.provider.AbstractProviderService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Implementation of the virtual network service. + */ +@Component(immediate = true) +@Service +public class VirtualNetworkManager + extends AbstractListenerProviderRegistry + implements VirtualNetworkService, VirtualNetworkAdminService, VirtualNetworkProviderRegistry { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private static final String TENANT_NULL = "Tenant ID cannot be null"; + private static final String NETWORK_NULL = "Network ID cannot be null"; + private static final String DEVICE_NULL = "Device ID cannot be null"; + private static final String LINK_POINT_NULL = "Link end-point cannot be null"; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected VirtualNetworkStore store; + + private VirtualNetworkStoreDelegate delegate = new InternalStoreDelegate(); + + // TODO: figure out how to coordinate "implementation" of a virtual network in a cluster + + @Activate + protected void activate() { + store.setDelegate(delegate); + log.info("Started"); + } + + @Deactivate + protected void deactivate() { + store.unsetDelegate(delegate); + log.info("Stopped"); + } + + @Override + public void registerTenantId(TenantId tenantId) { + checkNotNull(tenantId, TENANT_NULL); + store.addTenantId(tenantId); + } + + @Override + public void unregisterTenantId(TenantId tenantId) { + checkNotNull(tenantId, TENANT_NULL); + store.removeTenantId(tenantId); + } + + @Override + public Set getTenantIds() { + return store.getTenantIds(); + } + + @Override + public VirtualNetwork createVirtualNetwork(TenantId tenantId) { + checkNotNull(tenantId, TENANT_NULL); + return store.addNetwork(tenantId); + } + + @Override + public void removeVirtualNetwork(NetworkId networkId) { + checkNotNull(networkId, NETWORK_NULL); + store.removeNetwork(networkId); + } + + @Override + public VirtualDevice createVirtualDevice(NetworkId networkId, DeviceId deviceId) { + checkNotNull(networkId, NETWORK_NULL); + checkNotNull(deviceId, DEVICE_NULL); + return store.addDevice(networkId, deviceId); + } + + @Override + public void removeVirtualDevice(NetworkId networkId, DeviceId deviceId) { + checkNotNull(networkId, NETWORK_NULL); + checkNotNull(deviceId, DEVICE_NULL); + store.removeDevice(networkId, deviceId); + } + + @Override + public VirtualLink createVirtualLink(NetworkId networkId, + ConnectPoint src, ConnectPoint dst, + TunnelId realizedBy) { + checkNotNull(networkId, NETWORK_NULL); + checkNotNull(src, LINK_POINT_NULL); + checkNotNull(dst, LINK_POINT_NULL); + checkNotNull(realizedBy, "Tunnel ID cannot be null"); + return store.addLink(networkId, src, dst, realizedBy); + } + + @Override + public void removeVirtualLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst) { + checkNotNull(networkId, NETWORK_NULL); + checkNotNull(src, LINK_POINT_NULL); + checkNotNull(dst, LINK_POINT_NULL); + store.removeLink(networkId, src, dst); + } + + @Override + public VirtualPort createVirtualPort(NetworkId networkId, DeviceId deviceId, + PortNumber portNumber, Port realizedBy) { + checkNotNull(networkId, NETWORK_NULL); + checkNotNull(deviceId, DEVICE_NULL); + checkNotNull(portNumber, "Port description cannot be null"); + return store.addPort(networkId, deviceId, portNumber, realizedBy); + } + + @Override + public void removeVirtualPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) { + checkNotNull(networkId, NETWORK_NULL); + checkNotNull(deviceId, DEVICE_NULL); + checkNotNull(portNumber, "Port number cannot be null"); + store.removePort(networkId, deviceId, portNumber); + } + + @Override + public Set getVirtualNetworks(TenantId tenantId) { + checkNotNull(tenantId, TENANT_NULL); + return store.getNetworks(tenantId); + } + + @Override + public Set getVirtualDevices(NetworkId networkId) { + checkNotNull(networkId, NETWORK_NULL); + return store.getDevices(networkId); + } + + @Override + public Set getVirtualLinks(NetworkId networkId) { + checkNotNull(networkId, NETWORK_NULL); + return store.getLinks(networkId); + } + + @Override + public Set getVirtualPorts(NetworkId networkId, DeviceId deviceId) { + checkNotNull(networkId, NETWORK_NULL); + checkNotNull(deviceId, DEVICE_NULL); + return store.getPorts(networkId, deviceId); + } + + @Override + public T get(NetworkId networkId, Class serviceClass) { + checkNotNull(networkId, NETWORK_NULL); + return null; + } + + @Override + protected VirtualNetworkProviderService createProviderService(VirtualNetworkProvider provider) { + return new InternalVirtualNetworkProviderService(provider); + } + + // Service issued to registered virtual network providers so that they + // can interact with the core. + private class InternalVirtualNetworkProviderService + extends AbstractProviderService + implements VirtualNetworkProviderService { + InternalVirtualNetworkProviderService(VirtualNetworkProvider provider) { + super(provider); + } + } + + // Auxiliary store delegate to receive notification about changes in + // the virtual network configuration store state - by the store itself. + private class InternalStoreDelegate implements VirtualNetworkStoreDelegate { + @Override + public void notify(VirtualNetworkEvent event) { + post(event); + } + } + +} diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/package-info.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/package-info.java new file mode 100644 index 00000000..da4be5aa --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 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 the virtual network subsystem. + */ +package org.onosproject.incubator.net.virtual.impl; \ No newline at end of file diff --git a/framework/src/onos/incubator/net/src/test/java/org/onosproject/incubator/net/mcast/impl/MulticastRouteManagerTest.java b/framework/src/onos/incubator/net/src/test/java/org/onosproject/incubator/net/mcast/impl/MulticastRouteManagerTest.java new file mode 100644 index 00000000..545e21d0 --- /dev/null +++ b/framework/src/onos/incubator/net/src/test/java/org/onosproject/incubator/net/mcast/impl/MulticastRouteManagerTest.java @@ -0,0 +1,200 @@ +/* + * Copyright 2015 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.onosproject.incubator.net.mcast.impl; + +import com.google.common.collect.Lists; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onlab.junit.TestUtils; +import org.onlab.packet.IpPrefix; +import org.onosproject.common.event.impl.TestEventDispatcher; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.core.DefaultApplicationId; +import org.onosproject.core.IdGenerator; +import org.onosproject.core.Version; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.PortNumber; +import org.onosproject.net.mcast.McastEvent; +import org.onosproject.net.mcast.McastListener; +import org.onosproject.net.mcast.McastRoute; +import org.onosproject.store.service.TestStorageService; + +import java.util.List; +import java.util.Set; + +import static junit.framework.Assert.fail; +import static junit.framework.TestCase.assertEquals; +import static org.onosproject.net.NetTestTools.did; +import static org.onosproject.net.NetTestTools.injectEventDispatcher; + +/** + * Tests for the multicast RIB. + */ +public class MulticastRouteManagerTest { + + McastRoute r1 = new McastRoute(IpPrefix.valueOf("1.1.1.1/8"), + IpPrefix.valueOf("1.1.1.2/8"), + McastRoute.Type.IGMP); + + McastRoute r11 = new McastRoute(IpPrefix.valueOf("1.1.1.1/8"), + IpPrefix.valueOf("1.1.1.2/8"), + McastRoute.Type.STATIC); + + McastRoute r2 = new McastRoute(IpPrefix.valueOf("2.2.2.1/8"), + IpPrefix.valueOf("2.2.2.2/8"), + McastRoute.Type.PIM); + + ConnectPoint cp1 = new ConnectPoint(did("1"), PortNumber.portNumber(1)); + + ConnectPoint cp2 = new ConnectPoint(did("2"), PortNumber.portNumber(2)); + + private TestMulticastListener listener = new TestMulticastListener(); + + private MulticastRouteManager manager; + + private List events; + + @Before + public void setUp() throws Exception { + manager = new MulticastRouteManager(); + injectEventDispatcher(manager, new TestEventDispatcher()); + TestUtils.setField(manager, "storageService", new TestStorageService()); + TestUtils.setField(manager, "coreService", new TestCoreService()); + events = Lists.newArrayList(); + manager.activate(); + manager.addListener(listener); + } + + @After + public void tearDown() { + manager.removeListener(listener); + manager.deactivate(); + } + + @Test + public void testAdd() { + manager.add(r1); + + assertEquals("Add failed", manager.mcastRoutes.size(), 1); + validateEvents(McastEvent.Type.ROUTE_ADDED); + } + + @Test + public void testRemove() { + manager.add(r1); + + manager.remove(r1); + + assertEquals("Remove failed", manager.mcastRoutes.size(), 0); + validateEvents(McastEvent.Type.ROUTE_ADDED, McastEvent.Type.ROUTE_REMOVED); + } + + @Test + public void testAddSource() { + manager.add(r1); + + manager.addSource(r1, cp1); + + validateEvents(McastEvent.Type.ROUTE_ADDED, McastEvent.Type.SOURCE_ADDED); + assertEquals("Route is not equal", cp1, manager.fetchSource(r1)); + } + + @Test + public void testAddSink() { + manager.add(r1); + + manager.addSource(r1, cp1); + manager.addSink(r1, cp1); + + validateEvents(McastEvent.Type.ROUTE_ADDED, + McastEvent.Type.SOURCE_ADDED, + McastEvent.Type.SINK_ADDED); + assertEquals("Route is not equal", Lists.newArrayList(cp1), manager.fetchSinks(r1)); + } + + @Test + public void testRemoveSink() { + manager.add(r1); + + manager.addSource(r1, cp1); + manager.addSink(r1, cp1); + manager.addSink(r1, cp2); + manager.removeSink(r1, cp2); + + validateEvents(McastEvent.Type.ROUTE_ADDED, + McastEvent.Type.SOURCE_ADDED, + McastEvent.Type.SINK_ADDED, + McastEvent.Type.SINK_ADDED, + McastEvent.Type.SINK_REMOVED); + assertEquals("Route is not equal", Lists.newArrayList(cp1), manager.fetchSinks(r1)); + } + + private void validateEvents(McastEvent.Type... evs) { + if (events.size() != evs.length) { + fail(String.format("Mismatch number of events# obtained -> %s : expected %s", + events, evs)); + } + + for (int i = 0; i < evs.length; i++) { + if (evs[i] != events.get(i).type()) { + fail(String.format("Mismtached events# obtained -> %s : expected %s", + events, evs)); + } + } + } + + class TestMulticastListener implements McastListener { + + @Override + public void event(McastEvent event) { + events.add(event); + } + } + + private class TestCoreService implements CoreService { + @Override + public Version version() { + return null; + } + + @Override + public Set getAppIds() { + return null; + } + + @Override + public ApplicationId getAppId(Short id) { + return null; + } + + @Override + public ApplicationId getAppId(String name) { + return null; + } + + @Override + public ApplicationId registerApplication(String identifier) { + return new DefaultApplicationId(0, identifier); + } + + @Override + public IdGenerator getIdGenerator(String topic) { + return null; + } + } +} diff --git a/framework/src/onos/incubator/net/src/test/java/org/onosproject/incubator/net/meter/impl/MeterManagerTest.java b/framework/src/onos/incubator/net/src/test/java/org/onosproject/incubator/net/meter/impl/MeterManagerTest.java index e0c0c868..76caebcb 100644 --- a/framework/src/onos/incubator/net/src/test/java/org/onosproject/incubator/net/meter/impl/MeterManagerTest.java +++ b/framework/src/onos/incubator/net/src/test/java/org/onosproject/incubator/net/meter/impl/MeterManagerTest.java @@ -130,7 +130,7 @@ public class MeterManagerTest { m2 = DefaultMeter.builder() .forDevice(did("2")) .fromApp(APP_ID) - .withId(MeterId.meterId(2)) + .withId(MeterId.meterId(1)) .withUnit(Meter.Unit.KB_PER_SEC) .withBands(Collections.singletonList(band)) .build(); @@ -167,7 +167,7 @@ public class MeterManagerTest { assertTrue("The meter was not added", manager.getAllMeters().size() == 1); - assertThat(manager.getMeter(MeterId.meterId(1)), is(m1)); + assertThat(manager.getMeter(did("1"), MeterId.meterId(1)), is(m1)); } @Test @@ -175,7 +175,7 @@ public class MeterManagerTest { manager.submit(m1Request.add()); manager.withdraw(m1Request.remove(), m1.id()); - assertThat(manager.getMeter(MeterId.meterId(1)).state(), + assertThat(manager.getMeter(did("1"), MeterId.meterId(1)).state(), is(MeterState.PENDING_REMOVE)); providerService.pushMeterMetrics(m1.deviceId(), Collections.emptyList()); @@ -184,7 +184,16 @@ public class MeterManagerTest { } + @Test + public void testMultipleDevice() { + manager.submit(m1Request.add()); + manager.submit(m2Request.add()); + assertTrue("The meters were not added", manager.getAllMeters().size() == 2); + + assertThat(manager.getMeter(did("1"), MeterId.meterId(1)), is(m1)); + assertThat(manager.getMeter(did("2"), MeterId.meterId(1)), is(m2)); + } public class TestApplicationId extends DefaultApplicationId { public TestApplicationId(int id, String name) { diff --git a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java index 32890cb1..62a94675 100644 --- a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java +++ b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java @@ -33,6 +33,7 @@ import org.onosproject.net.meter.Meter; import org.onosproject.net.meter.MeterEvent; import org.onosproject.net.meter.MeterFailReason; import org.onosproject.net.meter.MeterId; +import org.onosproject.net.meter.MeterKey; import org.onosproject.net.meter.MeterOperation; import org.onosproject.net.meter.MeterState; import org.onosproject.net.meter.MeterStore; @@ -78,12 +79,12 @@ public class DistributedMeterStore extends AbstractStore meters; + private ConsistentMap meters; private NodeId local; - private MapEventListener mapListener = new InternalMapEventListener(); + private MapEventListener mapListener = new InternalMapEventListener(); - private Map> futures = + private Map> futures = Maps.newConcurrentMap(); @Activate @@ -92,9 +93,10 @@ public class DistributedMeterStore extends AbstractStoreconsistentMapBuilder() + meters = storageService.consistentMapBuilder() .withName(METERSTORE) .withSerializer(Serializer.using(Arrays.asList(KryoNamespaces.API), + MeterKey.class, MeterData.class, DefaultMeter.class, DefaultBand.class, @@ -120,11 +122,12 @@ public class DistributedMeterStore extends AbstractStore storeMeter(Meter meter) { CompletableFuture future = new CompletableFuture<>(); - futures.put(meter.id(), future); + MeterKey key = MeterKey.key(meter.deviceId(), meter.id()); + futures.put(key, future); MeterData data = new MeterData(meter, null, local); try { - meters.put(meter.id(), data); + meters.put(key, data); } catch (StorageException e) { future.completeExceptionally(e); } @@ -136,14 +139,15 @@ public class DistributedMeterStore extends AbstractStore deleteMeter(Meter meter) { CompletableFuture future = new CompletableFuture<>(); - futures.put(meter.id(), future); + MeterKey key = MeterKey.key(meter.deviceId(), meter.id()); + futures.put(key, future); MeterData data = new MeterData(meter, null, local); // update the state of the meter. It will be pruned by observing // that it has been removed from the dataplane. try { - if (meters.computeIfPresent(meter.id(), (k, v) -> data) == null) { + if (meters.computeIfPresent(key, (k, v) -> data) == null) { future.complete(MeterStoreResult.success()); } } catch (StorageException e) { @@ -157,11 +161,12 @@ public class DistributedMeterStore extends AbstractStore updateMeter(Meter meter) { CompletableFuture future = new CompletableFuture<>(); - futures.put(meter.id(), future); + MeterKey key = MeterKey.key(meter.deviceId(), meter.id()); + futures.put(key, future); MeterData data = new MeterData(meter, null, local); try { - if (meters.computeIfPresent(meter.id(), (k, v) -> data) == null) { + if (meters.computeIfPresent(key, (k, v) -> data) == null) { future.complete(MeterStoreResult.fail(MeterFailReason.INVALID_METER)); } } catch (StorageException e) { @@ -172,7 +177,8 @@ public class DistributedMeterStore extends AbstractStore { + MeterKey key = MeterKey.key(meter.deviceId(), meter.id()); + meters.computeIfPresent(key, (k, v) -> { DefaultMeter m = (DefaultMeter) v.meter(); m.setState(meter.state()); m.setProcessedPackets(meter.packetsSeen()); @@ -185,8 +191,8 @@ public class DistributedMeterStore extends AbstractStore + MeterKey key = MeterKey.key(op.meter().deviceId(), op.meter().id()); + meters.computeIfPresent(key, (k, v) -> new MeterData(v.meter(), reason, v.origin())); } @Override public void deleteMeterNow(Meter m) { - futures.remove(m.id()); - meters.remove(m.id()); + MeterKey key = MeterKey.key(m.deviceId(), m.id()); + futures.remove(key); + meters.remove(key); } - private class InternalMapEventListener implements MapEventListener { + private class InternalMapEventListener implements MapEventListener { @Override - public void event(MapEvent event) { + public void event(MapEvent event) { + MeterKey key = event.key(); MeterData data = event.value().value(); NodeId master = mastershipService.getMasterFor(data.meter().deviceId()); switch (event.type()) { @@ -227,17 +236,17 @@ public class DistributedMeterStore extends AbstractStore no friend - futures.get(data.meter().id()).complete(msr); + futures.get(key).complete(msr); } break; case ADDED: if (local.equals(data.origin()) && data.meter().state() == MeterState.PENDING_ADD) { - futures.remove(data.meter().id()).complete(MeterStoreResult.success()); + futures.remove(key).complete(MeterStoreResult.success()); } break; case REMOVED: if (local.equals(data.origin()) && data.meter().state() == MeterState.PENDING_REMOVE) { - futures.remove(data.meter().id()).complete(MeterStoreResult.success()); + futures.remove(key).complete(MeterStoreResult.success()); } break; default: diff --git a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/DistributedVirtualNetworkStore.java b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/DistributedVirtualNetworkStore.java new file mode 100644 index 00000000..69e56c0b --- /dev/null +++ b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/DistributedVirtualNetworkStore.java @@ -0,0 +1,147 @@ +/* + * Copyright 2015 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.onosproject.incubator.store.virtual.impl; + +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.Service; +import org.onosproject.incubator.net.tunnel.TunnelId; +import org.onosproject.incubator.net.virtual.DefaultVirtualDevice; +import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork; +import org.onosproject.incubator.net.virtual.NetworkId; +import org.onosproject.incubator.net.virtual.TenantId; +import org.onosproject.incubator.net.virtual.VirtualDevice; +import org.onosproject.incubator.net.virtual.VirtualLink; +import org.onosproject.incubator.net.virtual.VirtualNetwork; +import org.onosproject.incubator.net.virtual.VirtualNetworkEvent; +import org.onosproject.incubator.net.virtual.VirtualNetworkStore; +import org.onosproject.incubator.net.virtual.VirtualNetworkStoreDelegate; +import org.onosproject.incubator.net.virtual.VirtualPort; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; +import org.onosproject.store.AbstractStore; +import org.slf4j.Logger; + +import java.util.Set; + +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Implementation of the network store. + */ +@Component(immediate = true) +@Service +public class DistributedVirtualNetworkStore + extends AbstractStore + implements VirtualNetworkStore { + + private final Logger log = getLogger(getClass()); + + // TODO: track tenants by ID + // TODO: track networks by ID and by tenants + // TODO: track devices by network ID and device ID + // TODO: track devices by network ID + // TODO: setup block allocator for network IDs + + // TODO: notify delegate + + @Activate + public void activate() { + log.info("Started"); + } + + @Deactivate + public void deactivate() { + log.info("Stopped"); + } + + @Override + public void addTenantId(TenantId tenantId) { + } + + @Override + public void removeTenantId(TenantId tenantId) { + } + + @Override + public Set getTenantIds() { + return null; + } + + @Override + public VirtualNetwork addNetwork(TenantId tenantId) { + return new DefaultVirtualNetwork(genNetworkId(), tenantId); + } + + private NetworkId genNetworkId() { + return NetworkId.networkId(0); // TODO: use a block allocator + } + + + @Override + public void removeNetwork(NetworkId networkId) { + } + + @Override + public VirtualDevice addDevice(NetworkId networkId, DeviceId deviceId) { + return new DefaultVirtualDevice(networkId, deviceId); + } + + @Override + public void removeDevice(NetworkId networkId, DeviceId deviceId) { + } + + @Override + public VirtualLink addLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId realizedBy) { + return null; + } + + @Override + public void removeLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst) { + } + + @Override + public VirtualPort addPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber, Port realizedBy) { + return null; + } + + @Override + public void removePort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) { + } + + @Override + public Set getNetworks(TenantId tenantId) { + return null; + } + + @Override + public Set getDevices(NetworkId networkId) { + return null; + } + + @Override + public Set getLinks(NetworkId networkId) { + return null; + } + + @Override + public Set getPorts(NetworkId networkId, DeviceId deviceId) { + return null; + } +} diff --git a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/package-info.java b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/package-info.java new file mode 100644 index 00000000..12fa9091 --- /dev/null +++ b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 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 distributed virtual network store. + */ +package org.onosproject.incubator.store.virtual.impl; -- cgit 1.2.3-korg