[ONOS-6076] Moving tl1,snmp,rest netcfg to devices key
Change-Id: I332d6b9a3afad5bc8461f6bb94e2d0a3c2ca643e
diff --git a/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceConfig.java b/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceConfig.java
new file mode 100644
index 0000000..93acab5
--- /dev/null
+++ b/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceConfig.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.provider.rest.device.impl;
+
+import com.google.common.annotations.Beta;
+import org.apache.commons.lang3.tuple.Pair;
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.config.Config;
+
+/**
+ * Configuration to push devices to the REST provider.
+ */
+@Beta
+public class RestDeviceConfig extends Config<DeviceId> {
+
+ private static final String IP = "ip";
+ private static final String PORT = "port";
+ private static final String USERNAME = "username";
+ private static final String PASSWORD = "password";
+ private static final String PROTOCOL = "protocol";
+ private static final String URL = "url";
+ private static final String TESTURL = "testUrl";
+ private static final String MANUFACTURER = "manufacturer";
+ private static final String HWVERSION = "hwVersion";
+ private static final String SWVERSION = "swVersion";
+
+ @Override
+ public boolean isValid() {
+ return hasOnlyFields(IP, PORT, USERNAME, PASSWORD, PROTOCOL, URL,
+ TESTURL, MANUFACTURER, HWVERSION, SWVERSION) &&
+ ip() != null;
+ }
+
+ /**
+ * Gets the Ip of the REST device.
+ *
+ * @return ip
+ */
+ public IpAddress ip() {
+ return IpAddress.valueOf(get(IP, extractIpPort().getKey()));
+ }
+
+ /**
+ * Gets the port of the REST device.
+ *
+ * @return port
+ */
+ public int port() {
+ return get(PORT, extractIpPort().getValue());
+ }
+
+ /**
+ * Gets the protocol of the REST device.
+ *
+ * @return protocol
+ */
+ public String protocol() {
+ return get(PROTOCOL, "http");
+ }
+
+ /**
+ * Gets the username of the REST device.
+ *
+ * @return username
+ */
+ public String username() {
+ return get(USERNAME, "");
+ }
+
+ /**
+ * Gets the password of the REST device.
+ *
+ * @return password
+ */
+ public String password() {
+ return get(PASSWORD, "");
+ }
+
+ /**
+ * Gets the base url of the REST device.
+ *
+ * @return base url for the device config tree
+ */
+ public String url() {
+ return get(URL, "");
+ }
+
+ /**
+ * Gets the testUrl of the REST device.
+ *
+ * @return testUrl to test the device connection
+ */
+ public String testUrl() {
+ return get(TESTURL, "");
+ }
+
+ /**
+ * Gets the manufacturer of the REST device.
+ *
+ * @return manufacturer
+ */
+ public String manufacturer() {
+ return get(MANUFACTURER, "");
+ }
+
+ /**
+ * Gets the hwversion of the REST device.
+ *
+ * @return hwversion
+ */
+ public String hwVersion() {
+ return get(HWVERSION, "");
+ }
+
+ /**
+ * Gets the swversion of the REST device.
+ *
+ * @return swversion
+ */
+ public String swVersion() {
+ return get(SWVERSION, "");
+ }
+
+ private Pair<String, Integer> extractIpPort() {
+ String info = subject.toString();
+ if (info.startsWith(RestDeviceProvider.REST)) {
+ //+1 is due to length of colon separator
+ String ip = info.substring(info.indexOf(":") + 1, info.lastIndexOf(":"));
+ int port = Integer.parseInt(info.substring(info.lastIndexOf(":") + 1));
+ return Pair.of(ip, port);
+ }
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceProvider.java b/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceProvider.java
index 93f9ca9..478829e 100644
--- a/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceProvider.java
+++ b/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceProvider.java
@@ -17,6 +17,7 @@
package org.onosproject.provider.rest.device.impl;
import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -39,6 +40,7 @@
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.basics.SubjectFactories;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceDescriptionDiscovery;
@@ -54,15 +56,18 @@
import org.onosproject.net.driver.DriverService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
+import org.onosproject.protocol.rest.DefaultRestSBDevice;
import org.onosproject.protocol.rest.RestSBController;
import org.onosproject.protocol.rest.RestSBDevice;
import org.slf4j.Logger;
import javax.ws.rs.ProcessingException;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.groupedThreads;
@@ -78,7 +83,7 @@
public class RestDeviceProvider extends AbstractProvider
implements DeviceProvider {
private static final String APP_NAME = "org.onosproject.restsb";
- private static final String REST = "rest";
+ protected static final String REST = "rest";
private static final String JSON = "json";
private static final String PROVIDER = "org.onosproject.provider.rest.device";
private static final String IPADDRESS = "ipaddress";
@@ -115,7 +120,7 @@
private final ExecutorService executor =
Executors.newFixedThreadPool(5, groupedThreads("onos/restsbprovider", "device-installer-%d", log));
- private final ConfigFactory factory =
+ protected final List<ConfigFactory> factories = ImmutableList.of(
new ConfigFactory<ApplicationId, RestProviderConfig>(APP_SUBJECT_FACTORY,
RestProviderConfig.class,
"devices",
@@ -124,7 +129,16 @@
public RestProviderConfig createConfig() {
return new RestProviderConfig();
}
- };
+ },
+ new ConfigFactory<DeviceId, RestDeviceConfig>(SubjectFactories.DEVICE_SUBJECT_FACTORY,
+ RestDeviceConfig.class,
+ REST) {
+ @Override
+ public RestDeviceConfig createConfig() {
+ return new RestDeviceConfig();
+ }
+ });
+
private final NetworkConfigListener cfgLister = new InternalNetworkConfigListener();
private Set<DeviceId> addedDevices = new HashSet<>();
@@ -134,9 +148,10 @@
public void activate() {
appId = coreService.registerApplication(APP_NAME);
providerService = providerRegistry.register(this);
- cfgService.registerConfigFactory(factory);
+ factories.forEach(cfgService::registerConfigFactory);
cfgService.addListener(cfgLister);
- executor.execute(RestDeviceProvider.this::connectDevices);
+ executor.execute(RestDeviceProvider.this::createAndConnectDevices);
+ executor.execute(RestDeviceProvider.this::createDevices);
log.info("Started");
}
@@ -146,7 +161,7 @@
controller.getDevices().keySet().forEach(this::deviceRemoved);
providerRegistry.unregister(this);
providerService = null;
- cfgService.unregisterConfigFactory(factory);
+ factories.forEach(cfgService::unregisterConfigFactory);
log.info("Stopped");
}
@@ -319,25 +334,37 @@
controller.removeDevice(deviceId);
}
- private void connectDevices() {
+ //Method to connect devices provided via net-cfg under devices/ tree
+ private void createAndConnectDevices() {
+ Set<DeviceId> deviceSubjects =
+ cfgService.getSubjects(DeviceId.class, RestDeviceConfig.class);
+ connectDevices(deviceSubjects.stream()
+ .filter(deviceId -> deviceService.getDevice(deviceId) == null)
+ .map(deviceId -> {
+ RestDeviceConfig config =
+ cfgService.getConfig(deviceId, RestDeviceConfig.class);
+ RestSBDevice device = new DefaultRestSBDevice(config.ip(),
+ config.port(),
+ config.username(),
+ config.password(),
+ config.protocol(),
+ config.url(),
+ false, config.testUrl(),
+ config.manufacturer(),
+ config.hwVersion(),
+ config.swVersion());
+ return device;
+
+ }).collect(Collectors.toSet()));
+ }
+
+ //Old method to register devices provided via net-cfg under apps/rest/ tree
+ private void createDevices() {
RestProviderConfig cfg = cfgService.getConfig(appId, RestProviderConfig.class);
try {
if (cfg != null && cfg.getDevicesAddresses() != null) {
- //Precomputing the devices to be removed
- Set<RestSBDevice> toBeRemoved = new HashSet<>(controller.getDevices().values());
- toBeRemoved.removeAll(cfg.getDevicesAddresses());
- //Adding new devices
- cfg.getDevicesAddresses().stream()
- .filter(device -> {
- device.setActive(false);
- controller.addDevice(device);
- return testDeviceConnection(device);
- })
- .forEach(device -> {
- deviceAdded(device);
- });
- //Removing devices not wanted anymore
- toBeRemoved.forEach(device -> deviceRemoved(device.deviceId()));
+ connectDevices(cfg.getDevicesAddresses());
+
}
} catch (ConfigException e) {
log.error("Configuration error {}", e);
@@ -346,6 +373,24 @@
addedDevices.clear();
}
+ private void connectDevices(Set<RestSBDevice> devices) {
+ //Precomputing the devices to be removed
+ Set<RestSBDevice> toBeRemoved = new HashSet<>(controller.getDevices().values());
+ toBeRemoved.removeAll(devices);
+ //Adding new devices
+ devices.stream()
+ .filter(device -> {
+ device.setActive(false);
+ controller.addDevice(device);
+ return testDeviceConnection(device);
+ })
+ .forEach(device -> {
+ deviceAdded(device);
+ });
+ //Removing devices not wanted anymore
+ toBeRemoved.forEach(device -> deviceRemoved(device.deviceId()));
+ }
+
private void discoverPorts(DeviceId deviceId) {
Device device = deviceService.getDevice(deviceId);
//TODO remove when PortDiscovery is removed from master
@@ -376,13 +421,19 @@
private class InternalNetworkConfigListener implements NetworkConfigListener {
@Override
public void event(NetworkConfigEvent event) {
- executor.execute(RestDeviceProvider.this::connectDevices);
+ if (event.configClass().equals(RestDeviceConfig.class)) {
+ executor.execute(RestDeviceProvider.this::createAndConnectDevices);
+ } else {
+ log.warn("Injecting device via this Json is deprecated, " +
+ "please put configuration under devices/");
+ executor.execute(RestDeviceProvider.this::createDevices);
+ }
}
@Override
public boolean isRelevant(NetworkConfigEvent event) {
- //TODO refactor
- return event.configClass().equals(RestProviderConfig.class) &&
+ return (event.configClass().equals(RestDeviceConfig.class) ||
+ event.configClass().equals(RestProviderConfig.class)) &&
(event.type() == CONFIG_ADDED ||
event.type() == CONFIG_UPDATED);
}
diff --git a/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestProviderConfig.java b/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestProviderConfig.java
index 5e6fc96..d726143 100644
--- a/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestProviderConfig.java
+++ b/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestProviderConfig.java
@@ -30,7 +30,9 @@
/**
* Configuration for RestSB provider.
+ * @deprecated 1.10.0 Kingfisher. Please Use RestDeviceConfig
*/
+@Deprecated
@Beta
public class RestProviderConfig extends Config<ApplicationId> {
diff --git a/providers/snmp/device/src/main/java/org/onosproject/provider/snmp/device/impl/SnmpDeviceConfig.java b/providers/snmp/device/src/main/java/org/onosproject/provider/snmp/device/impl/SnmpDeviceConfig.java
new file mode 100644
index 0000000..293f5cd
--- /dev/null
+++ b/providers/snmp/device/src/main/java/org/onosproject/provider/snmp/device/impl/SnmpDeviceConfig.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.provider.snmp.device.impl;
+
+import com.google.common.annotations.Beta;
+import org.apache.commons.lang3.tuple.Pair;
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.config.Config;
+
+/**
+ * Configuration to push devices to the SNMP provider.
+ */
+@Beta
+public class SnmpDeviceConfig extends Config<DeviceId> {
+
+ private static final String IP = "ip";
+ private static final String PORT = "port";
+ private static final String USERNAME = "username";
+ private static final String PASSWORD = "password";
+
+ @Override
+ public boolean isValid() {
+ return hasOnlyFields(IP, PORT, USERNAME, PASSWORD) &&
+ ip() != null;
+ }
+
+ /**
+ * Gets the Ip of the SNMP device.
+ *
+ * @return ip
+ */
+ public IpAddress ip() {
+ return IpAddress.valueOf(get(IP, extractIpPort().getKey()));
+ }
+
+ /**
+ * Gets the port of the SNMP device.
+ *
+ * @return port
+ */
+ public int port() {
+ return get(PORT, extractIpPort().getValue());
+ }
+
+ /**
+ * Gets the username of the SNMP device.
+ *
+ * @return username
+ */
+ public String username() {
+ return get(USERNAME, "");
+ }
+
+ /**
+ * Gets the password of the SNMP device.
+ *
+ * @return password
+ */
+ public String password() {
+ return get(PASSWORD, "");
+ }
+
+
+ private Pair<String, Integer> extractIpPort() {
+ String info = subject.toString();
+ if (info.startsWith(SnmpDeviceProvider.SCHEME)) {
+ //+1 is due to length of colon separator
+ String ip = info.substring(info.indexOf(":") + 1, info.lastIndexOf(":"));
+ int port = Integer.parseInt(info.substring(info.lastIndexOf(":") + 1));
+ return Pair.of(ip, port);
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/providers/snmp/device/src/main/java/org/onosproject/provider/snmp/device/impl/SnmpDeviceProvider.java b/providers/snmp/device/src/main/java/org/onosproject/provider/snmp/device/impl/SnmpDeviceProvider.java
index 2a36950..fb77c70 100644
--- a/providers/snmp/device/src/main/java/org/onosproject/provider/snmp/device/impl/SnmpDeviceProvider.java
+++ b/providers/snmp/device/src/main/java/org/onosproject/provider/snmp/device/impl/SnmpDeviceProvider.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.provider.snmp.device.impl;
+import com.google.common.collect.ImmutableList;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -36,6 +37,7 @@
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.basics.SubjectFactories;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceDescriptionDiscovery;
@@ -52,6 +54,8 @@
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
+import java.util.List;
+import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@@ -72,7 +76,7 @@
private static final String UNKNOWN = "unknown";
private static final String APP_NAME = "org.onosproject.snmp";
- private static final String SCHEME = "snmp";
+ protected static final String SCHEME = "snmp";
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected SnmpController controller;
@@ -102,7 +106,7 @@
protected final NetworkConfigListener cfgLister = new InternalNetworkConfigListener();
- protected final ConfigFactory factory =
+ protected final List<ConfigFactory> factories = ImmutableList.of(
new ConfigFactory<ApplicationId, SnmpProviderConfig>(APP_SUBJECT_FACTORY,
SnmpProviderConfig.class,
"devices",
@@ -111,7 +115,15 @@
public SnmpProviderConfig createConfig() {
return new SnmpProviderConfig();
}
- };
+ },
+ new ConfigFactory<DeviceId, SnmpDeviceConfig>(SubjectFactories.DEVICE_SUBJECT_FACTORY,
+ SnmpDeviceConfig.class,
+ SCHEME) {
+ @Override
+ public SnmpDeviceConfig createConfig() {
+ return new SnmpDeviceConfig();
+ }
+ });
/**
@@ -127,8 +139,10 @@
providerService = providerRegistry.register(this);
appId = coreService.registerApplication(APP_NAME);
- netCfgService.registerConfigFactory(factory);
+ factories.forEach(netCfgService::registerConfigFactory);
netCfgService.addListener(cfgLister);
+ connectDevices();
+ addOrRemoveDevicesConfig();
modified(context);
log.info("Started");
}
@@ -145,7 +159,7 @@
log.error("Device builder did not terminate");
}
deviceBuilderExecutor.shutdownNow();
- netCfgService.unregisterConfigFactory(factory);
+ factories.forEach(netCfgService::unregisterConfigFactory);
netCfgService.removeListener(cfgLister);
providerRegistry.unregister(this);
providerService = null;
@@ -157,14 +171,16 @@
log.info("Modified");
}
+ //Old method to register devices provided via net-cfg under apps/snmp/ tree
private void addOrRemoveDevicesConfig() {
SnmpProviderConfig cfg = netCfgService.getConfig(appId, SnmpProviderConfig.class);
if (cfg != null) {
try {
cfg.getDevicesInfo().forEach(info -> {
- SnmpDevice device = new DefaultSnmpDevice(info.ip().toString(),
- info.port(), info.username(), info.password());
- buildDevice(device);
+ buildDevice(new DefaultSnmpDevice(info.ip().toString(),
+ info.port(), info.username(),
+ info.password()));
+
});
} catch (ConfigException e) {
log.error("Cannot read config error " + e);
@@ -172,6 +188,18 @@
}
}
+ //Method to register devices provided via net-cfg under devices/ tree
+ private void connectDevices() {
+ Set<DeviceId> deviceSubjects =
+ netCfgService.getSubjects(DeviceId.class, SnmpDeviceConfig.class);
+ deviceSubjects.forEach(deviceId -> {
+ SnmpDeviceConfig config =
+ netCfgService.getConfig(deviceId, SnmpDeviceConfig.class);
+ buildDevice(new DefaultSnmpDevice(config.ip().toString(),
+ config.port(), config.username(), config.password()));
+ });
+ }
+
private void buildDevice(SnmpDevice device) {
if (device != null) {
log.debug("Device Detail:host={}, port={}, state={}",
@@ -310,12 +338,19 @@
@Override
public void event(NetworkConfigEvent event) {
- addOrRemoveDevicesConfig();
+ if (event.configClass().equals(SnmpDeviceConfig.class)) {
+ connectDevices();
+ } else {
+ log.warn("Injecting device via this Json is deprecated, " +
+ "please put configuration under devices/");
+ addOrRemoveDevicesConfig();
+ }
}
@Override
public boolean isRelevant(NetworkConfigEvent event) {
- return event.configClass().equals(SnmpProviderConfig.class) &&
+ return (event.configClass().equals(SnmpDeviceConfig.class) ||
+ event.configClass().equals(SnmpProviderConfig.class)) &&
(event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED);
}
diff --git a/providers/snmp/device/src/main/java/org/onosproject/provider/snmp/device/impl/SnmpProviderConfig.java b/providers/snmp/device/src/main/java/org/onosproject/provider/snmp/device/impl/SnmpProviderConfig.java
index 0c3486a..9fecad3 100644
--- a/providers/snmp/device/src/main/java/org/onosproject/provider/snmp/device/impl/SnmpProviderConfig.java
+++ b/providers/snmp/device/src/main/java/org/onosproject/provider/snmp/device/impl/SnmpProviderConfig.java
@@ -27,7 +27,9 @@
/**
* Configuration decoder for SNMP provider.
+ * @deprecated 1.10.0 Kingfisher
*/
+@Deprecated
@Beta
public class SnmpProviderConfig extends Config<ApplicationId> {
diff --git a/providers/snmp/device/src/test/java/org/onosproject/provider/snmp/device/impl/SnmpDeviceProviderTest.java b/providers/snmp/device/src/test/java/org/onosproject/provider/snmp/device/impl/SnmpDeviceProviderTest.java
index ac7e2e0..462e05e 100644
--- a/providers/snmp/device/src/test/java/org/onosproject/provider/snmp/device/impl/SnmpDeviceProviderTest.java
+++ b/providers/snmp/device/src/test/java/org/onosproject/provider/snmp/device/impl/SnmpDeviceProviderTest.java
@@ -16,6 +16,8 @@
package org.onosproject.provider.snmp.device.impl;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableSet;
import org.junit.Before;
import org.junit.Test;
@@ -31,6 +33,7 @@
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigApplyDelegate;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
@@ -52,6 +55,7 @@
import org.onosproject.net.provider.ProviderId;
import org.onosproject.snmp.SnmpController;
+import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
@@ -64,6 +68,8 @@
*/
public class SnmpDeviceProviderTest {
+ public static final int TEST_DURATION = 1500;
+ public static final int DELAY = 500;
private final SnmpDeviceProvider provider = new SnmpDeviceProvider();
private final SnmpController controller = new SnmpControllerAdapter();
private final DeviceProviderRegistry providerRegistry = new MockDeviceProviderRegistry();
@@ -73,15 +79,26 @@
protected CoreService coreService = new MockCoreService();
private final DeviceProviderService deviceProviderService = new MockDeviceProviderService();
private final TestApplicationId applicationId = new TestApplicationId("TestAppId");
+ private final SnmpProviderConfig snmpProviderConfig = new MockSnmpProviderConfig();
+ private final DeviceId deviceId = DeviceId.deviceId("snmp:1.1.1.1:1");
+ private final DeviceId wrongDeviceId = DeviceId.deviceId("snmp:2.2.2.2:2");
+ private final Set<ConfigFactory> cfgFactories = new HashSet<>();
+ private final Set<NetworkConfigListener> netCfgListeners = new HashSet<>();
private final NetworkConfigEvent deviceAddedEvent =
new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_ADDED,
null, SnmpProviderConfig.class);
- private final SnmpProviderConfig snmpProviderConfig = new MockSnmpProviderConfig();
private final NetworkConfigEvent deviceAddedIrrelevantEvent =
new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_ADDED,
null, BasicDeviceConfig.class);
- private final DeviceId deviceId = DeviceId.deviceId("snmp:1.1.1.1:1");
- private final DeviceId wrongDeviceId = DeviceId.deviceId("snmp:2.2.2.2:2");
+ private final NetworkConfigEvent deviceAddedNewEvent =
+ new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_ADDED,
+ deviceId, SnmpDeviceConfig.class);
+ private final SnmpDeviceConfig config = new SnmpDeviceConfig();
+ //Testing Files
+ private final InputStream jsonStream = SnmpDeviceProviderTest.class
+ .getResourceAsStream("/device.json");
+ private final ObjectMapper mapper = new ObjectMapper();
+ private final String KEY = "snmp";
@Before
@@ -92,6 +109,9 @@
provider.netCfgService = netCfgService;
provider.deviceStore = deviceStore;
provider.coreService = coreService;
+ JsonNode jsonNode = mapper.readTree(jsonStream);
+ ConfigApplyDelegate delegate = new MockDelegate();
+ config.init(deviceId, KEY, jsonNode, mapper, delegate);
provider.activate(null);
}
@@ -99,7 +119,7 @@
public void testActivate() {
assertEquals("Incorrect provider service", deviceProviderService, provider.providerService);
assertEquals("Incorrect application id", applicationId, provider.appId);
- assertEquals("Incorrect config factory", cfgFactory, provider.factory);
+ assertTrue("Incorrect config factories", cfgFactories.containsAll(provider.factories));
assertTrue("Incorrect network config listener", netCfgListeners.contains(provider.cfgLister));
@@ -109,9 +129,9 @@
public void testDeactivate() {
this.addDevice();
provider.deactivate(null);
- assertAfter(500, () ->
+ assertAfter(DELAY, TEST_DURATION, () ->
assertNull("Device should be removed", controller.getDevice(deviceId)));
- assertNull("Network config factory not removed", cfgFactory);
+ assertTrue("Network config factory not removed", cfgFactories.isEmpty());
assertFalse("Network config listener not removed", netCfgListeners.contains(provider.cfgLister));
assertFalse("Provider not unregistered", providerRegistry.getProviders().contains(provider.id()));
assertNull("Provider registry not removed", provider.providerService);
@@ -129,7 +149,18 @@
provider.cfgLister.event(deviceAddedEvent);
AbstractProjectableModel.setDriverService(null, new MockDriverService());
//FIXME this needs sleep
- assertAfter(500, () ->
+ assertAfter(DELAY, TEST_DURATION, () ->
+ assertNotNull("Device should be added to controller", controller.getDevice(deviceId)));
+ assertTrue("Device should be reachable", provider.isReachable(deviceId));
+ }
+
+ @Test
+ public void addDeviceNew() {
+ assertTrue("Event should be relevant", provider.cfgLister.isRelevant(deviceAddedNewEvent));
+ provider.cfgLister.event(deviceAddedNewEvent);
+ AbstractProjectableModel.setDriverService(null, new MockDriverService());
+ //FIXME this needs sleep
+ assertAfter(DELAY, TEST_DURATION, () ->
assertNotNull("Device should be added to controller", controller.getDevice(deviceId)));
assertTrue("Device should be reachable", provider.isReachable(deviceId));
}
@@ -163,19 +194,16 @@
}
}
- private ConfigFactory cfgFactory;
- private Set<NetworkConfigListener> netCfgListeners = new HashSet<>();
-
private class MockNetworkConfigRegistry extends NetworkConfigRegistryAdapter {
@Override
public void registerConfigFactory(ConfigFactory configFactory) {
- cfgFactory = configFactory;
+ cfgFactories.add(configFactory);
}
@Override
public void unregisterConfigFactory(ConfigFactory configFactory) {
- cfgFactory = null;
+ cfgFactories.remove(configFactory);
}
@Override
@@ -193,10 +221,17 @@
public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
if (configClass.equals(SnmpProviderConfig.class)) {
return (C) snmpProviderConfig;
+ } else if (configClass.equals(SnmpDeviceConfig.class)) {
+ return (C) config;
} else {
return (C) new BasicDeviceConfig();
}
}
+
+ @Override
+ public <S, C extends Config<S>> Set<S> getSubjects(Class<S> subjectClass, Class<C> configClass) {
+ return ImmutableSet.of((S) deviceId);
+ }
}
private class MockDeviceStore extends DeviceStoreAdapter {
@@ -249,4 +284,11 @@
private class MockDriverService extends DriverServiceAdapter {
}
+
+ private class MockDelegate implements ConfigApplyDelegate {
+ @Override
+ public void onApply(Config config) {
+
+ }
+ }
}
\ No newline at end of file
diff --git a/providers/snmp/device/src/test/resources/device.json b/providers/snmp/device/src/test/resources/device.json
new file mode 100644
index 0000000..cb8b34b
--- /dev/null
+++ b/providers/snmp/device/src/test/resources/device.json
@@ -0,0 +1,8 @@
+{
+ "ip":"1.1.1.1",
+ "port":1,
+ "username":"test",
+ "password":"test",
+ "protocol":"http"
+}
+
diff --git a/providers/tl1/device/src/main/java/org/onosproject/provider/tl1/device/impl/Tl1DeviceConfig.java b/providers/tl1/device/src/main/java/org/onosproject/provider/tl1/device/impl/Tl1DeviceConfig.java
new file mode 100644
index 0000000..91c235d
--- /dev/null
+++ b/providers/tl1/device/src/main/java/org/onosproject/provider/tl1/device/impl/Tl1DeviceConfig.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2015-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.provider.tl1.device.impl;
+
+import com.google.common.annotations.Beta;
+import org.apache.commons.lang3.tuple.Pair;
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.config.Config;
+
+/**
+ * Configuration to push devices to the TL1 provider.
+ */
+@Beta
+public class Tl1DeviceConfig extends Config<DeviceId> {
+
+ private static final String IP = "ip";
+ private static final String PORT = "port";
+ private static final String USERNAME = "username";
+ private static final String PASSWORD = "password";
+
+ @Override
+ public boolean isValid() {
+ return hasOnlyFields(IP, PORT, USERNAME, PASSWORD) &&
+ ip() != null;
+ }
+
+ /**
+ * Gets the Ip of the TL1 device.
+ *
+ * @return ip
+ */
+ public IpAddress ip() {
+ return IpAddress.valueOf(get(IP, extractIpPort().getKey()));
+ }
+
+ /**
+ * Gets the port of the TL1 device.
+ *
+ * @return port
+ */
+ public int port() {
+ return get(PORT, extractIpPort().getValue());
+ }
+
+ /**
+ * Gets the username of the TL1 device.
+ *
+ * @return username
+ */
+ public String username() {
+ return get(USERNAME, "");
+ }
+
+ /**
+ * Gets the password of the TL1 device.
+ *
+ * @return password
+ */
+ public String password() {
+ return get(PASSWORD, "");
+ }
+
+
+ private Pair<String, Integer> extractIpPort() {
+ String info = subject.toString();
+ if (info.startsWith(Tl1DeviceProvider.TL1)) {
+ //+1 is due to length of colon separator
+ String ip = info.substring(info.indexOf(":") + 1, info.lastIndexOf(":"));
+ int port = Integer.parseInt(info.substring(info.lastIndexOf(":") + 1));
+ return Pair.of(ip, port);
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/providers/tl1/device/src/main/java/org/onosproject/provider/tl1/device/impl/Tl1DeviceProvider.java b/providers/tl1/device/src/main/java/org/onosproject/provider/tl1/device/impl/Tl1DeviceProvider.java
index e6f5e0b..6013aea 100644
--- a/providers/tl1/device/src/main/java/org/onosproject/provider/tl1/device/impl/Tl1DeviceProvider.java
+++ b/providers/tl1/device/src/main/java/org/onosproject/provider/tl1/device/impl/Tl1DeviceProvider.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.provider.tl1.device.impl;
+import com.google.common.collect.ImmutableList;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -35,6 +36,7 @@
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.basics.SubjectFactories;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DeviceAdminService;
import org.onosproject.net.device.DeviceDescription;
@@ -48,6 +50,7 @@
import org.onosproject.tl1.Tl1Controller;
import org.onosproject.tl1.Tl1Device;
import org.onosproject.tl1.Tl1Listener;
+import org.onosproject.tl1.impl.DefaultTl1Device;
import org.slf4j.Logger;
import java.io.IOException;
@@ -55,21 +58,23 @@
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.List;
import java.util.NoSuchElementException;
+import java.util.Set;
import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Device provider for TL1 devices.
- *
+ * <p>
* Sits between ONOS provider service and the TL1 controller.
* Relies on network config subsystem to know about devices.
*/
@Component(immediate = true)
public class Tl1DeviceProvider extends AbstractProvider implements DeviceProvider {
private static final String APP_NAME = "org.onosproject.tl1";
- private static final String TL1 = "tl1";
+ protected static final String TL1 = "tl1";
private static final String PROVIDER = "org.onosproject.provider.tl1.device";
private static final String UNKNOWN = "unknown";
private static final int REACHABILITY_TIMEOUT = 2000; // in milliseconds
@@ -99,16 +104,24 @@
private Tl1Listener tl1Listener = new InnerTl1Listener();
private DeviceProviderService providerService;
- private final ConfigFactory cfgFactory =
+ private final List<ConfigFactory> factories = ImmutableList.of(
new ConfigFactory<ApplicationId, Tl1ProviderConfig>(APP_SUBJECT_FACTORY,
- Tl1ProviderConfig.class,
- "tl1_devices",
- true) {
+ Tl1ProviderConfig.class,
+ "tl1_devices",
+ true) {
@Override
public Tl1ProviderConfig createConfig() {
return new Tl1ProviderConfig();
}
- };
+ },
+ new ConfigFactory<DeviceId, Tl1DeviceConfig>(SubjectFactories.DEVICE_SUBJECT_FACTORY,
+ Tl1DeviceConfig.class,
+ TL1) {
+ @Override
+ public Tl1DeviceConfig createConfig() {
+ return new Tl1DeviceConfig();
+ }
+ });
@Activate
public void activate() {
@@ -116,8 +129,9 @@
providerService = providerRegistry.register(this);
cfgRegistry.addListener(cfgListener);
controller.addListener(tl1Listener);
- cfgRegistry.registerConfigFactory(cfgFactory);
+ factories.forEach(cfgRegistry::registerConfigFactory);
registerDevices();
+ connectDevices();
log.info("Started");
}
@@ -130,7 +144,7 @@
deviceAdminService.removeDevice(deviceId);
});
providerRegistry.unregister(this);
- cfgRegistry.unregisterConfigFactory(cfgFactory);
+ factories.forEach(cfgRegistry::unregisterConfigFactory);
providerService = null;
log.info("Stopped");
}
@@ -191,7 +205,7 @@
// TODO
}
- // Register all devices in the core and in the TL1 controller
+ //Old method to register devices provided via net-cfg under apps/tl1/ tree
void registerDevices() {
Tl1ProviderConfig cfg = cfgRegistry.getConfig(appId, Tl1ProviderConfig.class);
@@ -200,30 +214,49 @@
}
try {
- cfg.readDevices().forEach(device -> {
- try {
- // Add device to TL1 controller
- DeviceId deviceId = DeviceId.deviceId(
- new URI(TL1, device.ip() + ":" + device.port(), null));
-
- if (controller.addDevice(deviceId, device)) {
- SparseAnnotations ann = DefaultAnnotations.builder()
- .set(AnnotationKeys.PROTOCOL, TL1.toUpperCase())
- .build();
- // Register device in the core with default parameters and mark it as unavailable
- DeviceDescription dd = new DefaultDeviceDescription(deviceId.uri(), Device.Type.SWITCH, UNKNOWN,
- UNKNOWN, UNKNOWN, UNKNOWN, new ChassisId(), false, ann);
- providerService.deviceConnected(deviceId, dd);
- }
- } catch (URISyntaxException e) {
- log.error("Skipping device {}", device, e);
- }
- });
+ cfg.readDevices().forEach(this::connectDevice);
} catch (ConfigException e) {
log.error("Cannot parse network configuration", e);
}
}
+ //Method to register devices provided via net-cfg under devices/ tree
+ private void connectDevices() {
+ Set<DeviceId> deviceSubjects =
+ cfgRegistry.getSubjects(DeviceId.class, Tl1DeviceConfig.class);
+ deviceSubjects.forEach(deviceId -> {
+ Tl1DeviceConfig config =
+ cfgRegistry.getConfig(deviceId, Tl1DeviceConfig.class);
+ connectDevice(new DefaultTl1Device(config.ip(), config.port(), config.username(),
+ config.password()));
+ });
+ }
+
+ // Register a device in the core and in the TL1 controller.
+ private void connectDevice(Tl1Device device) {
+ try {
+ // Add device to TL1 controller
+ DeviceId deviceId = DeviceId.deviceId(
+ new URI(TL1, device.ip() + ":" + device.port(), null));
+
+ if (controller.addDevice(deviceId, device)) {
+ SparseAnnotations ann = DefaultAnnotations.builder()
+ .set(AnnotationKeys.PROTOCOL, TL1.toUpperCase())
+ .build();
+ // Register device in the core with default parameters and mark it as unavailable
+ DeviceDescription dd = new DefaultDeviceDescription(deviceId.uri(),
+ Device.Type.SWITCH,
+ UNKNOWN, UNKNOWN,
+ UNKNOWN, UNKNOWN,
+ new ChassisId(),
+ false, ann);
+ providerService.deviceConnected(deviceId, dd);
+ }
+ } catch (URISyntaxException e) {
+ log.error("Skipping device {}", device, e);
+ }
+ }
+
/**
* Tries to update the device and port descriptions through the {@code DeviceDescriptionDiscovery} behaviour.
*
@@ -244,7 +277,7 @@
return;
}
providerService.deviceConnected(deviceId,
- new DefaultDeviceDescription(dd, true, dd.annotations()));
+ new DefaultDeviceDescription(dd, true, dd.annotations()));
// Update ports
providerService.updatePorts(deviceId, discovery.discoverPortDetails());
} catch (IllegalStateException | IllegalArgumentException e) {
@@ -259,10 +292,22 @@
@Override
public void event(NetworkConfigEvent event) {
if (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED) {
- registerDevices();
+ if (event.configClass().equals(Tl1DeviceConfig.class)) {
+ connectDevices();
+ } else {
+ log.warn("Injecting device via this Json is deprecated, " +
+ "please put configuration under devices/");
+ registerDevices();
+ }
} else if (event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) {
// TODO: calculate delta
- registerDevices();
+ if (event.configClass().equals(Tl1DeviceConfig.class)) {
+ connectDevices();
+ } else {
+ log.warn("Injecting device via this Json is deprecated, " +
+ "please put configuration under devices/");
+ registerDevices();
+ }
} else if (event.type() == NetworkConfigEvent.Type.CONFIG_REMOVED) {
controller.getDeviceIds().forEach(deviceId -> {
controller.removeDevice(deviceId);
@@ -273,7 +318,8 @@
@Override
public boolean isRelevant(NetworkConfigEvent event) {
- return event.configClass().equals(Tl1ProviderConfig.class) &&
+ return (event.configClass().equals(Tl1DeviceConfig.class) ||
+ event.configClass().equals(Tl1ProviderConfig.class)) &&
(event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED ||
event.type() == NetworkConfigEvent.Type.CONFIG_REMOVED);
diff --git a/providers/tl1/device/src/main/java/org/onosproject/provider/tl1/device/impl/Tl1ProviderConfig.java b/providers/tl1/device/src/main/java/org/onosproject/provider/tl1/device/impl/Tl1ProviderConfig.java
index a1db864..4f883cd 100644
--- a/providers/tl1/device/src/main/java/org/onosproject/provider/tl1/device/impl/Tl1ProviderConfig.java
+++ b/providers/tl1/device/src/main/java/org/onosproject/provider/tl1/device/impl/Tl1ProviderConfig.java
@@ -28,7 +28,10 @@
/**
* Configuration for TL1 provider.
+ * @deprecated 1.10.0 Kingfisher
+ *
*/
+@Deprecated
public class Tl1ProviderConfig extends Config<ApplicationId> {
public static final String CONFIG_VALUE_ERROR = "Error parsing config value";
private static final String IP = "ip";
diff --git a/tools/test/configs/restSB-cfg-old.json b/tools/test/configs/restSB-cfg-old.json
new file mode 100644
index 0000000..f7aa152
--- /dev/null
+++ b/tools/test/configs/restSB-cfg-old.json
@@ -0,0 +1,20 @@
+{
+ "devices": {
+ "rest:127.0.0.1:8080": {
+ "basic": {
+ "driver": "restCiena"
+ }
+ }
+ },
+ "apps": {
+ "org.onosproject.restsb": {
+ "devices": [{
+ "username": "dev",
+ "password": "",
+ "ip": "127.0.0.1",
+ "port": 8080,
+ "protocol": "http"
+ }]
+ }
+ }
+}
\ No newline at end of file
diff --git a/tools/test/configs/restSB-cfg.json b/tools/test/configs/restSB-cfg.json
index f7aa152..2ab6ab6 100644
--- a/tools/test/configs/restSB-cfg.json
+++ b/tools/test/configs/restSB-cfg.json
@@ -1,20 +1,16 @@
{
"devices": {
"rest:127.0.0.1:8080": {
+ "rest": {
+ "ip": "127.0.0.1",
+ "port": 8080,
+ "username": "dev",
+ "password": "dev",
+ "protocol": "http"
+ },
"basic": {
"driver": "restCiena"
}
}
- },
- "apps": {
- "org.onosproject.restsb": {
- "devices": [{
- "username": "dev",
- "password": "",
- "ip": "127.0.0.1",
- "port": 8080,
- "protocol": "http"
- }]
- }
}
}
\ No newline at end of file
diff --git a/tools/test/configs/snmp-cfg.json b/tools/test/configs/snmp-cfg.json
new file mode 100644
index 0000000..3818eff
--- /dev/null
+++ b/tools/test/configs/snmp-cfg.json
@@ -0,0 +1,12 @@
+{
+ "devices": {
+ "snmp:127.0.0.1:555": {
+ "snmp": {
+ "ip": "127.0.0.1",
+ "port": 555,
+ "username": "dev",
+ "password": "dev"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tools/test/configs/tl1-cfg.json b/tools/test/configs/tl1-cfg.json
new file mode 100644
index 0000000..aa73c30
--- /dev/null
+++ b/tools/test/configs/tl1-cfg.json
@@ -0,0 +1,12 @@
+{
+ "devices": {
+ "tl1:127.0.0.1:20": {
+ "tl1": {
+ "ip": "127.0.0.1",
+ "port": 20,
+ "username": "dev",
+ "password": "dev"
+ }
+ }
+ }
+}
\ No newline at end of file