Upgrading rest sb protocol with jersey 2.22.2, implementing different connection test
Change-Id: Iba64847b535826f24ae4dc0ab3454a31328406ac
diff --git a/protocols/rest/ctl/src/main/java/org/onosproject/protocol/rest/ctl/RestSBControllerImpl.java b/protocols/rest/ctl/src/main/java/org/onosproject/protocol/rest/ctl/RestSBControllerImpl.java
index c787fb9..d813221 100644
--- a/protocols/rest/ctl/src/main/java/org/onosproject/protocol/rest/ctl/RestSBControllerImpl.java
+++ b/protocols/rest/ctl/src/main/java/org/onosproject/protocol/rest/ctl/RestSBControllerImpl.java
@@ -36,18 +36,24 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -73,16 +79,16 @@
private static final String BASIC_AUTH_PREFIX = "Basic ";
private final Map<DeviceId, RestSBDevice> deviceMap = new ConcurrentHashMap<>();
- Client client;
+ private final Map<DeviceId, Client> clientMap = new ConcurrentHashMap<>();
@Activate
public void activate() {
- client = ClientBuilder.newClient();
log.info("Started");
}
@Deactivate
public void deactivate() {
+ clientMap.clear();
deviceMap.clear();
log.info("Stopped");
}
@@ -105,11 +111,24 @@
@Override
public void addDevice(RestSBDevice device) {
- deviceMap.put(device.deviceId(), device);
+ if (!deviceMap.containsKey(device.deviceId())) {
+ Client client = ignoreSslClient();
+ if (device.username() != null) {
+ String username = device.username();
+ String password = device.password() == null ? "" : device.password();
+ authenticate(client, username, password);
+ }
+ clientMap.put(device.deviceId(), client);
+ deviceMap.put(device.deviceId(), device);
+ } else {
+ log.warn("Trying to add a device that is already existing {}", device.deviceId());
+ }
+
}
@Override
public void removeDevice(DeviceId deviceId) {
+ clientMap.remove(deviceId);
deviceMap.remove(deviceId);
}
@@ -169,7 +188,8 @@
Response s = wt.request(type).get();
if (checkReply(s)) {
- return (InputStream) s.getEntity();
+ return new ByteArrayInputStream(wt.request(type)
+ .get(String.class).getBytes(StandardCharsets.UTF_8));
}
return null;
}
@@ -219,15 +239,13 @@
return checkReply(response);
}
+ private void authenticate(Client client, String username, String password) {
+ client.register(HttpAuthenticationFeature.basic(username, password));
+ }
+
private WebTarget getWebTarget(DeviceId device, String request) {
log.debug("Sending request to URL {} ", getUrlString(device, request));
- WebTarget wt = client.target(getUrlString(device, request));
- if (deviceMap.containsKey(device) && deviceMap.get(device).username() != null) {
- client.register(HttpAuthenticationFeature.basic(deviceMap.get(device).username(),
- deviceMap.get(device).password() == null ?
- "" : deviceMap.get(device).password()));
- }
- return wt;
+ return clientMap.get(device).target(getUrlString(device, request));
}
//FIXME security issue: this trusts every SSL certificate, even if is self-signed. Also deprecated methods.
@@ -271,4 +289,28 @@
return false;
}
}
+
+ private Client ignoreSslClient() {
+ SSLContext sslcontext = null;
+
+ try {
+ sslcontext = SSLContext.getInstance("TLS");
+ sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
+ public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+ }
+
+ public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+ }
+
+ public X509Certificate[] getAcceptedIssuers() {
+ return new X509Certificate[0];
+ }
+
+ } }, new java.security.SecureRandom());
+ } catch (NoSuchAlgorithmException | KeyManagementException e) {
+ e.printStackTrace();
+ }
+
+ return ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier((s1, s2) -> true).build();
+ }
}
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 d8ebda6..2f25bb3 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
@@ -50,14 +50,7 @@
import org.onosproject.protocol.rest.RestSBDevice;
import org.slf4j.Logger;
-import javax.net.ssl.HttpsURLConnection;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Base64;
+import javax.ws.rs.ProcessingException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
@@ -189,9 +182,8 @@
UNKNOWN, UNKNOWN,
cid,
annotations);
- providerService.deviceConnected(deviceId, deviceDescription);
nodeId.setActive(true);
- controller.addDevice(nodeId);
+ providerService.deviceConnected(deviceId, deviceDescription);
addedDevices.add(deviceId);
}
@@ -210,7 +202,11 @@
toBeRemoved.removeAll(cfg.getDevicesAddresses());
//Adding new devices
cfg.getDevicesAddresses().stream()
- .filter(device -> testDeviceConnection(device))
+ .filter(device -> {
+ device.setActive(false);
+ controller.addDevice(device);
+ return testDeviceConnection(device);
+ })
.forEach(device -> {
deviceAdded(device);
});
@@ -237,40 +233,9 @@
private boolean testDeviceConnection(RestSBDevice device) {
try {
- URL url;
- if (device.url() == null) {
- url = new URL(device.protocol(), device.ip().toString(), device.port(), "");
- } else {
- url = new URL(device.protocol() + URL_SEPARATOR + device.url());
- }
- HttpURLConnection urlConn;
- if (device.protocol().equals(HTTPS)) {
- //FIXME this method provides no security accepting all SSL certs.
- RestDeviceProviderUtilities.enableSslCert();
-
- urlConn = (HttpsURLConnection) url.openConnection();
- } else {
- urlConn = (HttpURLConnection) url.openConnection();
- }
- if (device.username() != null) {
- String pwd = device.password() == null ? "" : ":" + device.password();
- String userPassword = device.username() + pwd;
- String basicAuth = Base64.getEncoder()
- .encodeToString(userPassword.getBytes(StandardCharsets.UTF_8));
- urlConn.setRequestProperty(AUTHORIZATION_PROPERTY, BASIC_AUTH_PREFIX + basicAuth);
- }
- urlConn.setConnectTimeout(TEST_CONNECT_TIMEOUT);
- boolean open = urlConn.getResponseCode() == (HttpsURLConnection.HTTP_OK);
- if (!open) {
- log.error("Device {} not accessibile, response code {} ", device,
- urlConn.getResponseCode());
- }
- urlConn.disconnect();
- return open;
-
- } catch (IOException | NoSuchAlgorithmException | KeyManagementException e) {
- log.error("Device {} not reachable, error creating {} connection", device,
- device.protocol(), e);
+ return controller.get(device.deviceId(), "", "json") != null;
+ } catch (ProcessingException e) {
+ log.warn("Cannot connect to device {}", device, e);
}
return false;
}