Thomas Vachuska

Enhancing null providers for use in demos.

Change-Id: I079d19a98fba2312bd4b17d2e275b34f4dee6f19
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.provider.nil;
18 +
19 +import com.google.common.collect.Maps;
20 +import org.onlab.packet.MacAddress;
21 +import org.onlab.packet.VlanId;
22 +import org.onosproject.net.Device;
23 +import org.onosproject.net.DeviceId;
24 +import org.onosproject.net.HostId;
25 +
26 +import java.util.Map;
27 +
28 +import static org.onlab.util.Tools.toHex;
29 +import static org.onosproject.provider.nil.NullProviders.SCHEME;
30 +
31 +/**
32 + * Custom topology defined by a concise language.
33 + */
34 +public class CustomTopologySimulator extends TopologySimulator {
35 +
36 + private int nextDeviceId = 0;
37 + private int nextHostId = 0;
38 +
39 + private Map<String, DeviceId> nameToId = Maps.newConcurrentMap();
40 +
41 + /**
42 + * Returns the next device id.
43 + *
44 + * @return the next device id
45 + */
46 + public DeviceId nextDeviceId() {
47 + return DeviceId.deviceId(SCHEME + ":" + toHex(++nextDeviceId));
48 + }
49 +
50 + /**
51 + * Returns the next host id.
52 + *
53 + * @return the next host id
54 + */
55 + public HostId nextHostId() {
56 + return HostId.hostId(MacAddress.valueOf(nextHostId), VlanId.NONE);
57 + }
58 +
59 + /**
60 + * Returns the identifier of the device with the specified alias.
61 + *
62 + * @param name device name
63 + * @return device identifier
64 + */
65 + public DeviceId deviceId(String name) {
66 + return nameToId.get(name);
67 + }
68 +
69 + /**
70 + * Creates simulated device.
71 + *
72 + * @param id device identifier
73 + * @param name device name
74 + * @param type device type
75 + * @param portCount number of device ports
76 + */
77 + public void createDevice(DeviceId id, String name, Device.Type type, int portCount) {
78 + int chassisId = Integer.parseInt(id.uri().getSchemeSpecificPart());
79 + createDevice(id, chassisId, type, portCount);
80 + nameToId.put(name, id);
81 + }
82 +
83 + @Override
84 + protected void createDevices() {
85 + }
86 +
87 + @Override
88 + protected void createLinks() {
89 + }
90 +
91 + @Override
92 + protected void createHosts() {
93 + }
94 +}
...@@ -268,6 +268,15 @@ public class NullProviders { ...@@ -268,6 +268,15 @@ public class NullProviders {
268 } 268 }
269 269
270 /** 270 /**
271 + * Returns the currently active topology simulator.
272 + *
273 + * @return current simulator; null if none is active
274 + */
275 + public TopologySimulator currentSimulator() {
276 + return simulator;
277 + }
278 +
279 + /**
271 * Severs the link between the specified end-points in both directions. 280 * Severs the link between the specified end-points in both directions.
272 * 281 *
273 * @param one link endpoint 282 * @param one link endpoint
...@@ -356,6 +365,8 @@ public class NullProviders { ...@@ -356,6 +365,8 @@ public class NullProviders {
356 return new MeshTopologySimulator(); 365 return new MeshTopologySimulator();
357 } else if (topoShape.matches("grid([,].*|$)")) { 366 } else if (topoShape.matches("grid([,].*|$)")) {
358 return new GridTopologySimulator(); 367 return new GridTopologySimulator();
368 + } else if (topoShape.matches("custom([,].*|$)")) {
369 + return new CustomTopologySimulator();
359 } else { 370 } else {
360 return new ConfiguredTopologySimulator(); 371 return new ConfiguredTopologySimulator();
361 } 372 }
...@@ -424,7 +435,7 @@ public class NullProviders { ...@@ -424,7 +435,7 @@ public class NullProviders {
424 435
425 @Override 436 @Override
426 public boolean isReachable(DeviceId deviceId) { 437 public boolean isReachable(DeviceId deviceId) {
427 - return topoShape.equals("configured") || 438 + return topoShape.equals("custom") ||
428 (simulator != null && simulator.contains(deviceId) && 439 (simulator != null && simulator.contains(deviceId) &&
429 topologyMutationDriver.isReachable(deviceId)); 440 topologyMutationDriver.isReachable(deviceId));
430 } 441 }
......
...@@ -188,13 +188,25 @@ public abstract class TopologySimulator { ...@@ -188,13 +188,25 @@ public abstract class TopologySimulator {
188 * @param id device identifier 188 * @param id device identifier
189 * @param chassisId chassis identifier number 189 * @param chassisId chassis identifier number
190 */ 190 */
191 - protected void createDevice(DeviceId id, int chassisId) { 191 + public void createDevice(DeviceId id, int chassisId) {
192 + createDevice(id, chassisId, Device.Type.SWITCH, hostCount + infrastructurePorts);
193 + }
194 +
195 + /**
196 + * Creates simulated device.
197 + *
198 + * @param id device identifier
199 + * @param chassisId chassis identifier number
200 + * @param type device type
201 + * @param portCount number of device ports
202 + */
203 + public void createDevice(DeviceId id, int chassisId, Device.Type type, int portCount) {
192 DeviceDescription desc = 204 DeviceDescription desc =
193 - new DefaultDeviceDescription(id.uri(), Device.Type.SWITCH, 205 + new DefaultDeviceDescription(id.uri(), type,
194 "ON.Lab", "0.1", "0.1", "1234", 206 "ON.Lab", "0.1", "0.1", "1234",
195 new ChassisId(chassisId)); 207 new ChassisId(chassisId));
196 deviceProviderService.deviceConnected(id, desc); 208 deviceProviderService.deviceConnected(id, desc);
197 - deviceProviderService.updatePorts(id, buildPorts(hostCount + infrastructurePorts)); 209 + deviceProviderService.updatePorts(id, buildPorts(portCount));
198 } 210 }
199 211
200 /** 212 /**
...@@ -205,7 +217,7 @@ public abstract class TopologySimulator { ...@@ -205,7 +217,7 @@ public abstract class TopologySimulator {
205 * @param pi port number of i-th device 217 * @param pi port number of i-th device
206 * @param pj port number of j-th device 218 * @param pj port number of j-th device
207 */ 219 */
208 - protected void createLink(int i, int j, int pi, int pj) { 220 + public void createLink(int i, int j, int pi, int pj) {
209 ConnectPoint one = new ConnectPoint(deviceIds.get(i), PortNumber.portNumber(pi)); 221 ConnectPoint one = new ConnectPoint(deviceIds.get(i), PortNumber.portNumber(pi));
210 ConnectPoint two = new ConnectPoint(deviceIds.get(j), PortNumber.portNumber(pj)); 222 ConnectPoint two = new ConnectPoint(deviceIds.get(j), PortNumber.portNumber(pj));
211 createLink(one, two); 223 createLink(one, two);
...@@ -217,9 +229,23 @@ public abstract class TopologySimulator { ...@@ -217,9 +229,23 @@ public abstract class TopologySimulator {
217 * @param one one connection point 229 * @param one one connection point
218 * @param two another connection point 230 * @param two another connection point
219 */ 231 */
220 - protected void createLink(ConnectPoint one, ConnectPoint two) { 232 + public void createLink(ConnectPoint one, ConnectPoint two) {
221 - linkProviderService.linkDetected(new DefaultLinkDescription(one, two, DIRECT)); 233 + createLink(one, two, DIRECT, true);
222 - linkProviderService.linkDetected(new DefaultLinkDescription(two, one, DIRECT)); 234 + }
235 +
236 + /**
237 + * Creates simulated link between two connection points.
238 + *
239 + * @param one one connection point
240 + * @param two another connection point
241 + * @param type link type
242 + * @param isBidirectional true if link is bidirectional
243 + */
244 + public void createLink(ConnectPoint one, ConnectPoint two, Link.Type type, boolean isBidirectional) {
245 + linkProviderService.linkDetected(new DefaultLinkDescription(one, two, type));
246 + if (isBidirectional) {
247 + linkProviderService.linkDetected(new DefaultLinkDescription(two, one, type));
248 + }
223 } 249 }
224 250
225 /** 251 /**
...@@ -228,7 +254,7 @@ public abstract class TopologySimulator { ...@@ -228,7 +254,7 @@ public abstract class TopologySimulator {
228 * @param deviceId device identifier 254 * @param deviceId device identifier
229 * @param portOffset port offset where to start attaching hosts 255 * @param portOffset port offset where to start attaching hosts
230 */ 256 */
231 - protected void createHosts(DeviceId deviceId, int portOffset) { 257 + public void createHosts(DeviceId deviceId, int portOffset) {
232 String s = deviceId.toString(); 258 String s = deviceId.toString();
233 byte dByte = Byte.parseByte(s.substring(s.length() - 2), 16); 259 byte dByte = Byte.parseByte(s.substring(s.length() - 2), 16);
234 // TODO: this limits the simulation to 256 devices & 256 hosts/device. 260 // TODO: this limits the simulation to 256 devices & 256 hosts/device.
......
1 +/*
2 + * Copyright 2016 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.provider.nil.cli;
17 +
18 +import org.apache.karaf.shell.commands.Argument;
19 +import org.apache.karaf.shell.commands.Command;
20 +import org.onosproject.cli.AbstractShellCommand;
21 +import org.onosproject.net.Device;
22 +import org.onosproject.net.DeviceId;
23 +import org.onosproject.net.config.NetworkConfigService;
24 +import org.onosproject.net.config.basics.BasicDeviceConfig;
25 +import org.onosproject.provider.nil.CustomTopologySimulator;
26 +import org.onosproject.provider.nil.NullProviders;
27 +import org.onosproject.provider.nil.TopologySimulator;
28 +
29 +/**
30 + * Adds a simulated device to the custom topology simulation.
31 + */
32 +@Command(scope = "onos", name = "null-create-device",
33 + description = "Adds a simulated device to the custom topology simulation")
34 +public class CreateNullDevice extends AbstractShellCommand {
35 +
36 + @Argument(index = 0, name = "type", description = "Device type, e.g. switch, roadm",
37 + required = true, multiValued = false)
38 + String type = null;
39 +
40 + @Argument(index = 1, name = "name", description = "Device name",
41 + required = true, multiValued = false)
42 + String name = null;
43 +
44 + @Argument(index = 2, name = "portCount", description = "Port count",
45 + required = true, multiValued = false)
46 + Integer portCount = null;
47 +
48 + @Argument(index = 3, name = "latitude", description = "Geo latitude",
49 + required = true, multiValued = false)
50 + Double latitude = null;
51 +
52 + @Argument(index = 4, name = "longitude", description = "Geo longitude",
53 + required = true, multiValued = false)
54 + Double longitude = null;
55 +
56 + @Override
57 + protected void execute() {
58 + NullProviders service = get(NullProviders.class);
59 + NetworkConfigService cfgService = get(NetworkConfigService.class);
60 +
61 + TopologySimulator simulator = service.currentSimulator();
62 + if (!(simulator instanceof CustomTopologySimulator)) {
63 + error("Custom topology simulator is not active.");
64 + return;
65 + }
66 +
67 + CustomTopologySimulator sim = (CustomTopologySimulator) simulator;
68 + DeviceId deviceId = sim.nextDeviceId();
69 + BasicDeviceConfig cfg = cfgService.addConfig(deviceId, BasicDeviceConfig.class);
70 + cfg.name(name);
71 + cfg.latitude(latitude);
72 + cfg.longitude(longitude);
73 + cfg.apply();
74 +
75 + sim.createDevice(deviceId, name, Device.Type.valueOf(type.toUpperCase()), portCount);
76 + }
77 +
78 +}
1 +/*
2 + * Copyright 2016 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 +
17 +package org.onosproject.provider.nil.cli;
18 +
19 +import org.apache.karaf.shell.commands.Argument;
20 +import org.apache.karaf.shell.commands.Command;
21 +import org.apache.karaf.shell.commands.Option;
22 +import org.onosproject.cli.AbstractShellCommand;
23 +import org.onosproject.net.ConnectPoint;
24 +import org.onosproject.net.DeviceId;
25 +import org.onosproject.net.Link;
26 +import org.onosproject.net.edge.EdgePortService;
27 +import org.onosproject.provider.nil.CustomTopologySimulator;
28 +import org.onosproject.provider.nil.NullProviders;
29 +import org.onosproject.provider.nil.TopologySimulator;
30 +
31 +import java.util.Iterator;
32 +
33 +/**
34 + * Adds a simulated link to the custom topology simulation.
35 + */
36 +@Command(scope = "onos", name = "null-create-link",
37 + description = "Adds a simulated link to the custom topology simulation")
38 +public class CreateNullLink extends AbstractShellCommand {
39 +
40 + @Argument(index = 0, name = "type", description = "Link type, e.g. direct, indirect, optical",
41 + required = true, multiValued = false)
42 + String type = null;
43 +
44 + @Argument(index = 1, name = "src", description = "Source device name",
45 + required = true, multiValued = false)
46 + String src = null;
47 +
48 + @Argument(index = 2, name = "dst", description = "Destination device name",
49 + required = true, multiValued = false)
50 + String dst = null;
51 +
52 + @Option(name = "-u", aliases = "--unidirectional", description = "Unidirectional link only",
53 + required = false, multiValued = false)
54 + private boolean unidirectional = false;
55 +
56 + @Override
57 + protected void execute() {
58 + NullProviders service = get(NullProviders.class);
59 +
60 + TopologySimulator simulator = service.currentSimulator();
61 + if (!(simulator instanceof CustomTopologySimulator)) {
62 + error("Custom topology simulator is not active.");
63 + return;
64 + }
65 +
66 + CustomTopologySimulator sim = (CustomTopologySimulator) simulator;
67 + ConnectPoint one = findAvailablePort(sim.deviceId(src));
68 + ConnectPoint two = findAvailablePort(sim.deviceId(dst));
69 + sim.createLink(one, two, Link.Type.valueOf(type.toUpperCase()), !unidirectional);
70 + }
71 +
72 + private ConnectPoint findAvailablePort(DeviceId deviceId) {
73 + EdgePortService eps = get(EdgePortService.class);
74 + Iterator<ConnectPoint> points = eps.getEdgePoints(deviceId).iterator();
75 + return points.hasNext() ? points.next() : null;
76 + }
77 +
78 +}
...@@ -25,10 +25,10 @@ import static org.onosproject.cli.UpDownCompleter.DOWN; ...@@ -25,10 +25,10 @@ import static org.onosproject.cli.UpDownCompleter.DOWN;
25 import static org.onosproject.cli.UpDownCompleter.UP; 25 import static org.onosproject.cli.UpDownCompleter.UP;
26 26
27 /** 27 /**
28 - * Servers or repairs a simulated link. 28 + * Downs or repairs a simulated device.
29 */ 29 */
30 @Command(scope = "onos", name = "null-device", 30 @Command(scope = "onos", name = "null-device",
31 - description = "Severs or repairs a simulated link") 31 + description = "Downs or repairs a simulated device")
32 public class NullDeviceCommand extends AbstractShellCommand { 32 public class NullDeviceCommand extends AbstractShellCommand {
33 33
34 @Argument(index = 0, name = "id", description = "Device identifier", 34 @Argument(index = 0, name = "id", description = "Device identifier",
......
...@@ -25,7 +25,7 @@ import static org.onosproject.cli.UpDownCompleter.DOWN; ...@@ -25,7 +25,7 @@ import static org.onosproject.cli.UpDownCompleter.DOWN;
25 import static org.onosproject.cli.UpDownCompleter.UP; 25 import static org.onosproject.cli.UpDownCompleter.UP;
26 26
27 /** 27 /**
28 - * Servers or repairs a simulated link. 28 + * Severs or repairs a simulated link.
29 */ 29 */
30 @Command(scope = "onos", name = "null-link", 30 @Command(scope = "onos", name = "null-link",
31 description = "Severs or repairs a simulated link") 31 description = "Severs or repairs a simulated link")
......
...@@ -41,6 +41,12 @@ ...@@ -41,6 +41,12 @@
41 <null/> 41 <null/>
42 </completers> 42 </completers>
43 </command> 43 </command>
44 + <command>
45 + <action class="org.onosproject.provider.nil.cli.CreateNullDevice"/>
46 + </command>
47 + <command>
48 + <action class="org.onosproject.provider.nil.cli.CreateNullLink"/>
49 + </command>
44 </command-bundle> 50 </command-bundle>
45 51
46 <bean id="startStopCompleter" class="org.onosproject.cli.StartStopCompleter"/> 52 <bean id="startStopCompleter" class="org.onosproject.cli.StartStopCompleter"/>
......