Skip to content

Commit 2ab9822

Browse files
authored
[insteon] Use shared jetty http client (openhab#17922)
Signed-off-by: jsetton <[email protected]>
1 parent 5d40a71 commit 2ab9822

File tree

10 files changed

+91
-88
lines changed

10 files changed

+91
-88
lines changed

bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/InsteonHandlerFactory.java

+10-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.eclipse.jdt.annotation.NonNullByDefault;
2222
import org.eclipse.jdt.annotation.Nullable;
23+
import org.eclipse.jetty.client.HttpClient;
2324
import org.openhab.binding.insteon.internal.discovery.InsteonDiscoveryService;
2425
import org.openhab.binding.insteon.internal.discovery.InsteonLegacyDiscoveryService;
2526
import org.openhab.binding.insteon.internal.handler.InsteonBridgeHandler;
@@ -29,6 +30,7 @@
2930
import org.openhab.binding.insteon.internal.handler.InsteonSceneHandler;
3031
import org.openhab.binding.insteon.internal.handler.X10DeviceHandler;
3132
import org.openhab.core.config.discovery.DiscoveryService;
33+
import org.openhab.core.io.net.http.HttpClientFactory;
3234
import org.openhab.core.io.transport.serial.SerialPortManager;
3335
import org.openhab.core.storage.StorageService;
3436
import org.openhab.core.thing.Bridge;
@@ -56,6 +58,7 @@
5658
@Component(configurationPid = "binding.insteon", service = ThingHandlerFactory.class)
5759
public class InsteonHandlerFactory extends BaseThingHandlerFactory {
5860

61+
private final HttpClient httpClient;
5962
private final SerialPortManager serialPortManager;
6063
private final InsteonStateDescriptionProvider stateDescriptionProvider;
6164
private final StorageService storageService;
@@ -64,10 +67,12 @@ public class InsteonHandlerFactory extends BaseThingHandlerFactory {
6467
private final Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
6568

6669
@Activate
67-
public InsteonHandlerFactory(final @Reference SerialPortManager serialPortManager,
70+
public InsteonHandlerFactory(final @Reference HttpClientFactory httpClientFactory,
71+
final @Reference SerialPortManager serialPortManager,
6872
final @Reference InsteonStateDescriptionProvider stateDescriptionProvider,
6973
final @Reference StorageService storageService, final @Reference ThingManager thingManager,
7074
final @Reference ThingRegistry thingRegistry) {
75+
this.httpClient = httpClientFactory.getCommonHttpClient();
7176
this.serialPortManager = serialPortManager;
7277
this.stateDescriptionProvider = stateDescriptionProvider;
7378
this.storageService = storageService;
@@ -86,14 +91,14 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
8691

8792
if (THING_TYPE_HUB1.equals(thingTypeUID) || THING_TYPE_HUB2.equals(thingTypeUID)
8893
|| THING_TYPE_PLM.equals(thingTypeUID)) {
89-
InsteonBridgeHandler handler = new InsteonBridgeHandler((Bridge) thing, serialPortManager, storageService,
90-
thingRegistry);
94+
InsteonBridgeHandler handler = new InsteonBridgeHandler((Bridge) thing, httpClient, serialPortManager,
95+
storageService, thingRegistry);
9196
InsteonDiscoveryService service = new InsteonDiscoveryService(handler);
9297
registerDiscoveryService(handler, service);
9398
return handler;
9499
} else if (THING_TYPE_LEGACY_NETWORK.equals(thingTypeUID)) {
95-
InsteonLegacyNetworkHandler handler = new InsteonLegacyNetworkHandler((Bridge) thing, serialPortManager,
96-
thingManager, thingRegistry);
100+
InsteonLegacyNetworkHandler handler = new InsteonLegacyNetworkHandler((Bridge) thing, httpClient,
101+
serialPortManager, thingManager, thingRegistry);
97102
InsteonLegacyDiscoveryService service = new InsteonLegacyDiscoveryService(handler);
98103
registerDiscoveryService(handler, service);
99104
return handler;

bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/InsteonLegacyBinding.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import org.eclipse.jdt.annotation.NonNullByDefault;
2929
import org.eclipse.jdt.annotation.Nullable;
30+
import org.eclipse.jetty.client.HttpClient;
3031
import org.openhab.binding.insteon.internal.config.InsteonLegacyChannelConfiguration;
3132
import org.openhab.binding.insteon.internal.config.InsteonLegacyNetworkConfiguration;
3233
import org.openhab.binding.insteon.internal.device.DeviceAddress;
@@ -119,13 +120,13 @@ public class InsteonLegacyBinding implements LegacyDriverListener, LegacyPortLis
119120
private InsteonLegacyNetworkHandler handler;
120121

121122
public InsteonLegacyBinding(InsteonLegacyNetworkHandler handler, InsteonLegacyNetworkConfiguration config,
122-
SerialPortManager serialPortManager, ScheduledExecutorService scheduler) {
123+
HttpClient httpClient, ScheduledExecutorService scheduler, SerialPortManager serialPortManager) {
123124
this.handler = handler;
124125

125126
String port = config.getRedactedPort();
126127
logger.debug("port = '{}'", port);
127128

128-
driver = new LegacyDriver(config, this, serialPortManager, scheduler);
129+
driver = new LegacyDriver(config, this, httpClient, scheduler, serialPortManager);
129130
driver.addPortListener(this);
130131

131132
Integer devicePollIntervalSeconds = config.getDevicePollIntervalSeconds();

bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/InsteonModem.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.eclipse.jdt.annotation.NonNullByDefault;
2323
import org.eclipse.jdt.annotation.Nullable;
24+
import org.eclipse.jetty.client.HttpClient;
2425
import org.openhab.binding.insteon.internal.config.InsteonBridgeConfiguration;
2526
import org.openhab.binding.insteon.internal.device.database.DatabaseManager;
2627
import org.openhab.binding.insteon.internal.device.database.ModemDB;
@@ -53,10 +54,10 @@ public class InsteonModem extends BaseDevice<InsteonAddress, InsteonBridgeHandle
5354
private boolean initialized = false;
5455
private int msgsReceived = 0;
5556

56-
public InsteonModem(InsteonBridgeConfiguration config, ScheduledExecutorService scheduler,
57+
public InsteonModem(InsteonBridgeConfiguration config, HttpClient httpClient, ScheduledExecutorService scheduler,
5758
SerialPortManager serialPortManager) {
5859
super(InsteonAddress.UNKNOWN);
59-
this.port = new Port(config, scheduler, serialPortManager);
60+
this.port = new Port(config, httpClient, scheduler, serialPortManager);
6061
this.modemDB = new ModemDB(this);
6162
this.dbm = new DatabaseManager(this, scheduler);
6263
this.linker = new LinkManager(this, scheduler);
@@ -509,13 +510,14 @@ private void handleMessage(DeviceAddress address, Msg msg) throws FieldException
509510
*
510511
* @param handler the bridge handler
511512
* @param config the bridge config
513+
* @param httpClient the http client
512514
* @param scheduler the scheduler service
513515
* @param serialPortManager the serial port manager
514516
* @return the newly created InsteonModem
515517
*/
516518
public static InsteonModem makeModem(InsteonBridgeHandler handler, InsteonBridgeConfiguration config,
517-
ScheduledExecutorService scheduler, SerialPortManager serialPortManager) {
518-
InsteonModem modem = new InsteonModem(config, scheduler, serialPortManager);
519+
HttpClient httpClient, ScheduledExecutorService scheduler, SerialPortManager serialPortManager) {
520+
InsteonModem modem = new InsteonModem(config, httpClient, scheduler, serialPortManager);
519521
modem.setHandler(handler);
520522
return modem;
521523
}

bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/handler/InsteonBridgeHandler.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.eclipse.jdt.annotation.NonNullByDefault;
2323
import org.eclipse.jdt.annotation.Nullable;
24+
import org.eclipse.jetty.client.HttpClient;
2425
import org.openhab.binding.insteon.internal.config.InsteonBridgeConfiguration;
2526
import org.openhab.binding.insteon.internal.config.InsteonHub1Configuration;
2627
import org.openhab.binding.insteon.internal.config.InsteonHub2Configuration;
@@ -63,13 +64,15 @@ public class InsteonBridgeHandler extends InsteonBaseThingHandler implements Bri
6364
private @Nullable ScheduledFuture<?> reconnectJob;
6465
private @Nullable ScheduledFuture<?> resetJob;
6566
private @Nullable ScheduledFuture<?> statisticsJob;
67+
private HttpClient httpClient;
6668
private SerialPortManager serialPortManager;
6769
private Storage<DeviceCache> storage;
6870
private ThingRegistry thingRegistry;
6971

70-
public InsteonBridgeHandler(Bridge bridge, SerialPortManager serialPortManager, StorageService storageService,
71-
ThingRegistry thingRegistry) {
72+
public InsteonBridgeHandler(Bridge bridge, HttpClient httpClient, SerialPortManager serialPortManager,
73+
StorageService storageService, ThingRegistry thingRegistry) {
7274
super(bridge);
75+
this.httpClient = httpClient;
7376
this.serialPortManager = serialPortManager;
7477
this.storage = storageService.getStorage(bridge.getUID().toString(), DeviceCache.class.getClassLoader());
7578
this.thingRegistry = thingRegistry;
@@ -164,7 +167,7 @@ public void initialize() {
164167
legacyHandler.disable();
165168
}
166169

167-
InsteonModem modem = InsteonModem.makeModem(this, config, scheduler, serialPortManager);
170+
InsteonModem modem = InsteonModem.makeModem(this, config, httpClient, scheduler, serialPortManager);
168171
this.modem = modem;
169172

170173
if (isInitialized()) {

bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/handler/InsteonLegacyNetworkHandler.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.eclipse.jdt.annotation.NonNullByDefault;
2323
import org.eclipse.jdt.annotation.Nullable;
24+
import org.eclipse.jetty.client.HttpClient;
2425
import org.openhab.binding.insteon.internal.InsteonLegacyBinding;
2526
import org.openhab.binding.insteon.internal.config.InsteonBridgeConfiguration;
2627
import org.openhab.binding.insteon.internal.config.InsteonLegacyNetworkConfiguration;
@@ -67,16 +68,18 @@ public class InsteonLegacyNetworkHandler extends BaseBridgeHandler {
6768
private @Nullable ScheduledFuture<?> reconnectJob = null;
6869
private @Nullable ScheduledFuture<?> settleJob = null;
6970
private long lastInsteonDeviceCreatedTimestamp = 0;
71+
private HttpClient httpClient;
7072
private SerialPortManager serialPortManager;
7173
private ThingManager thingManager;
7274
private ThingRegistry thingRegistry;
7375
private Map<String, String> deviceInfo = new ConcurrentHashMap<>();
7476
private Map<String, String> channelInfo = new ConcurrentHashMap<>();
7577
private Map<ChannelUID, Configuration> channelConfigs = new ConcurrentHashMap<>();
7678

77-
public InsteonLegacyNetworkHandler(Bridge bridge, SerialPortManager serialPortManager, ThingManager thingManager,
78-
ThingRegistry thingRegistry) {
79+
public InsteonLegacyNetworkHandler(Bridge bridge, HttpClient httpClient, SerialPortManager serialPortManager,
80+
ThingManager thingManager, ThingRegistry thingRegistry) {
7981
super(bridge);
82+
this.httpClient = httpClient;
8083
this.serialPortManager = serialPortManager;
8184
this.thingManager = thingManager;
8285
this.thingRegistry = thingRegistry;
@@ -105,7 +108,7 @@ public void initialize() {
105108
return;
106109
}
107110

108-
insteonBinding = new InsteonLegacyBinding(this, config, serialPortManager, scheduler);
111+
insteonBinding = new InsteonLegacyBinding(this, config, httpClient, scheduler, serialPortManager);
109112
updateStatus(ThingStatus.UNKNOWN);
110113

111114
// hold off on starting to poll until devices that already are defined as things are added.
@@ -136,7 +139,7 @@ public void initialize() {
136139
this.driverInitializedJob = null;
137140
}
138141
} else {
139-
logger.debug("driver is not initialized yet");
142+
logger.trace("driver is not initialized yet");
140143
}
141144
}, 0, DRIVER_INITIALIZED_TIME_IN_SECONDS, TimeUnit.SECONDS);
142145
} else {

bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/HubIOStream.java

+31-44
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,27 @@
1212
*/
1313
package org.openhab.binding.insteon.internal.transport;
1414

15-
import java.io.BufferedInputStream;
1615
import java.io.ByteArrayOutputStream;
1716
import java.io.IOException;
1817
import java.io.InputStream;
1918
import java.io.OutputStream;
20-
import java.net.HttpURLConnection;
21-
import java.net.URL;
2219
import java.nio.ByteBuffer;
2320
import java.nio.charset.StandardCharsets;
2421
import java.util.Base64;
2522
import java.util.Objects;
23+
import java.util.concurrent.ExecutionException;
2624
import java.util.concurrent.ScheduledExecutorService;
2725
import java.util.concurrent.ScheduledFuture;
2826
import java.util.concurrent.TimeUnit;
27+
import java.util.concurrent.TimeoutException;
2928

3029
import org.eclipse.jdt.annotation.NonNullByDefault;
3130
import org.eclipse.jdt.annotation.Nullable;
31+
import org.eclipse.jetty.client.HttpClient;
32+
import org.eclipse.jetty.client.api.ContentResponse;
33+
import org.eclipse.jetty.client.api.Request;
34+
import org.eclipse.jetty.http.HttpHeader;
35+
import org.eclipse.jetty.http.HttpStatus;
3236
import org.openhab.binding.insteon.internal.utils.HexUtils;
3337
import org.slf4j.Logger;
3438
import org.slf4j.LoggerFactory;
@@ -47,11 +51,13 @@ public class HubIOStream extends IOStream {
4751

4852
private static final String BS_START = "<BS>";
4953
private static final String BS_END = "</BS>";
54+
private static final int REQUEST_TIMEOUT = 30; // in seconds
5055

5156
private String host;
5257
private int port;
5358
private String auth;
5459
private int pollInterval;
60+
private HttpClient httpClient;
5561
private ScheduledExecutorService scheduler;
5662
private @Nullable ScheduledFuture<?> job;
5763
// index of the last byte we have read in the buffer
@@ -65,14 +71,16 @@ public class HubIOStream extends IOStream {
6571
* @param username hub user name
6672
* @param password hub password
6773
* @param pollInterval hub poll interval (in milliseconds)
74+
* @param httpClient the http client
6875
* @param scheduler the scheduler
6976
*/
70-
public HubIOStream(String host, int port, String username, String password, int pollInterval,
77+
public HubIOStream(String host, int port, String username, String password, int pollInterval, HttpClient httpClient,
7178
ScheduledExecutorService scheduler) {
7279
this.host = host;
7380
this.port = port;
7481
this.auth = Base64.getEncoder().encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8));
7582
this.pollInterval = pollInterval;
83+
this.httpClient = httpClient;
7684
this.scheduler = scheduler;
7785
}
7886

@@ -265,54 +273,33 @@ private boolean isClearedBuffer(String data) {
265273
/**
266274
* Helper method to fetch url from http server
267275
*
268-
* @param resource the url
276+
* @param path the url path
269277
* @return contents returned by http server
270278
* @throws IOException
271279
*/
272-
private String getURL(String resource) throws IOException {
273-
String url = "http://" + host + ":" + port + resource;
280+
private String getURL(String path) throws IOException {
281+
Request request = httpClient.newRequest(host, port).path(path).header(HttpHeader.AUTHORIZATION, "Basic " + auth)
282+
.timeout(REQUEST_TIMEOUT, TimeUnit.SECONDS);
283+
logger.trace("getting {}", request.getURI());
274284

275-
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
276285
try {
277-
connection.setConnectTimeout(30000);
278-
connection.setReadTimeout(10000);
279-
connection.setUseCaches(false);
280-
connection.setDoInput(true);
281-
connection.setDoOutput(false);
282-
connection.setRequestProperty("Authorization", "Basic " + auth);
283-
284-
logger.trace("getting {}", url);
285-
286-
int responseCode = connection.getResponseCode();
287-
if (responseCode != 200) {
288-
if (responseCode == 401) {
286+
ContentResponse response = request.send();
287+
288+
int statusCode = response.getStatus();
289+
switch (statusCode) {
290+
case HttpStatus.OK_200:
291+
return response.getContentAsString();
292+
case HttpStatus.UNAUTHORIZED_401:
289293
throw new IOException(
290294
"Bad username or password. See the label on the bottom of the hub for the correct login information.");
291-
} else {
292-
throw new IOException(url + " failed with the response code: " + responseCode);
293-
}
294-
}
295-
296-
return getData(connection.getInputStream());
297-
} finally {
298-
connection.disconnect();
299-
}
300-
}
301-
302-
private String getData(InputStream is) throws IOException {
303-
BufferedInputStream bis = new BufferedInputStream(is);
304-
try {
305-
ByteArrayOutputStream baos = new ByteArrayOutputStream();
306-
byte[] buffer = new byte[1024];
307-
int length = 0;
308-
while ((length = bis.read(buffer)) != -1) {
309-
baos.write(buffer, 0, length);
295+
default:
296+
throw new IOException("GET " + request.getURI() + " failed with status code: " + statusCode);
310297
}
311-
312-
String s = baos.toString();
313-
return s;
314-
} finally {
315-
bis.close();
298+
} catch (InterruptedException e) {
299+
Thread.currentThread().interrupt();
300+
throw new IOException("GET " + request.getURI() + " interrupted");
301+
} catch (TimeoutException | ExecutionException e) {
302+
throw new IOException("GET " + request.getURI() + " failed with error: " + e.getMessage());
316303
}
317304
}
318305

bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/IOStream.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.eclipse.jdt.annotation.NonNullByDefault;
2222
import org.eclipse.jdt.annotation.Nullable;
23+
import org.eclipse.jetty.client.HttpClient;
2324
import org.openhab.binding.insteon.internal.config.InsteonBridgeConfiguration;
2425
import org.openhab.binding.insteon.internal.config.InsteonHub1Configuration;
2526
import org.openhab.binding.insteon.internal.config.InsteonHub2Configuration;
@@ -113,30 +114,32 @@ public void write(byte @Nullable [] b) throws InterruptedException, IOException
113114
* Creates an IOStream from an insteon bridge config object
114115
*
115116
* @param config
117+
* @param httpClient
116118
* @param scheduler
117119
* @param serialPortManager
118120
* @return reference to IOStream
119121
*/
120-
public static IOStream create(InsteonBridgeConfiguration config, ScheduledExecutorService scheduler,
121-
SerialPortManager serialPortManager) {
122+
public static IOStream create(InsteonBridgeConfiguration config, HttpClient httpClient,
123+
ScheduledExecutorService scheduler, SerialPortManager serialPortManager) {
122124
if (config instanceof InsteonHub1Configuration hub1Config) {
123125
return makeTcpIOStream(hub1Config);
124126
} else if (config instanceof InsteonHub2Configuration hub2Config) {
125-
return makeHubIOStream(hub2Config, scheduler);
127+
return makeHubIOStream(hub2Config, httpClient, scheduler);
126128
} else if (config instanceof InsteonPLMConfiguration plmConfig) {
127129
return makeSerialIOStream(plmConfig, serialPortManager);
128130
} else {
129131
throw new UnsupportedOperationException("unsupported bridge configuration");
130132
}
131133
}
132134

133-
private static HubIOStream makeHubIOStream(InsteonHub2Configuration config, ScheduledExecutorService scheduler) {
135+
private static HubIOStream makeHubIOStream(InsteonHub2Configuration config, HttpClient httpClient,
136+
ScheduledExecutorService scheduler) {
134137
String host = config.getHostname();
135138
int port = config.getPort();
136139
String user = config.getUsername();
137140
String pass = config.getPassword();
138141
int pollInterval = config.getHubPollInterval();
139-
return new HubIOStream(host, port, user, pass, pollInterval, scheduler);
142+
return new HubIOStream(host, port, user, pass, pollInterval, httpClient, scheduler);
140143
}
141144

142145
private static SerialIOStream makeSerialIOStream(InsteonPLMConfiguration config,

0 commit comments

Comments
 (0)