blob: b9e50ba7a9109dc5cb1df0c014c68fe04b570935 [file] [log] [blame]
alshabib61286342014-12-24 10:34:00 -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.onosproject.provider.nil.device.impl;
17
18
19import com.google.common.collect.Lists;
20import com.google.common.collect.Maps;
21import org.apache.felix.scr.annotations.Activate;
22import org.apache.felix.scr.annotations.Component;
23import org.apache.felix.scr.annotations.Deactivate;
24import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
26import org.onlab.packet.ChassisId;
suibinabeb7fa2015-01-20 20:58:49 -080027import org.onosproject.cluster.ClusterService;
alshabib61286342014-12-24 10:34:00 -080028import org.onosproject.net.Device;
29import org.onosproject.net.DeviceId;
30import org.onosproject.net.MastershipRole;
31import org.onosproject.net.Port;
32import org.onosproject.net.PortNumber;
33import org.onosproject.net.device.DefaultDeviceDescription;
34import org.onosproject.net.device.DefaultPortDescription;
35import org.onosproject.net.device.DeviceDescription;
36import org.onosproject.net.device.DeviceProvider;
37import org.onosproject.net.device.DeviceProviderRegistry;
38import org.onosproject.net.device.DeviceProviderService;
39import org.onosproject.net.device.PortDescription;
40import org.onosproject.net.provider.AbstractProvider;
41import org.onosproject.net.provider.ProviderId;
42import org.slf4j.Logger;
43
44import java.util.List;
45import java.util.Map;
46import java.util.concurrent.ExecutorService;
47import java.util.concurrent.Executors;
48import java.util.concurrent.TimeUnit;
49
50import static org.onlab.util.Tools.delay;
51import static org.onlab.util.Tools.namedThreads;
52import static org.slf4j.LoggerFactory.getLogger;
53
54/**
55 * Provider which advertises fake/nonexistant devices to the core.
suibinabeb7fa2015-01-20 20:58:49 -080056 * nodeID is passed as part of the fake device id so that multiple nodes can run simultaneously.
alshabib61286342014-12-24 10:34:00 -080057 * To be used for benchmarking only.
58 */
59@Component(immediate = true)
60public class NullDeviceProvider extends AbstractProvider implements DeviceProvider {
61
62 private static final Logger log = getLogger(NullDeviceProvider.class);
suibinabeb7fa2015-01-20 20:58:49 -080063
64 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
65 protected ClusterService clusterService;
alshabib61286342014-12-24 10:34:00 -080066
67 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 protected DeviceProviderRegistry providerRegistry;
69
70 private DeviceProviderService providerService;
71
72 private ExecutorService deviceBuilder = Executors.newFixedThreadPool(1,
73 namedThreads("null-device-creator"));
74
75
alshabib61286342014-12-24 10:34:00 -080076 //currently hardcoded. will be made configurable via rest/cli.
suibinabeb7fa2015-01-20 20:58:49 -080077 private static final String SCHEME = null;
alshabib61286342014-12-24 10:34:00 -080078 private static final int NUMDEVICES = 10;
79 private static final int NUMPORTSPERDEVICE = 10;
80
81 //Delay between events in ms.
82 private static final int EVENTINTERVAL = 5;
83
84 private final Map<Integer, DeviceDescription> descriptions = Maps.newHashMap();
85
86 private DeviceCreator creator;
87
88
89 /**
90 *
91 * Creates a provider with the supplier identifier.
92 *
93 */
94 public NullDeviceProvider() {
95 super(new ProviderId("null", "org.onosproject.provider.nil"));
96 }
97
98 @Activate
99 public void activate() {
100 providerService = providerRegistry.register(this);
101 deviceBuilder.submit(new DeviceCreator(true));
102 log.info("Started");
103
104 }
105
106 @Deactivate
107 public void deactivate() {
108 deviceBuilder.submit(new DeviceCreator(false));
109 try {
110 deviceBuilder.awaitTermination(1000, TimeUnit.MILLISECONDS);
111 } catch (InterruptedException e) {
112 log.error("Device builder did not terminate");
113 }
114 deviceBuilder.shutdownNow();
115 providerRegistry.unregister(this);
116 providerService = null;
117
118 log.info("Stopped");
119 }
120
121 @Override
122 public void triggerProbe(DeviceId deviceId) {}
123
124 @Override
125 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {}
126
127 @Override
128 public boolean isReachable(DeviceId deviceId) {
129 return descriptions.values().stream()
130 .anyMatch(desc -> desc.deviceURI().equals(deviceId.uri()));
131 }
132
133
134 private class DeviceCreator implements Runnable {
135
136 private boolean setup;
137
138 public DeviceCreator(boolean setup) {
139 this.setup = setup;
140 }
141
142 @Override
143 public void run() {
144 if (setup) {
145 advertiseDevices();
146 } else {
147 removeDevices();
148 }
149 }
150
151 private void removeDevices() {
152 for (DeviceDescription desc : descriptions.values()) {
153 providerService.deviceDisconnected(
154 DeviceId.deviceId(desc.deviceURI()));
155 delay(EVENTINTERVAL);
156 }
157 descriptions.clear();
158 }
159
160 private void advertiseDevices() {
161 DeviceId did;
162 ChassisId cid;
suibinabeb7fa2015-01-20 20:58:49 -0800163
164 // nodeIdHash takes into account for nodeID to avoid collisions when running multi-node providers.
165 int nodeIdHash = (clusterService.getLocalNode().hashCode() % NUMDEVICES) * NUMDEVICES;
166
167 for (int i = nodeIdHash; i < nodeIdHash + NUMDEVICES; i++) {
alshabib61286342014-12-24 10:34:00 -0800168 did = DeviceId.deviceId(String.format("%s:%d", SCHEME, i));
169 cid = new ChassisId(i);
170 DeviceDescription desc =
171 new DefaultDeviceDescription(did.uri(), Device.Type.SWITCH,
172 "ON.Lab", "0.0.1", "0.0.1", "1234",
173 cid);
174 descriptions.put(i, desc);
175 providerService.deviceConnected(did, desc);
176 providerService.updatePorts(did, buildPorts());
177 delay(EVENTINTERVAL);
178 }
179 }
180
181 private List<PortDescription> buildPorts() {
182 List<PortDescription> ports = Lists.newArrayList();
183 for (int i = 0; i < NUMPORTSPERDEVICE; i++) {
184 ports.add(new DefaultPortDescription(PortNumber.portNumber(i), true,
185 Port.Type.COPPER,
186 (long) 0));
187 }
188 return ports;
189 }
190 }
191}