Skip to content

Commit

Permalink
Fix error handling + migrate to the injected JAX-RS ClientBuilder
Browse files Browse the repository at this point in the history
Signed-Off-By: Karel Goderis <karel.goderis@me.com>
  • Loading branch information
kgoderis committed Jun 16, 2023
1 parent db01324 commit 16ce1a0
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,19 @@
import static org.openhab.binding.helios.internal.HeliosBindingConstants.HELIOS_VARIO_IP_2_21_TYPE;

import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.ws.rs.client.ClientBuilder;

import org.openhab.binding.helios.internal.handler.HeliosHandler221;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
* The {@link HeliosHandlerFactory} is responsible for creating things and thing
Expand All @@ -33,8 +38,19 @@
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.helios")
public class HeliosHandlerFactory extends BaseThingHandlerFactory {

private static final int EVENT_STREAM_CONNECT_TIMEOUT = 3;
private static final int EVENT_STREAM_READ_TIMEOUT = 200;
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(HELIOS_VARIO_IP_2_21_TYPE);

private final ClientBuilder clientBuilder;

@Activate
public HeliosHandlerFactory(@Reference ClientBuilder clientBuilder) {
this.clientBuilder = clientBuilder //
.connectTimeout(EVENT_STREAM_CONNECT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(EVENT_STREAM_READ_TIMEOUT, TimeUnit.SECONDS);
}

@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
Expand All @@ -45,7 +61,7 @@ protected ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();

if (thingTypeUID.equals(HELIOS_VARIO_IP_2_21_TYPE)) {
return new HeliosHandler221(thing);
return new HeliosHandler221(thing, clientBuilder);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.ProcessingException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.ClientRequestContext;
Expand Down Expand Up @@ -122,6 +123,7 @@ public class HeliosHandler221 extends BaseThingHandler {

// REST Client API variables
private Client heliosClient;
private final ClientBuilder heliosClientBuilder;
private WebTarget baseTarget;
private WebTarget systemTarget;
private WebTarget logTarget;
Expand All @@ -139,8 +141,9 @@ public class HeliosHandler221 extends BaseThingHandler {

private long logSubscriptionID = 0;

public HeliosHandler221(Thing thing) {
public HeliosHandler221(Thing thing, ClientBuilder heliosClientBuilder) {
super(thing);
this.heliosClientBuilder = heliosClientBuilder;
}

@Override
Expand Down Expand Up @@ -169,27 +172,26 @@ public void initialize() {
logger.error("An exception occurred while initialising the SSL context : '{}'", e1.getMessage(), e1);
}

heliosClient = ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier(new HostnameVerifier() {
heliosClient = heliosClientBuilder.sslContext(sslContext).hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
return true;
}
}).build();
heliosClient.register(new Authenticator(username, password));

baseTarget = heliosClient.target(BASE_URI);
baseTarget = heliosClient.target(BASE_URI.replace("{ip}", ipAddress));
systemTarget = baseTarget.path(SYSTEM_PATH);
logTarget = baseTarget.path(LOG_PATH);
switchTarget = baseTarget.path(SWITCH_PATH);

Response response = null;
try {
response = systemTarget.resolveTemplate("ip", ipAddress).resolveTemplate("cmd", INFO)
.request(MediaType.APPLICATION_JSON_TYPE).get();
} catch (NullPointerException e) {
response = systemTarget.resolveTemplate("cmd", INFO).request(MediaType.APPLICATION_JSON_TYPE).get();
} catch (ProcessingException e) {
logger.debug("An exception occurred while fetching system info of the Helios IP Vario '{}' : '{}'",
getThing().getUID().toString(), e.getMessage(), e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
scheduler.schedule(resetRunnable, RESET_INTERVAL, TimeUnit.SECONDS);
return;
}
Expand Down Expand Up @@ -241,6 +243,11 @@ public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
@Override
public void dispose() {
logger.debug("Disposing the Helios IP Vario handler for '{}'.", getThing().getUID().toString());
tearDown();
}

private void tearDown() {
logger.debug("Tearing down the Helios IP Vario handler for '{}'.", getThing().getUID().toString());

if (logSubscriptionID != 0) {
unsubscribe();
Expand Down Expand Up @@ -711,7 +718,7 @@ private List<RESTPort> getPorts() {

protected Runnable resetRunnable = () -> {
logger.debug("Resetting the Helios IP Vario handler for '{}'", getThing().getUID());
dispose();
tearDown();
initialize();
};

Expand Down Expand Up @@ -767,14 +774,24 @@ private List<RESTPort> getPorts() {
ChannelTypeUID enablerUID = new ChannelTypeUID(BINDING_ID, SWITCH_ENABLER);
ChannelTypeUID triggerUID = new ChannelTypeUID(BINDING_ID, SWITCH_TRIGGER);

Channel channel = ChannelBuilder
.create(new ChannelUID(getThing().getUID(), "switch" + aSwitch.id + "active"), "Switch")
.withType(enablerUID).build();
thingBuilder.withChannel(channel);
channel = ChannelBuilder
.create(new ChannelUID(getThing().getUID(), "switch" + aSwitch.id), "Switch")
.withType(triggerUID).build();
thingBuilder.withChannel(channel);
if (this.getThing().getChannel(
new ChannelUID(getThing().getUID(), "switch" + aSwitch.id + "active")) == null) {
logger.debug(
"Adding a channel with id '{}' to the Helios IP Vario '{}' for the switch with id '{}'",
new ChannelUID(getThing().getUID(), "switch" + aSwitch.id + "active").getId(),
getThing().getUID().toString(), aSwitch.id);
Channel channel = ChannelBuilder
.create(new ChannelUID(getThing().getUID(), "switch" + aSwitch.id + "active"), "Switch")
.withType(enablerUID).build();
thingBuilder.withChannel(channel);
}
if (this.getThing()
.getChannel(new ChannelUID(getThing().getUID(), "switch" + aSwitch.id)) == null) {
Channel channel = ChannelBuilder
.create(new ChannelUID(getThing().getUID(), "switch" + aSwitch.id), "Switch")
.withType(triggerUID).build();
thingBuilder.withChannel(channel);
}
updateThing(thingBuilder.build());
}
}
Expand All @@ -792,10 +809,16 @@ private List<RESTPort> getPorts() {
Map<String, String> channelProperties = new HashMap<>();
channelProperties.put("type", aPort.type);

Channel channel = ChannelBuilder
.create(new ChannelUID(getThing().getUID(), "io" + aPort.port), "Switch").withType(triggerUID)
.withProperties(channelProperties).build();
thingBuilder.withChannel(channel);
if (this.getThing().getChannel(new ChannelUID(getThing().getUID(), "io" + aPort.port)) == null) {
logger.debug(
"Adding a channel with id '{}' to the Helios IP Vario '{}' for the switch with id '{}'",
new ChannelUID(getThing().getUID(), "io" + aPort.port).getId(),
getThing().getUID().toString(), aPort.port);
Channel channel = ChannelBuilder
.create(new ChannelUID(getThing().getUID(), "io" + aPort.port), "Switch")
.withType(triggerUID).withProperties(channelProperties).build();
thingBuilder.withChannel(channel);
}
updateThing(thingBuilder.build());
}
}
Expand Down Expand Up @@ -979,6 +1002,11 @@ private List<RESTPort> getPorts() {
logger.trace("No events were retrieved");
}
}
} catch (ProcessingException e) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
logger.trace("An underlying exception forced the Helios IP Vario to go offline : '{}'",
e.getMessage(), e);
scheduler.schedule(resetRunnable, RESET_INTERVAL, TimeUnit.SECONDS);
} catch (Exception e) {
logger.error("An exception occurred while processing an event : '{}'", e.getMessage(), e);
}
Expand Down

0 comments on commit 16ce1a0

Please sign in to comment.