blob: efbaf9141f2a8e09a9fcaba4f66c9b6ab62c4153 [file] [log] [blame]
Brian Stankefb61df42016-07-25 11:47:51 -04001/*
2 * Copyright 2016-present 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
17package org.onosproject.incubator.net.virtual.impl;
18
19import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Deactivate;
22import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
24import org.apache.felix.scr.annotations.Service;
25import org.onosproject.incubator.net.tunnel.TunnelId;
26import org.onosproject.incubator.net.virtual.DefaultVirtualLink;
27import org.onosproject.incubator.net.virtual.NetworkId;
28import org.onosproject.incubator.net.virtual.VirtualNetworkProvider;
29import org.onosproject.incubator.net.virtual.VirtualNetworkProviderRegistry;
30import org.onosproject.incubator.net.virtual.VirtualNetworkProviderService;
31import org.onosproject.net.ConnectPoint;
32import org.onosproject.net.Link;
33import org.onosproject.net.Path;
34import org.onosproject.net.link.LinkEvent;
35import org.onosproject.net.provider.AbstractProvider;
36import org.onosproject.net.topology.Topology;
37import org.onosproject.net.topology.TopologyCluster;
38import org.onosproject.net.topology.TopologyEvent;
39import org.onosproject.net.topology.TopologyListener;
40import org.onosproject.net.topology.TopologyService;
41import org.slf4j.Logger;
42
43import java.util.HashSet;
44import java.util.Set;
45
46import static org.slf4j.LoggerFactory.getLogger;
47
48/**
49 * Virtual network topology provider.
50 */
51@Component(immediate = true)
52@Service
53public class VirtualNetworkTopologyProvider extends AbstractProvider implements VirtualNetworkProvider {
54
55 private final Logger log = getLogger(VirtualNetworkTopologyProvider.class);
56
57 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 protected VirtualNetworkProviderRegistry providerRegistry;
59
60 private VirtualNetworkProviderService providerService;
61
62 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 protected TopologyService topologyService;
64
65 protected TopologyListener topologyListener = new InternalTopologyListener();
66
67 /**
68 * Default constructor.
69 */
70 public VirtualNetworkTopologyProvider() {
71 super(DefaultVirtualLink.PID);
72 }
73
74 @Activate
75 public void activate() {
76 providerService = providerRegistry.register(this);
77 topologyService.addListener(topologyListener);
78
79 log.info("Started");
80 }
81
82 @Deactivate
83 public void deactivate() {
84 topologyService.removeListener(topologyListener);
85 providerRegistry.unregister(this);
86 providerService = null;
87 log.info("Stopped");
88 }
89
90 @Override
91 public boolean isTraversable(ConnectPoint src, ConnectPoint dst) {
92 final boolean[] foundSrc = new boolean[1];
93 final boolean[] foundDst = new boolean[1];
94 Topology topology = topologyService.currentTopology();
95 Set<Path> paths = topologyService.getPaths(topology, src.deviceId(), dst.deviceId());
96 paths.forEach(path -> {
97 foundDst[0] = false;
98 foundSrc[0] = false;
99 // Traverse the links in each path to determine if both the src and dst connection
100 // point are in the path, if so then this src/dst pair are traversable.
101 path.links().forEach(link -> {
102 if (link.src().equals(src)) {
103 foundSrc[0] = true;
104 }
105 if (link.dst().equals(dst)) {
106 foundDst[0] = true;
107 }
108 });
109 if (foundSrc[0] && foundDst[0]) {
110 return;
111 }
112 });
113 return foundSrc[0] && foundDst[0];
114 }
115
116 @Override
117 public TunnelId createTunnel(NetworkId networkId, ConnectPoint src, ConnectPoint dst) {
118 return null;
119 }
120
121 @Override
122 public void destroyTunnel(NetworkId networkId, TunnelId tunnelId) {
123
124 }
125
126 /**
127 * Returns a set of set of interconnected connect points in the default topology.
128 * The inner set represents the interconnected connect points, and the outerset
129 * represents separate clusters.
130 *
131 * @param topology the default topology
132 * @return set of set of interconnected connect points.
133 */
134 protected Set<Set<ConnectPoint>> getConnectPoints(Topology topology) {
135 Set<Set<ConnectPoint>> clusters = new HashSet<>();
136 Set<TopologyCluster> topologyClusters = topologyService.getClusters(topology);
137 topologyClusters.forEach(topologyCluster -> {
138 Set<ConnectPoint> connectPointSet = new HashSet<>();
139 Set<Link> clusterLinks = topologyService.getClusterLinks(topology, topologyCluster);
140 clusterLinks.forEach(link -> {
141 connectPointSet.add(link.src());
142 connectPointSet.add(link.dst());
143 });
144 if (!connectPointSet.isEmpty()) {
145 clusters.add(connectPointSet);
146 }
147 });
148 return clusters;
149 }
150
151 /**
152 * Topology event listener.
153 */
154 private class InternalTopologyListener implements TopologyListener {
155 @Override
156 public void event(TopologyEvent event) {
157 if (!isRelevant(event)) {
158 return;
159 }
160
161 Topology topology = event.subject();
162 providerService.topologyChanged(getConnectPoints(topology));
163 }
164
165 @Override
166 public boolean isRelevant(TopologyEvent event) {
167 final boolean[] relevant = {false};
168 if (event.type().equals(TopologyEvent.Type.TOPOLOGY_CHANGED)) {
169 event.reasons().forEach(event1 -> {
170 // Only LinkEvents are relevant events, ie: DeviceEvents and others are ignored.
171 if (event1 instanceof LinkEvent) {
172 relevant[0] = true;
173 return;
174 }
175 });
176 }
177 return relevant[0];
178 }
179 }
180}