Skip to content

Commit

Permalink
[insteon] Use shared jetty http client
Browse files Browse the repository at this point in the history
Signed-off-by: jsetton <[email protected]>
  • Loading branch information
jsetton committed Dec 18, 2024
1 parent f45f29f commit 89f93b4
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.insteon.internal.discovery.InsteonDiscoveryService;
import org.openhab.binding.insteon.internal.discovery.InsteonLegacyDiscoveryService;
import org.openhab.binding.insteon.internal.handler.InsteonBridgeHandler;
Expand All @@ -29,6 +30,7 @@
import org.openhab.binding.insteon.internal.handler.InsteonSceneHandler;
import org.openhab.binding.insteon.internal.handler.X10DeviceHandler;
import org.openhab.core.config.discovery.DiscoveryService;
import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.io.transport.serial.SerialPortManager;
import org.openhab.core.storage.StorageService;
import org.openhab.core.thing.Bridge;
Expand Down Expand Up @@ -56,6 +58,7 @@
@Component(configurationPid = "binding.insteon", service = ThingHandlerFactory.class)
public class InsteonHandlerFactory extends BaseThingHandlerFactory {

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

@Activate
public InsteonHandlerFactory(final @Reference SerialPortManager serialPortManager,
public InsteonHandlerFactory(final @Reference HttpClientFactory httpClientFactory,
final @Reference SerialPortManager serialPortManager,
final @Reference InsteonStateDescriptionProvider stateDescriptionProvider,
final @Reference StorageService storageService, final @Reference ThingManager thingManager,
final @Reference ThingRegistry thingRegistry) {
this.httpClient = httpClientFactory.getCommonHttpClient();
this.serialPortManager = serialPortManager;
this.stateDescriptionProvider = stateDescriptionProvider;
this.storageService = storageService;
Expand All @@ -86,14 +91,14 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {

if (THING_TYPE_HUB1.equals(thingTypeUID) || THING_TYPE_HUB2.equals(thingTypeUID)
|| THING_TYPE_PLM.equals(thingTypeUID)) {
InsteonBridgeHandler handler = new InsteonBridgeHandler((Bridge) thing, serialPortManager, storageService,
thingRegistry);
InsteonBridgeHandler handler = new InsteonBridgeHandler((Bridge) thing, httpClient, serialPortManager,
storageService, thingRegistry);
InsteonDiscoveryService service = new InsteonDiscoveryService(handler);
registerDiscoveryService(handler, service);
return handler;
} else if (THING_TYPE_LEGACY_NETWORK.equals(thingTypeUID)) {
InsteonLegacyNetworkHandler handler = new InsteonLegacyNetworkHandler((Bridge) thing, serialPortManager,
thingManager, thingRegistry);
InsteonLegacyNetworkHandler handler = new InsteonLegacyNetworkHandler((Bridge) thing, httpClient,
serialPortManager, thingManager, thingRegistry);
InsteonLegacyDiscoveryService service = new InsteonLegacyDiscoveryService(handler);
registerDiscoveryService(handler, service);
return handler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.insteon.internal.config.InsteonLegacyChannelConfiguration;
import org.openhab.binding.insteon.internal.config.InsteonLegacyNetworkConfiguration;
import org.openhab.binding.insteon.internal.device.DeviceAddress;
Expand Down Expand Up @@ -119,13 +120,13 @@ public class InsteonLegacyBinding implements LegacyDriverListener, LegacyPortLis
private InsteonLegacyNetworkHandler handler;

public InsteonLegacyBinding(InsteonLegacyNetworkHandler handler, InsteonLegacyNetworkConfiguration config,
SerialPortManager serialPortManager, ScheduledExecutorService scheduler) {
HttpClient httpClient, ScheduledExecutorService scheduler, SerialPortManager serialPortManager) {
this.handler = handler;

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

driver = new LegacyDriver(config, this, serialPortManager, scheduler);
driver = new LegacyDriver(config, this, httpClient, scheduler, serialPortManager);
driver.addPortListener(this);

Integer devicePollIntervalSeconds = config.getDevicePollIntervalSeconds();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.insteon.internal.config.InsteonBridgeConfiguration;
import org.openhab.binding.insteon.internal.device.database.DatabaseManager;
import org.openhab.binding.insteon.internal.device.database.ModemDB;
Expand Down Expand Up @@ -53,10 +54,10 @@ public class InsteonModem extends BaseDevice<InsteonAddress, InsteonBridgeHandle
private boolean initialized = false;
private int msgsReceived = 0;

public InsteonModem(InsteonBridgeConfiguration config, ScheduledExecutorService scheduler,
public InsteonModem(InsteonBridgeConfiguration config, HttpClient httpClient, ScheduledExecutorService scheduler,
SerialPortManager serialPortManager) {
super(InsteonAddress.UNKNOWN);
this.port = new Port(config, scheduler, serialPortManager);
this.port = new Port(config, httpClient, scheduler, serialPortManager);
this.modemDB = new ModemDB(this);
this.dbm = new DatabaseManager(this, scheduler);
this.linker = new LinkManager(this, scheduler);
Expand Down Expand Up @@ -509,13 +510,14 @@ private void handleMessage(DeviceAddress address, Msg msg) throws FieldException
*
* @param handler the bridge handler
* @param config the bridge config
* @param httpClient the http client
* @param scheduler the scheduler service
* @param serialPortManager the serial port manager
* @return the newly created InsteonModem
*/
public static InsteonModem makeModem(InsteonBridgeHandler handler, InsteonBridgeConfiguration config,
ScheduledExecutorService scheduler, SerialPortManager serialPortManager) {
InsteonModem modem = new InsteonModem(config, scheduler, serialPortManager);
HttpClient httpClient, ScheduledExecutorService scheduler, SerialPortManager serialPortManager) {
InsteonModem modem = new InsteonModem(config, httpClient, scheduler, serialPortManager);
modem.setHandler(handler);
return modem;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.insteon.internal.config.InsteonBridgeConfiguration;
import org.openhab.binding.insteon.internal.config.InsteonHub1Configuration;
import org.openhab.binding.insteon.internal.config.InsteonHub2Configuration;
Expand Down Expand Up @@ -63,13 +64,15 @@ public class InsteonBridgeHandler extends InsteonBaseThingHandler implements Bri
private @Nullable ScheduledFuture<?> reconnectJob;
private @Nullable ScheduledFuture<?> resetJob;
private @Nullable ScheduledFuture<?> statisticsJob;
private HttpClient httpClient;
private SerialPortManager serialPortManager;
private Storage<DeviceCache> storage;
private ThingRegistry thingRegistry;

public InsteonBridgeHandler(Bridge bridge, SerialPortManager serialPortManager, StorageService storageService,
ThingRegistry thingRegistry) {
public InsteonBridgeHandler(Bridge bridge, HttpClient httpClient, SerialPortManager serialPortManager,
StorageService storageService, ThingRegistry thingRegistry) {
super(bridge);
this.httpClient = httpClient;
this.serialPortManager = serialPortManager;
this.storage = storageService.getStorage(bridge.getUID().toString(), DeviceCache.class.getClassLoader());
this.thingRegistry = thingRegistry;
Expand Down Expand Up @@ -164,7 +167,7 @@ public void initialize() {
legacyHandler.disable();
}

InsteonModem modem = InsteonModem.makeModem(this, config, scheduler, serialPortManager);
InsteonModem modem = InsteonModem.makeModem(this, config, httpClient, scheduler, serialPortManager);
this.modem = modem;

if (isInitialized()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.insteon.internal.InsteonLegacyBinding;
import org.openhab.binding.insteon.internal.config.InsteonBridgeConfiguration;
import org.openhab.binding.insteon.internal.config.InsteonLegacyNetworkConfiguration;
Expand Down Expand Up @@ -67,16 +68,18 @@ public class InsteonLegacyNetworkHandler extends BaseBridgeHandler {
private @Nullable ScheduledFuture<?> reconnectJob = null;
private @Nullable ScheduledFuture<?> settleJob = null;
private long lastInsteonDeviceCreatedTimestamp = 0;
private HttpClient httpClient;
private SerialPortManager serialPortManager;
private ThingManager thingManager;
private ThingRegistry thingRegistry;
private Map<String, String> deviceInfo = new ConcurrentHashMap<>();
private Map<String, String> channelInfo = new ConcurrentHashMap<>();
private Map<ChannelUID, Configuration> channelConfigs = new ConcurrentHashMap<>();

public InsteonLegacyNetworkHandler(Bridge bridge, SerialPortManager serialPortManager, ThingManager thingManager,
ThingRegistry thingRegistry) {
public InsteonLegacyNetworkHandler(Bridge bridge, HttpClient httpClient, SerialPortManager serialPortManager,
ThingManager thingManager, ThingRegistry thingRegistry) {
super(bridge);
this.httpClient = httpClient;
this.serialPortManager = serialPortManager;
this.thingManager = thingManager;
this.thingRegistry = thingRegistry;
Expand Down Expand Up @@ -105,7 +108,7 @@ public void initialize() {
return;
}

insteonBinding = new InsteonLegacyBinding(this, config, serialPortManager, scheduler);
insteonBinding = new InsteonLegacyBinding(this, config, httpClient, scheduler, serialPortManager);
updateStatus(ThingStatus.UNKNOWN);

// hold off on starting to poll until devices that already are defined as things are added.
Expand Down Expand Up @@ -136,7 +139,7 @@ public void initialize() {
this.driverInitializedJob = null;
}
} else {
logger.debug("driver is not initialized yet");
logger.trace("driver is not initialized yet");
}
}, 0, DRIVER_INITIALIZED_TIME_IN_SECONDS, TimeUnit.SECONDS);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,27 @@
*/
package org.openhab.binding.insteon.internal.transport;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
import org.openhab.binding.insteon.internal.utils.HexUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -52,6 +56,7 @@ public class HubIOStream extends IOStream {
private int port;
private String auth;
private int pollInterval;
private HttpClient httpClient;
private ScheduledExecutorService scheduler;
private @Nullable ScheduledFuture<?> job;
// index of the last byte we have read in the buffer
Expand All @@ -65,14 +70,16 @@ public class HubIOStream extends IOStream {
* @param username hub user name
* @param password hub password
* @param pollInterval hub poll interval (in milliseconds)
* @param httpClient the http client
* @param scheduler the scheduler
*/
public HubIOStream(String host, int port, String username, String password, int pollInterval,
public HubIOStream(String host, int port, String username, String password, int pollInterval, HttpClient httpClient,
ScheduledExecutorService scheduler) {
this.host = host;
this.port = port;
this.auth = Base64.getEncoder().encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8));
this.pollInterval = pollInterval;
this.httpClient = httpClient;
this.scheduler = scheduler;
}

Expand Down Expand Up @@ -265,54 +272,30 @@ private boolean isClearedBuffer(String data) {
/**
* Helper method to fetch url from http server
*
* @param resource the url
* @param path the url path
* @return contents returned by http server
* @throws IOException
*/
private String getURL(String resource) throws IOException {
String url = "http://" + host + ":" + port + resource;
private String getURL(String path) throws IOException {
Request request = httpClient.newRequest(host, port).path(path).header(HttpHeader.AUTHORIZATION, "Basic " + auth)
.timeout(30, TimeUnit.SECONDS);
logger.trace("getting {}", request.getURI());

HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
try {
connection.setConnectTimeout(30000);
connection.setReadTimeout(10000);
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(false);
connection.setRequestProperty("Authorization", "Basic " + auth);

logger.trace("getting {}", url);

int responseCode = connection.getResponseCode();
if (responseCode != 200) {
if (responseCode == 401) {
ContentResponse response = request.send();

int statusCode = response.getStatus();
switch (statusCode) {
case HttpStatus.OK_200:
return response.getContentAsString();
case HttpStatus.UNAUTHORIZED_401:
throw new IOException(
"Bad username or password. See the label on the bottom of the hub for the correct login information.");
} else {
throw new IOException(url + " failed with the response code: " + responseCode);
}
}

return getData(connection.getInputStream());
} finally {
connection.disconnect();
}
}

private String getData(InputStream is) throws IOException {
BufferedInputStream bis = new BufferedInputStream(is);
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = 0;
while ((length = bis.read(buffer)) != -1) {
baos.write(buffer, 0, length);
default:
throw new IOException("GET " + request.getURI() + " failed with status code: " + statusCode);
}

String s = baos.toString();
return s;
} finally {
bis.close();
} catch (InterruptedException | TimeoutException | ExecutionException e) {
throw new IOException("GET " + request.getURI() + " failed with error: " + e.getMessage());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.insteon.internal.config.InsteonBridgeConfiguration;
import org.openhab.binding.insteon.internal.config.InsteonHub1Configuration;
import org.openhab.binding.insteon.internal.config.InsteonHub2Configuration;
Expand Down Expand Up @@ -113,30 +114,32 @@ public void write(byte @Nullable [] b) throws InterruptedException, IOException
* Creates an IOStream from an insteon bridge config object
*
* @param config
* @param httpClient
* @param scheduler
* @param serialPortManager
* @return reference to IOStream
*/
public static IOStream create(InsteonBridgeConfiguration config, ScheduledExecutorService scheduler,
SerialPortManager serialPortManager) {
public static IOStream create(InsteonBridgeConfiguration config, HttpClient httpClient,
ScheduledExecutorService scheduler, SerialPortManager serialPortManager) {
if (config instanceof InsteonHub1Configuration hub1Config) {
return makeTcpIOStream(hub1Config);
} else if (config instanceof InsteonHub2Configuration hub2Config) {
return makeHubIOStream(hub2Config, scheduler);
return makeHubIOStream(hub2Config, httpClient, scheduler);
} else if (config instanceof InsteonPLMConfiguration plmConfig) {
return makeSerialIOStream(plmConfig, serialPortManager);
} else {
throw new UnsupportedOperationException("unsupported bridge configuration");
}
}

private static HubIOStream makeHubIOStream(InsteonHub2Configuration config, ScheduledExecutorService scheduler) {
private static HubIOStream makeHubIOStream(InsteonHub2Configuration config, HttpClient httpClient,
ScheduledExecutorService scheduler) {
String host = config.getHostname();
int port = config.getPort();
String user = config.getUsername();
String pass = config.getPassword();
int pollInterval = config.getHubPollInterval();
return new HubIOStream(host, port, user, pass, pollInterval, scheduler);
return new HubIOStream(host, port, user, pass, pollInterval, httpClient, scheduler);
}

private static SerialIOStream makeSerialIOStream(InsteonPLMConfiguration config,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.insteon.internal.config.InsteonLegacyNetworkConfiguration;
import org.openhab.binding.insteon.internal.device.InsteonAddress;
import org.openhab.binding.insteon.internal.device.LegacyPollManager;
Expand All @@ -44,11 +45,11 @@ public class LegacyDriver {
private Map<InsteonAddress, LegacyModemDBEntry> modemDBEntries = new HashMap<>();
private ReentrantLock modemDBEntriesLock = new ReentrantLock();

public LegacyDriver(InsteonLegacyNetworkConfiguration config, LegacyDriverListener listener,
SerialPortManager serialPortManager, ScheduledExecutorService scheduler) {
public LegacyDriver(InsteonLegacyNetworkConfiguration config, LegacyDriverListener listener, HttpClient httpClient,
ScheduledExecutorService scheduler, SerialPortManager serialPortManager) {
this.listener = listener;

this.port = new LegacyPort(config, this, serialPortManager, scheduler);
this.port = new LegacyPort(config, this, httpClient, scheduler, serialPortManager);
this.poller = new LegacyPollManager(scheduler);
this.requester = new LegacyRequestManager(scheduler);
}
Expand Down
Loading

0 comments on commit 89f93b4

Please sign in to comment.