2  * Copyright 2015 Open Networking Laboratory
 
   4  * Licensed under the Apache License, Version 2.0 (the "License");
 
   5  * you may not use this file except in compliance with the License.
 
   6  * You may obtain a copy of the License at
 
   8  *     http://www.apache.org/licenses/LICENSE-2.0
 
  10  * Unless required by applicable law or agreed to in writing, software
 
  11  * distributed under the License is distributed on an "AS IS" BASIS,
 
  12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  13  * See the License for the specific language governing permissions and
 
  14  * limitations under the License.
 
  16 package org.onosproject.net.newresource.impl;
 
  18 import org.onlab.packet.MplsLabel;
 
  19 import org.onlab.packet.VlanId;
 
  20 import org.onlab.util.ItemNotFoundException;
 
  21 import org.onosproject.net.ConnectPoint;
 
  22 import org.onosproject.net.Link;
 
  23 import org.onosproject.net.LinkKey;
 
  24 import org.onosproject.net.behaviour.MplsQuery;
 
  25 import org.onosproject.net.behaviour.VlanQuery;
 
  26 import org.onosproject.net.driver.DriverHandler;
 
  27 import org.onosproject.net.driver.DriverService;
 
  28 import org.onosproject.net.link.LinkEvent;
 
  29 import org.onosproject.net.link.LinkListener;
 
  30 import org.onosproject.net.newresource.ResourceAdminService;
 
  31 import org.onosproject.net.newresource.ResourcePath;
 
  33 import java.util.List;
 
  34 import java.util.concurrent.ExecutorService;
 
  35 import java.util.function.Predicate;
 
  36 import java.util.stream.Collectors;
 
  37 import java.util.stream.IntStream;
 
  39 import static com.google.common.base.Preconditions.checkNotNull;
 
  42  * An implementation of LinkListener registering links as resources.
 
  44 final class ResourceLinkListener implements LinkListener {
 
  46     private static final int TOTAL_VLANS = 1024;
 
  47     private static final List<VlanId> ENTIRE_VLAN_IDS = getEntireVlans();
 
  49     private static final int TOTAL_MPLS_LABELS = 1048576;
 
  50     private static final List<MplsLabel> ENTIRE_MPLS_LABELS = getEntireMplsLabels();
 
  52     private final ResourceAdminService adminService;
 
  53     private final DriverService driverService;
 
  54     private final ExecutorService executor;
 
  57      * Creates an instance with the specified ResourceAdminService and ExecutorService.
 
  59      * @param adminService instance invoked to register resources
 
  60      * @param driverService driver service instance
 
  61      * @param executor executor used for processing resource registration
 
  63     ResourceLinkListener(ResourceAdminService adminService, DriverService driverService, ExecutorService executor) {
 
  64         this.adminService = checkNotNull(adminService);
 
  65         this.driverService = checkNotNull(driverService);
 
  66         this.executor = checkNotNull(executor);
 
  70     public void event(LinkEvent event) {
 
  71         Link link = event.subject();
 
  72         switch (event.type()) {
 
  74                 registerLinkResource(link);
 
  77                 unregisterLinkResource(link);
 
  84     private void registerLinkResource(Link link) {
 
  85         executor.submit(() -> {
 
  87             LinkKey linkKey = LinkKey.linkKey(link);
 
  88             adminService.registerResources(ResourcePath.ROOT, linkKey);
 
  90             ResourcePath linkPath = new ResourcePath(linkKey);
 
  91             // register VLAN IDs against the link
 
  92             if (isEnabled(link, this::isVlanEnabled)) {
 
  93                 adminService.registerResources(linkPath, ENTIRE_VLAN_IDS);
 
  96             // register MPLS labels against the link
 
  97             if (isEnabled(link, this::isMplsEnabled)) {
 
  98                 adminService.registerResources(linkPath, ENTIRE_MPLS_LABELS);
 
 103     private void unregisterLinkResource(Link link) {
 
 104         LinkKey linkKey = LinkKey.linkKey(link);
 
 105         executor.submit(() -> adminService.unregisterResources(ResourcePath.ROOT, linkKey));
 
 108     private boolean isEnabled(Link link, Predicate<ConnectPoint> predicate) {
 
 109         return predicate.test(link.src()) && predicate.test(link.dst());
 
 112     private boolean isVlanEnabled(ConnectPoint cp) {
 
 114             DriverHandler handler = driverService.createHandler(cp.deviceId());
 
 115             if (handler == null) {
 
 119             VlanQuery query = handler.behaviour(VlanQuery.class);
 
 120             return query != null && query.isEnabled(cp.port());
 
 121         } catch (ItemNotFoundException e) {
 
 126     private boolean isMplsEnabled(ConnectPoint cp) {
 
 128             DriverHandler handler = driverService.createHandler(cp.deviceId());
 
 129             if (handler == null) {
 
 133             MplsQuery query = handler.behaviour(MplsQuery.class);
 
 134             return query != null && query.isEnabled(cp.port());
 
 135         } catch (ItemNotFoundException e) {
 
 140     private static List<VlanId> getEntireVlans() {
 
 141         return IntStream.range(0, TOTAL_VLANS)
 
 142                 .mapToObj(x -> VlanId.vlanId((short) x))
 
 143                 .collect(Collectors.toList());
 
 146     private static List<MplsLabel> getEntireMplsLabels() {
 
 147         // potentially many objects are created
 
 148         return IntStream.range(0, TOTAL_MPLS_LABELS)
 
 149                 .mapToObj(MplsLabel::mplsLabel)
 
 150                 .collect(Collectors.toList());