aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/incubator/net/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/incubator/net/src/main')
-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
12 files changed, 1545 insertions, 0 deletions
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;