ONOS-3575 Netconf connection exceptions refactoring and port number in netconf-cfg.json
Change-Id: I46771a1a3ce99b25c2aecd7ba1838f9f1614e789
diff --git a/drivers/src/main/java/org/onosproject/driver/netconf/NetconfControllerConfig.java b/drivers/src/main/java/org/onosproject/driver/netconf/NetconfControllerConfig.java
index 84043b5..1805f53 100644
--- a/drivers/src/main/java/org/onosproject/driver/netconf/NetconfControllerConfig.java
+++ b/drivers/src/main/java/org/onosproject/driver/netconf/NetconfControllerConfig.java
@@ -27,6 +27,7 @@
import org.slf4j.Logger;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@@ -49,10 +50,14 @@
DeviceId ofDeviceId = handler.data().deviceId();
Preconditions.checkNotNull(controller, "Netconf controller is null");
List<ControllerInfo> controllers = new ArrayList<>();
- controllers.addAll(XmlConfigParser.parseStreamControllers(XmlConfigParser.
- loadXml(new ByteArrayInputStream(controller.
- getDevicesMap().get(ofDeviceId).getSession().
- getConfig("running").getBytes(StandardCharsets.UTF_8)))));
+ try {
+ controllers.addAll(XmlConfigParser.parseStreamControllers(XmlConfigParser.
+ loadXml(new ByteArrayInputStream(controller.
+ getDevicesMap().get(ofDeviceId).getSession().
+ getConfig("running").getBytes(StandardCharsets.UTF_8)))));
+ } catch (IOException e) {
+ log.error("Cannot comunicate to device {} ", ofDeviceId);
+ }
return controllers;
}
@@ -65,19 +70,26 @@
try {
NetconfDevice device = controller.getNetconfDevice(deviceId);
log.warn("provider map {}", controller.getDevicesMap());
- String config = XmlConfigParser.createControllersConfig(
- XmlConfigParser.loadXml(getClass().getResourceAsStream("controllers.xml")),
- XmlConfigParser.loadXml(
- new ByteArrayInputStream(device.getSession()
- .getConfig("running")
- .getBytes(
- StandardCharsets.UTF_8))),
- "running", "merge", "create", controllers
- );
+ String config = null;
+ try {
+ config = XmlConfigParser.createControllersConfig(
+ XmlConfigParser.loadXml(getClass().getResourceAsStream("controllers.xml")),
+ XmlConfigParser.loadXml(
+ new ByteArrayInputStream(device.getSession()
+ .getConfig("running")
+ .getBytes(
+ StandardCharsets.UTF_8))),
+ "running", "merge", "create", controllers
+ );
+ } catch (IOException e) {
+ log.error("Cannot comunicate to device {} , exception {}", deviceId, e.getMessage());
+ }
device.getSession().editConfig(config.substring(config.indexOf("-->") + 3));
} catch (NullPointerException e) {
log.warn("No NETCONF device with requested parameters " + e);
throw new NullPointerException("No NETCONF device with requested parameters " + e);
+ } catch (IOException e) {
+ log.error("Cannot comunicate to device {} , exception {}", deviceId, e.getMessage());
}
}
diff --git a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceInfo.java b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceInfo.java
index cb0e240..8331a12 100644
--- a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceInfo.java
+++ b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceInfo.java
@@ -68,7 +68,7 @@
* @param password the password for the device
* @param ipAddress the ip address
* @param port the tcp port
- * @param keyString the string cointaing the key.
+ * @param keyString the string containing the key.
*/
public NetconfDeviceInfo(String name, String password, IpAddress ipAddress,
int port, String keyString) {
diff --git a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSession.java b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSession.java
index 73c435f..2a19514 100644
--- a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSession.java
+++ b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSession.java
@@ -16,6 +16,7 @@
package org.onosproject.netconf;
+import java.io.IOException;
import java.util.List;
/**
@@ -30,14 +31,14 @@
* @param request the XML containing the request to the server.
* @return device running configuration
*/
- String get(String request);
+ String get(String request) throws IOException;
/**
* Executes an RPC to the server.
* @param request the XML containing the RPC for the server.
* @return Server response or ERROR
*/
- String doRPC(String request);
+ String doRPC(String request) throws IOException;
/**
* Retrives the specified configuration.
@@ -45,7 +46,7 @@
* @param targetConfiguration the type of configuration to retrieve.
* @return specified configuration.
*/
- String getConfig(String targetConfiguration);
+ String getConfig(String targetConfiguration) throws IOException;
/**
* Retrives part of the specivied configuration based on the filterSchema.
@@ -55,7 +56,8 @@
* elements we are interested in
* @return device running configuration.
*/
- String getConfig(String targetConfiguration, String configurationFilterSchema);
+ String getConfig(String targetConfiguration, String configurationFilterSchema)
+ throws IOException;
/**
* Retrives part of the specified configuration based on the filterSchema.
@@ -64,7 +66,7 @@
* @return true if the configuration was edited correctly
*/
- boolean editConfig(String newConfiguration);
+ boolean editConfig(String newConfiguration) throws IOException;
/**
* Copies the new configuration, an Url or a complete configuration xml tree
@@ -75,7 +77,8 @@
* @param newConfiguration configuration to set
* @return true if the configuration was copied correctly
*/
- boolean copyConfig(String targetConfiguration, String newConfiguration);
+ boolean copyConfig(String targetConfiguration, String newConfiguration)
+ throws IOException;
/**
* Deletes part of the specified configuration based on the filterSchema.
@@ -83,28 +86,28 @@
* @param targetConfiguration the name of the configuration to delete
* @return true if the configuration was copied correctly
*/
- boolean deleteConfig(String targetConfiguration);
+ boolean deleteConfig(String targetConfiguration) throws IOException;
/**
* Locks the candidate configuration.
*
* @return true if successful.
*/
- boolean lock();
+ boolean lock() throws IOException;
/**
* Unlocks the candidate configuration.
*
* @return true if successful.
*/
- boolean unlock();
+ boolean unlock() throws IOException;
/**
* Closes the Netconf session with the device.
* the first time it tries gracefully, then kills it forcefully
* @return true if closed
*/
- boolean close();
+ boolean close() throws IOException;
/**
* Gets the session ID of the Netconf session.
diff --git a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java
index cc53e37..7477238 100644
--- a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java
+++ b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java
@@ -80,20 +80,19 @@
@Override
public NetconfDevice getNetconfDevice(IpAddress ip, int port) {
- NetconfDevice device = null;
for (DeviceId info : netconfDeviceMap.keySet()) {
if (IpAddress.valueOf(info.uri().getHost()).equals(ip) &&
info.uri().getPort() == port) {
return netconfDeviceMap.get(info);
}
}
- return device;
+ return null;
}
@Override
public NetconfDevice connectDevice(NetconfDeviceInfo deviceInfo) throws IOException {
if (netconfDeviceMap.containsKey(deviceInfo.getDeviceId())) {
- log.info("Device {} is already present");
+ log.warn("Device {} is already present", deviceInfo);
return netconfDeviceMap.get(deviceInfo.getDeviceId());
} else {
log.info("Creating NETCONF device {}", deviceInfo);
@@ -104,7 +103,7 @@
@Override
public void removeDevice(NetconfDeviceInfo deviceInfo) {
if (netconfDeviceMap.containsKey(deviceInfo.getDeviceId())) {
- log.warn("Device {} is not present");
+ log.warn("Device {} is not present", deviceInfo);
} else {
stopDevice(deviceInfo);
}
diff --git a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfDeviceImpl.java b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfDeviceImpl.java
index 3141aaf..762c21c 100644
--- a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfDeviceImpl.java
+++ b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfDeviceImpl.java
@@ -19,6 +19,8 @@
import org.onosproject.netconf.NetconfDevice;
import org.onosproject.netconf.NetconfDeviceInfo;
import org.onosproject.netconf.NetconfSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.IOException;
@@ -27,10 +29,12 @@
*/
public class NetconfDeviceImpl implements NetconfDevice {
+ public static final Logger log = LoggerFactory
+ .getLogger(NetconfSessionImpl.class);
+
private NetconfDeviceInfo netconfDeviceInfo;
private boolean deviceState = false;
private NetconfSession netconfSession;
- //private String config;
public NetconfDeviceImpl(NetconfDeviceInfo deviceInfo) throws IOException {
netconfDeviceInfo = deviceInfo;
@@ -40,7 +44,6 @@
throw new IOException("Cannot create connection and session", e);
}
deviceState = true;
- //config = netconfSession.getConfig("running");
}
@Override
@@ -56,7 +59,11 @@
@Override
public void disconnect() {
deviceState = false;
- netconfSession.close();
+ try {
+ netconfSession.close();
+ } catch (IOException e) {
+ log.warn("Cannot communicate with the device {} ", netconfDeviceInfo);
+ }
}
@Override
diff --git a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfSessionImpl.java b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfSessionImpl.java
index 8619abc..1eff32a 100644
--- a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfSessionImpl.java
+++ b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfSessionImpl.java
@@ -18,6 +18,7 @@
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
+import ch.ethz.ssh2.StreamGobbler;
import com.google.common.base.Preconditions;
import org.onosproject.netconf.NetconfDeviceInfo;
import org.onosproject.netconf.NetconfSession;
@@ -29,8 +30,7 @@
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
/**
@@ -50,11 +50,9 @@
private BufferedReader bufferReader = null;
private PrintWriter out = null;
private int messageID = 0;
-
+ //TODO inject these capabilites from yang model provided by app
private List<String> deviceCapabilities =
- new ArrayList<>(
- Arrays.asList("urn:ietf:params:netconf:base:1.0"));
-
+ Collections.singletonList("urn:ietf:params:netconf:base:1.0");
private String serverCapabilities;
private String endpattern = "]]>]]>";
@@ -98,8 +96,8 @@
try {
sshSession = netconfConnection.openSession();
sshSession.startSubSystem("netconf");
- bufferReader = new BufferedReader(new InputStreamReader(
- sshSession.getStdout()));
+ bufferReader = new BufferedReader(new InputStreamReader(new StreamGobbler(
+ sshSession.getStdout())));
out = new PrintWriter(sshSession.getStdin());
sendHello();
} catch (IOException e) {
@@ -127,51 +125,50 @@
}
@Override
- public String doRPC(String request) {
- String reply = "ERROR";
- try {
- reply = doRequest(request);
- if (checkReply(reply)) {
- return reply;
- } else {
- return "ERROR " + reply;
- }
- } catch (IOException e) {
- log.error("Problem in the reading from the SSH connection " + e);
- }
- return reply;
+ public String doRPC(String request) throws IOException {
+ String reply = doRequest(request);
+ return checkReply(reply) ? reply : "ERROR " + reply;
}
private String doRequest(String request) throws IOException {
- log.info("sshState " + sshSession.getState() + "request" + request);
- if (sshSession.getState() != 2) {
- try {
- startSshSession();
- } catch (IOException e) {
- log.info("the connection had to be reopened");
- startConnection();
- }
- sendHello();
- }
- log.info("sshState after" + sshSession.getState());
+ //log.info("sshState " + sshSession.getState() + "request" + request);
+ checkAndRestablishSession();
+ //log.info("sshState after" + sshSession.getState());
out.print(request);
out.flush();
messageID++;
return readOne();
}
+ private void checkAndRestablishSession() throws IOException {
+ if (sshSession.getState() != 2) {
+ try {
+ startSshSession();
+ } catch (IOException e) {
+ log.info("the connection had to be reopened");
+ try {
+ startConnection();
+ } catch (IOException e2) {
+ log.error("No connection {} for device, exception {}", netconfConnection, e2);
+ throw new IOException(e.getMessage());
+ //TODO remove device from ONOS
+ }
+ }
+ }
+ }
+
@Override
- public String get(String request) {
+ public String get(String request) throws IOException {
return doRPC(request);
}
@Override
- public String getConfig(String targetConfiguration) {
+ public String getConfig(String targetConfiguration) throws IOException {
return getConfig(targetConfiguration, null);
}
@Override
- public String getConfig(String targetConfiguration, String configurationSchema) {
+ public String getConfig(String targetConfiguration, String configurationSchema) throws IOException {
StringBuilder rpc = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
rpc.append("<rpc message-id=\"" + messageID + "\" "
+ "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n");
@@ -187,30 +184,19 @@
rpc.append("</get-config>\n");
rpc.append("</rpc>\n");
rpc.append(endpattern);
- String reply = null;
- try {
- reply = doRequest(rpc.toString());
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- return checkReply(reply) ? reply : null;
+ String reply = doRequest(rpc.toString());
+ return checkReply(reply) ? reply : "ERROR " + reply;
}
@Override
- public boolean editConfig(String newConfiguration) {
+ public boolean editConfig(String newConfiguration) throws IOException {
newConfiguration = newConfiguration + endpattern;
- String reply = null;
- try {
- reply = doRequest(newConfiguration);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return checkReply(reply);
+ return checkReply(doRequest(newConfiguration));
}
@Override
- public boolean copyConfig(String targetConfiguration, String newConfiguration) {
+ public boolean copyConfig(String targetConfiguration, String newConfiguration)
+ throws IOException {
newConfiguration = newConfiguration.trim();
if (!newConfiguration.startsWith("<configuration>")) {
newConfiguration = "<configuration>" + newConfiguration
@@ -229,18 +215,11 @@
rpc.append("</copy-config>");
rpc.append("</rpc>");
rpc.append(endpattern);
- String reply = null;
- try {
- reply = doRequest(rpc.toString());
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- return checkReply(reply);
+ return checkReply(doRequest(rpc.toString()));
}
@Override
- public boolean deleteConfig(String targetConfiguration) {
+ public boolean deleteConfig(String targetConfiguration) throws IOException {
if (targetConfiguration.equals("running")) {
log.warn("Target configuration for delete operation can't be \"running\"",
targetConfiguration);
@@ -256,18 +235,11 @@
rpc.append("</delete-config>");
rpc.append("</rpc>");
rpc.append(endpattern);
- String reply = null;
- try {
- reply = doRequest(rpc.toString());
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- return checkReply(reply);
+ return checkReply(doRequest(rpc.toString()));
}
@Override
- public boolean lock() {
+ public boolean lock() throws IOException {
StringBuilder rpc = new StringBuilder("<?xml version=\"1.0\" " +
"encoding=\"UTF-8\"?>");
rpc.append("<rpc>");
@@ -278,17 +250,11 @@
rpc.append("</lock>");
rpc.append("</rpc>");
rpc.append(endpattern);
- String reply = null;
- try {
- reply = doRequest(rpc.toString());
- } catch (IOException e) {
- e.printStackTrace();
- }
- return checkReply(reply);
+ return checkReply(doRequest(rpc.toString()));
}
@Override
- public boolean unlock() {
+ public boolean unlock() throws IOException {
StringBuilder rpc = new StringBuilder("<?xml version=\"1.0\" " +
"encoding=\"UTF-8\"?>");
rpc.append("<rpc>");
@@ -299,21 +265,15 @@
rpc.append("</unlock>");
rpc.append("</rpc>");
rpc.append(endpattern);
- String reply = null;
- try {
- reply = doRequest(rpc.toString());
- } catch (IOException e) {
- e.printStackTrace();
- }
- return checkReply(reply);
+ return checkReply(doRequest(rpc.toString()));
}
@Override
- public boolean close() {
+ public boolean close() throws IOException {
return close(false);
}
- private boolean close(boolean force) {
+ private boolean close(boolean force) throws IOException {
StringBuilder rpc = new StringBuilder();
rpc.append("<rpc>");
if (force) {
@@ -324,7 +284,7 @@
rpc.append("<close-configuration/>");
rpc.append("</rpc>");
rpc.append(endpattern);
- return checkReply(rpc.toString()) ? true : close(true);
+ return checkReply(doRequest(rpc.toString())) || close(true);
}
@Override
diff --git a/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java b/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java
index 12b9351..860b1f8 100644
--- a/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java
+++ b/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java
@@ -40,7 +40,6 @@
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
-import org.onosproject.net.device.DeviceService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.netconf.NetconfController;
@@ -66,8 +65,8 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceProviderRegistry providerRegistry;
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected DeviceService deviceService;
+ // @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+// protected DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected NetconfController controller; //where is initiated ?
@@ -156,7 +155,6 @@
public void deviceAdded(NetconfDeviceInfo nodeId) {
Preconditions.checkNotNull(nodeId, ISNOTNULL);
DeviceId deviceId = nodeId.getDeviceId();
- //TODO filter for not netconf devices
//Netconf configuration object
ChassisId cid = new ChassisId();
String ipAddress = nodeId.ip().toString();
@@ -191,7 +189,6 @@
private void connectDevices() {
NetconfProviderConfig cfg = cfgService.getConfig(appId, NetconfProviderConfig.class);
if (cfg != null) {
- log.info("cfg {}", cfg);
try {
cfg.getDevicesAddresses().stream()
.forEach(addr -> {
@@ -204,8 +201,8 @@
} catch (IOException e) {
log.warn("Can't connect to NETCONF " +
"device on {}:{}",
- addr.ip(),
- addr.port());
+ addr.ip(),
+ addr.port());
}
}
);
diff --git a/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfProviderConfig.java b/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfProviderConfig.java
index 7ae116e..0227d89 100644
--- a/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfProviderConfig.java
+++ b/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfProviderConfig.java
@@ -89,5 +89,4 @@
}
}
-
}
diff --git a/tools/test/configs/netconf-cfg.json b/tools/test/configs/netconf-cfg.json
index 42778aa..3397cd1 100644
--- a/tools/test/configs/netconf-cfg.json
+++ b/tools/test/configs/netconf-cfg.json
@@ -1,6 +1,6 @@
{
"devices":{
- "netconf:mininet@10.1.9.24:1830":{
+ "netconf:mininet@10.1.9.24:830":{
"basic":{
"driver":"ovs-netconf"
}
@@ -12,7 +12,7 @@
"name":"mininet",
"password":"mininet",
"ip":"10.1.9.24",
- "port":1830
+ "port":830
}]
}
}