diff options
author | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:15:21 -0700 |
---|---|---|
committer | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:15:21 -0700 |
commit | 13d05bc8458758ee39cb829098241e89616717ee (patch) | |
tree | 22a4d1ce65f15952f07a3df5af4b462b4697cb3a /framework/src/onos/incubator | |
parent | 6139282e1e93c2322076de4b91b1c85d0bc4a8b3 (diff) |
ONOS checkin based on commit tag e796610b1f721d02f9b0e213cf6f7790c10ecd60
Change-Id: Ife8810491034fe7becdba75dda20de4267bd15cd
Diffstat (limited to 'framework/src/onos/incubator')
110 files changed, 9432 insertions, 0 deletions
diff --git a/framework/src/onos/incubator/api/pom.xml b/framework/src/onos/incubator/api/pom.xml new file mode 100644 index 00000000..b417af53 --- /dev/null +++ b/framework/src/onos/incubator/api/pom.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + ~ 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. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-incubator</artifactId> + <version>1.3.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>onos-incubator-api</artifactId> + <packaging>bundle</packaging> + + <description>ONOS incubating core API</description> + + <dependencies> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava-testlib</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymock</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + +</project> diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/PortStatisticsService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/PortStatisticsService.java new file mode 100644 index 00000000..746961e6 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/PortStatisticsService.java @@ -0,0 +1,36 @@ +/* + * 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; + +import com.google.common.annotations.Beta; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.statistic.Load; + +/** + * Service for obtaining statistic information about device ports. + */ +@Beta +public interface PortStatisticsService { + + /** + * Obtain the egress load for the given port. + * + * @param connectPoint the port to query + * @return egress traffic load + */ + Load load(ConnectPoint connectPoint); + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/ConfigException.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/ConfigException.java new file mode 100644 index 00000000..071be6a0 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/ConfigException.java @@ -0,0 +1,42 @@ +/* + * 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.config.basics; + +/** + * Signals that an error was encountered while reading/writing configuration. + */ +public class ConfigException extends Exception { + + /** + * Constructs a new ConfigException with the given message. + * + * @param message message + */ + public ConfigException(String message) { + super(message); + } + + /** + * Constructs a new ConfigException with the given message and cause. + * + * @param message message + * @param cause cause + */ + public ConfigException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/ExtraSubjectFactories.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/ExtraSubjectFactories.java new file mode 100644 index 00000000..474ef6ad --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/ExtraSubjectFactories.java @@ -0,0 +1,38 @@ +/* + * 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.config.basics; + +import org.onosproject.incubator.net.domain.IntentDomainId; +import org.onosproject.net.config.SubjectFactory; + +/** + * Set of subject factories for potential configuration subjects. + */ +public final class ExtraSubjectFactories { + + // Construction forbidden + private ExtraSubjectFactories() { + } + + public static final SubjectFactory<IntentDomainId> INTENT_DOMAIN_SUBJECT_FACTORY = + new SubjectFactory<IntentDomainId>(IntentDomainId.class, "domains") { + @Override + public IntentDomainId createSubject(String key) { + return IntentDomainId.valueOf(key); + } + }; + +} 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 new file mode 100644 index 00000000..47adf5c7 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/InterfaceConfig.java @@ -0,0 +1,87 @@ +/* + * 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.config.basics; + +import com.fasterxml.jackson.databind.JsonNode; +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.host.InterfaceIpAddress; + +import java.util.Set; + +/** + * Configuration for interfaces. + */ +public class InterfaceConfig extends Config<ConnectPoint> { + public static final String IPS = "ips"; + 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"; + + /** + * Retrieves all interfaces configured on this port. + * + * @return set of interfaces + * @throws ConfigException if there is any error in the JSON config + */ + public Set<Interface> getInterfaces() throws ConfigException { + Set<Interface> interfaces = Sets.newHashSet(); + + try { + for (JsonNode intfNode : array) { + Set<InterfaceIpAddress> ips = getIps(intfNode); + if (ips.isEmpty()) { + throw new ConfigException(IP_MISSING_ERROR); + } + + if (intfNode.path(MAC).isMissingNode()) { + throw new ConfigException(MAC_MISSING_ERROR); + } + + 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())); + } + + interfaces.add(new Interface(subject, ips, mac, vlan)); + } + } catch (IllegalArgumentException e) { + throw new ConfigException(CONFIG_VALUE_ERROR, e); + } + + return interfaces; + } + + private Set<InterfaceIpAddress> getIps(JsonNode node) { + Set<InterfaceIpAddress> ips = Sets.newHashSet(); + + JsonNode ipsNode = node.get(IPS); + ipsNode.forEach(jsonNode -> ips.add(InterfaceIpAddress.valueOf(jsonNode.asText()))); + + return ips; + } + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/package-info.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/package-info.java new file mode 100644 index 00000000..506f1fc1 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/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. + */ + +/** + * Various basic builtin network configurations. + */ +package org.onosproject.incubator.net.config.basics;
\ No newline at end of file diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/DomainEdge.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/DomainEdge.java new file mode 100644 index 00000000..4a42a740 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/DomainEdge.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.domain; + +import com.google.common.annotations.Beta; +import com.google.common.base.MoreObjects; +import org.onlab.graph.AbstractEdge; +import org.onosproject.net.ConnectPoint; + +import java.util.Objects; + +/** + * Representation of a connection between an intent domain and a device. This + * must happen using a connect point that is part of both the domain and the + * device. + */ +@Beta +public class DomainEdge extends AbstractEdge<DomainVertex> { + + ConnectPoint connectPoint; + + public DomainEdge(DomainVertex src, DomainVertex dst, ConnectPoint connectPoint) { + super(src, dst); + this.connectPoint = connectPoint; + } + + @Override + public int hashCode() { + return 43 * super.hashCode() + Objects.hash(connectPoint); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DomainEdge) { + final DomainEdge other = (DomainEdge) obj; + return super.equals(other) && + Objects.equals(this.connectPoint, other.connectPoint); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("src", src()) + .add("dst", dst()) + .add("connectPoint", connectPoint) + .toString(); + } + + /** + * Returns the connect point associated with the domain edge. + * + * @return this edges connect point + */ + public ConnectPoint connectPoint() { + return connectPoint; + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/DomainVertex.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/DomainVertex.java new file mode 100644 index 00000000..7d11a76c --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/DomainVertex.java @@ -0,0 +1,88 @@ +/* + * 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 com.google.common.annotations.Beta; +import com.google.common.base.MoreObjects; +import org.onlab.graph.Vertex; +import org.onosproject.net.DeviceId; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Representation of the intent domain or a device that is part of the intent + * domain graph. + */ +@Beta +public class DomainVertex implements Vertex { + // FIXME we will want to add a type enum or subclasses for the two different types + + // A domain vertex is either an intent domain or a device: + private final IntentDomainId domainId; + // ----- or ----- + + private final DeviceId deviceId; + + // Serialization constructor + private DomainVertex() { + this.domainId = null; + this.deviceId = null; + } + + public DomainVertex(IntentDomainId id) { + this.domainId = checkNotNull(id, "Intent domain ID cannot be null."); + this.deviceId = null; + } + + public DomainVertex(DeviceId id) { + this.domainId = null; + this.deviceId = checkNotNull(id, "Device ID cannot be null."); + } + + @Override + public String toString() { + if (domainId != null) { + return MoreObjects.toStringHelper(this) + .add("domainId", domainId) + .toString(); + } else if (deviceId != null) { + return MoreObjects.toStringHelper(this) + .add("deviceId", deviceId) + .toString(); + } else { + return MoreObjects.toStringHelper(this) + .toString(); + } + } + + /** + * Returns the device ID of this vertex if it is a device, returns null if it is a domain. + * + * @return the device ID of this vertex if applicable, else null + */ + public DeviceId deviceId() { + return deviceId; + } + + /** + * Returns the domain ID of this vertex if it is a domain, returns null if it is a device. + * + * @return the domain ID of this vertex if applicable, else null + */ + public IntentDomainId domainId() { + return domainId; + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomain.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomain.java new file mode 100644 index 00000000..a52dce69 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomain.java @@ -0,0 +1,124 @@ +/* + * 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 com.google.common.annotations.Beta; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; + +import java.util.Set; + +/** + * Representation of an intent domain which includes the set of internal devices, + * the set of edge ports, and the implementation of the domain provider. + */ +@Beta +public class IntentDomain { + + private final IntentDomainId id; + private String name; + + private Set<DeviceId> internalDevices; + private Set<ConnectPoint> edgePorts; + + private IntentDomainProvider provider; + + public IntentDomain(IntentDomainId id, String name, + Set<DeviceId> internalDevices, + Set<ConnectPoint> edgePorts) { + this.id = id; + this.name = name; + this.internalDevices = internalDevices; + this.edgePorts = edgePorts; + } + + /** + * Returns the id for the intent domain. + * + * @return intent domain id + */ + public IntentDomainId id() { + return id; + } + + /** + * Returns the friendly name for the intent domain. + * + * @return intent domain name + */ + public String name() { + return name; + } + + /** + * Returns the set of internal devices for the intent domain (devices under + * exclusive control of the intent domain). + * + * @return set of internal devices + */ + public Set<DeviceId> internalDevices() { + return internalDevices; + } + + /** + * Returns the set of edge ports for the intent domain. + * + * @return set of edge ports + */ + public Set<ConnectPoint> edgePorts() { + return edgePorts; + } + + /** + * Returns the provider for the intent domain. + * + * @return intent domain provider + */ + public IntentDomainProvider provider() { + return provider; + } + + /** + * Returns the status of the intent domain. An intent domain is active if it + * has an intent domain provider bound, and it is inactive if one is not bound. + * + * @return true if active; false otherwise + */ + public boolean isActive() { + return provider != null; + } + + /** + * Sets the provider for the intent domain if one is not already set. + * + * @param provider new intent domain provider + */ + public void setProvider(IntentDomainProvider provider) { + // TODO consider checkState depending on caller + if (this.provider == null) { + this.provider = provider; + } + } + + /** + * Unsets the provider for the intent domain. + */ + public void unsetProvider() { + this.provider = null; + } + + //TODO add remaining setters (we will probably want to link this to the network config) +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainAdminService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainAdminService.java new file mode 100644 index 00000000..f5ceaa9f --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainAdminService.java @@ -0,0 +1,53 @@ +/* + * 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 com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; + +/** + * Administrative interface for the intent domain service. + */ +@Beta +public interface IntentDomainAdminService extends IntentDomainService { + + /** + * Register an application that provides intent domain service. + * + * @param applicationId application id + * @param provider intent domain provider + */ + void registerApplication(ApplicationId applicationId, IntentDomainProvider provider); + + /** + * Unregisters an application that provides intent domain service. + * + * @param applicationId application id + */ + void unregisterApplication(ApplicationId applicationId); + + /* TODO we may be able to accomplish the following through network config: + void createDomain(String domainId); + void removeDomain(String domainId); + + void addInternalDeviceToDomain(IntentDomain domain, DeviceId deviceId); + void addPortToDomain(IntentDomain domain, ConnectPoint port); + + void bindApplicationToDomain(String domain, IntentDomain implementation); + void unbindApplicationToDomain(String domain, IntentDomain implementation); + */ +} + diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainConfig.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainConfig.java new file mode 100644 index 00000000..e903c324 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainConfig.java @@ -0,0 +1,115 @@ +/* + * 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 com.google.common.annotations.Beta; +import com.google.common.collect.ImmutableSet; +import org.onosproject.net.config.Config; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; + +import java.util.Set; + +/** + * Configuration for an intent domain including a name, set of internal devices, + * set of edge ports, and the application bound to control the domain. + */ +@Beta +public class IntentDomainConfig extends Config<IntentDomainId> { + + private static final String DOMAIN_NAME = "name"; + private static final String APPLICATION_NAME = "applicationName"; + private static final String INTERNAL_DEVICES = "internalDevices"; + private static final String EDGE_PORTS = "edgePorts"; + + + /** + * Returns the friendly name for the domain. + * + * @return domain name + */ + public String domainName() { + return get(DOMAIN_NAME, subject.toString()); + } + + /** + * Sets the friendly name for the domain. + * + * @param domainName new name for the domain; null to clear + * @return self + */ + public IntentDomainConfig domainName(String domainName) { + return (IntentDomainConfig) setOrClear(DOMAIN_NAME, domainName); + } + + /** + * Returns the friendly name for the domain. + * + * @return domain name + */ + public String applicationName() { + return get(APPLICATION_NAME, "FIXME"); //TODO maybe not null? + } + + /** + * Sets the friendly name for the domain. + * + * @param applicationName new name for the domain; null to clear + * @return self + */ + public IntentDomainConfig applicationName(String applicationName) { + return (IntentDomainConfig) setOrClear(APPLICATION_NAME, applicationName); + } + + /** + * Returns the set of internal devices. + * + * @return set of internal devices + */ + public Set<DeviceId> internalDevices() { + return ImmutableSet.copyOf(getList(INTERNAL_DEVICES, DeviceId::deviceId)); + } + + /** + * Sets the set of internal devices. + * + * @param devices set of devices; null to clear + * @return self + */ + public IntentDomainConfig internalDevices(Set<DeviceId> devices) { + return (IntentDomainConfig) setOrClear(INTERNAL_DEVICES, devices); + } + + /** + * Returns the set of edge ports. + * + * @return set of edge ports + */ + public Set<ConnectPoint> edgePorts() { + return ImmutableSet.copyOf(getList(EDGE_PORTS, ConnectPoint::deviceConnectPoint)); + } + + /** + * Sets the set of edge ports. + * + * @param connectPoints set of edge ports; null to clear + * @return self + */ + public IntentDomainConfig edgePorts(Set<ConnectPoint> connectPoints) { + return (IntentDomainConfig) setOrClear(EDGE_PORTS, connectPoints); + } + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainId.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainId.java new file mode 100644 index 00000000..554702a7 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainId.java @@ -0,0 +1,79 @@ +/* + * 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 com.google.common.annotations.Beta; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Intent domain identifier. + */ +@Beta +public class IntentDomainId { + + private final String id; + + /** + * Creates an intent domain identifier from the specified string representation. + * + * @param value string value + * @return intent identifier + */ + public static IntentDomainId valueOf(String value) { + return new IntentDomainId(value); + } + + /** + * Constructor for serializer. + */ + IntentDomainId() { + this.id = null; + } + + /** + * Constructs the ID corresponding to a given string value. + * + * @param value the underlying value of this ID + */ + IntentDomainId(String value) { + this.id = checkNotNull(value, "Intent domain ID cannot be null."); + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof IntentDomainId)) { + return false; + } + IntentDomainId that = (IntentDomainId) obj; + return Objects.equals(this.id, that.id); + } + + @Override + public String toString() { + return id; + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainListener.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainListener.java new file mode 100644 index 00000000..04080b20 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainListener.java @@ -0,0 +1,27 @@ +/* + * 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 com.google.common.annotations.Beta; + +/** + * Listener for intent domain events. + */ +@Beta +public interface IntentDomainListener { + //TODO create event types + //extends EventListener<IntentDomainEvent> +}
\ No newline at end of file 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 new file mode 100644 index 00000000..51265f71 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainProvider.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 com.google.common.annotations.Beta; + +import java.util.List; +import java.util.Set; + +/** + * FIXME. + */ +@Beta +public interface IntentDomainProvider { + + /** + * Requests that the provider attempt to satisfy the intent primitive. + * The application must apply the context before the intent resource + * can be used. Request contexts can be explictly cancelled, or they will + * eventually time out so that resources can be reused. + * + * @param domain intent domain for the request + * @param primitive intent primitive + * @return request contexts that contain resources to satisfy the intent + */ + //TODO Consider an iterable and/or holds (only hold one or two reservation(s) at a time) + List<RequestContext> 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 + * @return request contexts that contain resources to satisfy the intent + */ + List<RequestContext> modify(IntentResource resource, IntentPrimitive newPrimitive); + + /** + * Requests that the provider release an intent resource. + * + * @param resource intent resource + */ + void release(IntentResource resource); + + /** + * Requests that the provider apply the intent resource in the request context. + * + * @param context request context + * @return intent resource that satisfies the intent + */ + IntentResource apply(RequestContext context); + + /** + * Requests that the provider cancel the request. Requests that are not applied + * will be eventually timed out by the provider. + * + * @param context request context + */ + void cancel(RequestContext context); + + /** + * Returns all intent resources held by the provider. + * + * @return set of intent resources + */ + Set<IntentResource> getResources(); +} + + diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainService.java new file mode 100644 index 00000000..41508ad3 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainService.java @@ -0,0 +1,79 @@ +/* + * 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 com.google.common.annotations.Beta; +import org.onlab.graph.Graph; +import org.onosproject.net.DeviceId; + +import java.util.Set; + +/** + * Service for that maintains a graph of intent domains and a registry of intent + * domain providers. + */ +@Beta +public interface IntentDomainService { + + /** + * Returns the intent domain for the given id. + * + * @param id id to look up + * @return the intent domain; null if none found + */ + IntentDomain getDomain(IntentDomainId id); + + /** + * Returns a set of all intent domains. + * + * @return set of intent domains + */ + Set<IntentDomain> getDomains(); + + /** + * Returns any network domains associated with the given device id. + * + * @param deviceId device id to look up + * @return set of intent domain + */ + Set<IntentDomain> getDomains(DeviceId deviceId); + + /** + * Returns the graph of intent domains and connection devices. + * + * @return graph of network domains + */ + Graph<DomainVertex, DomainEdge> getDomainGraph(); + + /** + * Adds the specified listener for intent domain events. + * + * @param listener listener to be added + */ + void addListener(IntentDomainListener listener); + + /** + * Removes the specified listener for intent domain events. + * + * @param listener listener to be removed + */ + void removeListener(IntentDomainListener listener); +} + + + + + diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentPrimitive.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentPrimitive.java new file mode 100644 index 00000000..ad3081a2 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentPrimitive.java @@ -0,0 +1,41 @@ +/* + * 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 com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; + +/** + * Abstract base class for intent primitives. + */ +@Beta +public abstract class IntentPrimitive { + + private final ApplicationId appId; + + public IntentPrimitive(ApplicationId appId) { + this.appId = appId; + } + + /** + * The getter for the application ID associated with the intent primitive upon creation. + * + * @return the application ID associated with the intent primitive + */ + public ApplicationId appId() { + return appId; + } +}
\ No newline at end of file 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 new file mode 100644 index 00000000..9cd9aac0 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentResource.java @@ -0,0 +1,68 @@ +/* + * 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 com.google.common.annotations.Beta; + +/** + * The abstract base class for the resource that satisfies an intent primitive. + */ +@Beta +public class IntentResource { + + private final IntentPrimitive primitive; + private final long tunnelId; + private final IntentDomainId domainId; + + // TODO add other common fields + //String ingressTag; + //String egressTag; + //etc. + + public IntentResource(IntentPrimitive primitive, long tunnelId, IntentDomainId domainId) { + this.primitive = primitive; + this.tunnelId = tunnelId; + this.domainId = domainId; + } + + /** + * Returns the intent primitive associated with this resource as creation. + * + * @return this resource's intent primitive + */ + public IntentPrimitive primitive() { + return primitive; + } + + /** + * Returns the tunnel ID associated with this resource as creation. + * + * @return this resource's tunnel ID + */ + public long tunnelId() { + return tunnelId; + } + + /** + * Returns the domain ID associated with this resource as creation. + * + * @return this resource's domain ID + */ + public IntentDomainId domainId() { + return domainId; + } + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/RequestContext.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/RequestContext.java new file mode 100644 index 00000000..338c8408 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/RequestContext.java @@ -0,0 +1,54 @@ +/* + * 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 com.google.common.annotations.Beta; +import org.onosproject.net.Path; + +/** + * Context for intent primitive requests to an intent domain provider. A context + * must be explicitly applied before it can be used. The purpose of the request + * context is so that an application can coordinate multiple requests across multiple + * domains before committing. Contexts can be explicitly cancelled if they are not + * needed (due to a better context or incomplete path across domains); they can + * also be automatically cancelled by a provider after a short timeout. + */ +@Beta +public class RequestContext { + private final IntentDomain domain; + private final IntentResource resource; + private final Path path; + //TODO other common parameters: + //String cost; + + public RequestContext(IntentDomain domain, IntentResource resource, Path path) { + this.domain = domain; + this.resource = resource; + this.path = path; + } + + public IntentDomain domain() { + return domain; + } + + public IntentResource resource() { + return resource; + } + + public Path path() { + return path; + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/TunnelPrimitive.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/TunnelPrimitive.java new file mode 100644 index 00000000..975708d6 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/TunnelPrimitive.java @@ -0,0 +1,51 @@ +/* + * 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.net.ConnectPoint; + +/** + * Provides connectivity through a domain. + */ +public class TunnelPrimitive extends IntentPrimitive { + + private final ConnectPoint one; + private final ConnectPoint two; + + public TunnelPrimitive(ApplicationId appId, ConnectPoint one, ConnectPoint two) { + super(appId); + this.one = one; + this.two = two; + } + + /** + * The getter for the first connection point associated with a tunnel. + * + * @return the first connection point + */ + public ConnectPoint one() { + return one; + } + + /** + * The getter for the second connection point associated with a tunnel. + * @return the second connection point + */ + public ConnectPoint two() { + return two; + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/package-info.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/package-info.java new file mode 100644 index 00000000..b8340e01 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/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. + */ + +/** + * Subsystem for network intent domains. + */ +package org.onosproject.incubator.net.domain;
\ No newline at end of file diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/intf/Interface.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/intf/Interface.java new file mode 100644 index 00000000..15ecf340 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/intf/Interface.java @@ -0,0 +1,121 @@ +/* + * Copyright 2014-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 com.google.common.base.MoreObjects; +import com.google.common.collect.Sets; +import org.onlab.packet.MacAddress; +import org.onlab.packet.VlanId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.host.InterfaceIpAddress; + +import java.util.Objects; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * An Interface maps network configuration information (such as addresses and + * vlans) to a port in the network. + */ +public class Interface { + private final ConnectPoint connectPoint; + private final Set<InterfaceIpAddress> ipAddresses; + private final MacAddress macAddress; + private final VlanId vlan; + + /** + * Creates new Interface with the provided configuration. + * + * @param connectPoint the connect point this interface maps to + * @param ipAddresses Set of IP addresses + * @param macAddress MAC address + * @param vlan VLAN ID + */ + public Interface(ConnectPoint connectPoint, + Set<InterfaceIpAddress> ipAddresses, + MacAddress macAddress, VlanId vlan) { + this.connectPoint = checkNotNull(connectPoint); + this.ipAddresses = Sets.newHashSet(checkNotNull(ipAddresses)); + this.macAddress = checkNotNull(macAddress); + this.vlan = checkNotNull(vlan); + } + + /** + * Retrieves the connection point that this interface maps to. + * + * @return the connection point + */ + public ConnectPoint connectPoint() { + return connectPoint; + } + + /** + * Retrieves the set of IP addresses that are assigned to the interface. + * + * @return the set of interface IP addresses + */ + public Set<InterfaceIpAddress> ipAddresses() { + return ipAddresses; + } + + /** + * Retrieves the MAC address that is assigned to the interface. + * + * @return the MAC address + */ + public MacAddress mac() { + return macAddress; + } + + /** + * Retrieves the VLAN ID that is assigned to the interface. + * + * @return the VLAN ID + */ + public VlanId vlan() { + return vlan; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof Interface)) { + return false; + } + + Interface otherInterface = (Interface) other; + + return Objects.equals(connectPoint, otherInterface.connectPoint) && + Objects.equals(ipAddresses, otherInterface.ipAddresses) && + Objects.equals(macAddress, otherInterface.macAddress) && + Objects.equals(vlan, otherInterface.vlan); + } + + @Override + public int hashCode() { + return Objects.hash(connectPoint, ipAddresses, macAddress, vlan); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("connectPoint", connectPoint) + .add("ipAddresses", ipAddresses) + .add("macAddress", macAddress) + .add("vlan", vlan) + .toString(); + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/intf/InterfaceService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/intf/InterfaceService.java new file mode 100644 index 00000000..ad1bf34a --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/intf/InterfaceService.java @@ -0,0 +1,69 @@ +/* + * 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.IpAddress; +import org.onlab.packet.VlanId; +import org.onosproject.net.ConnectPoint; + +import java.util.Set; + +/** + * Service for interacting with interfaces. + */ +public interface InterfaceService { + + /** + * Returns the set of all interfaces in the system. + * + * @return set of interfaces + */ + Set<Interface> getInterfaces(); + + /** + * Returns the set of interfaces configured on the given port. + * + * @param port connect point + * @return set of interfaces + */ + Set<Interface> getInterfacesByPort(ConnectPoint port); + + /** + * Returns the set of interfaces with the given IP address. + * + * @param ip IP address + * @return set of interfaces + */ + Set<Interface> getInterfacesByIp(IpAddress ip); + + /** + * Returns the set of interfaces in the given VLAN. + * + * @param vlan VLAN ID of the interfaces + * @return set of interfaces + */ + Set<Interface> getInterfacesByVlan(VlanId vlan); + + /** + * Returns an interface that has an address that is in the same subnet as + * the given IP address. + * + * @param ip IP address to find matching subnet interface for + * @return interface + */ + Interface getMatchingInterface(IpAddress ip); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/package-info.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/package-info.java new file mode 100644 index 00000000..868eec7a --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/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. + */ + +/** + * Incubating network model abstractions and APIs. + */ +package org.onosproject.incubator.net;
\ No newline at end of file diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/DefaultLabelResource.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/DefaultLabelResource.java new file mode 100644 index 00000000..23663d38 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/DefaultLabelResource.java @@ -0,0 +1,83 @@ +package org.onosproject.incubator.net.resource.label; + +import java.util.Objects; + +import com.google.common.annotations.Beta; +import org.onosproject.net.Annotations; +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.ProviderId; +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * the implementation of a label resource of a device. + */ +@Beta +public final class DefaultLabelResource implements LabelResource { + + private DeviceId deviceId; + + private LabelResourceId labelResourceId; + + /** + * Initialize a label resource object. + * @param deviceId device identifier + * @param labelResourceId label resource id + */ + public DefaultLabelResource(String deviceId, long labelResourceId) { + this.deviceId = DeviceId.deviceId(deviceId); + this.labelResourceId = LabelResourceId.labelResourceId(labelResourceId); + } + + /** + * Initialize a label resource object. + * @param deviceId device identifier + * @param labelResourceId label resource id + */ + public DefaultLabelResource(DeviceId deviceId, + LabelResourceId labelResourceId) { + this.deviceId = deviceId; + this.labelResourceId = labelResourceId; + } + + @Override + public DeviceId deviceId() { + return deviceId; + } + + @Override + public LabelResourceId labelResourceId() { + return labelResourceId; + } + + @Override + public Annotations annotations() { + return null; + } + + @Override + public ProviderId providerId() { + return null; + } + + @Override + public int hashCode() { + return Objects.hash(deviceId, labelResourceId); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof DefaultLabelResource) { + DefaultLabelResource that = (DefaultLabelResource) obj; + return Objects.equals(this.deviceId, that.deviceId) + && Objects.equals(this.labelResourceId, + that.labelResourceId); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this).add("deviceId", deviceId) + .add("labelResourceId", labelResourceId).toString(); + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResource.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResource.java new file mode 100644 index 00000000..bb1b3167 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResource.java @@ -0,0 +1,26 @@ +package org.onosproject.incubator.net.resource.label; + +import com.google.common.annotations.Beta; +import org.onosproject.net.Annotated; +import org.onosproject.net.DeviceId; +import org.onosproject.net.NetworkResource; +import org.onosproject.net.Provided; + +/** + * Representation of label resource. + */ +@Beta +public interface LabelResource extends Annotated, Provided, NetworkResource { + /** + * Returns device id. + * @return DeviceId + */ + DeviceId deviceId(); + + /** + * Returns label resource identifier. + * + * @return resource id + */ + LabelResourceId labelResourceId(); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceAdminService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceAdminService.java new file mode 100644 index 00000000..f20ab59b --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceAdminService.java @@ -0,0 +1,51 @@ +package org.onosproject.incubator.net.resource.label; + +import com.google.common.annotations.Beta; +import org.onosproject.net.DeviceId; + +/** + * Service for managing label resource. + */ +@Beta +public interface LabelResourceAdminService { + /** + * Creates the only label resource of some device id from begin label to end + * label. + * + * @param deviceId device identifier + * @param beginLabel represents for the first label id in the range of label + * pool + * @param endLabel represents for the last label id in the range of label + * pool + * @return success or fail + */ + boolean createDevicePool(DeviceId deviceId, LabelResourceId beginLabel, + LabelResourceId endLabel); + + /** + * Creates the only global label resource pool. + * + * @param beginLabel represents for the first label id in the range of label + * pool + * @param endLabel represents for the last label id in the range of label + * pool + * @return success or fail + */ + boolean createGlobalPool(LabelResourceId beginLabel, + LabelResourceId endLabel); + + /** + * Destroys a label resource pool of a specific device id. + * + * @param deviceId device identifier + * @return success or fail + */ + boolean destroyDevicePool(DeviceId deviceId); + + /** + * Destroys the global label resource pool. + * + * @return success or fail + */ + boolean destroyGlobalPool(); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceDelegate.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceDelegate.java new file mode 100644 index 00000000..ea053afc --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceDelegate.java @@ -0,0 +1,12 @@ +package org.onosproject.incubator.net.resource.label; + +import com.google.common.annotations.Beta; +import org.onosproject.store.StoreDelegate; + +/** + * Label resource store delegate. + */ +@Beta +public interface LabelResourceDelegate extends StoreDelegate<LabelResourceEvent> { + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceEvent.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceEvent.java new file mode 100644 index 00000000..e77fdaf5 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceEvent.java @@ -0,0 +1,40 @@ +package org.onosproject.incubator.net.resource.label; + +import com.google.common.annotations.Beta; +import org.onosproject.event.AbstractEvent; + +/** + * Describes label resource event. + */ +@Beta +public final class LabelResourceEvent + extends AbstractEvent<LabelResourceEvent.Type, LabelResourcePool> { + + /** + * Type of label resource event. + */ + public enum Type { + /** + * Signifies that a new pool has been administratively created. + */ + POOL_CREATED, + /** + * Signifies that a new pool has been administratively destroyed. + */ + POOL_DESTROYED, + /** + * Signifies that a new pool has been administratively changed. + */ + POOL_CAPACITY_CHANGED + } + + /** + * Creates an event of a given type and the given LabelResourcePool. + * + * @param type event type + * @param subject pool + */ + public LabelResourceEvent(Type type, LabelResourcePool subject) { + super(type, subject); + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceId.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceId.java new file mode 100644 index 00000000..8936954a --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceId.java @@ -0,0 +1,48 @@ +package org.onosproject.incubator.net.resource.label; + +import com.google.common.annotations.Beta; +import org.onosproject.net.resource.ResourceId; + +import java.util.Objects; + +/** + * Representation of a label. + */ +@Beta +public final class LabelResourceId implements ResourceId { + + private long labelId; + + public static LabelResourceId labelResourceId(long labelResourceId) { + return new LabelResourceId(labelResourceId); + } + + // Public construction is prohibited + private LabelResourceId(long labelId) { + this.labelId = labelId; + } + + public long labelId() { + return labelId; + } + + @Override + public int hashCode() { + return Objects.hashCode(labelId); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof LabelResourceId) { + LabelResourceId that = (LabelResourceId) obj; + return Objects.equals(this.labelId, that.labelId); + } + return false; + } + + @Override + public String toString() { + return String.valueOf(this.labelId); + } + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceListener.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceListener.java new file mode 100644 index 00000000..72de0fb4 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceListener.java @@ -0,0 +1,12 @@ +package org.onosproject.incubator.net.resource.label; + +import com.google.common.annotations.Beta; +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving label resource related events. + */ +@Beta +public interface LabelResourceListener extends EventListener<LabelResourceEvent> { + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourcePool.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourcePool.java new file mode 100644 index 00000000..315abe61 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourcePool.java @@ -0,0 +1,176 @@ +package org.onosproject.incubator.net.resource.label; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +import com.google.common.annotations.Beta; +import org.onosproject.net.DeviceId; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableSet; + +/** + * Abstraction of the capacity of device label resource or global label + * resource. It's contiguous range of label resource. When a application apply + * some labels of some device, first catch from Set that store + * available labels, if the size of the Set less than the apply number, then get + * labels by calculating with three attributes, beginLabel,endLabel and + * currentUsedMaxLabelId. + */ +@Beta +public class LabelResourcePool { + + private final DeviceId deviceId; + private final LabelResourceId beginLabel; + private final LabelResourceId endLabel; + private final long totalNum; // capacity of label resource pool + private final long usedNum; // have used label number + private final LabelResourceId currentUsedMaxLabelId; // the maximal label + // number id + private ImmutableSet<LabelResource> releaseLabelId; // Set of released label + + /** + * Creates a pool by device id,begin label id,end label id. + * + * @param deviceId device identifier + * @param beginLabel represents for the first label id in the range of label + * resource pool + * @param endLabel represents for the last label id in the range of label + * resource pool + */ + public LabelResourcePool(String deviceId, long beginLabel, long endLabel) { + this(deviceId, beginLabel, endLabel, endLabel - beginLabel + 1, 0L, + beginLabel, ImmutableSet.copyOf(Collections.emptySet())); + } + + /** + * Creates a pool by device id,begin label id,end label id. + * Used to update a pool in the store. + * + * @param deviceId device identifier + * @param beginLabel represents for the first label id in the range of label + * resource pool + * @param endLabel represents for the last label id in the range of label + * resource pool + * @param totalNum capacity of label resource pool + * @param usedNum have used label number + * @param currentUsedMaxLabelId the maximal label number id + * @param releaseLabelId Set of released label + */ + public LabelResourcePool(String deviceId, long beginLabel, long endLabel, + long totalNum, long usedNum, + long currentUsedMaxLabelId, + ImmutableSet<LabelResource> releaseLabelId) { + checkArgument(endLabel >= beginLabel, + "endLabel %s must be greater than or equal to beginLabel %s", + endLabel, beginLabel); + this.deviceId = DeviceId.deviceId(deviceId); + this.beginLabel = LabelResourceId.labelResourceId(beginLabel); + this.endLabel = LabelResourceId.labelResourceId(endLabel); + this.totalNum = totalNum; + this.usedNum = usedNum; + this.currentUsedMaxLabelId = LabelResourceId + .labelResourceId(currentUsedMaxLabelId); + this.releaseLabelId = releaseLabelId; + } + + /** + * Returns a device id. + * + * @return DeviceId + */ + public DeviceId deviceId() { + return deviceId; + } + + /** + * Returns a begin Label id. + * + * @return begin Label id + */ + public LabelResourceId beginLabel() { + return beginLabel; + } + + /** + * Returns an end Label id. + * + * @return end Label id + */ + public LabelResourceId endLabel() { + return endLabel; + } + + /** + * Returns a begin Label id. + * + * @return current Used Maximal Label Id + */ + public LabelResourceId currentUsedMaxLabelId() { + return currentUsedMaxLabelId; + } + + /** + * Returns total number. + * + * @return the total label number + */ + public long totalNum() { + return totalNum; + } + + /** + * Returns used number. + * + * @return the used label number + */ + public long usedNum() { + return usedNum; + } + + /** + * Returns the Set of released label before. + * + * @return the Set of LabelResource + */ + public Set<LabelResource> releaseLabelId() { + return releaseLabelId; + } + + @Override + public int hashCode() { + return Objects.hash(this.deviceId, this.beginLabel, this.endLabel, + this.totalNum, this.usedNum, + this.currentUsedMaxLabelId, this.releaseLabelId); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof LabelResourcePool) { + LabelResourcePool that = (LabelResourcePool) obj; + return Objects.equals(this.deviceId, that.deviceId) + && Objects.equals(this.beginLabel, that.beginLabel) + && Objects.equals(this.endLabel, that.endLabel) + && Objects.equals(this.totalNum, that.totalNum) + && Objects.equals(this.usedNum, that.usedNum) + && Objects.equals(this.currentUsedMaxLabelId, + that.currentUsedMaxLabelId) + && Objects.equals(this.releaseLabelId, that.releaseLabelId); + } + return false; + } + + @Override + public String toString() { + // TODO Auto-generated method stub + return MoreObjects.toStringHelper(this).add("deviceId", this.deviceId) + .add("beginLabel", this.beginLabel) + .add("endLabel", this.endLabel).add("totalNum", this.totalNum) + .add("usedNum", this.usedNum) + .add("currentUsedMaxLabelId", this.currentUsedMaxLabelId) + .add("releaseLabelId", this.releaseLabelId).toString(); + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceProvider.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceProvider.java new file mode 100644 index 00000000..2ef966b6 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceProvider.java @@ -0,0 +1,13 @@ +package org.onosproject.incubator.net.resource.label; + +import com.google.common.annotations.Beta; +import org.onosproject.net.provider.Provider; + +/** + * Abstraction of an entity providing information about label resource + * to the core. + */ +@Beta +public interface LabelResourceProvider extends Provider { + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceProviderRegistry.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceProviderRegistry.java new file mode 100644 index 00000000..b8e0a299 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceProviderRegistry.java @@ -0,0 +1,13 @@ +package org.onosproject.incubator.net.resource.label; + +import com.google.common.annotations.Beta; +import org.onosproject.net.provider.ProviderRegistry; + +/** + * Abstraction of an label resource provider registry. + */ +@Beta +public interface LabelResourceProviderRegistry + extends ProviderRegistry<LabelResourceProvider, LabelResourceProviderService> { + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceProviderService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceProviderService.java new file mode 100644 index 00000000..93384c04 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceProviderService.java @@ -0,0 +1,28 @@ +package org.onosproject.incubator.net.resource.label; + +import com.google.common.annotations.Beta; +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.ProviderService; + +/** + * Means for injecting label information into the core. + */ +@Beta +public interface LabelResourceProviderService extends ProviderService<LabelResourceProvider> { + + /** + * Signals that a device label resource pool has been detected. + * @param deviceId device identifier + * @param beginLabel the begin label number of resource + * @param endLabel the end label number of resource + */ + void deviceLabelResourcePoolDetected(DeviceId deviceId, + LabelResourceId beginLabel, + LabelResourceId endLabel); + + /** + * Signals that an label resource pool has been destroyed. + * @param deviceId device identifier + */ + void deviceLabelResourcePoolDestroyed(DeviceId deviceId); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceRequest.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceRequest.java new file mode 100644 index 00000000..d81d7aa8 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceRequest.java @@ -0,0 +1,104 @@ +package org.onosproject.incubator.net.resource.label; + +import java.util.Collection; +import java.util.Objects; + +import com.google.common.annotations.Beta; +import org.onosproject.net.DeviceId; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableSet; + +/** + * Represents for a label request. + */ +@Beta +public class LabelResourceRequest { + + private final DeviceId deviceId; + private final Type type; + private final long applyNum; + private ImmutableSet<LabelResource> releaseCollection; + + /** + * Creates LabelResourceRequest object. + * @param deviceId device identifier + * @param type request type + * @param applyNum apply the number of labels + * @param releaseCollection Set of released label + */ + public LabelResourceRequest(DeviceId deviceId, + Type type, + long applyNum, + ImmutableSet<LabelResource> releaseCollection) { + this.deviceId = deviceId; + this.type = type; + this.applyNum = applyNum; + this.releaseCollection = releaseCollection; + } + /** + * Returns a device id. + * @return DeviceId + */ + public DeviceId deviceId() { + return deviceId; + } + + /** + * Returns request type. + * @return Type + */ + public Type type() { + return type; + } + + /** + * Returns apply label number. + * @return label number + */ + public long applyNum() { + return applyNum; + } + + /** + * Returns the collection of release labels. + * @return Collection of DefaultLabelResource + */ + public Collection<LabelResource> releaseCollection() { + return releaseCollection; + } + + /** + * Request type. + */ + public enum Type { + APPLY, //apple label request + RELEASE //release label request + } + + @Override + public int hashCode() { + return Objects.hash(this.deviceId, this.applyNum, this.type, + this.releaseCollection); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof LabelResourceRequest) { + LabelResourceRequest that = (LabelResourceRequest) obj; + return Objects.equals(this.deviceId, that.deviceId) + && Objects.equals(this.applyNum, that.applyNum) + && Objects.equals(this.type, that.type) + && Objects.equals(this.releaseCollection, + that.releaseCollection); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("deviceId", this.deviceId) + .add("applyNum", this.applyNum).add("type", this.type) + .add("releaseCollection", this.releaseCollection).toString(); + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceService.java new file mode 100644 index 00000000..02052c37 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceService.java @@ -0,0 +1,100 @@ +package org.onosproject.incubator.net.resource.label; + +import java.util.Collection; +import java.util.Set; + +import com.google.common.annotations.Beta; +import org.onosproject.event.ListenerService; +import org.onosproject.net.DeviceId; + +import com.google.common.collect.Multimap; + +/** + * Service for providing label resource allocation. + */ +@Beta +public interface LabelResourceService + extends ListenerService<LabelResourceEvent, LabelResourceListener> { + + /** + * Returns labels from resource pool by a specific device id. + * + * @param deviceId device identifier + * @param applyNum the applying number + * @return collection of applying labels + */ + Collection<LabelResource> applyFromDevicePool(DeviceId deviceId, + long applyNum); + + /** + * Returns labels from the global label resource pool. + * + * @param applyNum the applying number + * @return collection of applying labels + */ + Collection<LabelResource> applyFromGlobalPool(long applyNum); + + /** + * Releases unused labels to device pools . + * + * @param release the collection of releasing labels + * @return success or fail + */ + boolean releaseToDevicePool(Multimap<DeviceId, LabelResource> release); + + /** + * Releases unused labels to the global resource pool. + * + * @param release release the collection of releasing labels + * @return success or fail + */ + boolean releaseToGlobalPool(Set<LabelResourceId> release); + + /** + * Judges if the pool of a specific device id is full. + * + * @param deviceId device identifier + * @return yes or no + */ + boolean isDevicePoolFull(DeviceId deviceId); + + /** + * Judges if the global resource pool is full. + * + * @return yes or no + */ + boolean isGlobalPoolFull(); + + /** + * Returns the unused label number of a label resource pool by a specific device + * id. + * + * @param deviceId device identifier + * @return number of unused labels + */ + long getFreeNumOfDevicePool(DeviceId deviceId); + + /** + * Returns the unused label number of a global label resource pool. + * + * @return number of unused labels + */ + long getFreeNumOfGlobalPool(); + + /** + * Returns the label resource pool of a label resource by a specific device + * id. + * + * @param deviceId device identifier + * @return the device label resource pool + */ + LabelResourcePool getDeviceLabelResourcePool(DeviceId deviceId); + + /** + * Returns the global label resource pool. + * + * @return the global label resource pool + */ + LabelResourcePool getGlobalLabelResourcePool(); + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceStore.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceStore.java new file mode 100644 index 00000000..2da3e814 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceStore.java @@ -0,0 +1,139 @@ +package org.onosproject.incubator.net.resource.label; + +import java.util.Collection; +import java.util.Set; + +import com.google.common.annotations.Beta; +import org.onosproject.net.DeviceId; +import org.onosproject.store.Store; + +import com.google.common.collect.Multimap; + +/** + * Manages inventory of label; not intended for direct use. + * + */ +@Beta +public interface LabelResourceStore + extends Store<LabelResourceEvent, LabelResourceDelegate> { + + /** + * Creates a label resource of some device id from begin label to end label. + * + * @param deviceId device identifier + * @param beginLabel represents for the first label id in the range of label + * pool + * @param endLabel represents for the last label id in the range of label + * pool + * @return success or fail + */ + boolean createDevicePool(DeviceId deviceId, LabelResourceId beginLabel, + LabelResourceId endLabel); + + /** + * Creates the global label resource pool. + * + * @param beginLabel represents for the first label id in the range of label + * pool + * @param endLabel represents for the last label id in the range of label + * pool + * @return success or fail + */ + boolean createGlobalPool(LabelResourceId beginLabel, + LabelResourceId endLabel); + + /** + * Destroys a label resource pool of a specific device id. + * + * @param deviceId device identifier + * @return success or fail + */ + boolean destroyDevicePool(DeviceId deviceId); + + /** + * Destroys a the global label resource pool. + * + * @return success or fail + */ + boolean destroyGlobalPool(); + + /** + * Returns labels from resource pool by a specific device id. + * + * @param deviceId device identifier + * @param applyNum the applying number + * @return collection of applying labels + */ + Collection<LabelResource> applyFromDevicePool(DeviceId deviceId, + long applyNum); + + /** + * Returns labels from the global label resource pool. + * + * @param applyNum apply the number of labels + * @return collection of labels + */ + Collection<LabelResource> applyFromGlobalPool(long applyNum); + + /** + * Releases unused labels to device pools . + * + * @param release the collection of releasing labels + * @return success or fail + */ + boolean releaseToDevicePool(Multimap<DeviceId, LabelResource> release); + + /** + * Releases unused labels to the global resource pool. + * + * @param release release the collection of releasing labels + * @return success or fail + */ + boolean releaseToGlobalPool(Set<LabelResourceId> release); + + /** + * Judges if the pool of a specific device id is full. + * + * @param deviceId device identifier + * @return yes or no + */ + boolean isDevicePoolFull(DeviceId deviceId); + + /** + * Judges if the global resource pool is full. + * + * @return yes or no + */ + boolean isGlobalPoolFull(); + + /** + * Returns the unused label number of a label resource pool by a specific device + * id. + * + * @param deviceId device identifier + * @return number of unused labels + */ + long getFreeNumOfDevicePool(DeviceId deviceId); + + /** + * Returns the unused number of a global label resource pool. + * + * @return number of unused labels + */ + long getFreeNumOfGlobalPool(); + + /** + * Returns the label resource pool by a specific device id. + * + * @param deviceId device identifier + * @return the device label resource pool + */ + LabelResourcePool getDeviceLabelResourcePool(DeviceId deviceId); + + /** + * Returns the global label resource pool. + * + * @return the global label resource pool + */ + LabelResourcePool getGlobalLabelResourcePool(); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/package-info.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/package-info.java new file mode 100644 index 00000000..9df466e9 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/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. + */ + +/** + * Service for reserving labels as network resources. + */ +package org.onosproject.incubator.net.resource.label;
\ No newline at end of file diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultOpticalTunnelEndPoint.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultOpticalTunnelEndPoint.java new file mode 100644 index 00000000..ae0f5148 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultOpticalTunnelEndPoint.java @@ -0,0 +1,131 @@ +/* + * 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 static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; +import java.util.Optional; + +import com.google.common.annotations.Beta; +import org.onosproject.net.AbstractModel; +import org.onosproject.net.Annotations; +import org.onosproject.net.ElementId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.provider.ProviderId; + +/** + * Default optical tunnel point model implementation. + */ +@Beta +public class DefaultOpticalTunnelEndPoint extends AbstractModel implements OpticalTunnelEndPoint { + private final Optional<ElementId> elementId; + private final Optional<PortNumber> portNumber; + private final Optional<OpticalTunnelEndPoint> parentPoint; + private final Type type; + private final OpticalLogicId id; + private final boolean isGlobal; + + /** + * Creates a optical tunnel point attributed to the specified provider (may be null). + * if provider is null, which means the optical tunnel point is not managed by the SB. + * + * @param providerId tunnelProvider Id + * @param elementId parent network element + * @param number port number + * @param parentPoint parent port or parent label + * @param type port type + * @param id LabelId + * @param isGlobal indicator whether the label is global significant or not + * @param annotations optional key/value annotations + */ + public DefaultOpticalTunnelEndPoint(ProviderId providerId, Optional<ElementId> elementId, + Optional<PortNumber> number, Optional<OpticalTunnelEndPoint> parentPoint, + Type type, OpticalLogicId id, boolean isGlobal, Annotations... annotations) { + super(providerId, annotations); + this.elementId = elementId; + this.portNumber = number; + this.parentPoint = parentPoint; + this.id = id; + this.type = type; + this.isGlobal = isGlobal; + } + + @Override + public OpticalLogicId id() { + return id; + } + + @Override + public Optional<ElementId> elementId() { + return elementId; + } + + @Override + public Optional<PortNumber> portNumber() { + return portNumber; + } + + @Override + public Optional<OpticalTunnelEndPoint> parentPoint() { + return parentPoint; + } + + @Override + public boolean isGlobal() { + return isGlobal; + } + + @Override + public Type type() { + return type; + } + + @Override + public int hashCode() { + return Objects.hash(elementId, portNumber, parentPoint, id); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultOpticalTunnelEndPoint) { + final DefaultOpticalTunnelEndPoint other = (DefaultOpticalTunnelEndPoint) obj; + return Objects.equals(this.id, other.id) && + Objects.equals(this.type, other.type) && + Objects.equals(this.isGlobal, other.isGlobal) && + Objects.equals(this.elementId, other.elementId) && + Objects.equals(this.portNumber, other.portNumber) && + Objects.equals(this.parentPoint, other.parentPoint); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("elementId", elementId) + .add("portNumber", portNumber) + .add("parentPoint", parentPoint) + .add("type", type) + .add("id", id) + .add("isGlobal", isGlobal) + .toString(); + } + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnel.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnel.java new file mode 100755 index 00000000..86a790f4 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnel.java @@ -0,0 +1,178 @@ +/* + * Copyright 2014-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 static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +import com.google.common.annotations.Beta; +import org.onosproject.core.DefaultGroupId; +import org.onosproject.net.AbstractModel; +import org.onosproject.net.Annotations; +import org.onosproject.net.NetworkResource; +import org.onosproject.net.Path; +import org.onosproject.net.provider.ProviderId; + +/** + * The default implementation of an network tunnel. supports for creating a + * tunnel by connect point ,IP address, MAC address, device and so on. + */ +@Beta +public final class DefaultTunnel extends AbstractModel implements Tunnel { + + private final TunnelEndPoint src; // a source point of tunnel. + private final TunnelEndPoint dst; // a destination point of tunnel. + private final State state; + private final Type type; // tunnel type + private final DefaultGroupId groupId; // represent for a group flow table + // which a tunnel match up + // tunnel producer + private final TunnelId tunnelId; // tunnel identify generated by + // ONOS as primary key + private final TunnelName tunnelName; // name of a tunnel + private final Path path; + + /** + * Creates an active infrastructure tunnel using the supplied information. + * + * @param producerName provider identity + * @param src tunnel source + * @param dst tunnel destination + * @param type tunnel type + * @param groupId groupId + * @param tunnelId tunnelId + * @param tunnelName tunnel name + * @param path the path of tunnel + * @param annotations optional key/value annotations + */ + public DefaultTunnel(ProviderId producerName, TunnelEndPoint src, + TunnelEndPoint dst, Type type, DefaultGroupId groupId, + TunnelId tunnelId, TunnelName tunnelName, Path path, + Annotations... annotations) { + this(producerName, src, dst, type, Tunnel.State.ACTIVE, groupId, + tunnelId, tunnelName, path, annotations); + } + + /** + * Creates an tunnel using the supplied information. + * + * @param producerName provider identity + * @param src tunnel source + * @param dst tunnel destination + * @param type tunnel type + * @param state tunnel state + * @param groupId groupId + * @param tunnelId tunnelId + * @param tunnelName tunnel name + * @param path the path of tunnel + * @param annotations optional key/value annotations + */ + public DefaultTunnel(ProviderId producerName, TunnelEndPoint src, + TunnelEndPoint dst, Type type, State state, + DefaultGroupId groupId, TunnelId tunnelId, + TunnelName tunnelName, Path path, Annotations... annotations) { + super(producerName, annotations); + this.src = src; + this.dst = dst; + this.type = type; + this.state = state; + this.groupId = groupId; + this.tunnelId = tunnelId; + this.tunnelName = tunnelName; + this.path = path; + } + + @Override + public TunnelEndPoint src() { + return src; + } + + @Override + public TunnelEndPoint dst() { + return dst; + } + + @Override + public Type type() { + return type; + } + + @Override + public State state() { + return state; + } + + @Override + public NetworkResource resource() { + return null; + } + + @Override + public TunnelId tunnelId() { + return tunnelId; + } + + @Override + public DefaultGroupId groupId() { + return groupId; + } + + @Override + public TunnelName tunnelName() { + return tunnelName; + } + + + @Override + public Path path() { + return path; + } + + @Override + public int hashCode() { + return Objects.hash(src, dst, type, groupId, tunnelId, tunnelName, + state, path); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultTunnel) { + final DefaultTunnel other = (DefaultTunnel) obj; + return Objects.equals(this.src, other.src) + && Objects.equals(this.dst, other.dst) + && Objects.equals(this.type, other.type) + && Objects.equals(this.groupId, other.groupId) + && Objects.equals(this.tunnelId, other.tunnelId) + && Objects.equals(this.tunnelName, other.tunnelName) + && Objects.equals(this.state, other.state) + && Objects.equals(this.path, other.path); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this).add("src", src).add("dst", dst) + .add("type", type).add("state", state).add("groupId", groupId) + .add("producerTunnelId", tunnelId) + .add("tunnelName", tunnelName) + .add("path", path).toString(); + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnelDescription.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnelDescription.java new file mode 100755 index 00000000..055934a0 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnelDescription.java @@ -0,0 +1,130 @@ +/* + * 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; +import org.onosproject.core.DefaultGroupId; +import org.onosproject.net.AbstractDescription; +import org.onosproject.net.Path; +import org.onosproject.net.SparseAnnotations; +import org.onosproject.net.provider.ProviderId; + +import com.google.common.base.MoreObjects; + +/** + * Default implementation of immutable tunnel description entity. + */ +@Beta +public class DefaultTunnelDescription extends AbstractDescription + implements TunnelDescription { + + private final TunnelId tunnelId; + private final TunnelEndPoint src; + private final TunnelEndPoint dst; + private final Tunnel.Type type; + private final DefaultGroupId groupId; // represent for a group flow table + // which a tunnel match up + // tunnel producer + private final ProviderId producerName; // tunnel producer name + private final TunnelName tunnelName; // name of a tunnel + private final Path path; + + /** + * Creates a tunnel description using the supplied information. + * + * @param id TunnelId + * @param src TunnelPoint source + * @param dst TunnelPoint destination + * @param type tunnel type + * @param groupId groupId + * @param producerName tunnel producer + * @param tunnelName tunnel name + * @param path the path of tunnel + * @param annotations optional key/value annotations + */ + public DefaultTunnelDescription(TunnelId id, TunnelEndPoint src, + TunnelEndPoint dst, Tunnel.Type type, + DefaultGroupId groupId, + ProviderId producerName, + TunnelName tunnelName, + Path path, + SparseAnnotations... annotations) { + super(annotations); + this.tunnelId = id; + this.src = src; + this.dst = dst; + this.type = type; + this.groupId = groupId; + this.producerName = producerName; + this.tunnelName = tunnelName; + this.path = path; + } + + @Override + public TunnelId id() { + return tunnelId; + } + + @Override + public TunnelEndPoint src() { + return src; + } + + @Override + public TunnelEndPoint dst() { + return dst; + } + + @Override + public Tunnel.Type type() { + return type; + } + + @Override + public DefaultGroupId groupId() { + return groupId; + } + + @Override + public ProviderId producerName() { + return producerName; + } + + @Override + public TunnelName tunnelName() { + return tunnelName; + } + + + @Override + public Path path() { + return path; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("tunnelId", id()) + .add("src", src()) + .add("dst", dst()) + .add("type", type()) + .add("tunnelName", tunnelName()) + .add("producerName", producerName()) + .add("groupId", groupId()) + .add("path", path) + .toString(); + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnelStatistics.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnelStatistics.java new file mode 100644 index 00000000..6358ca92 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnelStatistics.java @@ -0,0 +1,168 @@ +/* + * + * * 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 java.time.Duration; +import java.util.List; + +/** + * Default implementation of immutable tunnel statistics. + */ +public final class DefaultTunnelStatistics implements TunnelStatistics { + private final TunnelId tunnelId; + private final double bwUtilization; + private final double packetLossRatio; + private final Duration flowDelay; + private final List<String> alarms; + + private DefaultTunnelStatistics(TunnelId tunnelId, + double bwUtilization, + double packetLossRatio, + Duration flowDelay, + List<String> alarms) { + this.tunnelId = tunnelId; + this.bwUtilization = bwUtilization; + this.packetLossRatio = packetLossRatio; + this.flowDelay = flowDelay; + this.alarms = alarms; + } + + private DefaultTunnelStatistics() { + this.tunnelId = null; + this.bwUtilization = 0; + this.packetLossRatio = 0; + this.flowDelay = null; + this.alarms = null; + } + + + @Override + public TunnelId id() { + return this.tunnelId; + } + + @Override + public double bandwidthUtilization() { + return this.bwUtilization; + } + + @Override + public double packetLossRate() { + return this.packetLossRatio; + } + + @Override + public Duration flowDelay() { + return this.flowDelay; + } + + + @Override + public List<String> alarms() { + return this.alarms; + } + + /** + * Builder for tunnelStatistics. + */ + public static final class Builder { + TunnelId tunnelId; + double bwUtilization; + double packetLossRatio; + Duration flowDelay; + List<String> alarms; + + public Builder() { + + } + + /** + * Set tunnel id. + * + * @param tunnelId tunnel id + * @return builder object + */ + public Builder setTunnelId(TunnelId tunnelId) { + this.tunnelId = tunnelId; + + return this; + } + + /** + * set bandwidth utilization. + * + * @param bwUtilization bandwidth utilization + * @return builder object + */ + public Builder setBwUtilization(double bwUtilization) { + this.bwUtilization = bwUtilization; + + return this; + } + + /** + * Set packet loss ratio. + * + * @param packetLossRatio packet loss ratio + * @return builder object + */ + public Builder setPacketLossRatio(double packetLossRatio) { + this.packetLossRatio = packetLossRatio; + + return this; + } + + /** + * Set flow delay. + * + * @param flowDelay flow delay + * @return builder object + */ + public Builder setFlowDelay(Duration flowDelay) { + this.flowDelay = flowDelay; + + return this; + } + + /** + * Set alarms. + * + * @param alarms alarms of a tunnel + * @return builder object + */ + public Builder setAlarms(List<String> alarms) { + this.alarms = alarms; + + return this; + } + + /** + * Creates a TunnelStatistics object. + * + * @return DefaultTunnelStatistics + */ + public DefaultTunnelStatistics build() { + return new DefaultTunnelStatistics(tunnelId, + bwUtilization, + packetLossRatio, + flowDelay, + alarms); + } + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/IpTunnelEndPoint.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/IpTunnelEndPoint.java new file mode 100644 index 00000000..ad41adf6 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/IpTunnelEndPoint.java @@ -0,0 +1,80 @@ +/* + * 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 java.util.Objects; + +import com.google.common.annotations.Beta; +import org.onlab.packet.IpAddress; + +import com.google.common.base.MoreObjects; + +/** + * Represent for a tunnel point using ip address. + */ +@Beta +public final class IpTunnelEndPoint implements TunnelEndPoint { + + private final IpAddress ip; + + /** + * Public construction is prohibited. + * @param ip ip address + */ + private IpTunnelEndPoint(IpAddress ip) { + this.ip = ip; + } + + /** + * Create a IP tunnel end point. + * @param ip IP address + * @return IpTunnelEndPoint + */ + public static IpTunnelEndPoint ipTunnelPoint(IpAddress ip) { + return new IpTunnelEndPoint(ip); + } + + /** + * Returns IP address. + * @return IP address + */ + public IpAddress ip() { + return ip; + } + + @Override + public int hashCode() { + return Objects.hash(ip); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof IpTunnelEndPoint) { + final IpTunnelEndPoint other = (IpTunnelEndPoint) obj; + return Objects.equals(this.ip, other.ip); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).add("ip", ip).toString(); + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/OpticalLogicId.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/OpticalLogicId.java new file mode 100644 index 00000000..90f5eab6 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/OpticalLogicId.java @@ -0,0 +1,81 @@ +/* + * 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 java.util.Objects; + +import com.google.common.annotations.Beta; +import com.google.common.primitives.UnsignedLongs; + +/** + * Representation of a label Id, a logical port identifier. + */ +@Beta +public final class OpticalLogicId { + /** + * Represents a logical Id. + */ + private final long logicId; + + /** + * Constructor, public creation is prohibited. + */ + private OpticalLogicId(long id) { + this.logicId = id; + } + + /** + * Returns the LabelId representing the specified long value. + * + * @param id identifier as long value + * @return LabelId + */ + public static OpticalLogicId logicId(long id) { + return new OpticalLogicId(id); + } + + public static OpticalLogicId logicId(String string) { + return new OpticalLogicId(UnsignedLongs.decode(string)); + } + + public long toLong() { + return logicId; + } + + @Override + public String toString() { + return UnsignedLongs.toString(logicId); + } + + @Override + public int hashCode() { + return Objects.hash(logicId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof OpticalLogicId) { + final OpticalLogicId other = (OpticalLogicId) obj; + return this.logicId == other.logicId; + } + return false; + } + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/OpticalTunnelEndPoint.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/OpticalTunnelEndPoint.java new file mode 100644 index 00000000..7d72398d --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/OpticalTunnelEndPoint.java @@ -0,0 +1,90 @@ +/* + * 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 java.util.Optional; + +import com.google.common.annotations.Beta; +import org.onosproject.net.Annotated; +import org.onosproject.net.ElementId; +import org.onosproject.net.NetworkResource; +import org.onosproject.net.PortNumber; +import org.onosproject.net.Provided; + +/** + * Generic representation of a logical port entity in a consistent way, + * it is used to identify e.g., ODUk timeSlot, WDM lambda, etc. + * It supports nested case. + */ +@Beta +public interface OpticalTunnelEndPoint extends TunnelEndPoint, Annotated, Provided, NetworkResource { + + /** Represents coarse tunnel point type classification. */ + public enum Type { + /** + * Signifies optical data unit-based tunnel point. + */ + TIMESLOT, + + /** + * Signifies optical wavelength-based tunnel point. + */ + LAMBDA + } + + /** + * Returns the identifier. + * + * @return identifier + */ + OpticalLogicId id(); + + /** + * Returns the parent network element to which this tunnel point belongs. + * + * @return parent network element + */ + Optional<ElementId> elementId(); + + /** + * Returns the parent network port to which this tunnel point belongs, can not be be null. + * + * @return port number + */ + Optional<PortNumber> portNumber(); + + /** + * Returns the parent tunnel point to which this tunnel point belongs, optional. + * + * @return parent tunnel point, if it is null, the parent is a physical port + */ + Optional<OpticalTunnelEndPoint> parentPoint(); + + /** + * Indicates whether or not the port is global significant. + * + * @return true if the port is global significant + */ + boolean isGlobal(); + + /** + * Returns the tunnel point type. + * + * @return tunnel point type + */ + Type type(); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/Tunnel.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/Tunnel.java new file mode 100755 index 00000000..33af106d --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/Tunnel.java @@ -0,0 +1,155 @@ +/* + * 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; +import org.onosproject.core.DefaultGroupId; +import org.onosproject.net.Annotated; +import org.onosproject.net.NetworkResource; +import org.onosproject.net.Path; +import org.onosproject.net.Provided; + +/** + * Abstraction of a generalized Tunnel entity (bandwidth pipe) for either L3/L2 + * networks or L1/L0 networks, representation of e.g., VLAN, GRE tunnel, MPLS + * LSP, L1 ODUk connection, WDM OCH, etc.. Each Tunnel is associated with at + * least two tunnel end point objects that model the logical ports essentially. + * Note that it supports nested case. + */ +@Beta +public interface Tunnel extends Annotated, Provided, NetworkResource { + + /** + * Tunnel technology type. + */ + enum Type { + /** + * Signifies that this is a MPLS tunnel. + */ + MPLS, + /** + * Signifies that this is a L2 tunnel. + */ + VLAN, + /** + * Signifies that this is a DC L2 extension tunnel. + */ + VXLAN, + /** + * Signifies that this is a L3 tunnel. + */ + GRE, + /** + * Signifies that this is a L1 OTN tunnel. + */ + ODUK, + /** + * Signifies that this is a L0 OCH tunnel. + */ + OCH + } + + /** + * Representation of the tunnel state. + */ + public enum State { + /** + * Signifies that a tunnel is currently in a initialized state. + */ + INIT, + /** + * Signifies that a tunnel is currently established but no traffic. + */ + ESTABLISHED, + /** + * Signifies that a tunnel is currently active. This state means that + * this tunnel is available. It can be borrowed by consumer. + */ + ACTIVE, + /** + * Signifies that a tunnel is currently out of service. + */ + FAILED, + /** + * Signifies that a tunnel is currently inactive. This state means that + * this tunnel can not be borrowed by consumer. + */ + INACTIVE + } + + /** + * Returns the tunnel state. + * + * @return tunnel state + */ + State state(); + + /** + * the origin of a tunnel. + * + * @return the origin of a tunnel + */ + TunnelEndPoint src(); + + /** + * the terminal of a tunnel. + * + * @return the terminal of a tunnel + */ + TunnelEndPoint dst(); + + /** + * Returns the tunnel type. + * + * @return tunnel type + */ + Type type(); + + /** + * Returns group flow table id which a tunnel match up. + * + * @return OpenFlowGroupId + */ + DefaultGroupId groupId(); + + /** + * Returns tunnel identify generated by ONOS as primary key. + * + * @return TunnelId + */ + TunnelId tunnelId(); + + /** + * Return the name of a tunnel. + * + * @return Tunnel Name + */ + TunnelName tunnelName(); + + /** + * Network resource backing the tunnel, e.g. lambda, VLAN id, MPLS tag. + * + * @return backing resource + */ + NetworkResource resource(); + + /** + * Returns the path of the tunnel. + * + * @return the path of the tunnel + */ + Path path(); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelAdminService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelAdminService.java new file mode 100644 index 00000000..5165a68e --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelAdminService.java @@ -0,0 +1,65 @@ +/* + * 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; +import org.onosproject.net.Path; +import org.onosproject.net.provider.ProviderId; + +/** + * Service for administering the inventory of provisioned tunnels. + */ +@Beta +public interface TunnelAdminService { + + /** + * Removes the provisioned tunnel. + * + * @param tunnelId tunnel ID + */ + void removeTunnel(TunnelId tunnelId); + + /** + * Removes the provisioned tunnel leading to and from the + * specified labels. + * + * @param src source label + * @param dst destination label + * @param producerName producer name + */ + void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst, ProviderId producerName); + + /** + * Removes all provisioned tunnels leading to and from the + * specified connection point. + * + * @param src source connection point + * @param dst destination connection point + * @param type tunnel type + * @param producerName producer name + */ + void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst, Tunnel.Type type, ProviderId producerName); + + /** + * Invokes the core to update a tunnel based on specified tunnel parameters. + * + * @param tunnel Tunnel + * @param path explicit route (path changed) or null (path not changed) for the tunnel + */ + void updateTunnel(Tunnel tunnel, Path path); + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelDescription.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelDescription.java new file mode 100755 index 00000000..a8408bef --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelDescription.java @@ -0,0 +1,87 @@ +/* + * 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; +import org.onosproject.core.DefaultGroupId; +import org.onosproject.incubator.net.tunnel.Tunnel.Type; +import org.onosproject.net.Annotated; +import org.onosproject.net.Description; +import org.onosproject.net.Path; +import org.onosproject.net.provider.ProviderId; + +/** + * Describes a tunnel. + */ +@Beta +public interface TunnelDescription extends Description, Annotated { + + /** + * Returns the tunnel id. + * + * @return tunnelId + */ + TunnelId id(); + + /** + * Returns the connection point source. + * + * @return tunnel source ConnectionPoint + */ + TunnelEndPoint src(); + + /** + * Returns the connection point destination. + * + * @return tunnel destination + */ + TunnelEndPoint dst(); + + /** + * Returns the tunnel type. + * + * @return tunnel type + */ + Type type(); + + /** + * Returns group flow table id which a tunnel match up. + * + * @return OpenFlowGroupId + */ + DefaultGroupId groupId(); + + /** + * Returns tunnel producer name. + * + * @return producer name + */ + ProviderId producerName(); + + /** + * Return the name of a tunnel. + * + * @return Tunnel Name + */ + TunnelName tunnelName(); + + /** + * Returns the path of the tunnel. + * + * @return the path of the tunnel + */ + Path path(); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelEndPoint.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelEndPoint.java new file mode 100644 index 00000000..55890289 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelEndPoint.java @@ -0,0 +1,28 @@ +/* + * 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; + +/** + * Represents for source end point or destination end point of a tunnel. Maybe a tunnel + * based on ConnectPoint, IpAddress, MacAddress and so on is built. + */ +@Beta +public interface TunnelEndPoint { + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelEndPointFormatter.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelEndPointFormatter.java new file mode 100644 index 00000000..964d451a --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelEndPointFormatter.java @@ -0,0 +1,33 @@ +package org.onosproject.incubator.net.tunnel; + + +import org.onosproject.ui.table.CellFormatter; +import org.onosproject.ui.table.cell.AbstractCellFormatter; + +/** + * Formats a optical tunnel endpoint as "(type)/(element-id)/(port)". + * Formats a ip tunnel endpoint as "ip". + */ +public final class TunnelEndPointFormatter extends AbstractCellFormatter { + //non-instantiable + private TunnelEndPointFormatter() { + } + + @Override + protected String nonNullFormat(Object value) { + + if (value instanceof DefaultOpticalTunnelEndPoint) { + DefaultOpticalTunnelEndPoint cp = (DefaultOpticalTunnelEndPoint) value; + return cp.type() + "/" + cp.elementId().get() + "/" + cp.portNumber().get(); + } else if (value instanceof IpTunnelEndPoint) { + IpTunnelEndPoint cp = (IpTunnelEndPoint) value; + return cp.ip().toString(); + } + return ""; + } + + /** + * An instance of this class. + */ + public static final CellFormatter INSTANCE = new TunnelEndPointFormatter(); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelEvent.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelEvent.java new file mode 100644 index 00000000..18044ee7 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelEvent.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.tunnel; + +import com.google.common.annotations.Beta; +import org.onosproject.event.AbstractEvent; + +/** + * Describes tunnel events. + */ +@Beta +public final class TunnelEvent extends AbstractEvent<TunnelEvent.Type, Tunnel> { + + /** + * Type of tunnel events. + */ + public enum Type { + /** + * Signifies that a new tunnel has been added. + */ + TUNNEL_ADDED, + + /** + * Signifies that a tunnel has been updated or changed state. + */ + TUNNEL_UPDATED, + + /** + * Signifies that a tunnel has been removed. + */ + TUNNEL_REMOVED + } + + /** + * Creates an event of a given type and for the specified tunnel. + * + * @param type tunnel event type + * @param tunnel event tunnel subject + */ + public TunnelEvent(Type type, Tunnel tunnel) { + super(type, tunnel); + } + + /** + * Creates an event of a given type and for the specified link and + * the current time. + * + * @param type tunnel event type + * @param tunnel event tunnel subject + * @param time occurrence time + */ + public TunnelEvent(Type type, Tunnel tunnel, long time) { + super(type, tunnel, time); + } + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelId.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelId.java new file mode 100644 index 00000000..5a3f97f2 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelId.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 Tunnel Id. + */ +@Beta +public final class TunnelId { + private final long value; + + /** + * Creates an tunnel identifier from the specified tunnel. + * + * @param value long value + * @return tunnel identifier + */ + public static TunnelId valueOf(long value) { + return new TunnelId(value); + } + + public static TunnelId valueOf(String value) { + return new TunnelId(Long.parseLong(value)); + } + + /** + * Constructor for serializer. + */ + TunnelId() { + this.value = 0; + } + + /** + * Constructs the ID corresponding to a given long value. + * + * @param value the underlying value of this ID + */ + TunnelId(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 TunnelId)) { + return false; + } + TunnelId that = (TunnelId) 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/TunnelListener.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelListener.java new file mode 100644 index 00000000..b3a69fd4 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelListener.java @@ -0,0 +1,27 @@ +/* + * 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; +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving tunnel related events. + */ +@Beta +public interface TunnelListener extends EventListener<TunnelEvent> { +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelName.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelName.java new file mode 100644 index 00000000..77a8c8e8 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelName.java @@ -0,0 +1,79 @@ +/* + * 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; + +import java.util.Objects; + +/** + * Represents for a unique tunnel name. TunnelId is generated by ONOS while + * TunnelName is given by producer. The consumer can borrow tunnels with + * TunnelId or TunnelName. + */ +@Beta +public final class TunnelName { + private final String str; + + // Default constructor for serialization + private TunnelName(String tunnelName) { + this.str = tunnelName; + } + + + /** + * Creates a tunnel name using the supplied URI string. + * + * @param tunnelName tunnel name string + * @return tunnel name object + */ + public static TunnelName tunnelName(String tunnelName) { + return new TunnelName(tunnelName); + } + + /** + * The string of tunnel name. + * + * @return the string of tunnel name + */ + public String value() { + return str; + } + + @Override + public int hashCode() { + return Objects.hash(str); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof TunnelName) { + final TunnelName that = (TunnelName) obj; + return this.getClass() == that.getClass() + && Objects.equals(this.str, that.str); + } + return false; + } + + @Override + public String toString() { + return str; + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProvider.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProvider.java new file mode 100644 index 00000000..5677901f --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProvider.java @@ -0,0 +1,115 @@ +/* + * 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; +import org.onosproject.net.ElementId; +import org.onosproject.net.Path; +import org.onosproject.net.provider.Provider; + +/** + * Abstraction of an entity providing tunnel setup/release services to the core. + */ +@Beta +public interface TunnelProvider extends Provider { + + /** + * Instructs the provider to setup a tunnel. It's used by consumers. + * + * @param tunnel Tunnel + * @param path explicit route or null for the tunnel + */ + void setupTunnel(Tunnel tunnel, Path path); + + /** + * Instructs the provider to setup a tunnel given the respective device. + * It's used by consumers. + * + * @param srcElement device + * @param tunnel Tunnel + * @param path explicit route (not null) for the tunnel + */ + void setupTunnel(ElementId srcElement, Tunnel tunnel, Path path); + + /** + * Instructs the provider to release a tunnel. It's used by consumers. + * + * @param tunnel Tunnel + */ + void releaseTunnel(Tunnel tunnel); + + /** + * Instructs the provider to release a tunnel given the respective device. + * It's used by consumers. + * + * @param srcElement device + * @param tunnel Tunnel + */ + void releaseTunnel(ElementId srcElement, Tunnel tunnel); + + /** + * Instructs the provider to update a tunnel. It's used by consumers. Maybe + * some consumers enable to update a tunnel. + * + * @param tunnel Tunnel + * @param path explicit route (path changed) or null (path not changed) for + * the tunnel + */ + void updateTunnel(Tunnel tunnel, Path path); + + /** + * Instructs the provider to update a tunnel given the respective device. + * It's used by consumers. Maybe some consumers enable to update a tunnel. + * + * @param srcElement device + * @param tunnel Tunnel + * @param path explicit route (path changed) or null (path not changed) for + * the tunnel + */ + void updateTunnel(ElementId srcElement, Tunnel tunnel, Path path); + + /** + * Signals that the provider has added a tunnel. It's used by producers. + * + * @param tunnel tunnel information + * @return tunnel identity + */ + TunnelId tunnelAdded(TunnelDescription tunnel); + + /** + * Signals that the provider has removed a tunnel. It's used by producers. + * + * @param tunnel tunnel information + */ + void tunnelRemoved(TunnelDescription tunnel); + + /** + * Signals that the a tunnel was changed (e.g., sensing changes of + * tunnel).It's used by producers. + * + * @param tunnel tunnel information + */ + void tunnelUpdated(TunnelDescription tunnel); + + /** + * Signals that the a tunnel was queried. + * It's used by producers. + * @param tunnelId tunnel identity + * @return tunnel entity + */ + Tunnel tunnelQueryById(TunnelId tunnelId); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProviderRegistry.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProviderRegistry.java new file mode 100644 index 00000000..069455ac --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProviderRegistry.java @@ -0,0 +1,28 @@ +/* + * 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; +import org.onosproject.net.provider.ProviderRegistry; + +/** + * Abstraction of an tunnel provider registry. + */ +@Beta +public interface TunnelProviderRegistry + extends ProviderRegistry<TunnelProvider, TunnelProviderService> { +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProviderService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProviderService.java new file mode 100644 index 00000000..bb158bfa --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProviderService.java @@ -0,0 +1,58 @@ +/* + * 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; +import org.onosproject.net.provider.ProviderService; + +/** + * APIs for tunnel provider to notify the tunnel subSystem. + */ +@Beta +public interface TunnelProviderService extends ProviderService<TunnelProvider> { + + /** + * Signals that the provider has added a tunnel. + * + * @param tunnel tunnel information + * @return tunnel identity + */ + TunnelId tunnelAdded(TunnelDescription tunnel); + + /** + * Signals that the provider has removed a tunnel. + * + * @param tunnel tunnel information + */ + void tunnelRemoved(TunnelDescription tunnel); + + /** + * Signals that the a tunnel was changed (e.g., sensing changes of tunnel). + * + * @param tunnel tunnel information + */ + void tunnelUpdated(TunnelDescription tunnel); + + /** + * Signals that the a tunnel was queried. + * + * @param tunnelId tunnel identity + * @return tunnel entity + */ + Tunnel tunnelQueryById(TunnelId tunnelId); + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelService.java new file mode 100644 index 00000000..2a10a4c1 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelService.java @@ -0,0 +1,201 @@ +/* + * 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 java.util.Collection; + +import com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; +import org.onosproject.event.ListenerService; +import org.onosproject.incubator.net.tunnel.Tunnel.Type; +import org.onosproject.net.Annotations; +import org.onosproject.net.DeviceId; + +/** + * Service for interacting with the inventory of tunnels. + */ +@Beta +public interface TunnelService + extends ListenerService<TunnelEvent, TunnelListener> { + + /** + * Borrows a specific tunnel. Annotations parameter is reserved.If there + * is no tunnel in the store, returns a "null" object, and record the tunnel subscription. + * Where tunnel is created, ONOS notifies this consumer actively. + * + * @param consumerId a tunnel consumer + * @param tunnelId tunnel identify generated by onos + * @param annotations Annotations + * @return Tunnel subscribed tunnel + */ + Tunnel borrowTunnel(ApplicationId consumerId, TunnelId tunnelId, + Annotations... annotations); + + /** + * Borrows a specific tunnel by tunnelName. Annotations parameter is reserved.If there + * is no tunnel in the store, return a "null" object, and record the tunnel subscription. + * Where tunnel is created, ONOS notifies this consumer actively. + * + * @param consumerId a tunnel consumer + * @param tunnelName tunnel name + * @param annotations Annotations + * @return collection of subscribed Tunnels + */ + Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelName tunnelName, + Annotations... annotations); + + /** + * Borrows all tunnels between source and destination. Annotations + * parameter is reserved.If there is no any tunnel in the store, return a + * empty collection,and record the tunnel subscription. Where tunnel is created, ONOS + * notifies this consumer actively. Otherwise ONOS core returns all the + * tunnels, consumer determined which one to use. + * + * @param consumerId a tunnel consumer + * @param src a source point of tunnel. + * @param dst a destination point of tunnel + * @param annotations Annotations + * @return collection of subscribed Tunnels + */ + Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelEndPoint src, + TunnelEndPoint dst, Annotations... annotations); + + /** + * Borrows all specified type tunnels between source and destination. + * Annotations parameter is reserved.If there is no any tunnel in the store, + * return a empty collection, and record the tunnel subscription. Where tunnel is + * created, ONOS notifies this consumer actively. Otherwise,ONOS core returns + * all available tunnels, consumer determined which one to use. + * + * @param consumerId a tunnel consumer + * @param src a source point of tunnel. + * @param dst a destination point of tunnel + * @param type tunnel type + * @param annotations Annotations + * @return collection of available Tunnels + */ + Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelEndPoint src, + TunnelEndPoint dst, Type type, + Annotations... annotations); + + /** + * Returns back a specific tunnel to store. + * + * @param consumerId a tunnel consumer + * @param tunnelId tunnel identify generated by ONOS + * @param annotations Annotations + * @return success or fail + */ + boolean returnTunnel(ApplicationId consumerId, TunnelId tunnelId, + Annotations... annotations); + + /** + * Returns all specific name tunnel back store. Annotations parameter is reserved.if there + * is no tunnel in the store, return a "null" object, and record the tunnel subscription. + * Where tunnel is created, ONOS notifies this consumer actively. + * + * @param consumerId a tunnel consumer + * @param tunnelName tunnel name + * @param annotations Annotations + * @return boolean + */ + boolean returnTunnel(ApplicationId consumerId, TunnelName tunnelName, + Annotations... annotations); + + /** + * Returns all specific type tunnels between source and destination back + * store. Annotations parameter is reserved. + * + * @param consumerId a tunnel consumer + * @param src a source point of tunnel. + * @param dst a destination point of tunnel + * @param type tunnel type + * @param annotations Annotations + * @return success or fail + */ + boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src, + TunnelEndPoint dst, Type type, + Annotations... annotations); + + /** + * Returns all tunnels between source and destination back the store. + * Annotations parameter is reserved. + * + * @param consumerId a tunnel consumer + * @param src a source point of tunnel. + * @param dst a destination point of tunnel. + * @param annotations Annotations + * @return success or fail + */ + boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src, + TunnelEndPoint dst, Annotations... annotations); + + /** + * Returns a tunnel by a specific tunnel identity. + * + * @param tunnelId tunnel identify generated by tunnel producer + * @return Tunnel + */ + Tunnel queryTunnel(TunnelId tunnelId); + + /** + * Returns all tunnel subscription record by consumer. + * + * @param consumerId consumer identity + * @return Collection of TunnelSubscription + */ + Collection<TunnelSubscription> queryTunnelSubscription(ApplicationId consumerId); + + /** + * Returns all specified type tunnels. + * + * @param type tunnel type + * @return Collection of tunnels + */ + Collection<Tunnel> queryTunnel(Type type); + + /** + * Returns all tunnels between source point and destination point. + * + * @param src a source point of tunnel. + * @param dst a destination point of tunnel. + * @return Collection of tunnels + */ + Collection<Tunnel> queryTunnel(TunnelEndPoint src, TunnelEndPoint dst); + + /** + * Returns all tunnels. + * + * @return Collection of tunnels + */ + Collection<Tunnel> queryAllTunnels(); + + /** + * Returns all tunnels. + * + * @return all tunnels + */ + int tunnelCount(); + + /** + * Returns the collection of tunnels applied on the specified device. + * + * @param deviceId device identifier + * @return collection of tunnels + */ + Iterable<Tunnel> getTunnels(DeviceId deviceId); + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStatistics.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStatistics.java new file mode 100644 index 00000000..650f9941 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStatistics.java @@ -0,0 +1,63 @@ +/* + * + * * 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 java.time.Duration; +import java.util.List; + +/** + * Statistics of a tunnel. + */ +public interface TunnelStatistics { + + /** + * Returns the tunnel id. + * + * @return tunnelId id of tunnel + */ + TunnelId id(); + + /** + * Returns the bandwidth utilization of a tunnel. + * + * @return bandwidth utilization + */ + double bandwidthUtilization(); + + /** + * Returns the packet loss ratio of a tunnel. + * + * @return tunnel packet loss ratio + */ + double packetLossRate(); + + /** + * Returns the end-to-end traffic flow delay of a tunnel. + * + * @return tunnel flow delay + */ + Duration flowDelay(); + + /** + * Returns the alarms on a tunnel. + * + * @return tunnel alarms + */ + List<String> alarms(); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStore.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStore.java new file mode 100644 index 00000000..00ed5776 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStore.java @@ -0,0 +1,229 @@ +/* + * 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 java.util.Collection; + +import com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; +import org.onosproject.incubator.net.tunnel.Tunnel.Type; +import org.onosproject.net.Annotations; +import org.onosproject.net.provider.ProviderId; +import org.onosproject.store.Store; + +/** + * Manages inventory of tunnel; not intended for direct use. + */ +@Beta +public interface TunnelStore extends Store<TunnelEvent, TunnelStoreDelegate> { + /** + * Creates or updates a tunnel. + * + * @param tunnel tunnel + * @return tunnel identity + */ + TunnelId createOrUpdateTunnel(Tunnel tunnel); + + /** + * Deletes a tunnel by a specific tunnel identifier. + * + * @param tunnelId tunnel unique identifier generated by ONOS + */ + void deleteTunnel(TunnelId tunnelId); + + /** + * Deletes all tunnels between source point and destination point. + * + * @param src a source point of tunnel. + * @param dst a destination point of tunnel. + * @param producerName producerName + */ + void deleteTunnel(TunnelEndPoint src, TunnelEndPoint dst, + ProviderId producerName); + + /** + * Deletes all specific type tunnels between source point and destination + * point. + * + * @param src a source point of tunnel. + * @param dst a destination point of tunnel. + * @param type tunnel type + * @param producerName producerName + */ + void deleteTunnel(TunnelEndPoint src, TunnelEndPoint dst, + Tunnel.Type type, ProviderId producerName); + + /** + * Returns a specific tunnel. Annotations parameter is reserved. If there + * is no tunnel in the store, return a "null" object, and record the tunnel subscription. + * Where tunnel is created, ONOS notifies this consumer actively. + * + * @param consumerId a tunnel consumer + * @param tunnelId tunnel identify generated by onos + * @param annotations parameter + * @return Tunnel subscribed tunnel + */ + Tunnel borrowTunnel(ApplicationId consumerId, TunnelId tunnelId, + Annotations... annotations); + + /** + * Returns a specific tunnel by tunnelName. Annotations parameter is + * reserved. If there is no tunnel in the store, return a "null" object,and + * record the tunnel subscription. Where tunnel is created, ONOS notifies this consumer + * actively. + * + * @param consumerId a tunnel consumer + * @param tunnelName tunnel name + * @param annotations parameter + * @return collection of subscribed Tunnels + */ + Collection<Tunnel> borrowTunnel(ApplicationId consumerId, + TunnelName tunnelName, + Annotations... annotations); + + /** + * Returns all tunnels between source and destination. Annotations + * parameter is reserved. If there is no any tunnel in the store, return a + * empty collection, and record the tunnel subscription. Where tunnel is created, ONOS + * notifies this consumer actively. Otherwise ONOS core returns all the + * tunnels, consumer determined which one to use. + * + * @param consumerId a tunnel consumer + * @param src a source point of tunnel. + * @param dst a destination point of tunnel + * @param annotations parameter + * @return collection of subscribed Tunnels + */ + Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelEndPoint src, + TunnelEndPoint dst, Annotations... annotations); + + /** + * Returns all specified type tunnels between source and destination. + * Annotations parameter is reserved. If there is no any tunnel in the store, + * return a empty collection, and record the tunnel subscription. Where tunnel is + * created, ONOS notifies this consumer actively. Otherwise,ONOS core returns + * all available tunnels, consumer determined which one to use. + * + * @param consumerId a tunnel consumer + * @param src a source point of tunnel. + * @param dst a destination point of tunnel + * @param type tunnel type + * @param annotations Annotations + * @return collection of available Tunnels + */ + Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelEndPoint src, + TunnelEndPoint dst, Type type, + Annotations... annotations); + + /** + * Returns back a specific tunnel to store. + * + * @param consumerId a tunnel consumer + * @param tunnelId tunnel identify generated by ONOS + * @param annotations Annotations + * @return success or fail + */ + boolean returnTunnel(ApplicationId consumerId, TunnelId tunnelId, + Annotations... annotations); + + /** + * Returns all specific name tunnel back store. Annotations parameter is + * reserved.If there is no tunnel in the store, return a "null" object,and + * record the tunnel subscription. Where tunnel is created, ONOS notifies this consumer + * actively. + * + * @param consumerId a tunnel consumer + * @param tunnelName tunnel name + * @param annotations Annotations + * @return boolean + */ + boolean returnTunnel(ApplicationId consumerId, TunnelName tunnelName, + Annotations... annotations); + + /** + * Returns all specific type tunnels between source and destination back + * store. Annotations parameter is reserved. + * + * @param consumerId a tunnel consumer + * @param src a source point of tunnel. + * @param dst a destination point of tunnel + * @param type tunnel type + * @param annotations Annotations + * @return success or fail + */ + boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src, + TunnelEndPoint dst, Type type, + Annotations... annotations); + + /** + * Returns all tunnels between source and destination back the store. + * Annotations parameter is reserved. + * + * @param consumerId a tunnel consumer + * @param src a source point of tunnel. + * @param dst a destination point of tunnel. + * @param annotations Annotations + * @return success or fail + */ + boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src, + TunnelEndPoint dst, Annotations... annotations); + + /** + * Returns a tunnel by a specific tunnel identity. + * + * @param tunnelId tunnel identify generated by tunnel producer + * @return Tunnel + */ + Tunnel queryTunnel(TunnelId tunnelId); + + /** + * Returns all tunnel subscription record by consumer. + * + * @param consumerId consumer identity + * @return Collection of TunnelSubscription + */ + Collection<TunnelSubscription> queryTunnelSubscription(ApplicationId consumerId); + + /** + * Returns all specified type tunnels. + * + * @param type tunnel type + * @return Collection of tunnels + */ + Collection<Tunnel> queryTunnel(Type type); + + /** + * Returns all tunnels between source point and destination point. + * + * @param src a source point of tunnel. + * @param dst a destination point of tunnel. + * @return Collection of tunnels + */ + Collection<Tunnel> queryTunnel(TunnelEndPoint src, TunnelEndPoint dst); + + /** + * Returns all tunnels. + * + * @return Collection of tunnels + */ + Collection<Tunnel> queryAllTunnels(); + + /** + * Returns all tunnels. + * @return all tunnels + */ + int tunnelCount(); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStoreDelegate.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStoreDelegate.java new file mode 100644 index 00000000..dfbc6ec0 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStoreDelegate.java @@ -0,0 +1,27 @@ +/* + * 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; +import org.onosproject.store.StoreDelegate; + +/** + * Tunnel store delegate abstraction. + */ +@Beta +public interface TunnelStoreDelegate extends StoreDelegate<TunnelEvent> { +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelSubscription.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelSubscription.java new file mode 100644 index 00000000..336789b1 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelSubscription.java @@ -0,0 +1,156 @@ +/* + * 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 static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Objects; + +import com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.AbstractAnnotated; +import org.onosproject.net.Annotations; +import org.onosproject.incubator.net.tunnel.Tunnel.Type; + +import com.google.common.base.MoreObjects; + +/** + * Represents for a order that consumer subscribe tunnel. ONOS maintains request + * information, it means ONOS knows how much resource echo consumer uses in the + * ONOS. Although there is no a tunnel that consumer want to use, when producer + * creates a new tunnel, ONOS will notify the consumers that want to use it. + */ +@Beta +public final class TunnelSubscription extends AbstractAnnotated { + private final ApplicationId consumerId; + private final TunnelEndPoint src; + private final TunnelEndPoint dst; + private final Type type; + private final TunnelId tunnelId; + private final TunnelName tunnelName; + + /** + * Creates a TunnelSubscription. + * + * @param consumerId consumer identity + * @param src source tunnel end point of tunnel + * @param dst destination tunnel end point of tunnel + * @param tunnelId tunnel identity + * @param type tunnel type + * @param tunnelName the name of a tunnel + * @param annotations parameter + */ + public TunnelSubscription(ApplicationId consumerId, TunnelEndPoint src, + TunnelEndPoint dst, TunnelId tunnelId, Type type, + TunnelName tunnelName, Annotations... annotations) { + super(annotations); + checkNotNull(consumerId, "consumerId cannot be null"); + this.consumerId = consumerId; + this.src = src; + this.dst = dst; + this.type = type; + this.tunnelId = tunnelId; + this.tunnelName = tunnelName; + } + + /** + * Returns consumer identity. + * + * @return consumerId consumer id + */ + public ApplicationId consumerId() { + return consumerId; + } + + /** + * Returns source point of tunnel. + * + * @return source point + */ + public TunnelEndPoint src() { + return src; + } + + /** + * Returns destination point of tunnel. + * + * @return destination point + */ + public TunnelEndPoint dst() { + return dst; + } + + /** + * Returns tunnel type. + * + * @return tunnel type + */ + public Type type() { + return type; + } + + /** + * Returns tunnel identity. + * + * @return tunnel id + */ + public TunnelId tunnelId() { + return tunnelId; + } + + /** + * Returns tunnel name. + * + * @return tunnel name + */ + public TunnelName tunnelName() { + return tunnelName; + } + + @Override + public int hashCode() { + return Objects.hash(consumerId, src, dst, type, tunnelId, tunnelName); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof TunnelSubscription) { + final TunnelSubscription other = (TunnelSubscription) obj; + return Objects.equals(this.src, other.src) + && Objects.equals(this.dst, other.dst) + && Objects.equals(this.consumerId, other.consumerId) + && Objects.equals(this.type, other.type) + && Objects.equals(this.tunnelId, other.tunnelId) + && Objects.equals(this.tunnelName, other.tunnelName); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("src", src) + .add("dst", dst) + .add("consumerId", consumerId) + .add("type", type) + .add("tunnelId", tunnelId) + .add("tunnelName", tunnelName).toString(); + } +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/package-info.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/package-info.java new file mode 100644 index 00000000..d31aab55 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/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. + */ + +/** + * Tunnel model related services and providers API definitions. + */ +package org.onosproject.incubator.net.tunnel; diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/NetworkId.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/NetworkId.java new file mode 100644 index 00000000..27123287 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/NetworkId.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.virtual; + +import com.google.common.annotations.Beta; + +import java.util.Objects; + +/** + * Representation of network identity. + */ +@Beta +public final class NetworkId { + + /** + * Represents no network, or an unspecified network. + */ + public static final NetworkId NONE = networkId(-1L); + + /** + * Represents the underlying physical network. + */ + public static final NetworkId PHYSICAL = networkId(0L); + + + private final long id; + + // Public construction is prohibited + private NetworkId(long id) { + this.id = id; + } + + + // Default constructor for serialization + protected NetworkId() { + this.id = -1; + } + + /** + * Creates a network id using the supplied backing id. + * + * @param id network id + * @return network identifier + */ + public static NetworkId networkId(long id) { + return new NetworkId(id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof NetworkId) { + final NetworkId that = (NetworkId) obj; + return this.getClass() == that.getClass() && this.id == that.id; + } + return false; + } + + @Override + public String toString() { + return Long.toString(id); + } + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/TenantId.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/TenantId.java new file mode 100644 index 00000000..a00f8807 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/TenantId.java @@ -0,0 +1,83 @@ +/* + * 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 com.google.common.annotations.Beta; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Representation of network tenant. + */ +@Beta +public final class TenantId { + + /** + * Represents no tenant, or an unspecified tenant. + */ + public static final TenantId NONE = new TenantId(); + + + private final String id; + + // Public construction is prohibited + private TenantId(String id) { + checkArgument(id != null && id.length() > 0, "Tenant ID cannot be null or empty"); + this.id = id; + } + + + // Default constructor for serialization + protected TenantId() { + this.id = ""; + } + + /** + * Creates a tenant id using the supplied backing id. + * + * @param id network id + * @return network identifier + */ + public static TenantId tenantId(String id) { + return new TenantId(id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof TenantId) { + final TenantId that = (TenantId) obj; + return this.getClass() == that.getClass() && + Objects.equals(this.id, that.id); + } + return false; + } + + @Override + public String toString() { + return id; + } + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualDevice.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualDevice.java new file mode 100644 index 00000000..59e781a3 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualDevice.java @@ -0,0 +1,26 @@ +/* + * 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 com.google.common.annotations.Beta; +import org.onosproject.net.Device; + +/** + * Abstraction of a virtual device. + */ +@Beta +public interface VirtualDevice extends VirtualElement, Device { +} 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 new file mode 100644 index 00000000..1c74b92a --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualElement.java @@ -0,0 +1,39 @@ +/* + * 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 com.google.common.annotations.Beta; + +/** + * Abstraction of a virtual element. + */ +@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. + * + * @return network identifier + */ + NetworkId networkId(); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualHost.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualHost.java new file mode 100644 index 00000000..fdea8b61 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualHost.java @@ -0,0 +1,26 @@ +/* + * 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 com.google.common.annotations.Beta; +import org.onosproject.net.Host; + +/** + * Abstraction of a virtual end-station host. + */ +@Beta +public interface VirtualHost extends VirtualElement, Host { +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualLink.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualLink.java new file mode 100644 index 00000000..ac0063fe --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualLink.java @@ -0,0 +1,26 @@ +/* + * 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 com.google.common.annotations.Beta; +import org.onosproject.net.Link; + +/** + * Abstraction of a virtual link. + */ +@Beta +public interface VirtualLink extends VirtualElement, Link { +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetwork.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetwork.java new file mode 100644 index 00000000..b28a5d3a --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetwork.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.virtual; + +import com.google.common.annotations.Beta; + +/** + * Representation of a virtual network. + */ +@Beta +public interface VirtualNetwork { + + /** + * Returns the network identifier. + * + * @return network id + */ + NetworkId id(); + + /** + * Returns the identifier of the tenant to which this virtual network belongs. + * + * @return tenant identifier + */ + TenantId tenantId(); + +} 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 new file mode 100644 index 00000000..1e3648b5 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminService.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.net.virtual; + +import com.google.common.annotations.Beta; +import org.onosproject.incubator.net.tunnel.Tunnel; +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; + +/** + * Service for managing the inventory of virtual networks. + */ +@Beta +public interface VirtualNetworkAdminService extends VirtualNetworkService { + + /** + * Registers the specified, externally generated tenant identifier. + * + * @param tenantId tenant identifier + */ + void registerTenantId(TenantId tenantId); + + /** + * Unregisters the specified, externally generated tenant identifier. + * + * @param tenantId tenant identifier + * @throws IllegalStateException if there are networks still owned by this tenant + */ + void unregisterTenantId(TenantId tenantId); + + /** + * Returns the set of tenant identifiers known to the system. + * + * @return set of known tenant identifiers + */ + Set<TenantId> getTenantIds(); + + + /** + * Creates a new virtual network for the specified tenant. + * + * @param tenantId tenant identifier + * @return newly created virtual network + */ + VirtualNetwork createVirtualNetwork(TenantId tenantId); + + /** + * Removes the specified virtual network and all its devices and links. + * + * @param networkId network identifier + */ + void removeVirtualNetwork(NetworkId networkId); + + + /** + * 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 + * @return newly created device + * @throws org.onlab.util.ItemNotFoundException if no such network found + */ + VirtualDevice createVirtualDevice(NetworkId networkId, DeviceDescription description); + + /** + * Removes the specified virtual device and all its ports and affiliated links. + * + * @param networkId network identifier + * @param deviceId device identifier + * @throws org.onlab.util.ItemNotFoundException if no such network or device found + */ + void removeVirtualDevice(NetworkId networkId, DeviceId deviceId); + + + /** + * 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 + * @return newly created virtual link + * @throws org.onlab.util.ItemNotFoundException if no such network found + */ + VirtualLink createVirtualLink(NetworkId networkId, LinkDescription description, + Tunnel realizedBy); + + // TODO: Discuss whether we should provide an alternate createVirtualLink + // which is backed by a Path instead; I'm leaning towards not doing that. + + /** + * Removes the specified virtual link. + * + * @param networkId network identifier + * @param src source connection point + * @param dst destination connection point + * @throws org.onlab.util.ItemNotFoundException if no such network or link found + */ + 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. + * + * @param networkId network identifier + * @param deviceId device identifier + * @param description port description + * @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); + + /** + * Removes the specified virtual port. + * + * @param networkId network identifier + * @param deviceId device identifier + * @param portNumber port number + * @throws org.onlab.util.ItemNotFoundException if no such network or port found + */ + void removeVirtualPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber); + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java new file mode 100644 index 00000000..01681ef4 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.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.virtual; + +import com.google.common.annotations.Beta; +import org.onosproject.net.DeviceId; + +import java.util.Set; + +/** + * Service for querying virtual network inventory. + */ +@Beta +public interface VirtualNetworkService { + + /** + * Returns a collection of all virtual networks created on behalf of the + * specified tenant. + * + * @param tenantId tenant identifier + * @return collection of networks + * @throws org.onlab.util.ItemNotFoundException if no such network found + */ + Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId); + + /** + * Returns a collection of all virtual devices in the specified network. + * + * @param networkId network identifier + * @return collection of devices + * @throws org.onlab.util.ItemNotFoundException if no such network found + */ + Set<VirtualDevice> getVirtualDevices(NetworkId networkId); + + /** + * Returns collection of all virtual links in the specified network. + * + * @param networkId network identifier + * @return collection of links + * @throws org.onlab.util.ItemNotFoundException if no such network found + */ + Set<VirtualLink> getVirtualLinks(NetworkId networkId); + + /** + * Returns list of all virtual ports of the specified device. + * + * @param networkId network identifier + * @param deviceId device identifier + * @return list of ports + * @throws org.onlab.util.ItemNotFoundException if no such network found + */ + Set<VirtualPort> getVirtualPorts(NetworkId networkId, DeviceId deviceId); + + /** + * Returns implementation of the specified service class for operating + * in the context of the given network. + * <p> + * The following services will be available: + * <ul> + * <li>{@link org.onosproject.net.device.DeviceService}</li> + * <li>{@link org.onosproject.net.link.LinkService}</li> + * <li>{@link org.onosproject.net.host.HostService}</li> + * <li>{@link org.onosproject.net.topology.TopologyService}</li> + * <li>{@link org.onosproject.net.topology.PathService}</li> + * <li>{@link org.onosproject.net.flow.FlowRuleService}</li> + * <li>{@link org.onosproject.net.flowobjective.FlowObjectiveService}</li> + * <li>{@link org.onosproject.net.intent.IntentService}</li> + * </ul> + * + * @param networkId network identifier + * @param serviceClass service class + * @param <T> type of service + * @return implementation class + * @throws org.onlab.util.ItemNotFoundException if no such network found + * @throws org.onlab.osgi.ServiceNotFoundException if no implementation found + */ + <T> T get(NetworkId networkId, Class<T> serviceClass); + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualPort.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualPort.java new file mode 100644 index 00000000..179bb2c9 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualPort.java @@ -0,0 +1,34 @@ +/* + * 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 com.google.common.annotations.Beta; +import org.onosproject.net.Port; + +/** + * Representation of a virtual port. + */ +@Beta +public interface VirtualPort extends Port { + + /** + * Returns the underlying port using which this port is realized. + * + * @return underlying port which realizes this virtual port + */ + Port realizedBy(); + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/package-info.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/package-info.java new file mode 100644 index 00000000..3a0676a5 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/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. + */ + +/** + * Network virtualization data models and services. + */ +package org.onosproject.incubator.net.virtual;
\ No newline at end of file diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/package-info.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/package-info.java new file mode 100644 index 00000000..6aedd3b2 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/package-info.java @@ -0,0 +1,21 @@ +/* + * 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. + */ + +/** + * Incubating abstractions and APIs. This subsystem is + * experimental and its interfaces will change in the upcoming release. + */ +package org.onosproject.incubator;
\ No newline at end of file diff --git a/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/config/basics/OpticalPortConfigTest.java b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/config/basics/OpticalPortConfigTest.java new file mode 100644 index 00000000..9d56ca23 --- /dev/null +++ b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/config/basics/OpticalPortConfigTest.java @@ -0,0 +1,142 @@ +package org.onosproject.incubator.net.config.basics; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.onosproject.net.config.basics.OpticalPortConfig.TYPE; +import static org.onosproject.net.config.basics.OpticalPortConfig.NAME; +import static org.onosproject.net.config.basics.OpticalPortConfig.PORT; +import static org.onosproject.net.config.basics.OpticalPortConfig.STATIC_LAMBDA; +import static org.onosproject.net.config.basics.OpticalPortConfig.STATIC_PORT; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.onosproject.net.config.Config; +import org.onosproject.net.config.ConfigApplyDelegate; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.Lists; +import org.onosproject.net.config.basics.OpticalPortConfig; + +public class OpticalPortConfigTest { + private static final String FIELD = "ports"; + private static final String KEY = "opc-test"; + + private static final DeviceId DID = DeviceId.deviceId(KEY); + private static final PortNumber PN = PortNumber.portNumber(100); + private static final ConnectPoint CPT = new ConnectPoint(DID, PN); + private static final String DEMOTREE = "{" + + "\"ports\": [" + + // config entity 0 + "{" + + "\"name\": \"1-10-E1_WPORT\"," + + "\"type\": \"OMS\"" + + "}," + + // config entity 1 + "{" + + "\"type\": \"OCH\"," + + "\"speed\": 0," + + "\"port\": 10" + + "}," + + // config entity 2 + "{" + + "\"name\": \"1-1-E1_LPORT\"," + + "\"type\": \"OCH\"," + + "\"annotations\": {" + + "\"staticLambda\": 1," + + "\"staticPort\": \"1-22-E1_WPORT\"" + + "}" + + "}" + + "]" + + "}"; + + private final ConfigApplyDelegate delegate = new MockCfgDelegate(); + private final ObjectMapper mapper = new ObjectMapper(); + + // one OPC per port in DEMOTREE + private List<OpticalPortConfig> opcl = Lists.newArrayList(); + // JsonNodes representing each port. + private List<JsonNode> testNodes = Lists.newArrayList(); + + @Before + public void setUp() { + try { + JsonNode tree = new ObjectMapper().readTree(DEMOTREE); + Iterator<JsonNode> pitr = tree.get(FIELD).elements(); + while (pitr.hasNext()) { + // initialize a config entity, add to lists + JsonNode jn = pitr.next(); + OpticalPortConfig opc = new OpticalPortConfig(); + ObjectNode node = JsonNodeFactory.instance.objectNode(); + opc.init(CPT, KEY, node, mapper, delegate); + + testNodes.add(jn); + opcl.add(opc); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Test + public void testBaseAttrs() { + // configs 0 and 1 - port with and without alphanumeric names + OpticalPortConfig op0 = opcl.get(0); + OpticalPortConfig op1 = opcl.get(1); + // config 2 - no name + OpticalPortConfig op2 = opcl.get(2); + JsonNode jn0 = testNodes.get(0); + JsonNode jn1 = testNodes.get(1); + + op0.portType(Port.Type.valueOf(jn0.path(TYPE).asText())) + .portName(jn0.path(NAME).asText()); + op1.portType(Port.Type.valueOf(jn1.path(TYPE).asText())) + .portNumberName(jn1.path(PORT).asLong()); + + assertEquals(Port.Type.OMS, op0.type()); + assertEquals(jn0.path(NAME).asText(), op0.name()); + assertEquals(jn1.path(PORT).asText(), op1.numberName()); + assertEquals("", op1.name()); + assertEquals("", op2.name()); + } + + @Test + public void testAdditionalAttrs() { + // config 1 has no annotations, 2 has predefined ones + OpticalPortConfig op1 = opcl.get(1); + OpticalPortConfig op2 = opcl.get(2); + JsonNode jn2 = testNodes.get(2); + Long sl = 1L; + + // see config entity 2 in DEMOTREE + op2.staticLambda(jn2.path("annotations").path(STATIC_LAMBDA).asLong()); + op2.staticPort(jn2.path("annotations").path(STATIC_PORT).asText()); + + assertEquals(sl, op2.staticLambda().get()); + assertFalse(op1.staticLambda().isPresent()); + assertEquals("1-22-E1_WPORT", op2.staticPort()); + assertEquals("", op1.staticPort()); + + op2.staticLambda(null); + assertFalse(op2.staticLambda().isPresent()); + } + + private class MockCfgDelegate implements ConfigApplyDelegate { + + @Override + public void onApply(@SuppressWarnings("rawtypes") Config config) { + config.apply(); + } + + } +} diff --git a/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/resource/label/DefaultLabelResourceTest.java b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/resource/label/DefaultLabelResourceTest.java new file mode 100644 index 00000000..5d7c02fc --- /dev/null +++ b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/resource/label/DefaultLabelResourceTest.java @@ -0,0 +1,31 @@ +package org.onosproject.incubator.net.resource.label; + +import org.junit.Test; +import org.onosproject.event.AbstractEventTest; + +import com.google.common.testing.EqualsTester; + +/** + * Tests of default label resource. + */ +public class DefaultLabelResourceTest extends AbstractEventTest { + + @Test + public void testEquality() { + String deviceId1 = "of:001"; + String deviceId2 = "of:002"; + long labelResourceId1 = 100; + long labelResourceId2 = 200; + DefaultLabelResource h1 = new DefaultLabelResource(deviceId1, + labelResourceId1); + DefaultLabelResource h2 = new DefaultLabelResource(deviceId1, + labelResourceId1); + DefaultLabelResource h3 = new DefaultLabelResource(deviceId2, + labelResourceId2); + DefaultLabelResource h4 = new DefaultLabelResource(deviceId2, + labelResourceId2); + + new EqualsTester().addEqualityGroup(h1, h2).addEqualityGroup(h3, h4) + .testEquals(); + } +} diff --git a/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/resource/label/LabelResourcePoolTest.java b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/resource/label/LabelResourcePoolTest.java new file mode 100644 index 00000000..87835080 --- /dev/null +++ b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/resource/label/LabelResourcePoolTest.java @@ -0,0 +1,23 @@ +package org.onosproject.incubator.net.resource.label; + +import org.junit.Test; +import org.onosproject.event.AbstractEventTest; + +import com.google.common.testing.EqualsTester; + +/** + * Tests of the label resource pool. + */ +public class LabelResourcePoolTest extends AbstractEventTest { + + @Test + public void testEquality() { + LabelResourcePool h1 = new LabelResourcePool("of:001", 0, 100); + LabelResourcePool h2 = new LabelResourcePool("of:001", 0, 100); + LabelResourcePool h3 = new LabelResourcePool("of:002", 0, 100); + LabelResourcePool h4 = new LabelResourcePool("of:002", 0, 100); + new EqualsTester().addEqualityGroup(h1, h2).addEqualityGroup(h3, h4) + .testEquals(); + } + +} diff --git a/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/resource/label/LabelResourceRequestTest.java b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/resource/label/LabelResourceRequestTest.java new file mode 100644 index 00000000..1b08f7c0 --- /dev/null +++ b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/resource/label/LabelResourceRequestTest.java @@ -0,0 +1,44 @@ +package org.onosproject.incubator.net.resource.label; + +import java.util.Collections; + +import org.junit.Test; +import org.onosproject.event.AbstractEventTest; +import org.onosproject.net.DeviceId; + +import com.google.common.collect.ImmutableSet; +import com.google.common.testing.EqualsTester; + +/** + * Tests of the label resource request. + */ +public class LabelResourceRequestTest extends AbstractEventTest { + + @Test + public void testEquality() { + DeviceId deviceId1 = DeviceId.deviceId("of:0001"); + DeviceId deviceId2 = DeviceId.deviceId("of:0002"); + long apply = 2; + ImmutableSet<LabelResource> releaseCollection = ImmutableSet + .copyOf(Collections.emptySet()); + LabelResourceRequest h1 = new LabelResourceRequest( + deviceId1, + LabelResourceRequest.Type.APPLY, + apply, null); + LabelResourceRequest h2 = new LabelResourceRequest( + deviceId1, + LabelResourceRequest.Type.APPLY, + apply, null); + LabelResourceRequest h3 = new LabelResourceRequest( + deviceId2, + LabelResourceRequest.Type.RELEASE, + 0, releaseCollection); + LabelResourceRequest h4 = new LabelResourceRequest( + deviceId2, + LabelResourceRequest.Type.RELEASE, + 0, releaseCollection); + + new EqualsTester().addEqualityGroup(h1, h2).addEqualityGroup(h3, h4) + .testEquals(); + } +} diff --git a/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/DefaultTunnelTest.java b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/DefaultTunnelTest.java new file mode 100644 index 00000000..ae94991f --- /dev/null +++ b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/DefaultTunnelTest.java @@ -0,0 +1,47 @@ +package org.onosproject.incubator.net.tunnel; + +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onosproject.core.DefaultGroupId; +import org.onosproject.net.provider.ProviderId; + +import com.google.common.testing.EqualsTester; + +/** + * Test of the default tunnel model entity. + */ +public class DefaultTunnelTest { + /** + * Checks that the Order class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(DefaultTunnel.class); + } + + @Test + public void testEquality() { + TunnelEndPoint src = IpTunnelEndPoint.ipTunnelPoint(IpAddress + .valueOf(23423)); + TunnelEndPoint dst = IpTunnelEndPoint.ipTunnelPoint(IpAddress + .valueOf(32421)); + DefaultGroupId groupId = new DefaultGroupId(92034); + TunnelName tunnelName = TunnelName.tunnelName("TunnelName"); + TunnelId tunnelId = TunnelId.valueOf(41654654); + ProviderId producerName1 = new ProviderId("producer1", "13"); + ProviderId producerName2 = new ProviderId("producer2", "13"); + Tunnel p1 = new DefaultTunnel(producerName1, src, dst, Tunnel.Type.VXLAN, + Tunnel.State.ACTIVE, groupId, tunnelId, + tunnelName, null); + Tunnel p2 = new DefaultTunnel(producerName1, src, dst, Tunnel.Type.VXLAN, + Tunnel.State.ACTIVE, groupId, tunnelId, + tunnelName, null); + Tunnel p3 = new DefaultTunnel(producerName2, src, dst, Tunnel.Type.OCH, + Tunnel.State.ACTIVE, groupId, tunnelId, + tunnelName, null); + new EqualsTester().addEqualityGroup(p1, p2).addEqualityGroup(p3) + .testEquals(); + } +} diff --git a/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelEventTest.java b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelEventTest.java new file mode 100644 index 00000000..a58e10b5 --- /dev/null +++ b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelEventTest.java @@ -0,0 +1,46 @@ +package org.onosproject.incubator.net.tunnel; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onosproject.core.DefaultGroupId; +import org.onosproject.net.provider.ProviderId; + +/** + * Test of a tunnel event. + */ +public class TunnelEventTest { + /** + * Checks that the Order class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(TunnelEvent.class); + } + + /** + * Checks the operation of equals(), hashCode() and toString() methods. + */ + @Test + public void testConstructor() { + TunnelEndPoint src = IpTunnelEndPoint.ipTunnelPoint(IpAddress + .valueOf(23423)); + TunnelEndPoint dst = IpTunnelEndPoint.ipTunnelPoint(IpAddress + .valueOf(32421)); + DefaultGroupId groupId = new DefaultGroupId(92034); + TunnelName tunnelName = TunnelName.tunnelName("TunnelName"); + TunnelId tunnelId = TunnelId.valueOf(41654654); + ProviderId producerName1 = new ProviderId("producer1", "13"); + Tunnel p1 = new DefaultTunnel(producerName1, src, dst, Tunnel.Type.VXLAN, + Tunnel.State.ACTIVE, groupId, tunnelId, + tunnelName, null); + TunnelEvent e1 = new TunnelEvent(TunnelEvent.Type.TUNNEL_ADDED, p1); + assertThat(e1, is(notNullValue())); + assertThat(e1.type(), is(TunnelEvent.Type.TUNNEL_ADDED)); + assertThat(e1.subject(), is(p1)); + } +} diff --git a/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelIdTest.java b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelIdTest.java new file mode 100644 index 00000000..f4c109f9 --- /dev/null +++ b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelIdTest.java @@ -0,0 +1,66 @@ +/* + * 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 static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for tunnel id class. + */ +public class TunnelIdTest { + + final TunnelId tunnelId1 = TunnelId.valueOf(1); + final TunnelId sameAstunnelId1 = TunnelId.valueOf(1); + final TunnelId tunnelId2 = TunnelId.valueOf(2); + + /** + * Checks that the TunnelId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(TunnelId.class); + } + + /** + * Checks the operation of equals(), hashCode() and toString() methods. + */ + @Test + public void testEquals() { + new EqualsTester() + .addEqualityGroup(tunnelId1, sameAstunnelId1) + .addEqualityGroup(tunnelId2) + .testEquals(); + } + + /** + * Checks the construction of a FlowId object. + */ + @Test + public void testConstruction() { + final long tunnelIdValue = 7777L; + final TunnelId tunnelId = TunnelId.valueOf(tunnelIdValue); + assertThat(tunnelId, is(notNullValue())); + assertThat(tunnelId.id(), is(tunnelIdValue)); + } +} diff --git a/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelNameTest.java b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelNameTest.java new file mode 100644 index 00000000..d0fc49c7 --- /dev/null +++ b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelNameTest.java @@ -0,0 +1,64 @@ +/* + * 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 static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for tunnel name class. + */ +public class TunnelNameTest { + final TunnelName name1 = TunnelName.tunnelName("name1"); + final TunnelName sameAsName1 = TunnelName.tunnelName("name1"); + final TunnelName name2 = TunnelName.tunnelName("name2"); + + /** + * Checks that the TunnelName class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(TunnelName.class); + } + + /** + * Checks the operation of equals(), hashCode() and toString() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(name1, sameAsName1) + .addEqualityGroup(name2).testEquals(); + } + + /** + * Checks the construction of a OpenFlowGroupId object. + */ + @Test + public void testConstruction() { + final String nameValue = "name3"; + final TunnelName name = TunnelName.tunnelName(nameValue); + assertThat(name, is(notNullValue())); + assertThat(name.value(), is(nameValue)); + } + +} diff --git a/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelSubscriptionTest.java b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelSubscriptionTest.java new file mode 100644 index 00000000..46634c7c --- /dev/null +++ b/framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelSubscriptionTest.java @@ -0,0 +1,58 @@ +/* + * 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 static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.DefaultApplicationId; + +import com.google.common.testing.EqualsTester; + +/** + * Test of order model entity. + */ +public class TunnelSubscriptionTest { + /** + * Checks that the Order class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(TunnelSubscription.class); + } + + /** + * Checks the operation of equals(), hashCode() and toString() methods. + */ + @Test + public void testEquality() { + TunnelEndPoint src = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(23423)); + TunnelEndPoint dst = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(32421)); + ApplicationId appId = new DefaultApplicationId(243, "test"); + ApplicationId appId2 = new DefaultApplicationId(2431, "test1"); + TunnelId tunnelId = TunnelId.valueOf(41654654); + TunnelSubscription p1 = new TunnelSubscription(appId, src, dst, tunnelId, Tunnel.Type.VXLAN, + null); + TunnelSubscription p2 = new TunnelSubscription(appId, src, dst, tunnelId, Tunnel.Type.VXLAN, + null); + TunnelSubscription p3 = new TunnelSubscription(appId2, src, dst, tunnelId, Tunnel.Type.VXLAN, + null); + new EqualsTester().addEqualityGroup(p1, p2).addEqualityGroup(p3) + .testEquals(); + } +} diff --git a/framework/src/onos/incubator/net/pom.xml b/framework/src/onos/incubator/net/pom.xml new file mode 100644 index 00000000..a0b5391d --- /dev/null +++ b/framework/src/onos/incubator/net/pom.xml @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-incubator</artifactId> + <version>1.3.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>onos-incubator-net</artifactId> + <packaging>bundle</packaging> + + <description>ONOS incubating network control core subsystems</description> + + <dependencies> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-incubator-api</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-core-common</artifactId> + <version>${project.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-core-serializers</artifactId> + <version>${project.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-core-common</artifactId> + </dependency> + + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymock</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.scr.annotations</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.karaf.features</groupId> + <artifactId>org.apache.karaf.features.core</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.karaf.system</groupId> + <artifactId>org.apache.karaf.system.core</artifactId> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-incubator-store</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-scr-plugin</artifactId> + </plugin> + </plugins> + </build> + +</project> diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/config/impl/ExtraNetworkConfigs.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/config/impl/ExtraNetworkConfigs.java new file mode 100644 index 00000000..e77e1da0 --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/config/impl/ExtraNetworkConfigs.java @@ -0,0 +1,69 @@ +/* + * 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.config.impl; + +import com.google.common.collect.ImmutableSet; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.onosproject.incubator.net.domain.IntentDomainConfig; +import org.onosproject.incubator.net.domain.IntentDomainId; +import org.onosproject.net.config.ConfigFactory; +import org.onosproject.net.config.NetworkConfigRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Set; + +import static org.onosproject.incubator.net.config.basics.ExtraSubjectFactories.INTENT_DOMAIN_SUBJECT_FACTORY; + +/** + * Component for registration of builtin basic network configurations. + */ +@Component(immediate = true) +public class ExtraNetworkConfigs { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final Set<ConfigFactory> factories = ImmutableSet.of( + new ConfigFactory<IntentDomainId, IntentDomainConfig>(INTENT_DOMAIN_SUBJECT_FACTORY, + IntentDomainConfig.class, + "basic") { + @Override + public IntentDomainConfig createConfig() { + return new IntentDomainConfig(); + } + } + ); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected NetworkConfigRegistry registry; + + @Activate + public void activate() { + factories.forEach(registry::registerConfigFactory); + log.info("Started"); + } + + @Deactivate + public void deactivate() { + factories.forEach(registry::unregisterConfigFactory); + log.info("Stopped"); + } + +} diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/config/impl/package-info.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/config/impl/package-info.java new file mode 100644 index 00000000..a2375429 --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/config/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 network configuration subsystem. + */ +package org.onosproject.incubator.net.config.impl;
\ No newline at end of file diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/domain/impl/IntentDomainManager.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/domain/impl/IntentDomainManager.java new file mode 100644 index 00000000..33c8a3c5 --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/domain/impl/IntentDomainManager.java @@ -0,0 +1,210 @@ +/* + * 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.impl; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; +import com.google.common.collect.Sets; +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.graph.AdjacencyListsGraph; +import org.onlab.graph.Graph; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.net.config.NetworkConfigEvent; +import org.onosproject.net.config.NetworkConfigListener; +import org.onosproject.net.config.NetworkConfigService; +import org.onosproject.incubator.net.domain.DomainEdge; +import org.onosproject.incubator.net.domain.DomainVertex; +import org.onosproject.incubator.net.domain.IntentDomain; +import org.onosproject.incubator.net.domain.IntentDomainAdminService; +import org.onosproject.incubator.net.domain.IntentDomainConfig; +import org.onosproject.incubator.net.domain.IntentDomainId; +import org.onosproject.incubator.net.domain.IntentDomainListener; +import org.onosproject.incubator.net.domain.IntentDomainProvider; +import org.onosproject.incubator.net.domain.IntentDomainService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; +import java.util.stream.Collectors; + +/** + * Implementation of the intent domain service. + */ +@Component(immediate = true) +@Service +public class IntentDomainManager + implements IntentDomainService, IntentDomainAdminService { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected NetworkConfigService configService; + + private NetworkConfigListener cfgListener = new InternalConfigListener(); + + private final ConcurrentMap<IntentDomainId, IntentDomain> domains = Maps.newConcurrentMap(); + + private final Multimap<String, IntentDomainId> appToDomain = + Multimaps.synchronizedSetMultimap(HashMultimap.<String, IntentDomainId>create()); + + private Graph<DomainVertex, DomainEdge> graph; + + @Activate + protected void activate() { + configService.addListener(cfgListener); + configService.getSubjects(IntentDomainId.class, IntentDomainConfig.class) + .forEach(this::processConfig); + graph = buildGraph(); + log.debug("Graph: {}", graph); + log.info("Started"); + } + + private void processConfig(IntentDomainId intentDomainId) { + IntentDomainConfig cfg = configService.getConfig(intentDomainId, + IntentDomainConfig.class); + + domains.put(intentDomainId, createDomain(intentDomainId, cfg)); + appToDomain.put(cfg.applicationName(), intentDomainId); + } + + private IntentDomain createDomain(IntentDomainId id, IntentDomainConfig cfg) { + return new IntentDomain(id, cfg.domainName(), cfg.internalDevices(), cfg.edgePorts()); + } + + private Graph<DomainVertex, DomainEdge> buildGraph() { + Set<DomainVertex> vertices = Sets.newHashSet(); + Set<DomainEdge> edges = Sets.newHashSet(); + + Map<DeviceId, DomainVertex> deviceVertices = Maps.newHashMap(); + domains.forEach((id, domain) -> { + DomainVertex domainVertex = new DomainVertex(id); + + // Add vertex for domain + vertices.add(domainVertex); + + // Add vertices for connection devices + domain.edgePorts().stream() + .map(ConnectPoint::deviceId) + .collect(Collectors.toSet()) + .forEach(did -> deviceVertices.putIfAbsent(did, new DomainVertex(did))); + + // Add bi-directional edges between each domain and connection device + domain.edgePorts().forEach(cp -> { + DomainVertex deviceVertex = deviceVertices.get(cp.deviceId()); + edges.add(new DomainEdge(domainVertex, deviceVertex, cp)); + edges.add(new DomainEdge(deviceVertex, domainVertex, cp)); + }); + }); + + vertices.addAll(deviceVertices.values()); + //FIXME verify graph integrity... + return new AdjacencyListsGraph<>(vertices, edges); + } + + @Deactivate + protected void deactivate() { + configService.removeListener(cfgListener); + log.info("Stopped"); + } + + @Override + public IntentDomain getDomain(IntentDomainId id) { + return domains.get(id); + } + + @Override + public Set<IntentDomain> getDomains() { + return ImmutableSet.copyOf(domains.values()); + } + + @Override + public Set<IntentDomain> getDomains(DeviceId deviceId) { + return domains.values().stream() + .filter(domain -> + domain.internalDevices().contains(deviceId) || + domain.edgePorts().stream() + .map(ConnectPoint::deviceId) + .anyMatch(d -> d.equals(deviceId))) + .collect(Collectors.toSet()); + } + + @Override + public Graph<DomainVertex, DomainEdge> getDomainGraph() { + return graph; + } + + @Override + public void addListener(IntentDomainListener listener) { + //TODO slide in AbstractListenerManager + } + + @Override + public void removeListener(IntentDomainListener listener) { + //TODO slide in AbstractListenerManager + } + + @Override + public void registerApplication(ApplicationId applicationId, IntentDomainProvider provider) { + appToDomain.get(applicationId.name()).forEach(d -> domains.get(d).setProvider(provider)); + } + + @Override + public void unregisterApplication(ApplicationId applicationId) { + appToDomain.get(applicationId.name()).forEach(d -> domains.get(d).unsetProvider()); + } + + private class InternalConfigListener implements NetworkConfigListener { + @Override + public void event(NetworkConfigEvent event) { + switch (event.type()) { + case CONFIG_ADDED: + case CONFIG_UPDATED: + processConfig((IntentDomainId) event.subject()); + graph = buildGraph(); + log.debug("Graph: {}", graph); + break; + + case CONFIG_REGISTERED: + case CONFIG_UNREGISTERED: + case CONFIG_REMOVED: + default: + //TODO + break; + } + } + + @Override + public boolean isRelevant(NetworkConfigEvent event) { + return event.configClass().equals(IntentDomainConfig.class); + } + } +} diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/domain/impl/package-info.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/domain/impl/package-info.java new file mode 100644 index 00000000..8fe3a3c6 --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/domain/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 intent domain subsystem. + */ +package org.onosproject.incubator.net.domain.impl;
\ No newline at end of file diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/impl/PortStatisticsManager.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/impl/PortStatisticsManager.java new file mode 100644 index 00000000..1a615481 --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/impl/PortStatisticsManager.java @@ -0,0 +1,162 @@ +/* + * 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.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; +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.PortStatisticsService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.device.DeviceEvent; +import org.onosproject.net.device.DeviceListener; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.device.PortStatistics; +import org.onosproject.net.statistic.DefaultLoad; +import org.onosproject.net.statistic.Load; +import org.slf4j.Logger; + +import java.util.Map; +import java.util.stream.Collectors; + +import static org.onosproject.net.PortNumber.portNumber; +import static org.onosproject.net.device.DeviceEvent.Type.*; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Implementation of the port statistics service. + */ +@Component(immediate = true) +@Service +public class PortStatisticsManager implements PortStatisticsService { + + private final Logger log = getLogger(getClass()); + + private static final long POLL_FREQUENCY = 10_000; // milliseconds + private static final long STALE_LIMIT = (long) (1.5 * POLL_FREQUENCY); + private static final int SECOND = 1_000; // milliseconds + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DeviceService deviceService; + + private final DeviceListener deviceListener = new InternalDeviceListener(); + + private Map<ConnectPoint, DataPoint> current = Maps.newConcurrentMap(); + private Map<ConnectPoint, DataPoint> previous = Maps.newConcurrentMap(); + + @Activate + public void activate() { + deviceService.addListener(deviceListener); + log.info("Started"); + } + + @Deactivate + public void deactivate() { + deviceService.removeListener(deviceListener); + log.info("Stopped"); + } + + @Override + public Load load(ConnectPoint connectPoint) { + DataPoint c = current.get(connectPoint); + DataPoint p = previous.get(connectPoint); + long now = System.currentTimeMillis(); + + if (c != null && p != null && (now - c.time < STALE_LIMIT)) { + if (c.time > p.time + SECOND) { + //Use max of either Tx or Rx load as the total load of a port + Load load = null; + if (c.stats.bytesSent() >= p.stats.bytesSent()) { + load = new DefaultLoad(c.stats.bytesSent(), p.stats.bytesSent(), + (int) (c.time - p.time) / SECOND); + } + if (c.stats.bytesReceived() >= p.stats.bytesReceived()) { + Load rcvLoad = new DefaultLoad(c.stats.bytesReceived(), p.stats.bytesReceived(), + (int) (c.time - p.time) / SECOND); + load = ((load == null) || (rcvLoad.rate() > load.rate())) ? rcvLoad : load; + } + return load; + } + } + return null; + } + + // Monitors port stats update messages. + private class InternalDeviceListener implements DeviceListener { + @Override + public void event(DeviceEvent event) { + DeviceEvent.Type type = event.type(); + DeviceId deviceId = event.subject().id(); + if (type == PORT_STATS_UPDATED) { + // Update port load + updateDeviceData(deviceId); + + } else if (type == DEVICE_REMOVED || + (type == DEVICE_AVAILABILITY_CHANGED && + !deviceService.isAvailable(deviceId))) { + // Clean-up all port loads + pruneDeviceData(deviceId); + } + } + } + + // Updates the port stats for the specified device + private void updateDeviceData(DeviceId deviceId) { + deviceService.getPortStatistics(deviceId) + .forEach(stats -> updatePortData(deviceId, stats)); + } + + // Updates the port stats for the specified port + private void updatePortData(DeviceId deviceId, PortStatistics stats) { + ConnectPoint cp = new ConnectPoint(deviceId, portNumber(stats.port())); + DataPoint c = current.get(cp); + + // Create a new data point and make it the current one + current.put(cp, new DataPoint(stats)); + + // If we have a current data point, demote it to previous + if (c != null) { + previous.put(cp, c); + } + } + + // Cleans all port loads for the specified device + private void pruneDeviceData(DeviceId deviceId) { + pruneMap(current, deviceId); + pruneMap(previous, deviceId); + } + + private void pruneMap(Map<ConnectPoint, DataPoint> map, DeviceId deviceId) { + map.keySet().stream().filter(cp -> deviceId.equals(cp.deviceId())) + .collect(Collectors.toSet()).forEach(map::remove); + } + + // Auxiliary data point to track when we receive different samples. + private class DataPoint { + long time; + PortStatistics stats; + + DataPoint(PortStatistics stats) { + time = System.currentTimeMillis(); + this.stats = stats; + } + } + +} diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/impl/package-info.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/impl/package-info.java new file mode 100644 index 00000000..842a58fb --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/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. + */ + +/** + * Implementations of incubating core subsystems. + */ +package org.onosproject.incubator.net.impl;
\ No newline at end of file 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 new file mode 100644 index 00000000..f82cdbf2 --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/intf/impl/InterfaceManager.java @@ -0,0 +1,184 @@ +/* + * 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.impl; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.packet.IpAddress; +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.InterfaceService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.config.NetworkConfigEvent; +import org.onosproject.net.config.NetworkConfigListener; +import org.onosproject.net.config.NetworkConfigService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collections; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toSet; + +/** + * Manages the inventory of interfaces in the system. + */ +@Service +@Component(immediate = true) +public class InterfaceManager implements InterfaceService { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private static final Class<ConnectPoint> SUBJECT_CLASS = ConnectPoint.class; + private static final Class<InterfaceConfig> CONFIG_CLASS = InterfaceConfig.class; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected NetworkConfigService configService; + + private final InternalConfigListener listener = new InternalConfigListener(); + + private final Map<ConnectPoint, Set<Interface>> interfaces = Maps.newConcurrentMap(); + + @Activate + public void activate() { + configService.addListener(listener); + + // TODO address concurrency issues here + for (ConnectPoint subject : configService.getSubjects(SUBJECT_CLASS, CONFIG_CLASS)) { + InterfaceConfig config = configService.getConfig(subject, CONFIG_CLASS); + + if (config != null) { + updateInterfaces(config); + } + } + + log.info("Started"); + } + + @Deactivate + public void deactivate() { + configService.removeListener(listener); + + log.info("Stopped"); + } + + @Override + public Set<Interface> getInterfaces() { + return interfaces.values() + .stream() + .flatMap(set -> set.stream()) + .collect(collectingAndThen(toSet(), ImmutableSet::copyOf)); + } + + @Override + public Set<Interface> getInterfacesByPort(ConnectPoint port) { + Set<Interface> intfs = interfaces.get(port); + if (intfs == null) { + return Collections.emptySet(); + } + return ImmutableSet.copyOf(intfs); + } + + @Override + public Set<Interface> getInterfacesByIp(IpAddress ip) { + return interfaces.values() + .stream() + .flatMap(set -> set.stream()) + .filter(intf -> intf.ipAddresses() + .stream() + .anyMatch(ia -> ia.ipAddress().equals(ip))) + .collect(collectingAndThen(toSet(), ImmutableSet::copyOf)); + } + + @Override + public Interface getMatchingInterface(IpAddress ip) { + Optional<Interface> match = interfaces.values() + .stream() + .flatMap(set -> set.stream()) + .filter(intf -> intf.ipAddresses() + .stream() + .anyMatch(intfIp -> intfIp.subnetAddress().contains(ip))) + .findFirst(); + + if (match.isPresent()) { + return match.get(); + } + + return null; + } + + @Override + public Set<Interface> getInterfacesByVlan(VlanId vlan) { + return interfaces.values() + .stream() + .flatMap(set -> set.stream()) + .filter(intf -> intf.vlan().equals(vlan)) + .collect(collectingAndThen(toSet(), ImmutableSet::copyOf)); + } + + private void updateInterfaces(InterfaceConfig intfConfig) { + try { + interfaces.put(intfConfig.subject(), intfConfig.getInterfaces()); + } catch (ConfigException e) { + log.error("Error in interface config", e); + } + } + + private void removeInterfaces(ConnectPoint port) { + interfaces.remove(port); + } + + /** + * Listener for network config events. + */ + private class InternalConfigListener implements NetworkConfigListener { + + @Override + public void event(NetworkConfigEvent event) { + switch (event.type()) { + case CONFIG_ADDED: + case CONFIG_UPDATED: + if (event.configClass() == InterfaceConfig.class) { + InterfaceConfig config = + configService.getConfig((ConnectPoint) event.subject(), InterfaceConfig.class); + updateInterfaces(config); + } + break; + case CONFIG_REMOVED: + if (event.configClass() == InterfaceConfig.class) { + removeInterfaces((ConnectPoint) event.subject()); + } + break; + case CONFIG_REGISTERED: + case CONFIG_UNREGISTERED: + default: + break; + } + } + } +} 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 new file mode 100644 index 00000000..575a7153 --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java @@ -0,0 +1,233 @@ +/* + * 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.meter.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.util.TriConsumer; +import org.onosproject.net.meter.DefaultMeter; +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.MeterListener; +import org.onosproject.net.meter.MeterOperation; +import org.onosproject.net.meter.MeterProvider; +import org.onosproject.net.meter.MeterProviderRegistry; +import org.onosproject.net.meter.MeterProviderService; +import org.onosproject.net.meter.MeterRequest; +import org.onosproject.net.meter.MeterService; +import org.onosproject.net.meter.MeterState; +import org.onosproject.net.meter.MeterStore; +import org.onosproject.net.meter.MeterStoreDelegate; +import org.onosproject.net.meter.MeterStoreResult; +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.AbstractListenerProviderRegistry; +import org.onosproject.net.provider.AbstractProviderService; +import org.onosproject.store.service.AtomicCounter; +import org.onosproject.store.service.StorageService; +import org.slf4j.Logger; + +import java.util.Collection; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.slf4j.LoggerFactory.getLogger; + + +/** + * Provides implementation of the meter service APIs. + */ +@Component(immediate = true, enabled = true) +@Service +public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, MeterListener, + MeterProvider, MeterProviderService> + implements MeterService, MeterProviderRegistry { + + private final String meterIdentifier = "meter-id-counter"; + private final Logger log = getLogger(getClass()); + private final MeterStoreDelegate delegate = new InternalMeterStoreDelegate(); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected StorageService storageService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected MeterStore store; + + private AtomicCounter meterIdCounter; + + private TriConsumer<MeterRequest, MeterStoreResult, Throwable> onComplete; + + @Activate + public void activate() { + meterIdCounter = storageService.atomicCounterBuilder() + .withName(meterIdentifier) + .build(); + + store.setDelegate(delegate); + + onComplete = (request, result, error) -> + { + request.context().ifPresent(c -> { + if (error != null) { + c.onError(request, MeterFailReason.UNKNOWN); + } else { + if (result.reason().isPresent()) { + c.onError(request, result.reason().get()); + } else { + c.onSuccess(request); + } + } + }); + + }; + log.info("Started"); + } + + @Deactivate + public void deactivate() { + store.unsetDelegate(delegate); + log.info("Stopped"); + } + + @Override + protected MeterProviderService createProviderService(MeterProvider provider) { + return new InternalMeterProviderService(provider); + } + + @Override + public Meter submit(MeterRequest request) { + + Meter.Builder mBuilder = DefaultMeter.builder() + .forDevice(request.deviceId()) + .fromApp(request.appId()) + .withBands(request.bands()) + .withId(allocateMeterId()) + .withUnit(request.unit()); + + if (request.isBurst()) { + mBuilder.burst(); + } + DefaultMeter m = (DefaultMeter) mBuilder.build(); + m.setState(MeterState.PENDING_ADD); + store.storeMeter(m).whenComplete((result, error) -> + onComplete.accept(request, result, error)); + return m; + } + + @Override + public void withdraw(MeterRequest request, MeterId meterId) { + Meter.Builder mBuilder = DefaultMeter.builder() + .forDevice(request.deviceId()) + .fromApp(request.appId()) + .withBands(request.bands()) + .withId(meterId) + .withUnit(request.unit()); + + if (request.isBurst()) { + mBuilder.burst(); + } + + DefaultMeter m = (DefaultMeter) mBuilder.build(); + m.setState(MeterState.PENDING_REMOVE); + store.deleteMeter(m).whenComplete((result, error) -> + onComplete.accept(request, result, error)); + } + + @Override + public Meter getMeter(MeterId id) { + return store.getMeter(id); + } + + @Override + public Collection<Meter> getAllMeters() { + return store.getAllMeters(); + } + + private MeterId allocateMeterId() { + // FIXME: This will break one day. + return MeterId.meterId((int) meterIdCounter.incrementAndGet()); + } + + private class InternalMeterProviderService + extends AbstractProviderService<MeterProvider> + implements MeterProviderService { + + /** + * Creates a provider service on behalf of the specified provider. + * + * @param provider provider to which this service is being issued + */ + protected InternalMeterProviderService(MeterProvider provider) { + super(provider); + } + + @Override + public void meterOperationFailed(MeterOperation operation, + MeterFailReason reason) { + store.failedMeter(operation, reason); + } + + @Override + public void pushMeterMetrics(DeviceId deviceId, Collection<Meter> meterEntries) { + //FIXME: FOLLOWING CODE CANNOT BE TESTED UNTIL SOMETHING THAT + //FIXME: IMPLEMENTS METERS EXISTS + Map<MeterId, Meter> storedMeterMap = store.getAllMeters().stream() + .collect(Collectors.toMap(Meter::id, m -> m)); + + meterEntries.stream() + .filter(m -> storedMeterMap.remove(m.id()) != null) + .forEach(m -> store.updateMeterState(m)); + + storedMeterMap.values().stream().forEach(m -> { + if (m.state() == MeterState.PENDING_ADD) { + provider().performMeterOperation(m.deviceId(), + new MeterOperation(m, + MeterOperation.Type.ADD)); + } else { + store.deleteMeterNow(m); + } + }); + } + } + + private class InternalMeterStoreDelegate implements MeterStoreDelegate { + + @Override + public void notify(MeterEvent event) { + DeviceId deviceId = event.subject().deviceId(); + MeterProvider p = getProvider(event.subject().deviceId()); + switch (event.type()) { + case METER_ADD_REQ: + p.performMeterOperation(deviceId, new MeterOperation(event.subject(), + MeterOperation.Type.ADD)); + break; + case METER_REM_REQ: + p.performMeterOperation(deviceId, new MeterOperation(event.subject(), + MeterOperation.Type.REMOVE)); + break; + default: + log.warn("Unknown meter event {}", event.type()); + } + + } + } + +} diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/resource/label/impl/LabelResourceManager.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/resource/label/impl/LabelResourceManager.java new file mode 100644 index 00000000..56167c48 --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/resource/label/impl/LabelResourceManager.java @@ -0,0 +1,221 @@ +package org.onosproject.incubator.net.resource.label.impl; + +import com.google.common.collect.Multimap; +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.net.provider.AbstractListenerProviderRegistry; +import org.onosproject.incubator.net.resource.label.LabelResource; +import org.onosproject.incubator.net.resource.label.LabelResourceAdminService; +import org.onosproject.incubator.net.resource.label.LabelResourceDelegate; +import org.onosproject.incubator.net.resource.label.LabelResourceEvent; +import org.onosproject.incubator.net.resource.label.LabelResourceId; +import org.onosproject.incubator.net.resource.label.LabelResourceListener; +import org.onosproject.incubator.net.resource.label.LabelResourcePool; +import org.onosproject.incubator.net.resource.label.LabelResourceProvider; +import org.onosproject.incubator.net.resource.label.LabelResourceProviderRegistry; +import org.onosproject.incubator.net.resource.label.LabelResourceProviderService; +import org.onosproject.incubator.net.resource.label.LabelResourceService; +import org.onosproject.incubator.net.resource.label.LabelResourceStore; +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.device.DeviceEvent; +import org.onosproject.net.device.DeviceEvent.Type; +import org.onosproject.net.device.DeviceListener; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.provider.AbstractProviderService; +import org.slf4j.Logger; + +import java.util.Collection; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * provides implementation of the label resource NB & SB APIs. + * + */ +@Component(immediate = true) +@Service +public class LabelResourceManager + extends AbstractListenerProviderRegistry<LabelResourceEvent, LabelResourceListener, + LabelResourceProvider, LabelResourceProviderService> + implements LabelResourceService, LabelResourceAdminService, LabelResourceProviderRegistry { + private final Logger log = getLogger(getClass()); + private final LabelResourceDelegate delegate = new InternalLabelResourceDelegate(); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected LabelResourceStore store; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DeviceService deviceService; + + private DeviceListener deviceListener = new InternalDeviceListener(); + + @Activate + public void activate() { + store.setDelegate(delegate); + eventDispatcher.addSink(LabelResourceEvent.class, listenerRegistry); + deviceService.addListener(deviceListener); + log.info("Started"); + + } + + @Deactivate + public void deactivate() { + deviceService.removeListener(deviceListener); + store.unsetDelegate(delegate); + eventDispatcher.removeSink(LabelResourceEvent.class); + log.info("Stopped"); + } + + @Override + public boolean createDevicePool(DeviceId deviceId, + LabelResourceId beginLabel, + LabelResourceId endLabel) { + checkNotNull(deviceId, "deviceId is not null"); + checkNotNull(beginLabel, "beginLabel is not null"); + checkNotNull(endLabel, "endLabel is not null"); + checkArgument(beginLabel.labelId() >= 0 || endLabel.labelId() >= 0, + "The value of beginLabel and the value of endLabel must be both positive number."); + checkArgument(beginLabel.labelId() < endLabel.labelId(), + "The value of endLabel must be greater than the value of beginLabel."); + return store.createDevicePool(deviceId, beginLabel, endLabel); + } + + @Override + public boolean createGlobalPool(LabelResourceId beginLabel, + LabelResourceId endLabel) { + checkNotNull(beginLabel, "beginLabel is not null"); + checkNotNull(endLabel, "endLabel is not null"); + checkArgument(beginLabel.labelId() >= 0 && endLabel.labelId() >= 0, + "The value of beginLabel and the value of endLabel must be both positive number."); + checkArgument(beginLabel.labelId() < endLabel.labelId(), + "The value of endLabel must be greater than the value of beginLabel."); + return store.createGlobalPool(beginLabel, endLabel); + } + + @Override + public boolean destroyDevicePool(DeviceId deviceId) { + checkNotNull(deviceId, "deviceId is not null"); + return store.destroyDevicePool(deviceId); + } + + @Override + public boolean destroyGlobalPool() { + return store.destroyGlobalPool(); + } + + @Override + public Collection<LabelResource> applyFromDevicePool(DeviceId deviceId, + long applyNum) { + checkNotNull(deviceId, "deviceId is not null"); + checkNotNull(applyNum, "applyNum is not null"); + return store.applyFromDevicePool(deviceId, applyNum); + } + + @Override + public Collection<LabelResource> applyFromGlobalPool(long applyNum) { + checkNotNull(applyNum, "applyNum is not null"); + return store.applyFromGlobalPool(applyNum); + } + + @Override + public boolean releaseToDevicePool(Multimap<DeviceId, LabelResource> release) { + checkNotNull(release, "release is not null"); + return store.releaseToDevicePool(release); + } + + @Override + public boolean releaseToGlobalPool(Set<LabelResourceId> release) { + checkNotNull(release, "release is not null"); + return store.releaseToGlobalPool(release); + } + + @Override + public boolean isDevicePoolFull(DeviceId deviceId) { + checkNotNull(deviceId, "deviceId is not null"); + return store.isDevicePoolFull(deviceId); + } + + @Override + public boolean isGlobalPoolFull() { + return store.isGlobalPoolFull(); + } + + @Override + public long getFreeNumOfDevicePool(DeviceId deviceId) { + checkNotNull(deviceId, "deviceId is not null"); + return store.getFreeNumOfDevicePool(deviceId); + } + + @Override + public long getFreeNumOfGlobalPool() { + return store.getFreeNumOfGlobalPool(); + } + + @Override + public LabelResourcePool getDeviceLabelResourcePool(DeviceId deviceId) { + checkNotNull(deviceId, "deviceId is not null"); + return store.getDeviceLabelResourcePool(deviceId); + } + + @Override + public LabelResourcePool getGlobalLabelResourcePool() { + return store.getGlobalLabelResourcePool(); + } + + private class InternalLabelResourceDelegate implements LabelResourceDelegate { + @Override + public void notify(LabelResourceEvent event) { + post(event); + } + + } + + private class InternalDeviceListener implements DeviceListener { + @Override + public void event(DeviceEvent event) { + Device device = event.subject(); + if (Type.DEVICE_REMOVED.equals(event.type())) { + destroyDevicePool(device.id()); + } + } + } + + private class InternalLabelResourceProviderService + extends AbstractProviderService<LabelResourceProvider> + implements LabelResourceProviderService { + + protected InternalLabelResourceProviderService(LabelResourceProvider provider) { + super(provider); + } + + @Override + public void deviceLabelResourcePoolDetected(DeviceId deviceId, + LabelResourceId beginLabel, + LabelResourceId endLabel) { + checkNotNull(deviceId, "deviceId is not null"); + checkNotNull(beginLabel, "beginLabel is not null"); + checkNotNull(endLabel, "endLabel is not null"); + createDevicePool(deviceId, beginLabel, endLabel); + } + + @Override + public void deviceLabelResourcePoolDestroyed(DeviceId deviceId) { + checkNotNull(deviceId, "deviceId is not null"); + destroyDevicePool(deviceId); + } + + } + + @Override + protected LabelResourceProviderService createProviderService(LabelResourceProvider provider) { + return new InternalLabelResourceProviderService(provider); + } +} diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/resource/label/impl/package-info.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/resource/label/impl/package-info.java new file mode 100644 index 00000000..afd31b48 --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/resource/label/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 label resource subsystem. + */ +package org.onosproject.incubator.net.resource.label.impl;
\ No newline at end of file diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/tunnel/impl/TunnelManager.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/tunnel/impl/TunnelManager.java new file mode 100644 index 00000000..d316388f --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/tunnel/impl/TunnelManager.java @@ -0,0 +1,366 @@ +/* + * 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.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.net.provider.AbstractListenerProviderRegistry; +import org.onosproject.core.ApplicationId; +import org.onosproject.incubator.net.tunnel.DefaultTunnel; +import org.onosproject.incubator.net.tunnel.Tunnel; +import org.onosproject.incubator.net.tunnel.Tunnel.Type; +import org.onosproject.incubator.net.tunnel.TunnelAdminService; +import org.onosproject.incubator.net.tunnel.TunnelDescription; +import org.onosproject.incubator.net.tunnel.TunnelEndPoint; +import org.onosproject.incubator.net.tunnel.TunnelEvent; +import org.onosproject.incubator.net.tunnel.TunnelId; +import org.onosproject.incubator.net.tunnel.TunnelListener; +import org.onosproject.incubator.net.tunnel.TunnelName; +import org.onosproject.incubator.net.tunnel.TunnelProvider; +import org.onosproject.incubator.net.tunnel.TunnelProviderRegistry; +import org.onosproject.incubator.net.tunnel.TunnelProviderService; +import org.onosproject.incubator.net.tunnel.TunnelService; +import org.onosproject.incubator.net.tunnel.TunnelStore; +import org.onosproject.incubator.net.tunnel.TunnelStoreDelegate; +import org.onosproject.incubator.net.tunnel.TunnelSubscription; +import org.onosproject.net.Annotations; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Path; +import org.onosproject.net.provider.AbstractProviderService; +import org.onosproject.net.provider.ProviderId; +import org.slf4j.Logger; + +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Provides implementation of the tunnel NB/SB APIs. + */ +@Component(immediate = true, enabled = true) +@Service +public class TunnelManager + extends AbstractListenerProviderRegistry<TunnelEvent, TunnelListener, + TunnelProvider, TunnelProviderService> + implements TunnelService, TunnelAdminService, TunnelProviderRegistry { + + private static final String TUNNNEL_ID_NULL = "Tunnel ID cannot be null"; + + private final Logger log = getLogger(getClass()); + + private final TunnelStoreDelegate delegate = new InternalStoreDelegate(); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected TunnelStore store; + + + @Activate + public void activate() { + store.setDelegate(delegate); + eventDispatcher.addSink(TunnelEvent.class, listenerRegistry); + log.info("Started"); + } + + @Deactivate + public void deactivate() { + store.unsetDelegate(delegate); + eventDispatcher.removeSink(TunnelEvent.class); + log.info("Stopped"); + } + + @Override + public void removeTunnel(TunnelId tunnelId) { + checkNotNull(tunnelId, TUNNNEL_ID_NULL); + store.deleteTunnel(tunnelId); + Tunnel tunnel = store.queryTunnel(tunnelId); + if (tunnel.providerId() != null) { + TunnelProvider provider = getProvider(tunnel.providerId()); + if (provider != null) { + provider.releaseTunnel(tunnel); + } + } else { + Set<ProviderId> ids = getProviders(); + for (ProviderId providerId : ids) { + TunnelProvider provider = getProvider(providerId); + provider.releaseTunnel(tunnel); + } + } + } + + @Override + public void updateTunnel(Tunnel tunnel, Path path) { + store.createOrUpdateTunnel(tunnel); + if (tunnel.providerId() != null) { + TunnelProvider provider = getProvider(tunnel.providerId()); + if (provider != null) { + provider.updateTunnel(tunnel, path); + } + } else { + Set<ProviderId> ids = getProviders(); + for (ProviderId providerId : ids) { + TunnelProvider provider = getProvider(providerId); + provider.updateTunnel(tunnel, path); + } + } + } + + @Override + public void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst, + ProviderId producerName) { + store.deleteTunnel(src, dst, producerName); + Collection<Tunnel> setTunnels = store.queryTunnel(src, dst); + for (Tunnel tunnel : setTunnels) { + if (producerName != null + && !tunnel.providerId().equals(producerName)) { + continue; + } + if (tunnel.providerId() != null) { + TunnelProvider provider = getProvider(tunnel.providerId()); + if (provider != null) { + provider.releaseTunnel(tunnel); + } + } else { + Set<ProviderId> ids = getProviders(); + for (ProviderId providerId : ids) { + TunnelProvider provider = getProvider(providerId); + provider.releaseTunnel(tunnel); + } + } + } + } + + @Override + public void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst, Type type, + ProviderId producerName) { + store.deleteTunnel(src, dst, type, producerName); + Collection<Tunnel> setTunnels = store.queryTunnel(src, dst); + for (Tunnel tunnel : setTunnels) { + if (producerName != null + && !tunnel.providerId().equals(producerName) + || !type.equals(tunnel.type())) { + continue; + } + if (tunnel.providerId() != null) { + TunnelProvider provider = getProvider(tunnel.providerId()); + if (provider != null) { + provider.releaseTunnel(tunnel); + } + } else { + Set<ProviderId> ids = getProviders(); + for (ProviderId providerId : ids) { + TunnelProvider provider = getProvider(providerId); + provider.releaseTunnel(tunnel); + } + } + } + } + + @Override + public Tunnel borrowTunnel(ApplicationId consumerId, TunnelId tunnelId, + Annotations... annotations) { + return store.borrowTunnel(consumerId, tunnelId, annotations); + } + + @Override + public Collection<Tunnel> borrowTunnel(ApplicationId consumerId, + TunnelName tunnelName, + Annotations... annotations) { + return store.borrowTunnel(consumerId, tunnelName, annotations); + } + + @Override + public Collection<Tunnel> borrowTunnel(ApplicationId consumerId, + TunnelEndPoint src, TunnelEndPoint dst, + Annotations... annotations) { + Collection<Tunnel> tunnels = store.borrowTunnel(consumerId, src, + dst, annotations); + if (tunnels == null || tunnels.size() == 0) { + Tunnel tunnel = new DefaultTunnel(null, src, dst, null, null, null, + null, null, annotations); + Set<ProviderId> ids = getProviders(); + for (ProviderId providerId : ids) { + TunnelProvider provider = getProvider(providerId); + provider.setupTunnel(tunnel, null); + } + } + return tunnels; + } + + @Override + public Collection<Tunnel> borrowTunnel(ApplicationId consumerId, + TunnelEndPoint src, TunnelEndPoint dst, + Type type, Annotations... annotations) { + Collection<Tunnel> tunnels = store.borrowTunnel(consumerId, src, + dst, type, + annotations); + if (tunnels == null || tunnels.size() == 0) { + Tunnel tunnel = new DefaultTunnel(null, src, dst, type, null, null, + null, null, annotations); + Set<ProviderId> ids = getProviders(); + for (ProviderId providerId : ids) { + TunnelProvider provider = getProvider(providerId); + provider.setupTunnel(tunnel, null); + } + } + return tunnels; + } + + @Override + public boolean returnTunnel(ApplicationId consumerId, + TunnelId tunnelId, Annotations... annotations) { + return store.returnTunnel(consumerId, tunnelId, annotations); + } + + @Override + public boolean returnTunnel(ApplicationId consumerId, + TunnelName tunnelName, + Annotations... annotations) { + return store.returnTunnel(consumerId, tunnelName, annotations); + } + + @Override + public boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src, + TunnelEndPoint dst, Type type, + Annotations... annotations) { + return store.returnTunnel(consumerId, src, dst, type, annotations); + } + + @Override + public boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src, + TunnelEndPoint dst, Annotations... annotations) { + return store.returnTunnel(consumerId, src, dst, annotations); + } + + @Override + public Tunnel queryTunnel(TunnelId tunnelId) { + return store.queryTunnel(tunnelId); + } + + @Override + public Collection<TunnelSubscription> queryTunnelSubscription(ApplicationId consumerId) { + return store.queryTunnelSubscription(consumerId); + } + + @Override + public Collection<Tunnel> queryTunnel(Type type) { + return store.queryTunnel(type); + } + + @Override + public Collection<Tunnel> queryTunnel(TunnelEndPoint src, TunnelEndPoint dst) { + return store.queryTunnel(src, dst); + } + + + @Override + public Collection<Tunnel> queryAllTunnels() { + return store.queryAllTunnels(); + } + + @Override + public int tunnelCount() { + return store.tunnelCount(); + } + + @Override + protected TunnelProviderService createProviderService(TunnelProvider provider) { + return new InternalTunnelProviderService(provider); + } + + private class InternalTunnelProviderService + extends AbstractProviderService<TunnelProvider> + implements TunnelProviderService { + protected InternalTunnelProviderService(TunnelProvider provider) { + super(provider); + } + + + @Override + public TunnelId tunnelAdded(TunnelDescription tunnel) { + Tunnel storedTunnel = new DefaultTunnel(provider().id(), + tunnel.src(), tunnel.dst(), + tunnel.type(), + tunnel.groupId(), + tunnel.id(), + tunnel.tunnelName(), + tunnel.path(), + tunnel.annotations()); + return store.createOrUpdateTunnel(storedTunnel); + } + + @Override + public void tunnelUpdated(TunnelDescription tunnel) { + Tunnel storedTunnel = new DefaultTunnel(provider().id(), + tunnel.src(), tunnel.dst(), + tunnel.type(), + tunnel.groupId(), + tunnel.id(), + tunnel.tunnelName(), + tunnel.path(), + tunnel.annotations()); + store.createOrUpdateTunnel(storedTunnel); + } + + @Override + public void tunnelRemoved(TunnelDescription tunnel) { + if (tunnel.id() != null) { + store.deleteTunnel(tunnel.id()); + return; + } + if (tunnel.src() != null && tunnel.dst() != null + && tunnel.type() != null) { + store.deleteTunnel(tunnel.src(), tunnel.dst(), tunnel.type(), + provider().id()); + return; + } + if (tunnel.src() != null && tunnel.dst() != null + && tunnel.type() == null) { + store.deleteTunnel(tunnel.src(), tunnel.dst(), provider().id()); + return; + } + } + + + @Override + public Tunnel tunnelQueryById(TunnelId tunnelId) { + return store.queryTunnel(tunnelId); + } + + + } + + private class InternalStoreDelegate implements TunnelStoreDelegate { + @Override + public void notify(TunnelEvent event) { + if (event != null) { + post(event); + } + } + } + + @Override + public Iterable<Tunnel> getTunnels(DeviceId deviceId) { + return Collections.emptyList(); + } + +} diff --git a/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/tunnel/impl/package-info.java b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/tunnel/impl/package-info.java new file mode 100644 index 00000000..6e0de551 --- /dev/null +++ b/framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/tunnel/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. + */ + +/** + * Core subsystem for tracking global inventory of tunnels. + */ +package org.onosproject.incubator.net.tunnel.impl; 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 new file mode 100644 index 00000000..e0c0c868 --- /dev/null +++ b/framework/src/onos/incubator/net/src/test/java/org/onosproject/incubator/net/meter/impl/MeterManagerTest.java @@ -0,0 +1,234 @@ +/* + * 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.meter.impl; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onlab.junit.TestUtils; +import org.onlab.packet.IpAddress; +import org.onosproject.cluster.ClusterServiceAdapter; +import org.onosproject.cluster.ControllerNode; +import org.onosproject.cluster.DefaultControllerNode; +import org.onosproject.cluster.NodeId; +import org.onosproject.common.event.impl.TestEventDispatcher; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.DefaultApplicationId; +import org.onosproject.incubator.store.meter.impl.DistributedMeterStore; +import org.onosproject.mastership.MastershipServiceAdapter; +import org.onosproject.net.DeviceId; +import org.onosproject.net.meter.Band; +import org.onosproject.net.meter.DefaultBand; +import org.onosproject.net.meter.DefaultMeter; +import org.onosproject.net.meter.DefaultMeterRequest; +import org.onosproject.net.meter.Meter; +import org.onosproject.net.meter.MeterId; +import org.onosproject.net.meter.MeterOperation; +import org.onosproject.net.meter.MeterOperations; +import org.onosproject.net.meter.MeterProvider; +import org.onosproject.net.meter.MeterProviderRegistry; +import org.onosproject.net.meter.MeterProviderService; +import org.onosproject.net.meter.MeterRequest; +import org.onosproject.net.meter.MeterService; +import org.onosproject.net.meter.MeterState; +import org.onosproject.net.provider.AbstractProvider; +import org.onosproject.net.provider.ProviderId; +import org.onosproject.store.service.TestStorageService; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.onosproject.net.NetTestTools.APP_ID; +import static org.onosproject.net.NetTestTools.did; +import static org.onosproject.net.NetTestTools.injectEventDispatcher; + +/** + * Meter manager tests. + */ +public class MeterManagerTest { + + private static final ProviderId PID = new ProviderId("of", "foo"); + private static final NodeId NID_LOCAL = new NodeId("local"); + private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1"); + + private MeterService service; + private MeterManager manager; + private DistributedMeterStore meterStore; + private MeterProviderRegistry registry; + private MeterProviderService providerService; + + private TestProvider provider; + + private ApplicationId appId; + + + private Meter m1; + private Meter m2; + private MeterRequest.Builder m1Request; + private MeterRequest.Builder m2Request; + + private Map<MeterId, Meter> meters = Maps.newHashMap(); + + @Before + public void setup() throws Exception { + meterStore = new DistributedMeterStore(); + TestUtils.setField(meterStore, "storageService", new TestStorageService()); + TestUtils.setField(meterStore, "clusterService", new TestClusterService()); + TestUtils.setField(meterStore, "mastershipService", new TestMastershipService()); + meterStore.activate(); + + manager = new MeterManager(); + manager.store = meterStore; + TestUtils.setField(manager, "storageService", new TestStorageService()); + injectEventDispatcher(manager, new TestEventDispatcher()); + service = manager; + registry = manager; + + manager.activate(); + + provider = new TestProvider(PID); + providerService = registry.register(provider); + + appId = new TestApplicationId(0, "MeterManagerTest"); + + assertTrue("provider should be registered", + registry.getProviders().contains(provider.id())); + + Band band = DefaultBand.builder() + .ofType(Band.Type.DROP) + .withRate(500) + .build(); + + m1 = DefaultMeter.builder() + .forDevice(did("1")) + .fromApp(APP_ID) + .withId(MeterId.meterId(1)) + .withUnit(Meter.Unit.KB_PER_SEC) + .withBands(Collections.singletonList(band)) + .build(); + + m2 = DefaultMeter.builder() + .forDevice(did("2")) + .fromApp(APP_ID) + .withId(MeterId.meterId(2)) + .withUnit(Meter.Unit.KB_PER_SEC) + .withBands(Collections.singletonList(band)) + .build(); + + m1Request = DefaultMeterRequest.builder() + .forDevice(did("1")) + .fromApp(APP_ID) + .withUnit(Meter.Unit.KB_PER_SEC) + .withBands(Collections.singletonList(band)); + + m2Request = DefaultMeterRequest.builder() + .forDevice(did("2")) + .fromApp(APP_ID) + .withUnit(Meter.Unit.KB_PER_SEC) + .withBands(Collections.singletonList(band)); + + + } + + @After + public void tearDown() { + registry.unregister(provider); + assertFalse("provider should not be registered", + registry.getProviders().contains(provider.id())); + + manager.deactivate(); + injectEventDispatcher(manager, null); + + } + + @Test + public void testAddition() { + manager.submit(m1Request.add()); + + assertTrue("The meter was not added", manager.getAllMeters().size() == 1); + + assertThat(manager.getMeter(MeterId.meterId(1)), is(m1)); + } + + @Test + public void testRemove() { + manager.submit(m1Request.add()); + manager.withdraw(m1Request.remove(), m1.id()); + + assertThat(manager.getMeter(MeterId.meterId(1)).state(), + is(MeterState.PENDING_REMOVE)); + + providerService.pushMeterMetrics(m1.deviceId(), Collections.emptyList()); + + assertTrue("The meter was not removed", manager.getAllMeters().size() == 0); + + } + + + + public class TestApplicationId extends DefaultApplicationId { + public TestApplicationId(int id, String name) { + super(id, name); + } + } + + private class TestProvider extends AbstractProvider implements MeterProvider { + + protected TestProvider(ProviderId id) { + super(PID); + } + + @Override + public void performMeterOperation(DeviceId deviceId, MeterOperations meterOps) { + //Currently unused. + } + + @Override + public void performMeterOperation(DeviceId deviceId, MeterOperation meterOp) { + meters.put(meterOp.meter().id(), meterOp.meter()); + } + } + + private final class TestClusterService extends ClusterServiceAdapter { + + ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST); + + @Override + public ControllerNode getLocalNode() { + return local; + } + + @Override + public Set<ControllerNode> getNodes() { + return Sets.newHashSet(); + } + + } + + private class TestMastershipService extends MastershipServiceAdapter { + @Override + public NodeId getMasterFor(DeviceId deviceId) { + return NID_LOCAL; + } + } +} diff --git a/framework/src/onos/incubator/net/src/test/resources/domain-config.json b/framework/src/onos/incubator/net/src/test/resources/domain-config.json new file mode 100644 index 00000000..beda11aa --- /dev/null +++ b/framework/src/onos/incubator/net/src/test/resources/domain-config.json @@ -0,0 +1,36 @@ +{ + "domains" : { + "cord" : { + "basic" : { + "name" : "Core Fabric", + "applicationName" : "org.onosproject.testdomain", + "internalDevices" : [ "of:1" ], + "edgePorts" : [ "of:12/1", "of:14/1" ] + } + }, + "mpls" : { + "basic" : { + "name" : "MPLS Core", + "applicationName" : "org.onosproject.testdomain", + "internalDevices" : [ "of:2" ], + "edgePorts" : [ "of:12/2", "of:23/2" ] + } + }, + "dc" : { + "basic" : { + "name" : "Data Center Fabric", + "applicationName" : "org.onosproject.testdomain", + "internalDevices" : [ "of:3" ], + "edgePorts" : [ "of:23/3", "of:34/3" ] + } + }, + "optical" : { + "basic" : { + "name" : "Optical Core", + "applicationName" : "org.onosproject.testdomain", + "internalDevices" : [ "of:4" ], + "edgePorts" : [ "of:14/4", "of:34/4" ] + } + } + } +}
\ No newline at end of file diff --git a/framework/src/onos/incubator/net/src/test/resources/fractal-domain-config.json b/framework/src/onos/incubator/net/src/test/resources/fractal-domain-config.json new file mode 100644 index 00000000..521c840b --- /dev/null +++ b/framework/src/onos/incubator/net/src/test/resources/fractal-domain-config.json @@ -0,0 +1,28 @@ +{ + "domains" : { + "domain1" : { + "basic" : { + "name" : "Domain 1", + "applicationName" : "org.onosproject.meshdomain", + "internalDevices" : [ "of:0000000000001001", "of:0000000000001002", "of:0000000000001003" ], + "edgePorts" : [ "of:0000000000010000/1", "of:0000000003010000/2", "of:0000000002010000/1" ] + } + }, + "domain2" : { + "basic" : { + "name" : "Domain 2", + "applicationName" : "org.onosproject.meshdomain", + "internalDevices" : [ "of:0000000000002001", "of:0000000000002002", "of:0000000000002003" ], + "edgePorts" : [ "of:0000000000020000/1", "of:0000000003020000/1", "of:0000000002010000/2" ] + } + }, + "domain3" : { + "basic" : { + "name" : "Domain 3", + "applicationName" : "org.onosproject.meshdomain", + "internalDevices" : [ "of:0000000000003001", "of:0000000000003002", "of:0000000000003003" ], + "edgePorts" : [ "of:0000000000030000/1", "of:0000000003010000/1", "of:0000000003020000/2" ] + } + } + } +}
\ No newline at end of file diff --git a/framework/src/onos/incubator/pom.xml b/framework/src/onos/incubator/pom.xml new file mode 100644 index 00000000..6e6c229d --- /dev/null +++ b/framework/src/onos/incubator/pom.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos</artifactId> + <version>1.3.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>onos-incubator</artifactId> + <packaging>pom</packaging> + + <description>ONOS Incubator root project</description> + + <modules> + <module>api</module> + <module>net</module> + <module>store</module> + </modules> + + <dependencies> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onlab-misc</artifactId> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onlab-junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.onosproject</groupId> + <artifactId>onos-maven-plugin</artifactId> + </plugin> + </plugins> + </build> + +</project> diff --git a/framework/src/onos/incubator/store/pom.xml b/framework/src/onos/incubator/store/pom.xml new file mode 100644 index 00000000..54575582 --- /dev/null +++ b/framework/src/onos/incubator/store/pom.xml @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-incubator</artifactId> + <version>1.3.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>onos-incubator-store</artifactId> + <packaging>bundle</packaging> + + <description>ONOS incubating distributed store subsystems</description> + + <dependencies> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-incubator-api</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-incubator-api</artifactId> + <version>${project.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-core-dist</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava-testlib</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymock</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.scr.annotations</artifactId> + </dependency> + </dependencies> + + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-scr-plugin</artifactId> + </plugin> + </plugins> + </build> + +</project> diff --git a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/impl/package-info.java b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/impl/package-info.java new file mode 100644 index 00000000..2755a98f --- /dev/null +++ b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/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. + */ + +/** + * Incubating distributed store implementations. + */ +package org.onosproject.incubator.store.impl;
\ No newline at end of file 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 new file mode 100644 index 00000000..32890cb1 --- /dev/null +++ b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java @@ -0,0 +1,258 @@ +/* + * 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.meter.impl; + +import com.google.common.collect.Collections2; +import com.google.common.collect.Maps; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onosproject.cluster.ClusterService; +import org.onosproject.cluster.NodeId; +import org.onosproject.mastership.MastershipService; +import org.onosproject.net.meter.Band; +import org.onosproject.net.meter.DefaultBand; +import org.onosproject.net.meter.DefaultMeter; +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.MeterOperation; +import org.onosproject.net.meter.MeterState; +import org.onosproject.net.meter.MeterStore; +import org.onosproject.net.meter.MeterStoreDelegate; +import org.onosproject.net.meter.MeterStoreResult; +import org.onosproject.store.AbstractStore; +import org.onosproject.store.serializers.KryoNamespaces; +import org.onosproject.store.service.ConsistentMap; +import org.onosproject.store.service.MapEvent; +import org.onosproject.store.service.MapEventListener; +import org.onosproject.store.service.Serializer; +import org.onosproject.store.service.StorageException; +import org.onosproject.store.service.StorageService; +import org.onosproject.store.service.Versioned; +import org.slf4j.Logger; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +import static org.slf4j.LoggerFactory.getLogger; + +/** + * A distributed meter store implementation. Meters are stored consistently + * across the cluster. + */ +@Component(immediate = true) +@Service +public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreDelegate> + implements MeterStore { + + private Logger log = getLogger(getClass()); + + private static final String METERSTORE = "onos-meter-store"; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + private StorageService storageService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + private MastershipService mastershipService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + private ClusterService clusterService; + + private ConsistentMap<MeterId, MeterData> meters; + private NodeId local; + + private MapEventListener mapListener = new InternalMapEventListener(); + + private Map<MeterId, CompletableFuture<MeterStoreResult>> futures = + Maps.newConcurrentMap(); + + @Activate + public void activate() { + + local = clusterService.getLocalNode().id(); + + + meters = storageService.<MeterId, MeterData>consistentMapBuilder() + .withName(METERSTORE) + .withSerializer(Serializer.using(Arrays.asList(KryoNamespaces.API), + MeterData.class, + DefaultMeter.class, + DefaultBand.class, + Band.Type.class, + MeterState.class, + Meter.Unit.class, + MeterFailReason.class, + MeterId.class)).build(); + + meters.addListener(mapListener); + + log.info("Started"); + } + + @Deactivate + public void deactivate() { + + meters.removeListener(mapListener); + log.info("Stopped"); + } + + + @Override + public CompletableFuture<MeterStoreResult> storeMeter(Meter meter) { + CompletableFuture<MeterStoreResult> future = new CompletableFuture<>(); + futures.put(meter.id(), future); + MeterData data = new MeterData(meter, null, local); + + try { + meters.put(meter.id(), data); + } catch (StorageException e) { + future.completeExceptionally(e); + } + + return future; + + } + + @Override + public CompletableFuture<MeterStoreResult> deleteMeter(Meter meter) { + CompletableFuture<MeterStoreResult> future = new CompletableFuture<>(); + futures.put(meter.id(), 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) { + future.complete(MeterStoreResult.success()); + } + } catch (StorageException e) { + future.completeExceptionally(e); + } + + + return future; + } + + @Override + public CompletableFuture<MeterStoreResult> updateMeter(Meter meter) { + CompletableFuture<MeterStoreResult> future = new CompletableFuture<>(); + futures.put(meter.id(), future); + + MeterData data = new MeterData(meter, null, local); + try { + if (meters.computeIfPresent(meter.id(), (k, v) -> data) == null) { + future.complete(MeterStoreResult.fail(MeterFailReason.INVALID_METER)); + } + } catch (StorageException e) { + future.completeExceptionally(e); + } + return future; + } + + @Override + public void updateMeterState(Meter meter) { + meters.computeIfPresent(meter.id(), (id, v) -> { + DefaultMeter m = (DefaultMeter) v.meter(); + m.setState(meter.state()); + m.setProcessedPackets(meter.packetsSeen()); + m.setProcessedBytes(meter.bytesSeen()); + m.setLife(meter.life()); + // TODO: Prune if drops to zero. + m.setReferenceCount(meter.referenceCount()); + return new MeterData(m, null, v.origin()); + }); + } + + @Override + public Meter getMeter(MeterId meterId) { + MeterData data = Versioned.valueOrElse(meters.get(meterId), null); + return data == null ? null : data.meter(); + } + + @Override + public Collection<Meter> getAllMeters() { + return Collections2.transform(meters.asJavaMap().values(), + MeterData::meter); + } + + @Override + public void failedMeter(MeterOperation op, MeterFailReason reason) { + meters.computeIfPresent(op.meter().id(), (k, v) -> + new MeterData(v.meter(), reason, v.origin())); + } + + @Override + public void deleteMeterNow(Meter m) { + futures.remove(m.id()); + meters.remove(m.id()); + } + + private class InternalMapEventListener implements MapEventListener<MeterId, MeterData> { + @Override + public void event(MapEvent<MeterId, MeterData> event) { + MeterData data = event.value().value(); + NodeId master = mastershipService.getMasterFor(data.meter().deviceId()); + switch (event.type()) { + case INSERT: + case UPDATE: + switch (data.meter().state()) { + case PENDING_ADD: + case PENDING_REMOVE: + if (!data.reason().isPresent() && local.equals(master)) { + notifyDelegate( + new MeterEvent(data.meter().state() == MeterState.PENDING_ADD ? + MeterEvent.Type.METER_ADD_REQ : MeterEvent.Type.METER_REM_REQ, + data.meter())); + } else if (data.reason().isPresent() && local.equals(data.origin())) { + MeterStoreResult msr = MeterStoreResult.fail(data.reason().get()); + //TODO: No future -> no friend + futures.get(data.meter().id()).complete(msr); + } + break; + case ADDED: + if (local.equals(data.origin()) && data.meter().state() == MeterState.PENDING_ADD) { + futures.remove(data.meter().id()).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()); + } + break; + default: + log.warn("Unknown meter state type {}", data.meter().state()); + } + break; + case REMOVE: + //Only happens at origin so we do not need to care. + break; + default: + log.warn("Unknown Map event type {}", event.type()); + } + + } + } + + +} diff --git a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/MeterData.java b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/MeterData.java new file mode 100644 index 00000000..c72bc2e3 --- /dev/null +++ b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/MeterData.java @@ -0,0 +1,52 @@ +/* + * 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.meter.impl; + +import org.onosproject.cluster.NodeId; +import org.onosproject.net.meter.Meter; +import org.onosproject.net.meter.MeterFailReason; + +import java.util.Optional; + +/** + * A class representing the meter information stored in the meter store. + */ +public class MeterData { + + private final Meter meter; + private final Optional<MeterFailReason> reason; + private final NodeId origin; + + public MeterData(Meter meter, MeterFailReason reason, NodeId origin) { + this.meter = meter; + this.reason = Optional.ofNullable(reason); + this.origin = origin; + } + + public Meter meter() { + return meter; + } + + public Optional<MeterFailReason> reason() { + return this.reason; + } + + public NodeId origin() { + return this.origin; + } + + +} diff --git a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/DistributedLabelResourceStore.java b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/DistributedLabelResourceStore.java new file mode 100644 index 00000000..a014504c --- /dev/null +++ b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/DistributedLabelResourceStore.java @@ -0,0 +1,543 @@ +package org.onosproject.incubator.store.resource.impl; + +import static org.onlab.util.Tools.groupedThreads; +import static org.slf4j.LoggerFactory.getLogger; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.util.KryoNamespace; +import org.onosproject.cluster.ClusterService; +import org.onosproject.cluster.NodeId; +import org.onosproject.incubator.net.resource.label.DefaultLabelResource; +import org.onosproject.incubator.net.resource.label.LabelResource; +import org.onosproject.incubator.net.resource.label.LabelResourceDelegate; +import org.onosproject.incubator.net.resource.label.LabelResourceEvent; +import org.onosproject.incubator.net.resource.label.LabelResourceEvent.Type; +import org.onosproject.incubator.net.resource.label.LabelResourceId; +import org.onosproject.incubator.net.resource.label.LabelResourcePool; +import org.onosproject.incubator.net.resource.label.LabelResourceRequest; +import org.onosproject.incubator.net.resource.label.LabelResourceStore; +import org.onosproject.mastership.MastershipService; +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.device.DeviceService; +import org.onosproject.store.AbstractStore; +import org.onosproject.store.cluster.messaging.ClusterCommunicationService; +import org.onosproject.store.cluster.messaging.ClusterMessage; +import org.onosproject.store.cluster.messaging.ClusterMessageHandler; +import org.onosproject.store.serializers.KryoNamespaces; +import org.onosproject.store.service.ConsistentMap; +import org.onosproject.store.service.Serializer; +import org.onosproject.store.service.StorageService; +import org.onosproject.store.service.Versioned; +import org.slf4j.Logger; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Multimap; + +/** + * Manages label resources using copycat. + */ +@Component(immediate = true, enabled = true) +@Service +public class DistributedLabelResourceStore + extends AbstractStore<LabelResourceEvent, LabelResourceDelegate> + implements LabelResourceStore { + private final Logger log = getLogger(getClass()); + + private static final String POOL_MAP_NAME = "labelresourcepool"; + + private static final String GLOBAL_RESOURCE_POOL_DEVICE_ID = "global_resource_pool_device_id"; + + private ConsistentMap<DeviceId, LabelResourcePool> resourcePool = null; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected StorageService storageService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected MastershipService mastershipService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected ClusterCommunicationService clusterCommunicator; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected ClusterService clusterService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DeviceService deviceService; + + private ExecutorService messageHandlingExecutor; + private static final int MESSAGE_HANDLER_THREAD_POOL_SIZE = 8; + private static final long PEER_REQUEST_TIMEOUT_MS = 5000; + + private static final Serializer SERIALIZER = Serializer + .using(new KryoNamespace.Builder().register(KryoNamespaces.API) + .register(LabelResourceEvent.class) + .register(LabelResourcePool.class).register(DeviceId.class) + .register(LabelResourceRequest.class) + .register(LabelResourceRequest.Type.class) + .register(LabelResourceEvent.Type.class) + .register(DefaultLabelResource.class) + .register(LabelResourceId.class) + .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID).build()); + + @Activate + public void activate() { + + resourcePool = storageService + .<DeviceId, LabelResourcePool>consistentMapBuilder() + .withName(POOL_MAP_NAME).withSerializer(SERIALIZER) + .withPartitionsDisabled().build(); + messageHandlingExecutor = Executors + .newFixedThreadPool(MESSAGE_HANDLER_THREAD_POOL_SIZE, + groupedThreads("onos/store/flow", + "message-handlers")); + clusterCommunicator + .addSubscriber(LabelResourceMessageSubjects.LABEL_POOL_CREATED, + new ClusterMessageHandler() { + + @Override + public void handle(ClusterMessage message) { + LabelResourcePool operation = SERIALIZER + .decode(message.payload()); + log.trace("received get flow entry request for {}", + operation); + boolean b = internalCreate(operation); + message.respond(SERIALIZER.encode(b)); + } + }, messageHandlingExecutor); + clusterCommunicator + .addSubscriber(LabelResourceMessageSubjects.LABEL_POOL_DESTROYED, + new ClusterMessageHandler() { + + @Override + public void handle(ClusterMessage message) { + DeviceId deviceId = SERIALIZER + .decode(message.payload()); + log.trace("received get flow entry request for {}", + deviceId); + boolean b = internalDestroy(deviceId); + message.respond(SERIALIZER.encode(b)); + } + }, messageHandlingExecutor); + clusterCommunicator + .addSubscriber(LabelResourceMessageSubjects.LABEL_POOL_APPLY, + new ClusterMessageHandler() { + + @Override + public void handle(ClusterMessage message) { + LabelResourceRequest request = SERIALIZER + .decode(message.payload()); + log.trace("received get flow entry request for {}", + request); + final Collection<LabelResource> resource = internalApply(request); + message.respond(SERIALIZER + .encode(resource)); + } + }, messageHandlingExecutor); + clusterCommunicator + .addSubscriber(LabelResourceMessageSubjects.LABEL_POOL_RELEASE, + new ClusterMessageHandler() { + + @Override + public void handle(ClusterMessage message) { + LabelResourceRequest request = SERIALIZER + .decode(message.payload()); + log.trace("received get flow entry request for {}", + request); + final boolean isSuccess = internalRelease(request); + message.respond(SERIALIZER + .encode(isSuccess)); + } + }, messageHandlingExecutor); + log.info("Started"); + } + + @Deactivate + public void deactivate() { + clusterCommunicator + .removeSubscriber(LabelResourceMessageSubjects.LABEL_POOL_CREATED); + clusterCommunicator + .removeSubscriber(LabelResourceMessageSubjects.LABEL_POOL_APPLY); + clusterCommunicator + .removeSubscriber(LabelResourceMessageSubjects.LABEL_POOL_DESTROYED); + clusterCommunicator + .removeSubscriber(LabelResourceMessageSubjects.LABEL_POOL_RELEASE); + messageHandlingExecutor.shutdown(); + log.info("Stopped"); + } + + @Override + public boolean createDevicePool(DeviceId deviceId, + LabelResourceId beginLabel, + LabelResourceId endLabel) { + LabelResourcePool pool = new LabelResourcePool(deviceId.toString(), + beginLabel.labelId(), + endLabel.labelId()); + return this.create(pool); + } + + @Override + public boolean createGlobalPool(LabelResourceId beginLabel, + LabelResourceId endLabel) { + LabelResourcePool pool = new LabelResourcePool( + GLOBAL_RESOURCE_POOL_DEVICE_ID, + beginLabel.labelId(), + endLabel.labelId()); + return this.internalCreate(pool); + } + + private boolean create(LabelResourcePool pool) { + Device device = (Device) deviceService.getDevice(pool.deviceId()); + if (device == null) { + return false; + } + + NodeId master = mastershipService.getMasterFor(pool.deviceId()); + + if (master == null) { + log.warn("Failed to create label resource pool: No master for {}", pool); + return false; + } + + if (master.equals(clusterService.getLocalNode().id())) { + return internalCreate(pool); + } + + log.trace("Forwarding getFlowEntries to {}, which is the primary (master) for device {}", + master, pool.deviceId()); + + return complete(clusterCommunicator + .sendAndReceive(pool, + LabelResourceMessageSubjects.LABEL_POOL_CREATED, + SERIALIZER::encode, SERIALIZER::decode, + master)); + } + + private boolean internalCreate(LabelResourcePool pool) { + Versioned<LabelResourcePool> poolOld = resourcePool + .get(pool.deviceId()); + if (poolOld == null) { + resourcePool.put(pool.deviceId(), pool); + LabelResourceEvent event = new LabelResourceEvent( + Type.POOL_CREATED, + pool); + notifyDelegate(event); + return true; + } + return false; + } + + @Override + public boolean destroyDevicePool(DeviceId deviceId) { + Device device = (Device) deviceService.getDevice(deviceId); + if (device == null) { + return false; + } + + NodeId master = mastershipService.getMasterFor(deviceId); + + if (master == null) { + log.warn("Failed to destroyDevicePool. No master for {}", deviceId); + return false; + } + + if (master.equals(clusterService.getLocalNode().id())) { + return internalDestroy(deviceId); + } + + log.trace("Forwarding request to {}, which is the primary (master) for device {}", + master, deviceId); + + return complete(clusterCommunicator + .sendAndReceive(deviceId, + LabelResourceMessageSubjects.LABEL_POOL_DESTROYED, + SERIALIZER::encode, SERIALIZER::decode, + master)); + } + + private boolean internalDestroy(DeviceId deviceId) { + Versioned<LabelResourcePool> poolOld = resourcePool.get(deviceId); + if (poolOld != null) { + resourcePool.remove(deviceId); + LabelResourceEvent event = new LabelResourceEvent( + Type.POOL_CREATED, + poolOld.value()); + notifyDelegate(event); + } + log.info("success to destroy the label resource pool of device id {}", + deviceId); + return true; + } + + @Override + public Collection<LabelResource> applyFromDevicePool(DeviceId deviceId, + long applyNum) { + Device device = (Device) deviceService.getDevice(deviceId); + if (device == null) { + return Collections.emptyList(); + } + LabelResourceRequest request = new LabelResourceRequest( + deviceId, + LabelResourceRequest.Type.APPLY, + applyNum, null); + NodeId master = mastershipService.getMasterFor(deviceId); + + if (master == null) { + log.warn("Failed to applyFromDevicePool: No master for {}", deviceId); + return Collections.emptyList(); + } + + if (master.equals(clusterService.getLocalNode().id())) { + return internalApply(request); + } + + log.trace("Forwarding request to {}, which is the primary (master) for device {}", + master, deviceId); + + return complete(clusterCommunicator + .sendAndReceive(request, + LabelResourceMessageSubjects.LABEL_POOL_APPLY, + SERIALIZER::encode, SERIALIZER::decode, + master)); + } + + private Collection<LabelResource> internalApply(LabelResourceRequest request) { + DeviceId deviceId = request.deviceId(); + long applyNum = request.applyNum(); + Versioned<LabelResourcePool> poolOld = resourcePool.get(deviceId); + LabelResourcePool pool = poolOld.value(); + Collection<LabelResource> result = new HashSet<LabelResource>(); + long freeNum = this.getFreeNumOfDevicePool(deviceId); + if (applyNum > freeNum) { + log.info("the free number of the label resource pool of deviceId {} is not enough."); + return Collections.emptyList(); + } + Set<LabelResource> releaseLabels = new HashSet<LabelResource>( + pool.releaseLabelId()); + long tmp = releaseLabels.size() > applyNum ? applyNum : releaseLabels + .size(); + LabelResource resource = null; + for (int i = 0; i < tmp; i++) { + Iterator<LabelResource> it = releaseLabels.iterator(); + if (it.hasNext()) { + resource = it.next(); + releaseLabels.remove(resource); + } + result.add(resource); + } + for (long j = pool.currentUsedMaxLabelId().labelId(); j < pool + .currentUsedMaxLabelId().labelId() + applyNum - tmp; j++) { + resource = new DefaultLabelResource(deviceId, + LabelResourceId + .labelResourceId(j)); + result.add(resource); + } + long beginLabel = pool.beginLabel().labelId(); + long endLabel = pool.endLabel().labelId(); + long totalNum = pool.totalNum(); + long current = pool.currentUsedMaxLabelId().labelId() + applyNum - tmp; + long usedNum = pool.usedNum() + applyNum; + ImmutableSet<LabelResource> freeLabel = ImmutableSet + .copyOf(releaseLabels); + LabelResourcePool newPool = new LabelResourcePool(deviceId.toString(), + beginLabel, endLabel, + totalNum, usedNum, + current, freeLabel); + resourcePool.put(deviceId, newPool); + log.info("success to apply label resource"); + return result; + } + + @Override + public boolean releaseToDevicePool(Multimap<DeviceId, LabelResource> release) { + Map<DeviceId, Collection<LabelResource>> maps = release.asMap(); + Set<DeviceId> deviceIdSet = maps.keySet(); + LabelResourceRequest request = null; + for (Iterator<DeviceId> it = deviceIdSet.iterator(); it.hasNext();) { + DeviceId deviceId = (DeviceId) it.next(); + Device device = (Device) deviceService.getDevice(deviceId); + if (device == null) { + continue; + } + ImmutableSet<LabelResource> collection = ImmutableSet.copyOf(maps + .get(deviceId)); + request = new LabelResourceRequest( + deviceId, + LabelResourceRequest.Type.RELEASE, + 0, collection); + NodeId master = mastershipService.getMasterFor(deviceId); + + if (master == null) { + log.warn("Failed to releaseToDevicePool: No master for {}", deviceId); + return false; + } + + if (master.equals(clusterService.getLocalNode().id())) { + return internalRelease(request); + } + + log.trace("Forwarding request to {}, which is the primary (master) for device {}", + master, deviceId); + + return complete(clusterCommunicator + .sendAndReceive(request, + LabelResourceMessageSubjects.LABEL_POOL_RELEASE, + SERIALIZER::encode, SERIALIZER::decode, + master)); + } + return false; + } + + private boolean internalRelease(LabelResourceRequest request) { + DeviceId deviceId = request.deviceId(); + Collection<LabelResource> release = request.releaseCollection(); + Versioned<LabelResourcePool> poolOld = resourcePool.get(deviceId); + LabelResourcePool pool = poolOld.value(); + if (pool == null) { + log.info("the label resource pool of device id {} does not exist"); + return false; + } + Set<LabelResource> storeSet = new HashSet<LabelResource>( + pool.releaseLabelId()); + LabelResource labelResource = null; + long realReleasedNum = 0; + for (Iterator<LabelResource> it = release.iterator(); it.hasNext();) { + labelResource = it.next(); + if (labelResource.labelResourceId().labelId() < pool.beginLabel() + .labelId() + || labelResource.labelResourceId().labelId() > pool + .endLabel().labelId()) { + continue; + } + if (pool.currentUsedMaxLabelId().labelId() > labelResource + .labelResourceId().labelId() + || !storeSet.contains(labelResource)) { + storeSet.add(labelResource); + realReleasedNum++; + } + } + long beginNum = pool.beginLabel().labelId(); + long endNum = pool.endLabel().labelId(); + long totalNum = pool.totalNum(); + long usedNum = pool.usedNum() - realReleasedNum; + long current = pool.currentUsedMaxLabelId().labelId(); + ImmutableSet<LabelResource> s = ImmutableSet.copyOf(storeSet); + LabelResourcePool newPool = new LabelResourcePool(deviceId.toString(), + beginNum, endNum, + totalNum, usedNum, + current, s); + resourcePool.put(deviceId, newPool); + log.info("success to release label resource"); + return true; + } + + @Override + public boolean isDevicePoolFull(DeviceId deviceId) { + Versioned<LabelResourcePool> pool = resourcePool.get(deviceId); + if (pool == null) { + return true; + } + return pool.value().currentUsedMaxLabelId() == pool.value().endLabel() + && pool.value().releaseLabelId().size() == 0 ? true : false; + } + + @Override + public long getFreeNumOfDevicePool(DeviceId deviceId) { + Versioned<LabelResourcePool> pool = resourcePool.get(deviceId); + if (pool == null) { + return 0; + } + return pool.value().endLabel().labelId() + - pool.value().currentUsedMaxLabelId().labelId() + + pool.value().releaseLabelId().size(); + } + + @Override + public LabelResourcePool getDeviceLabelResourcePool(DeviceId deviceId) { + Versioned<LabelResourcePool> pool = resourcePool.get(deviceId); + return pool == null ? null : pool.value(); + } + + @Override + public boolean destroyGlobalPool() { + return this.internalDestroy(DeviceId + .deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID)); + } + + @Override + public Collection<LabelResource> applyFromGlobalPool(long applyNum) { + LabelResourceRequest request = new LabelResourceRequest( + DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID), + LabelResourceRequest.Type.APPLY, + applyNum, null); + return this.internalApply(request); + } + + @Override + public boolean releaseToGlobalPool(Set<LabelResourceId> release) { + Set<LabelResource> set = new HashSet<LabelResource>(); + DefaultLabelResource resource = null; + for (LabelResourceId labelResource : release) { + resource = new DefaultLabelResource( + DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID), + labelResource); + set.add(resource); + } + LabelResourceRequest request = new LabelResourceRequest( + DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID), + LabelResourceRequest.Type.APPLY, + 0, + ImmutableSet + .copyOf(set)); + return this.internalRelease(request); + } + + @Override + public boolean isGlobalPoolFull() { + return this.isDevicePoolFull(DeviceId + .deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID)); + } + + @Override + public long getFreeNumOfGlobalPool() { + return this.getFreeNumOfDevicePool(DeviceId + .deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID)); + } + + @Override + public LabelResourcePool getGlobalLabelResourcePool() { + return this.getDeviceLabelResourcePool(DeviceId + .deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID)); + } + + private <T> T complete(Future<T> future) { + try { + return future.get(PEER_REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.error("Interrupted while waiting for operation to complete.", e); + return null; + } catch (TimeoutException | ExecutionException e) { + log.error("Failed remote operation", e); + return null; + } + } +} diff --git a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/LabelResourceMessageSubjects.java b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/LabelResourceMessageSubjects.java new file mode 100644 index 00000000..0a6f1640 --- /dev/null +++ b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/LabelResourceMessageSubjects.java @@ -0,0 +1,17 @@ +package org.onosproject.incubator.store.resource.impl; + +import org.onosproject.store.cluster.messaging.MessageSubject; + +public final class LabelResourceMessageSubjects { + + private LabelResourceMessageSubjects() { + } + public static final MessageSubject LABEL_POOL_CREATED + = new MessageSubject("label-resource-pool-created"); + public static final MessageSubject LABEL_POOL_DESTROYED + = new MessageSubject("label-resource-pool-destroyed"); + public static final MessageSubject LABEL_POOL_APPLY + = new MessageSubject("label-resource-pool-apply"); + public static final MessageSubject LABEL_POOL_RELEASE + = new MessageSubject("label-resource-pool-release"); +} diff --git a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/package-info.java b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/package-info.java new file mode 100644 index 00000000..da0dc2e5 --- /dev/null +++ b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/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 label resource distributed store. + */ +package org.onosproject.incubator.store.resource.impl;
\ No newline at end of file diff --git a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/DistributedTunnelStore.java b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/DistributedTunnelStore.java new file mode 100644 index 00000000..78c6468e --- /dev/null +++ b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/DistributedTunnelStore.java @@ -0,0 +1,532 @@ +/* + * Copyright 2014-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.tunnel.impl; + +import static org.slf4j.LoggerFactory.getLogger; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.util.KryoNamespace; +import org.onosproject.cluster.ClusterService; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.core.IdGenerator; +import org.onosproject.incubator.net.tunnel.DefaultTunnel; +import org.onosproject.incubator.net.tunnel.Tunnel; +import org.onosproject.incubator.net.tunnel.Tunnel.Type; +import org.onosproject.incubator.net.tunnel.TunnelEndPoint; +import org.onosproject.incubator.net.tunnel.TunnelEvent; +import org.onosproject.incubator.net.tunnel.TunnelId; +import org.onosproject.incubator.net.tunnel.TunnelName; +import org.onosproject.incubator.net.tunnel.TunnelStore; +import org.onosproject.incubator.net.tunnel.TunnelStoreDelegate; +import org.onosproject.incubator.net.tunnel.TunnelSubscription; +import org.onosproject.net.Annotations; +import org.onosproject.net.DefaultAnnotations; +import org.onosproject.net.SparseAnnotations; +import org.onosproject.net.provider.ProviderId; +import org.onosproject.store.AbstractStore; +import org.onosproject.store.app.GossipApplicationStore.InternalState; +import org.onosproject.store.cluster.messaging.ClusterCommunicationService; +import org.onosproject.store.serializers.KryoNamespaces; +import org.onosproject.store.service.EventuallyConsistentMap; +import org.onosproject.store.service.MultiValuedTimestamp; +import org.onosproject.store.service.StorageService; +import org.onosproject.store.service.WallClockTimestamp; +import org.slf4j.Logger; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableSet; + +/** + * Manages inventory of tunnel in distributed data store that uses optimistic + * replication and gossip based techniques. + */ +@Component(immediate = true) +@Service +public class DistributedTunnelStore + extends AbstractStore<TunnelEvent, TunnelStoreDelegate> + implements TunnelStore { + + private final Logger log = getLogger(getClass()); + + /** + * The topic used for obtaining globally unique ids. + */ + private String runnelOpTopoic = "tunnel-ops-ids"; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected ClusterCommunicationService clusterCommunicator; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected ClusterService clusterService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected StorageService storageService; + + // tunnel identity as map key in the store. + private EventuallyConsistentMap<TunnelId, Tunnel> tunnelIdAsKeyStore; + // tunnel name as map key in the store. + private EventuallyConsistentMap<TunnelName, Set<TunnelId>> tunnelNameAsKeyStore; + // maintains all the tunnels between source and destination. + private EventuallyConsistentMap<TunnelKey, Set<TunnelId>> srcAndDstKeyStore; + // maintains all the tunnels by tunnel type. + private EventuallyConsistentMap<Tunnel.Type, Set<TunnelId>> typeKeyStore; + // maintains records that app subscribes tunnel. + private EventuallyConsistentMap<ApplicationId, Set<TunnelSubscription>> orderRelationship; + + private IdGenerator idGenerator; + + @Activate + public void activate() { + KryoNamespace.Builder serializer = KryoNamespace.newBuilder() + .register(KryoNamespaces.API) + .register(MultiValuedTimestamp.class) + .register(InternalState.class); + tunnelIdAsKeyStore = storageService + .<TunnelId, Tunnel>eventuallyConsistentMapBuilder() + .withName("all_tunnel").withSerializer(serializer) + .withTimestampProvider((k, v) -> new WallClockTimestamp()).build(); + tunnelNameAsKeyStore = storageService + .<TunnelName, Set<TunnelId>>eventuallyConsistentMapBuilder() + .withName("tunnel_name_tunnel").withSerializer(serializer) + .withTimestampProvider((k, v) -> new WallClockTimestamp()).build(); + srcAndDstKeyStore = storageService + .<TunnelKey, Set<TunnelId>>eventuallyConsistentMapBuilder() + .withName("src_dst_tunnel").withSerializer(serializer) + .withTimestampProvider((k, v) -> new WallClockTimestamp()).build(); + typeKeyStore = storageService + .<Tunnel.Type, Set<TunnelId>>eventuallyConsistentMapBuilder() + .withName("type_tunnel").withSerializer(serializer) + .withTimestampProvider((k, v) -> new WallClockTimestamp()).build(); + orderRelationship = storageService + .<ApplicationId, Set<TunnelSubscription>>eventuallyConsistentMapBuilder() + .withName("type_tunnel").withSerializer(serializer) + .withTimestampProvider((k, v) -> new WallClockTimestamp()).build(); + idGenerator = coreService.getIdGenerator(runnelOpTopoic); + log.info("Started"); + } + + @Deactivate + public void deactivate() { + orderRelationship.destroy(); + tunnelIdAsKeyStore.destroy(); + srcAndDstKeyStore.destroy(); + typeKeyStore.destroy(); + tunnelNameAsKeyStore.destroy(); + log.info("Stopped"); + } + + @Override + public TunnelId createOrUpdateTunnel(Tunnel tunnel) { + // tunnelIdAsKeyStore. + if (tunnel.tunnelId() != null && !"".equals(tunnel.tunnelId())) { + Tunnel old = tunnelIdAsKeyStore.get(tunnel.tunnelId()); + if (old == null) { + log.info("This tunnel[" + tunnel.tunnelId() + "] is not available."); + return tunnel.tunnelId(); + } + DefaultAnnotations oldAnno = (DefaultAnnotations) old.annotations(); + SparseAnnotations newAnno = (SparseAnnotations) tunnel.annotations(); + Tunnel newT = new DefaultTunnel(old.providerId(), old.src(), + old.dst(), old.type(), + old.state(), old.groupId(), + old.tunnelId(), + old.tunnelName(), + old.path(), + DefaultAnnotations.merge(oldAnno, newAnno)); + tunnelIdAsKeyStore.put(tunnel.tunnelId(), newT); + TunnelEvent event = new TunnelEvent( + TunnelEvent.Type.TUNNEL_UPDATED, + tunnel); + notifyDelegate(event); + return tunnel.tunnelId(); + } else { + TunnelId tunnelId = TunnelId.valueOf(idGenerator.getNewId()); + Tunnel newT = new DefaultTunnel(tunnel.providerId(), tunnel.src(), + tunnel.dst(), tunnel.type(), + tunnel.state(), tunnel.groupId(), + tunnelId, + tunnel.tunnelName(), + tunnel.path(), + tunnel.annotations()); + TunnelKey key = TunnelKey.tunnelKey(tunnel.src(), tunnel.dst()); + tunnelIdAsKeyStore.put(tunnelId, newT); + Set<TunnelId> tunnelnameSet = tunnelNameAsKeyStore.get(tunnel + .tunnelName()); + if (tunnelnameSet == null) { + tunnelnameSet = new HashSet<TunnelId>(); + } + tunnelnameSet.add(tunnelId); + tunnelNameAsKeyStore.put(tunnel + .tunnelName(), tunnelnameSet); + Set<TunnelId> srcAndDstKeySet = srcAndDstKeyStore.get(key); + if (srcAndDstKeySet == null) { + srcAndDstKeySet = new HashSet<TunnelId>(); + } + srcAndDstKeySet.add(tunnelId); + srcAndDstKeyStore.put(key, srcAndDstKeySet); + Set<TunnelId> typeKeySet = typeKeyStore.get(tunnel.type()); + if (typeKeySet == null) { + typeKeySet = new HashSet<TunnelId>(); + } + typeKeySet.add(tunnelId); + typeKeyStore.put(tunnel.type(), typeKeySet); + TunnelEvent event = new TunnelEvent(TunnelEvent.Type.TUNNEL_ADDED, + tunnel); + notifyDelegate(event); + return tunnelId; + } + } + + @Override + public void deleteTunnel(TunnelId tunnelId) { + Tunnel deletedTunnel = tunnelIdAsKeyStore.get(tunnelId); + if (deletedTunnel == null) { + return; + } + tunnelNameAsKeyStore.get(deletedTunnel.tunnelName()).remove(tunnelId); + tunnelIdAsKeyStore.remove(tunnelId); + TunnelKey key = new TunnelKey(deletedTunnel.src(), deletedTunnel.dst()); + srcAndDstKeyStore.get(key).remove(tunnelId); + typeKeyStore.get(deletedTunnel.type()).remove(tunnelId); + TunnelEvent event = new TunnelEvent(TunnelEvent.Type.TUNNEL_REMOVED, + deletedTunnel); + notifyDelegate(event); + } + + @Override + public void deleteTunnel(TunnelEndPoint src, TunnelEndPoint dst, + ProviderId producerName) { + TunnelKey key = TunnelKey.tunnelKey(src, dst); + Set<TunnelId> idSet = srcAndDstKeyStore.get(key); + if (idSet == null) { + return; + } + Tunnel deletedTunnel = null; + TunnelEvent event = null; + List<TunnelEvent> ls = new ArrayList<TunnelEvent>(); + for (TunnelId id : idSet) { + deletedTunnel = tunnelIdAsKeyStore.get(id); + event = new TunnelEvent(TunnelEvent.Type.TUNNEL_REMOVED, + deletedTunnel); + ls.add(event); + if (producerName.equals(deletedTunnel.providerId())) { + tunnelIdAsKeyStore.remove(deletedTunnel.tunnelId()); + tunnelNameAsKeyStore.get(deletedTunnel.tunnelName()) + .remove(deletedTunnel.tunnelId()); + srcAndDstKeyStore.get(key).remove(deletedTunnel.tunnelId()); + typeKeyStore.get(deletedTunnel.type()) + .remove(deletedTunnel.tunnelId()); + } + } + notifyDelegate(ls); + } + + @Override + public void deleteTunnel(TunnelEndPoint src, TunnelEndPoint dst, Type type, + ProviderId producerName) { + TunnelKey key = TunnelKey.tunnelKey(src, dst); + Set<TunnelId> idSet = srcAndDstKeyStore.get(key); + if (idSet == null) { + return; + } + Tunnel deletedTunnel = null; + TunnelEvent event = null; + List<TunnelEvent> ls = new ArrayList<TunnelEvent>(); + for (TunnelId id : idSet) { + deletedTunnel = tunnelIdAsKeyStore.get(id); + event = new TunnelEvent(TunnelEvent.Type.TUNNEL_REMOVED, + deletedTunnel); + ls.add(event); + if (producerName.equals(deletedTunnel.providerId()) + && type.equals(deletedTunnel.type())) { + tunnelIdAsKeyStore.remove(deletedTunnel.tunnelId()); + tunnelNameAsKeyStore.get(deletedTunnel.tunnelName()) + .remove(deletedTunnel.tunnelId()); + srcAndDstKeyStore.get(key).remove(deletedTunnel.tunnelId()); + typeKeyStore.get(deletedTunnel.type()) + .remove(deletedTunnel.tunnelId()); + } + } + notifyDelegate(ls); + } + + @Override + public Tunnel borrowTunnel(ApplicationId appId, TunnelId tunnelId, + Annotations... annotations) { + Set<TunnelSubscription> orderSet = orderRelationship.get(appId); + if (orderSet == null) { + orderSet = new HashSet<TunnelSubscription>(); + } + TunnelSubscription order = new TunnelSubscription(appId, null, null, tunnelId, null, null, + annotations); + Tunnel result = tunnelIdAsKeyStore.get(tunnelId); + if (result != null || Tunnel.State.INACTIVE.equals(result.state())) { + return null; + } + orderSet.add(order); + orderRelationship.put(appId, orderSet); + return result; + } + + @Override + public Collection<Tunnel> borrowTunnel(ApplicationId appId, + TunnelEndPoint src, + TunnelEndPoint dst, + Annotations... annotations) { + Set<TunnelSubscription> orderSet = orderRelationship.get(appId); + if (orderSet == null) { + orderSet = new HashSet<TunnelSubscription>(); + } + TunnelSubscription order = new TunnelSubscription(appId, src, dst, null, null, null, annotations); + boolean isExist = orderSet.contains(order); + if (!isExist) { + orderSet.add(order); + } + orderRelationship.put(appId, orderSet); + TunnelKey key = TunnelKey.tunnelKey(src, dst); + Set<TunnelId> idSet = srcAndDstKeyStore.get(key); + if (idSet == null || idSet.size() == 0) { + return Collections.emptySet(); + } + Collection<Tunnel> tunnelSet = new HashSet<Tunnel>(); + for (TunnelId tunnelId : idSet) { + Tunnel result = tunnelIdAsKeyStore.get(tunnelId); + if (Tunnel.State.ACTIVE.equals(result.state())) { + tunnelSet.add(result); + } + } + return tunnelSet; + } + + @Override + public Collection<Tunnel> borrowTunnel(ApplicationId appId, + TunnelEndPoint src, + TunnelEndPoint dst, Type type, + Annotations... annotations) { + Set<TunnelSubscription> orderSet = orderRelationship.get(appId); + if (orderSet == null) { + orderSet = new HashSet<TunnelSubscription>(); + } + TunnelSubscription order = new TunnelSubscription(appId, src, dst, null, type, null, annotations); + boolean isExist = orderSet.contains(order); + if (!isExist) { + orderSet.add(order); + } + orderRelationship.put(appId, orderSet); + TunnelKey key = TunnelKey.tunnelKey(src, dst); + Set<TunnelId> idSet = srcAndDstKeyStore.get(key); + if (idSet == null || idSet.size() == 0) { + return Collections.emptySet(); + } + Collection<Tunnel> tunnelSet = new HashSet<Tunnel>(); + for (TunnelId tunnelId : idSet) { + Tunnel result = tunnelIdAsKeyStore.get(tunnelId); + if (type.equals(result.type()) + && Tunnel.State.ACTIVE.equals(result.state())) { + tunnelSet.add(result); + } + } + return tunnelSet; + } + + @Override + public Collection<Tunnel> borrowTunnel(ApplicationId appId, + TunnelName tunnelName, + Annotations... annotations) { + Set<TunnelSubscription> orderSet = orderRelationship.get(appId); + if (orderSet == null) { + orderSet = new HashSet<TunnelSubscription>(); + } + TunnelSubscription order = new TunnelSubscription(appId, null, null, null, null, tunnelName, + annotations); + boolean isExist = orderSet.contains(order); + if (!isExist) { + orderSet.add(order); + } + orderRelationship.put(appId, orderSet); + Set<TunnelId> idSet = tunnelNameAsKeyStore.get(tunnelName); + if (idSet == null || idSet.size() == 0) { + return Collections.emptySet(); + } + Collection<Tunnel> tunnelSet = new HashSet<Tunnel>(); + for (TunnelId tunnelId : idSet) { + Tunnel result = tunnelIdAsKeyStore.get(tunnelId); + if (Tunnel.State.ACTIVE.equals(result.state())) { + tunnelSet.add(result); + } + } + return tunnelSet; + } + + @Override + public boolean returnTunnel(ApplicationId appId, TunnelName tunnelName, + Annotations... annotations) { + TunnelSubscription order = new TunnelSubscription(appId, null, null, null, null, tunnelName, + annotations); + return deleteOrder(order); + } + + @Override + public boolean returnTunnel(ApplicationId appId, TunnelId tunnelId, + Annotations... annotations) { + TunnelSubscription order = new TunnelSubscription(appId, null, null, tunnelId, null, null, + annotations); + return deleteOrder(order); + } + + @Override + public boolean returnTunnel(ApplicationId appId, TunnelEndPoint src, + TunnelEndPoint dst, Type type, + Annotations... annotations) { + TunnelSubscription order = new TunnelSubscription(appId, src, dst, null, type, null, annotations); + return deleteOrder(order); + } + + @Override + public boolean returnTunnel(ApplicationId appId, TunnelEndPoint src, + TunnelEndPoint dst, Annotations... annotations) { + TunnelSubscription order = new TunnelSubscription(appId, src, dst, null, null, null, annotations); + return deleteOrder(order); + } + + private boolean deleteOrder(TunnelSubscription order) { + Set<TunnelSubscription> orderSet = orderRelationship.get(order.consumerId()); + if (orderSet == null) { + return true; + } + if (orderSet.contains(order)) { + orderSet.remove(order); + return true; + } + return false; + } + + @Override + public Tunnel queryTunnel(TunnelId tunnelId) { + return tunnelIdAsKeyStore.get(tunnelId); + } + + @Override + public Collection<TunnelSubscription> queryTunnelSubscription(ApplicationId appId) { + return orderRelationship.get(appId) != null ? ImmutableSet.copyOf(orderRelationship + .get(appId)) : Collections.emptySet(); + } + + @Override + public Collection<Tunnel> queryTunnel(Type type) { + Collection<Tunnel> result = new HashSet<Tunnel>(); + Set<TunnelId> tunnelIds = typeKeyStore.get(type); + if (tunnelIds == null) { + return Collections.emptySet(); + } + for (TunnelId id : tunnelIds) { + result.add(tunnelIdAsKeyStore.get(id)); + } + return result.size() == 0 ? Collections.emptySet() : ImmutableSet + .copyOf(result); + } + + @Override + public Collection<Tunnel> queryTunnel(TunnelEndPoint src, TunnelEndPoint dst) { + Collection<Tunnel> result = new HashSet<Tunnel>(); + TunnelKey key = TunnelKey.tunnelKey(src, dst); + Set<TunnelId> tunnelIds = srcAndDstKeyStore.get(key); + if (tunnelIds == null) { + return Collections.emptySet(); + } + for (TunnelId id : tunnelIds) { + result.add(tunnelIdAsKeyStore.get(id)); + } + return result.size() == 0 ? Collections.emptySet() : ImmutableSet + .copyOf(result); + } + + @Override + public Collection<Tunnel> queryAllTunnels() { + return tunnelIdAsKeyStore.values(); + } + + @Override + public int tunnelCount() { + return tunnelIdAsKeyStore.size(); + } + + /** + * Uses source TunnelPoint and destination TunnelPoint as map key. + */ + private static final class TunnelKey { + private final TunnelEndPoint src; + private final TunnelEndPoint dst; + + private TunnelKey(TunnelEndPoint src, TunnelEndPoint dst) { + this.src = src; + this.dst = dst; + + } + + /** + * create a map key. + * + * @param src + * @param dst + * @return a key using source ip and destination ip + */ + static TunnelKey tunnelKey(TunnelEndPoint src, TunnelEndPoint dst) { + return new TunnelKey(src, dst); + } + + @Override + public int hashCode() { + return Objects.hash(src, dst); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof TunnelKey) { + final TunnelKey other = (TunnelKey) obj; + return Objects.equals(this.src, other.src) + && Objects.equals(this.dst, other.dst); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).add("src", src) + .add("dst", dst).toString(); + } + } +} diff --git a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/package-info.java b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/package-info.java new file mode 100644 index 00000000..f0c06f74 --- /dev/null +++ b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/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 tunnel store using p2p synchronization protocol. + */ +package org.onosproject.incubator.store.tunnel.impl; |