Committed by
Gerrit Code Review
Upgrading rest sb protocol with jersey 2.22.2, implementing different connection test
Change-Id: Iba64847b535826f24ae4dc0ab3454a31328406ac
Showing
2 changed files
with
63 additions
and
56 deletions
| ... | @@ -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 | } | ... | ... |
-
Please register or login to post a comment