aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/incubator
diff options
context:
space:
mode:
authorAshlee Young <ashlee@onosfw.com>2015-09-09 22:15:21 -0700
committerAshlee Young <ashlee@onosfw.com>2015-09-09 22:15:21 -0700
commit13d05bc8458758ee39cb829098241e89616717ee (patch)
tree22a4d1ce65f15952f07a3df5af4b462b4697cb3a /framework/src/onos/incubator
parent6139282e1e93c2322076de4b91b1c85d0bc4a8b3 (diff)
ONOS checkin based on commit tag e796610b1f721d02f9b0e213cf6f7790c10ecd60
Change-Id: Ife8810491034fe7becdba75dda20de4267bd15cd
Diffstat (limited to 'framework/src/onos/incubator')
-rw-r--r--framework/src/onos/incubator/api/pom.xml49
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/PortStatisticsService.java36
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/ConfigException.java42
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/ExtraSubjectFactories.java38
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/InterfaceConfig.java87
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/package-info.java20
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/DomainEdge.java75
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/DomainVertex.java88
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomain.java124
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainAdminService.java53
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainConfig.java115
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainId.java79
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainListener.java27
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainProvider.java84
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentDomainService.java79
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentPrimitive.java41
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/IntentResource.java68
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/RequestContext.java54
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/TunnelPrimitive.java51
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/domain/package-info.java20
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/intf/Interface.java121
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/intf/InterfaceService.java69
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/package-info.java20
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/DefaultLabelResource.java83
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResource.java26
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceAdminService.java51
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceDelegate.java12
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceEvent.java40
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceId.java48
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceListener.java12
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourcePool.java176
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceProvider.java13
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceProviderRegistry.java13
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceProviderService.java28
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceRequest.java104
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceService.java100
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/LabelResourceStore.java139
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/resource/label/package-info.java20
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultOpticalTunnelEndPoint.java131
-rwxr-xr-xframework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnel.java178
-rwxr-xr-xframework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnelDescription.java130
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnelStatistics.java168
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/IpTunnelEndPoint.java80
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/OpticalLogicId.java81
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/OpticalTunnelEndPoint.java90
-rwxr-xr-xframework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/Tunnel.java155
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelAdminService.java65
-rwxr-xr-xframework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelDescription.java87
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelEndPoint.java28
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelEndPointFormatter.java33
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelEvent.java70
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelId.java89
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelListener.java27
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelName.java79
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProvider.java115
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProviderRegistry.java28
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProviderService.java58
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelService.java201
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStatistics.java63
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStore.java229
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStoreDelegate.java27
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelSubscription.java156
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/package-info.java20
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/NetworkId.java84
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/TenantId.java83
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualDevice.java26
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualElement.java39
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualHost.java26
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualLink.java26
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetwork.java40
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminService.java147
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java92
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualPort.java34
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/package-info.java20
-rw-r--r--framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/package-info.java21
-rw-r--r--framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/config/basics/OpticalPortConfigTest.java142
-rw-r--r--framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/resource/label/DefaultLabelResourceTest.java31
-rw-r--r--framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/resource/label/LabelResourcePoolTest.java23
-rw-r--r--framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/resource/label/LabelResourceRequestTest.java44
-rw-r--r--framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/DefaultTunnelTest.java47
-rw-r--r--framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelEventTest.java46
-rw-r--r--framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelIdTest.java66
-rw-r--r--framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelNameTest.java64
-rw-r--r--framework/src/onos/incubator/api/src/test/java/org/onosproject/incubator/net/tunnel/TunnelSubscriptionTest.java58
-rw-r--r--framework/src/onos/incubator/net/pom.xml101
-rw-r--r--framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/config/impl/ExtraNetworkConfigs.java69
-rw-r--r--framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/config/impl/package-info.java20
-rw-r--r--framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/domain/impl/IntentDomainManager.java210
-rw-r--r--framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/domain/impl/package-info.java20
-rw-r--r--framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/impl/PortStatisticsManager.java162
-rw-r--r--framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/impl/package-info.java20
-rw-r--r--framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/intf/impl/InterfaceManager.java184
-rw-r--r--framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java233
-rw-r--r--framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/resource/label/impl/LabelResourceManager.java221
-rw-r--r--framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/resource/label/impl/package-info.java20
-rw-r--r--framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/tunnel/impl/TunnelManager.java366
-rw-r--r--framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/tunnel/impl/package-info.java20
-rw-r--r--framework/src/onos/incubator/net/src/test/java/org/onosproject/incubator/net/meter/impl/MeterManagerTest.java234
-rw-r--r--framework/src/onos/incubator/net/src/test/resources/domain-config.json36
-rw-r--r--framework/src/onos/incubator/net/src/test/resources/fractal-domain-config.json28
-rw-r--r--framework/src/onos/incubator/pom.xml85
-rw-r--r--framework/src/onos/incubator/store/pom.xml89
-rw-r--r--framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/impl/package-info.java20
-rw-r--r--framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java258
-rw-r--r--framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/MeterData.java52
-rw-r--r--framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/DistributedLabelResourceStore.java543
-rw-r--r--framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/LabelResourceMessageSubjects.java17
-rw-r--r--framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/package-info.java20
-rw-r--r--framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/DistributedTunnelStore.java532
-rw-r--r--framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/package-info.java20
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.&nbsp; 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 &amp; 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;