blob: 4be8f5ce15f15e3563ec9629b581d2c6934dc4cf [file] [log] [blame]
Sanjay Se8dcfee2015-04-23 10:07:08 +05301/*
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 */
andreaeb70a942015-10-16 21:34:46 -070016
Sanjay Se8dcfee2015-04-23 10:07:08 +053017package org.onosproject.provider.netconf.device.impl;
18
andreaeb70a942015-10-16 21:34:46 -070019import com.google.common.base.Preconditions;
Sanjay Se8dcfee2015-04-23 10:07:08 +053020import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
22import org.apache.felix.scr.annotations.Deactivate;
Sanjay Se8dcfee2015-04-23 10:07:08 +053023import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
25import org.onlab.packet.ChassisId;
andreaeb70a942015-10-16 21:34:46 -070026import org.onosproject.core.ApplicationId;
27import org.onosproject.core.CoreService;
28import org.onosproject.incubator.net.config.basics.ConfigException;
29import org.onosproject.net.DefaultAnnotations;
Sanjay Se8dcfee2015-04-23 10:07:08 +053030import org.onosproject.net.Device;
31import org.onosproject.net.DeviceId;
32import org.onosproject.net.MastershipRole;
andreaeb70a942015-10-16 21:34:46 -070033import org.onosproject.net.SparseAnnotations;
Aaron Kruglikov17b4c852016-01-15 16:37:04 -080034import org.onosproject.net.behaviour.PortDiscovery;
andreaeb70a942015-10-16 21:34:46 -070035import org.onosproject.net.config.ConfigFactory;
36import org.onosproject.net.config.NetworkConfigEvent;
37import org.onosproject.net.config.NetworkConfigListener;
38import org.onosproject.net.config.NetworkConfigRegistry;
Sanjay Se8dcfee2015-04-23 10:07:08 +053039import org.onosproject.net.device.DefaultDeviceDescription;
40import org.onosproject.net.device.DeviceDescription;
41import org.onosproject.net.device.DeviceProvider;
42import org.onosproject.net.device.DeviceProviderRegistry;
43import org.onosproject.net.device.DeviceProviderService;
Aaron Kruglikov17b4c852016-01-15 16:37:04 -080044import org.onosproject.net.device.DeviceService;
45import org.onosproject.net.driver.DriverService;
Sanjay Se8dcfee2015-04-23 10:07:08 +053046import org.onosproject.net.provider.AbstractProvider;
47import org.onosproject.net.provider.ProviderId;
andreaeb70a942015-10-16 21:34:46 -070048import org.onosproject.netconf.NetconfController;
49import org.onosproject.netconf.NetconfDevice;
50import org.onosproject.netconf.NetconfDeviceInfo;
51import org.onosproject.netconf.NetconfDeviceListener;
Andrea Campanella8b1cb672016-01-25 13:58:58 -080052import org.onosproject.netconf.NetconfException;
Sanjay Se8dcfee2015-04-23 10:07:08 +053053import org.slf4j.Logger;
54
Andrea Campanella087ceb92015-12-07 09:58:34 -080055import java.io.IOException;
Andrea Campanella5c999e22016-03-01 15:12:53 -080056import java.util.concurrent.ExecutorService;
57import java.util.concurrent.Executors;
andreaeb70a942015-10-16 21:34:46 -070058
Andrea Campanella5c999e22016-03-01 15:12:53 -080059import static org.onlab.util.Tools.groupedThreads;
andreaeb70a942015-10-16 21:34:46 -070060import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
61import static org.slf4j.LoggerFactory.getLogger;
62
Sanjay Se8dcfee2015-04-23 10:07:08 +053063/**
andreaeb70a942015-10-16 21:34:46 -070064 * Provider which uses an NETCONF controller to detect device.
Sanjay Se8dcfee2015-04-23 10:07:08 +053065 */
66@Component(immediate = true)
67public class NetconfDeviceProvider extends AbstractProvider
68 implements DeviceProvider {
andreaeb70a942015-10-16 21:34:46 -070069 private final Logger log = getLogger(getClass());
Sanjay Se8dcfee2015-04-23 10:07:08 +053070
71 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
72 protected DeviceProviderRegistry providerRegistry;
73
andreaeb70a942015-10-16 21:34:46 -070074 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Andrea Campanella101417d2015-12-11 17:58:07 -080075 protected NetconfController controller;
Sanjay Se8dcfee2015-04-23 10:07:08 +053076
77 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
andreaeb70a942015-10-16 21:34:46 -070078 protected NetworkConfigRegistry cfgService;
Sanjay Se8dcfee2015-04-23 10:07:08 +053079
Thomas Vachuskad6811712015-04-29 21:37:04 -070080 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
andreaeb70a942015-10-16 21:34:46 -070081 protected CoreService coreService;
Thomas Vachuskad6811712015-04-29 21:37:04 -070082
Aaron Kruglikov17b4c852016-01-15 16:37:04 -080083 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
84 protected DriverService driverService;
85
86 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
87 protected DeviceService deviceService;
88
Andrea Campanella101417d2015-12-11 17:58:07 -080089 private static final String APP_NAME = "org.onosproject.netconf";
90 private static final String SCHEME_NAME = "netconf";
91 private static final String DEVICE_PROVIDER_PACKAGE = "org.onosproject.netconf.provider.device";
92 private static final String UNKNOWN = "unknown";
Sanjay Se8dcfee2015-04-23 10:07:08 +053093
Andrea Campanella5c999e22016-03-01 15:12:53 -080094 private final ExecutorService executor =
95 Executors.newFixedThreadPool(5, groupedThreads("onos/netconfdeviceprovider", "device-installer-%d"));
96
andreaeb70a942015-10-16 21:34:46 -070097 private DeviceProviderService providerService;
98 private NetconfDeviceListener innerNodeListener = new InnerNetconfDeviceListener();
Sanjay Se8dcfee2015-04-23 10:07:08 +053099
andreaeb70a942015-10-16 21:34:46 -0700100 private final ConfigFactory factory =
101 new ConfigFactory<ApplicationId, NetconfProviderConfig>(APP_SUBJECT_FACTORY,
102 NetconfProviderConfig.class,
103 "devices",
104 true) {
105 @Override
106 public NetconfProviderConfig createConfig() {
107 return new NetconfProviderConfig();
108 }
109 };
110 private final NetworkConfigListener cfgLister = new InternalNetworkConfigListener();
111 private ApplicationId appId;
Sanjay Se8dcfee2015-04-23 10:07:08 +0530112
Sanjay Se8dcfee2015-04-23 10:07:08 +0530113
114 @Activate
andreaeb70a942015-10-16 21:34:46 -0700115 public void activate() {
Sanjay Se8dcfee2015-04-23 10:07:08 +0530116 providerService = providerRegistry.register(this);
Andrea Campanella101417d2015-12-11 17:58:07 -0800117 appId = coreService.registerApplication(APP_NAME);
andreaeb70a942015-10-16 21:34:46 -0700118 cfgService.registerConfigFactory(factory);
119 cfgService.addListener(cfgLister);
120 controller.addDeviceListener(innerNodeListener);
Andrea Campanella8e290c52016-01-12 15:54:50 -0800121 connectDevices();
Thomas Vachuskad6811712015-04-29 21:37:04 -0700122 log.info("Started");
Sanjay Se8dcfee2015-04-23 10:07:08 +0530123 }
124
andreaeb70a942015-10-16 21:34:46 -0700125
Sanjay Se8dcfee2015-04-23 10:07:08 +0530126 @Deactivate
andreaeb70a942015-10-16 21:34:46 -0700127 public void deactivate() {
Sanjay Se8dcfee2015-04-23 10:07:08 +0530128 providerRegistry.unregister(this);
129 providerService = null;
andreaeb70a942015-10-16 21:34:46 -0700130 cfgService.unregisterConfigFactory(factory);
Andrea Campanella101417d2015-12-11 17:58:07 -0800131 controller.removeDeviceListener(innerNodeListener);
Sanjay Seb5eebb2015-04-24 15:44:50 +0530132 log.info("Stopped");
Sanjay Se8dcfee2015-04-23 10:07:08 +0530133 }
134
andreaeb70a942015-10-16 21:34:46 -0700135 public NetconfDeviceProvider() {
Andrea Campanella101417d2015-12-11 17:58:07 -0800136 super(new ProviderId(SCHEME_NAME, DEVICE_PROVIDER_PACKAGE));
Sanjay Se8dcfee2015-04-23 10:07:08 +0530137 }
138
139 @Override
140 public void triggerProbe(DeviceId deviceId) {
andreaeb70a942015-10-16 21:34:46 -0700141 // TODO: This will be implemented later.
142 log.info("Triggering probe on device {}", deviceId);
Sanjay Se8dcfee2015-04-23 10:07:08 +0530143 }
144
145 @Override
146 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
andreaeb70a942015-10-16 21:34:46 -0700147 // TODO: This will be implemented later.
Sanjay Se8dcfee2015-04-23 10:07:08 +0530148 }
149
150 @Override
151 public boolean isReachable(DeviceId deviceId) {
Andrea Campanella8e290c52016-01-12 15:54:50 -0800152 NetconfDevice netconfDevice = controller.getNetconfDevice(deviceId);
Sanjay Se8dcfee2015-04-23 10:07:08 +0530153 if (netconfDevice == null) {
Andrea Campanellad264b492016-03-01 09:46:06 -0800154 log.debug("Requested device id: {} is not associated to any " +
155 "NETCONF Device", deviceId.toString());
Sanjay Se8dcfee2015-04-23 10:07:08 +0530156 return false;
157 }
andreaeb70a942015-10-16 21:34:46 -0700158 return netconfDevice.isActive();
Sanjay Se8dcfee2015-04-23 10:07:08 +0530159 }
160
andreaeb70a942015-10-16 21:34:46 -0700161 private class InnerNetconfDeviceListener implements NetconfDeviceListener {
Sanjay Se8dcfee2015-04-23 10:07:08 +0530162
Andrea Campanella101417d2015-12-11 17:58:07 -0800163 private static final String IPADDRESS = "ipaddress";
164 protected static final String ISNULL = "NetconfDeviceInfo is null";
165
andreaeb70a942015-10-16 21:34:46 -0700166 @Override
167 public void deviceAdded(NetconfDeviceInfo nodeId) {
Andrea Campanella101417d2015-12-11 17:58:07 -0800168 Preconditions.checkNotNull(nodeId, ISNULL);
andreaeb70a942015-10-16 21:34:46 -0700169 DeviceId deviceId = nodeId.getDeviceId();
andreaeb70a942015-10-16 21:34:46 -0700170 //Netconf configuration object
171 ChassisId cid = new ChassisId();
172 String ipAddress = nodeId.ip().toString();
173 SparseAnnotations annotations = DefaultAnnotations.builder()
Andrea Campanella101417d2015-12-11 17:58:07 -0800174 .set(IPADDRESS, ipAddress).build();
andreaeb70a942015-10-16 21:34:46 -0700175 DeviceDescription deviceDescription = new DefaultDeviceDescription(
176 deviceId.uri(),
177 Device.Type.SWITCH,
178 UNKNOWN, UNKNOWN,
179 UNKNOWN, UNKNOWN,
180 cid,
181 annotations);
182 providerService.deviceConnected(deviceId, deviceDescription);
Sanjay Se8dcfee2015-04-23 10:07:08 +0530183 }
184
185 @Override
andreaeb70a942015-10-16 21:34:46 -0700186 public void deviceRemoved(NetconfDeviceInfo nodeId) {
Andrea Campanella101417d2015-12-11 17:58:07 -0800187 Preconditions.checkNotNull(nodeId, ISNULL);
andreaeb70a942015-10-16 21:34:46 -0700188 DeviceId deviceId = nodeId.getDeviceId();
189 providerService.deviceDisconnected(deviceId);
Sanjay Se8dcfee2015-04-23 10:07:08 +0530190
andreaeb70a942015-10-16 21:34:46 -0700191 }
192 }
193
andreaeb70a942015-10-16 21:34:46 -0700194 private void connectDevices() {
195 NetconfProviderConfig cfg = cfgService.getConfig(appId, NetconfProviderConfig.class);
196 if (cfg != null) {
Sanjay Se8dcfee2015-04-23 10:07:08 +0530197 try {
Andrea Campanella087ceb92015-12-07 09:58:34 -0800198 cfg.getDevicesAddresses().stream()
199 .forEach(addr -> {
200 try {
Aaron Kruglikov17b4c852016-01-15 16:37:04 -0800201 NetconfDeviceInfo netconf = new NetconfDeviceInfo(addr.name(),
202 addr.password(),
203 addr.ip(),
204 addr.port());
205 controller.connectDevice(netconf);
206 Device device = deviceService.getDevice(netconf.getDeviceId());
207 if (device.is(PortDiscovery.class)) {
208 PortDiscovery portConfig = device.as(PortDiscovery.class);
209 if (portConfig != null) {
210 providerService.updatePorts(netconf.getDeviceId(),
211 portConfig.getPorts());
212 }
213 } else {
214 log.warn("No portGetter behaviour for device {}", netconf.getDeviceId());
215 }
216
Andrea Campanella087ceb92015-12-07 09:58:34 -0800217 } catch (IOException e) {
Andrea Campanella8b1cb672016-01-25 13:58:58 -0800218 throw new RuntimeException(
219 new NetconfException(
220 "Can't connect to NETCONF " +
221 "device on " + addr.ip() +
222 ":" + addr.port(), e));
Andrea Campanella087ceb92015-12-07 09:58:34 -0800223 }
224 }
225 );
226
andreaeb70a942015-10-16 21:34:46 -0700227 } catch (ConfigException e) {
228 log.error("Cannot read config error " + e);
Sanjay Se8dcfee2015-04-23 10:07:08 +0530229 }
230 }
andreaeb70a942015-10-16 21:34:46 -0700231 }
Sanjay Se8dcfee2015-04-23 10:07:08 +0530232
andreaeb70a942015-10-16 21:34:46 -0700233 private class InternalNetworkConfigListener implements NetworkConfigListener {
Sanjay Se8dcfee2015-04-23 10:07:08 +0530234
andreaeb70a942015-10-16 21:34:46 -0700235
236 @Override
237 public void event(NetworkConfigEvent event) {
Andrea Campanella5c999e22016-03-01 15:12:53 -0800238 executor.submit(NetconfDeviceProvider.this::connectDevices);
Sanjay Se8dcfee2015-04-23 10:07:08 +0530239 }
240
andreaeb70a942015-10-16 21:34:46 -0700241 @Override
242 public boolean isRelevant(NetworkConfigEvent event) {
243 //TODO refactor
244 return event.configClass().equals(NetconfProviderConfig.class) &&
245 (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
246 event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED);
Sanjay Se8dcfee2015-04-23 10:07:08 +0530247 }
248 }
249}