blob: 0f9a29bf784c6b906168cfd399d8d508f04930e6 [file] [log] [blame]
Thomas Vachuska5fedb7a2014-11-20 00:55:08 -08001/*
2 * Copyright 2014 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 */
16package org.onlab.onos.gui;
17
18import org.onlab.onos.net.ConnectPoint;
19import org.onlab.onos.net.Device;
20import org.onlab.onos.net.DeviceId;
21import org.onlab.onos.net.Host;
22import org.onlab.onos.net.HostId;
23import org.onlab.onos.net.Link;
24import org.onlab.onos.net.device.DeviceService;
25import org.onlab.onos.net.host.HostService;
26import org.onlab.onos.net.intent.HostToHostIntent;
27import org.onlab.onos.net.intent.Intent;
28import org.onlab.onos.net.intent.IntentService;
29import org.onlab.onos.net.intent.LinkCollectionIntent;
30import org.onlab.onos.net.intent.MultiPointToSinglePointIntent;
31import org.onlab.onos.net.intent.OpticalConnectivityIntent;
32import org.onlab.onos.net.intent.PathIntent;
33import org.onlab.onos.net.intent.PointToPointIntent;
34import org.onlab.onos.net.link.LinkService;
35
36import java.util.HashSet;
37import java.util.List;
38import java.util.Set;
39
40import static org.onlab.onos.net.intent.IntentState.INSTALLED;
41
42/**
43 * Auxiliary facility to query the intent service based on the specified
44 * set of end-station hosts, edge points or infrastructure devices.
45 */
46public class TopologyViewIntentFilter {
47
48 private final IntentService intentService;
49 private final DeviceService deviceService;
50 private final HostService hostService;
51 private final LinkService linkService;
52
53 /**
54 * Crreates an intent filter.
55 *
56 * @param intentService intent service reference
57 * @param deviceService device service reference
58 * @param hostService host service reference
59 * @param linkService link service reference
60 */
61 TopologyViewIntentFilter(IntentService intentService,
62 DeviceService deviceService,
63 HostService hostService, LinkService linkService) {
64 this.intentService = intentService;
65 this.deviceService = deviceService;
66 this.hostService = hostService;
67 this.linkService = linkService;
68 }
69
70 /**
71 * Finds all path (host-to-host or point-to-point) intents that pertains
72 * to the given hosts.
73 *
74 * @param hosts set of hosts to query by
75 * @param devices set of devices to query by
76 * @return set of intents that 'match' all hosts and devices given
77 */
78 Set<Intent> findPathIntents(Set<Host> hosts, Set<Device> devices) {
79 // Derive from this the set of edge connect points.
80 Set<ConnectPoint> edgePoints = getEdgePoints(hosts);
81
82 // Iterate over all intents and produce a set that contains only those
83 // intents that target all selected hosts or derived edge connect points.
84 return getIntents(hosts, devices, edgePoints);
85 }
86
87
88 // Produces a set of edge points from the specified set of hosts.
89 private Set<ConnectPoint> getEdgePoints(Set<Host> hosts) {
90 Set<ConnectPoint> edgePoints = new HashSet<>();
91 for (Host host : hosts) {
92 edgePoints.add(host.location());
93 }
94 return edgePoints;
95 }
96
97 // Produces a set of intents that target all selected hosts, devices or connect points.
98 private Set<Intent> getIntents(Set<Host> hosts, Set<Device> devices,
99 Set<ConnectPoint> edgePoints) {
100 Set<Intent> intents = new HashSet<>();
101 if (hosts.isEmpty() && devices.isEmpty()) {
102 return intents;
103 }
104
105 Set<OpticalConnectivityIntent> opticalIntents = new HashSet<>();
106
107 // Search through all intents and see if they are relevant to our search.
108 for (Intent intent : intentService.getIntents()) {
109 if (intentService.getIntentState(intent.id()) == INSTALLED) {
110 boolean isRelevant = false;
111 if (intent instanceof HostToHostIntent) {
112 isRelevant = isIntentRelevantToHosts((HostToHostIntent) intent, hosts) &&
113 isIntentRelevantToDevices(intent, devices);
114 } else if (intent instanceof PointToPointIntent) {
115 isRelevant = isIntentRelevant((PointToPointIntent) intent, edgePoints) &&
116 isIntentRelevantToDevices(intent, devices);
117 } else if (intent instanceof MultiPointToSinglePointIntent) {
118 isRelevant = isIntentRelevant((MultiPointToSinglePointIntent) intent, edgePoints) &&
119 isIntentRelevantToDevices(intent, devices);
120 } else if (intent instanceof OpticalConnectivityIntent) {
121 opticalIntents.add((OpticalConnectivityIntent) intent);
122 }
123 // TODO: add other intents, e.g. SinglePointToMultiPointIntent
124
125 if (isRelevant) {
126 intents.add(intent);
127 }
128 }
129 }
130
131 // As a second pass, try to link up any optical intents with the
132 // packet-level ones.
133 for (OpticalConnectivityIntent intent : opticalIntents) {
134 if (isIntentRelevant(intent, intents) &&
135 isIntentRelevantToDevices(intent, devices)) {
136 intents.add(intent);
137 }
138 }
139 return intents;
140 }
141
142 // Indicates whether the specified intent involves all of the given hosts.
143 private boolean isIntentRelevantToHosts(HostToHostIntent intent, Set<Host> hosts) {
144 for (Host host : hosts) {
145 HostId id = host.id();
146 // Bail if intent does not involve this host.
147 if (!id.equals(intent.one()) && !id.equals(intent.two())) {
148 return false;
149 }
150 }
151 return true;
152 }
153
154 // Indicates whether the specified intent involves all of the given devices.
155 private boolean isIntentRelevantToDevices(Intent intent, Set<Device> devices) {
156 List<Intent> installables = intentService.getInstallableIntents(intent.id());
157 for (Device device : devices) {
158 if (!isIntentRelevantToDevice(installables, device)) {
159 return false;
160 }
161 }
162 return true;
163 }
164
165 // Indicates whether the specified intent involves the given device.
166 private boolean isIntentRelevantToDevice(List<Intent> installables, Device device) {
167 for (Intent installable : installables) {
168 if (installable instanceof PathIntent) {
169 PathIntent pathIntent = (PathIntent) installable;
170 if (pathContainsDevice(pathIntent.path().links(), device.id())) {
171 return true;
172 }
173 } else if (installable instanceof LinkCollectionIntent) {
174 LinkCollectionIntent linksIntent = (LinkCollectionIntent) installable;
175 if (pathContainsDevice(linksIntent.links(), device.id())) {
176 return true;
177 }
178 }
179 }
180 return false;
181 }
182
183 // Indicates whether the specified intent involves the given device.
184 private boolean pathContainsDevice(Iterable<Link> links, DeviceId id) {
185 for (Link link : links) {
186 if (link.src().elementId().equals(id) || link.dst().elementId().equals(id)) {
187 return true;
188 }
189 }
190 return false;
191 }
192
193 private boolean isIntentRelevant(PointToPointIntent intent, Set<ConnectPoint> edgePoints) {
194 for (ConnectPoint point : edgePoints) {
195 // Bail if intent does not involve this edge point.
196 if (!point.equals(intent.egressPoint()) &&
197 !point.equals(intent.ingressPoint())) {
198 return false;
199 }
200 }
201 return true;
202 }
203
204 // Indicates whether the specified intent involves all of the given edge points.
205 private boolean isIntentRelevant(MultiPointToSinglePointIntent intent,
206 Set<ConnectPoint> edgePoints) {
207 for (ConnectPoint point : edgePoints) {
208 // Bail if intent does not involve this edge point.
209 if (!point.equals(intent.egressPoint()) &&
210 !intent.ingressPoints().contains(point)) {
211 return false;
212 }
213 }
214 return true;
215 }
216
217 // Indicates whether the specified intent involves all of the given edge points.
218 private boolean isIntentRelevant(OpticalConnectivityIntent opticalIntent,
219 Set<Intent> intents) {
220 Link ccSrc = getFirstLink(opticalIntent.getSrc(), false);
221 Link ccDst = getFirstLink(opticalIntent.getDst(), true);
222
223 for (Intent intent : intents) {
224 List<Intent> installables = intentService.getInstallableIntents(intent.id());
225 for (Intent installable : installables) {
226 if (installable instanceof PathIntent) {
227 List<Link> links = ((PathIntent) installable).path().links();
228 if (links.size() == 3) {
229 Link tunnel = links.get(1);
230 if (tunnel.src().equals(ccSrc.src()) &&
231 tunnel.dst().equals(ccDst.dst())) {
232 return true;
233 }
234 }
235 }
236 }
237 }
238 return false;
239 }
240
241 private Link getFirstLink(ConnectPoint point, boolean ingress) {
242 for (Link link : linkService.getLinks(point)) {
243 if (point.equals(ingress ? link.src() : link.dst())) {
244 return link;
245 }
246 }
247 return null;
248 }
249
250}