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