Andrea Campanella
Committed by Gerrit Code Review

Upgrading rest sb protocol with jersey 2.22.2, implementing different connection test

Change-Id: Iba64847b535826f24ae4dc0ab3454a31328406ac
...@@ -36,18 +36,24 @@ import org.onosproject.protocol.rest.RestSBDevice; ...@@ -36,18 +36,24 @@ import org.onosproject.protocol.rest.RestSBDevice;
36 import org.slf4j.Logger; 36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory; 37 import org.slf4j.LoggerFactory;
38 38
39 +import javax.net.ssl.SSLContext;
40 +import javax.net.ssl.TrustManager;
41 +import javax.net.ssl.X509TrustManager;
39 import javax.ws.rs.client.Client; 42 import javax.ws.rs.client.Client;
40 import javax.ws.rs.client.ClientBuilder; 43 import javax.ws.rs.client.ClientBuilder;
41 import javax.ws.rs.client.Entity; 44 import javax.ws.rs.client.Entity;
42 import javax.ws.rs.client.WebTarget; 45 import javax.ws.rs.client.WebTarget;
43 import javax.ws.rs.core.MediaType; 46 import javax.ws.rs.core.MediaType;
44 import javax.ws.rs.core.Response; 47 import javax.ws.rs.core.Response;
48 +import java.io.ByteArrayInputStream;
45 import java.io.IOException; 49 import java.io.IOException;
46 import java.io.InputStream; 50 import java.io.InputStream;
47 import java.nio.charset.StandardCharsets; 51 import java.nio.charset.StandardCharsets;
48 import java.security.KeyManagementException; 52 import java.security.KeyManagementException;
49 import java.security.KeyStoreException; 53 import java.security.KeyStoreException;
50 import java.security.NoSuchAlgorithmException; 54 import java.security.NoSuchAlgorithmException;
55 +import java.security.cert.CertificateException;
56 +import java.security.cert.X509Certificate;
51 import java.util.Base64; 57 import java.util.Base64;
52 import java.util.Map; 58 import java.util.Map;
53 import java.util.concurrent.ConcurrentHashMap; 59 import java.util.concurrent.ConcurrentHashMap;
...@@ -73,16 +79,16 @@ public class RestSBControllerImpl implements RestSBController { ...@@ -73,16 +79,16 @@ public class RestSBControllerImpl implements RestSBController {
73 private static final String BASIC_AUTH_PREFIX = "Basic "; 79 private static final String BASIC_AUTH_PREFIX = "Basic ";
74 80
75 private final Map<DeviceId, RestSBDevice> deviceMap = new ConcurrentHashMap<>(); 81 private final Map<DeviceId, RestSBDevice> deviceMap = new ConcurrentHashMap<>();
76 - Client client; 82 + private final Map<DeviceId, Client> clientMap = new ConcurrentHashMap<>();
77 83
78 @Activate 84 @Activate
79 public void activate() { 85 public void activate() {
80 - client = ClientBuilder.newClient();
81 log.info("Started"); 86 log.info("Started");
82 } 87 }
83 88
84 @Deactivate 89 @Deactivate
85 public void deactivate() { 90 public void deactivate() {
91 + clientMap.clear();
86 deviceMap.clear(); 92 deviceMap.clear();
87 log.info("Stopped"); 93 log.info("Stopped");
88 } 94 }
...@@ -105,11 +111,24 @@ public class RestSBControllerImpl implements RestSBController { ...@@ -105,11 +111,24 @@ public class RestSBControllerImpl implements RestSBController {
105 111
106 @Override 112 @Override
107 public void addDevice(RestSBDevice device) { 113 public void addDevice(RestSBDevice device) {
108 - deviceMap.put(device.deviceId(), device); 114 + if (!deviceMap.containsKey(device.deviceId())) {
115 + Client client = ignoreSslClient();
116 + if (device.username() != null) {
117 + String username = device.username();
118 + String password = device.password() == null ? "" : device.password();
119 + authenticate(client, username, password);
120 + }
121 + clientMap.put(device.deviceId(), client);
122 + deviceMap.put(device.deviceId(), device);
123 + } else {
124 + log.warn("Trying to add a device that is already existing {}", device.deviceId());
125 + }
126 +
109 } 127 }
110 128
111 @Override 129 @Override
112 public void removeDevice(DeviceId deviceId) { 130 public void removeDevice(DeviceId deviceId) {
131 + clientMap.remove(deviceId);
113 deviceMap.remove(deviceId); 132 deviceMap.remove(deviceId);
114 } 133 }
115 134
...@@ -169,7 +188,8 @@ public class RestSBControllerImpl implements RestSBController { ...@@ -169,7 +188,8 @@ public class RestSBControllerImpl implements RestSBController {
169 188
170 Response s = wt.request(type).get(); 189 Response s = wt.request(type).get();
171 if (checkReply(s)) { 190 if (checkReply(s)) {
172 - return (InputStream) s.getEntity(); 191 + return new ByteArrayInputStream(wt.request(type)
192 + .get(String.class).getBytes(StandardCharsets.UTF_8));
173 } 193 }
174 return null; 194 return null;
175 } 195 }
...@@ -219,15 +239,13 @@ public class RestSBControllerImpl implements RestSBController { ...@@ -219,15 +239,13 @@ public class RestSBControllerImpl implements RestSBController {
219 return checkReply(response); 239 return checkReply(response);
220 } 240 }
221 241
242 + private void authenticate(Client client, String username, String password) {
243 + client.register(HttpAuthenticationFeature.basic(username, password));
244 + }
245 +
222 private WebTarget getWebTarget(DeviceId device, String request) { 246 private WebTarget getWebTarget(DeviceId device, String request) {
223 log.debug("Sending request to URL {} ", getUrlString(device, request)); 247 log.debug("Sending request to URL {} ", getUrlString(device, request));
224 - WebTarget wt = client.target(getUrlString(device, request)); 248 + return clientMap.get(device).target(getUrlString(device, request));
225 - if (deviceMap.containsKey(device) && deviceMap.get(device).username() != null) {
226 - client.register(HttpAuthenticationFeature.basic(deviceMap.get(device).username(),
227 - deviceMap.get(device).password() == null ?
228 - "" : deviceMap.get(device).password()));
229 - }
230 - return wt;
231 } 249 }
232 250
233 //FIXME security issue: this trusts every SSL certificate, even if is self-signed. Also deprecated methods. 251 //FIXME security issue: this trusts every SSL certificate, even if is self-signed. Also deprecated methods.
...@@ -271,4 +289,28 @@ public class RestSBControllerImpl implements RestSBController { ...@@ -271,4 +289,28 @@ public class RestSBControllerImpl implements RestSBController {
271 return false; 289 return false;
272 } 290 }
273 } 291 }
292 +
293 + private Client ignoreSslClient() {
294 + SSLContext sslcontext = null;
295 +
296 + try {
297 + sslcontext = SSLContext.getInstance("TLS");
298 + sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
299 + public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
300 + }
301 +
302 + public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
303 + }
304 +
305 + public X509Certificate[] getAcceptedIssuers() {
306 + return new X509Certificate[0];
307 + }
308 +
309 + } }, new java.security.SecureRandom());
310 + } catch (NoSuchAlgorithmException | KeyManagementException e) {
311 + e.printStackTrace();
312 + }
313 +
314 + return ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier((s1, s2) -> true).build();
315 + }
274 } 316 }
......
...@@ -50,14 +50,7 @@ import org.onosproject.protocol.rest.RestSBController; ...@@ -50,14 +50,7 @@ import org.onosproject.protocol.rest.RestSBController;
50 import org.onosproject.protocol.rest.RestSBDevice; 50 import org.onosproject.protocol.rest.RestSBDevice;
51 import org.slf4j.Logger; 51 import org.slf4j.Logger;
52 52
53 -import javax.net.ssl.HttpsURLConnection; 53 +import javax.ws.rs.ProcessingException;
54 -import java.io.IOException;
55 -import java.net.HttpURLConnection;
56 -import java.net.URL;
57 -import java.nio.charset.StandardCharsets;
58 -import java.security.KeyManagementException;
59 -import java.security.NoSuchAlgorithmException;
60 -import java.util.Base64;
61 import java.util.HashSet; 54 import java.util.HashSet;
62 import java.util.Set; 55 import java.util.Set;
63 import java.util.concurrent.ExecutorService; 56 import java.util.concurrent.ExecutorService;
...@@ -189,9 +182,8 @@ public class RestDeviceProvider extends AbstractProvider ...@@ -189,9 +182,8 @@ public class RestDeviceProvider extends AbstractProvider
189 UNKNOWN, UNKNOWN, 182 UNKNOWN, UNKNOWN,
190 cid, 183 cid,
191 annotations); 184 annotations);
192 - providerService.deviceConnected(deviceId, deviceDescription);
193 nodeId.setActive(true); 185 nodeId.setActive(true);
194 - controller.addDevice(nodeId); 186 + providerService.deviceConnected(deviceId, deviceDescription);
195 addedDevices.add(deviceId); 187 addedDevices.add(deviceId);
196 } 188 }
197 189
...@@ -210,7 +202,11 @@ public class RestDeviceProvider extends AbstractProvider ...@@ -210,7 +202,11 @@ public class RestDeviceProvider extends AbstractProvider
210 toBeRemoved.removeAll(cfg.getDevicesAddresses()); 202 toBeRemoved.removeAll(cfg.getDevicesAddresses());
211 //Adding new devices 203 //Adding new devices
212 cfg.getDevicesAddresses().stream() 204 cfg.getDevicesAddresses().stream()
213 - .filter(device -> testDeviceConnection(device)) 205 + .filter(device -> {
206 + device.setActive(false);
207 + controller.addDevice(device);
208 + return testDeviceConnection(device);
209 + })
214 .forEach(device -> { 210 .forEach(device -> {
215 deviceAdded(device); 211 deviceAdded(device);
216 }); 212 });
...@@ -237,40 +233,9 @@ public class RestDeviceProvider extends AbstractProvider ...@@ -237,40 +233,9 @@ public class RestDeviceProvider extends AbstractProvider
237 233
238 private boolean testDeviceConnection(RestSBDevice device) { 234 private boolean testDeviceConnection(RestSBDevice device) {
239 try { 235 try {
240 - URL url; 236 + return controller.get(device.deviceId(), "", "json") != null;
241 - if (device.url() == null) { 237 + } catch (ProcessingException e) {
242 - url = new URL(device.protocol(), device.ip().toString(), device.port(), ""); 238 + log.warn("Cannot connect to device {}", device, e);
243 - } else {
244 - url = new URL(device.protocol() + URL_SEPARATOR + device.url());
245 - }
246 - HttpURLConnection urlConn;
247 - if (device.protocol().equals(HTTPS)) {
248 - //FIXME this method provides no security accepting all SSL certs.
249 - RestDeviceProviderUtilities.enableSslCert();
250 -
251 - urlConn = (HttpsURLConnection) url.openConnection();
252 - } else {
253 - urlConn = (HttpURLConnection) url.openConnection();
254 - }
255 - if (device.username() != null) {
256 - String pwd = device.password() == null ? "" : ":" + device.password();
257 - String userPassword = device.username() + pwd;
258 - String basicAuth = Base64.getEncoder()
259 - .encodeToString(userPassword.getBytes(StandardCharsets.UTF_8));
260 - urlConn.setRequestProperty(AUTHORIZATION_PROPERTY, BASIC_AUTH_PREFIX + basicAuth);
261 - }
262 - urlConn.setConnectTimeout(TEST_CONNECT_TIMEOUT);
263 - boolean open = urlConn.getResponseCode() == (HttpsURLConnection.HTTP_OK);
264 - if (!open) {
265 - log.error("Device {} not accessibile, response code {} ", device,
266 - urlConn.getResponseCode());
267 - }
268 - urlConn.disconnect();
269 - return open;
270 -
271 - } catch (IOException | NoSuchAlgorithmException | KeyManagementException e) {
272 - log.error("Device {} not reachable, error creating {} connection", device,
273 - device.protocol(), e);
274 } 239 }
275 return false; 240 return false;
276 } 241 }
......