f04c78b9bd1294d322aa1a5fe149e214d95268c7
[onosfw.git] /
1 /*
2  * Copyright 2015 Open Networking Laboratory
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package org.onosproject.net.newresource.impl;
17
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;
32
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;
38
39 import static com.google.common.base.Preconditions.checkNotNull;
40
41 /**
42  * An implementation of LinkListener registering links as resources.
43  */
44 final class ResourceLinkListener implements LinkListener {
45
46     private static final int TOTAL_VLANS = 1024;
47     private static final List<VlanId> ENTIRE_VLAN_IDS = getEntireVlans();
48
49     private static final int TOTAL_MPLS_LABELS = 1048576;
50     private static final List<MplsLabel> ENTIRE_MPLS_LABELS = getEntireMplsLabels();
51
52     private final ResourceAdminService adminService;
53     private final DriverService driverService;
54     private final ExecutorService executor;
55
56     /**
57      * Creates an instance with the specified ResourceAdminService and ExecutorService.
58      *
59      * @param adminService instance invoked to register resources
60      * @param driverService driver service instance
61      * @param executor executor used for processing resource registration
62      */
63     ResourceLinkListener(ResourceAdminService adminService, DriverService driverService, ExecutorService executor) {
64         this.adminService = checkNotNull(adminService);
65         this.driverService = checkNotNull(driverService);
66         this.executor = checkNotNull(executor);
67     }
68
69     @Override
70     public void event(LinkEvent event) {
71         Link link = event.subject();
72         switch (event.type()) {
73             case LINK_ADDED:
74                 registerLinkResource(link);
75                 break;
76             case LINK_REMOVED:
77                 unregisterLinkResource(link);
78                 break;
79             default:
80                 break;
81         }
82     }
83
84     private void registerLinkResource(Link link) {
85         executor.submit(() -> {
86             // register the link
87             LinkKey linkKey = LinkKey.linkKey(link);
88             adminService.registerResources(ResourcePath.ROOT, linkKey);
89
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);
94             }
95
96             // register MPLS labels against the link
97             if (isEnabled(link, this::isMplsEnabled)) {
98                 adminService.registerResources(linkPath, ENTIRE_MPLS_LABELS);
99             }
100         });
101     }
102
103     private void unregisterLinkResource(Link link) {
104         LinkKey linkKey = LinkKey.linkKey(link);
105         executor.submit(() -> adminService.unregisterResources(ResourcePath.ROOT, linkKey));
106     }
107
108     private boolean isEnabled(Link link, Predicate<ConnectPoint> predicate) {
109         return predicate.test(link.src()) && predicate.test(link.dst());
110     }
111
112     private boolean isVlanEnabled(ConnectPoint cp) {
113         try {
114             DriverHandler handler = driverService.createHandler(cp.deviceId());
115             if (handler == null) {
116                 return false;
117             }
118
119             VlanQuery query = handler.behaviour(VlanQuery.class);
120             return query != null && query.isEnabled(cp.port());
121         } catch (ItemNotFoundException e) {
122             return false;
123         }
124     }
125
126     private boolean isMplsEnabled(ConnectPoint cp) {
127         try {
128             DriverHandler handler = driverService.createHandler(cp.deviceId());
129             if (handler == null) {
130                 return false;
131             }
132
133             MplsQuery query = handler.behaviour(MplsQuery.class);
134             return query != null && query.isEnabled(cp.port());
135         } catch (ItemNotFoundException e) {
136             return false;
137         }
138     }
139
140     private static List<VlanId> getEntireVlans() {
141         return IntStream.range(0, TOTAL_VLANS)
142                 .mapToObj(x -> VlanId.vlanId((short) x))
143                 .collect(Collectors.toList());
144     }
145
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());
151     }
152 }