]> git.basschouten.com Git - openhab-addons.git/commitdiff
[sleepiq] Use constructor injection for ClientBuilder (#11700)
authorMark Hilbush <mark@hilbush.com>
Sun, 5 Dec 2021 10:20:20 +0000 (05:20 -0500)
committerGitHub <noreply@github.com>
Sun, 5 Dec 2021 10:20:20 +0000 (11:20 +0100)
Fixes #11696

Signed-off-by: Mark Hilbush <mark@hilbush.com>
bundles/org.openhab.binding.sleepiq/src/3rdparty/java/org/openhab/binding/sleepiq/api/SleepIQ.java
bundles/org.openhab.binding.sleepiq/src/3rdparty/java/org/openhab/binding/sleepiq/api/impl/SleepIQImpl.java
bundles/org.openhab.binding.sleepiq/src/3rdparty/java/org/openhab/binding/sleepiq/api/model/TimeSince.java
bundles/org.openhab.binding.sleepiq/src/main/java/org/openhab/binding/sleepiq/internal/SleepIQHandlerFactory.java
bundles/org.openhab.binding.sleepiq/src/main/java/org/openhab/binding/sleepiq/internal/handler/SleepIQCloudHandler.java

index dcb01b80f7040c381d238c751cc1e76c2b670ad9..5785b24f791e97e6f39c01a0a8b1c252223587df 100644 (file)
@@ -17,6 +17,8 @@ package org.openhab.binding.sleepiq.api;
 
 import java.util.List;
 
+import javax.ws.rs.client.ClientBuilder;
+
 import org.openhab.binding.sleepiq.api.impl.SleepIQImpl;
 import org.openhab.binding.sleepiq.api.model.Bed;
 import org.openhab.binding.sleepiq.api.model.FamilyStatus;
@@ -29,8 +31,7 @@ import org.openhab.binding.sleepiq.api.model.Sleeper;
  *
  * @author Gregory Moyer
  */
-public interface SleepIQ
-{
+public interface SleepIQ {
     /**
      * Login to the {@link Configuration configured} account. This method is not
      * required to be called before other methods because all methods must
@@ -94,8 +95,7 @@ public interface SleepIQ
      *            the configuration to use for the new instance
      * @return a concrete implementation of this interface
      */
-    public static SleepIQ create(Configuration config)
-    {
-        return new SleepIQImpl(config);
+    public static SleepIQ create(Configuration config, ClientBuilder clientBuilder) {
+        return new SleepIQImpl(config, clientBuilder);
     }
 }
index 666eb93388d926d114af32ca6e067971ba01daca..df1b85a387bd756dd42e102d933d98666a2b6ba1 100644 (file)
@@ -49,8 +49,7 @@ import org.openhab.binding.sleepiq.api.model.Sleeper;
 import org.openhab.binding.sleepiq.api.model.SleepersResponse;
 import org.openhab.binding.sleepiq.internal.GsonProvider;
 
-public class SleepIQImpl extends AbstractClient implements SleepIQ
-{
+public class SleepIQImpl extends AbstractClient implements SleepIQ {
     protected static final String PARAM_KEY = "_k";
 
     protected static final String DATA_BED_ID = "bedId";
@@ -59,47 +58,36 @@ public class SleepIQImpl extends AbstractClient implements SleepIQ
 
     private volatile LoginInfo loginInfo;
 
-    public SleepIQImpl(Configuration config)
-    {
+    private final ClientBuilder clientBuilder;
+
+    public SleepIQImpl(Configuration config, ClientBuilder clientBuilder) {
         this.config = config;
+        this.clientBuilder = clientBuilder;
     }
 
     @Override
-    public LoginInfo login() throws LoginException
-    {
-        if (loginInfo == null)
-        {
-            synchronized (this)
-            {
-                if (loginInfo == null)
-                {
-                    Response response = getClient().target(config.getBaseUri())
-                                                   .path(Endpoints.login())
-                                                   .request(MediaType.APPLICATION_JSON_TYPE)
-                                                   .put(Entity.json(new LoginRequest().withLogin(config.getUsername())
-                                                                                      .withPassword(config.getPassword())));
-
-                    if (isUnauthorized(response))
-                    {
+    public LoginInfo login() throws LoginException {
+        if (loginInfo == null) {
+            synchronized (this) {
+                if (loginInfo == null) {
+                    Response response = getClient().target(config.getBaseUri()).path(Endpoints.login())
+                            .request(MediaType.APPLICATION_JSON_TYPE).put(Entity.json(new LoginRequest()
+                                    .withLogin(config.getUsername()).withPassword(config.getPassword())));
+
+                    if (isUnauthorized(response)) {
                         throw new UnauthorizedException(response.readEntity(Failure.class));
                     }
 
-                    if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily()))
-                    {
+                    if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
                         throw new LoginException(response.readEntity(Failure.class));
                     }
 
                     // add the received cookies to all future requests
-                    getClient().register(new ClientRequestFilter()
-                    {
+                    getClient().register(new ClientRequestFilter() {
                         @Override
-                        public void filter(ClientRequestContext requestContext) throws IOException
-                        {
-                            List<Object> cookies = response.getCookies()
-                                                           .values()
-                                                           .stream()
-                                                           .map(newCookie -> newCookie.toCookie())
-                                                           .collect(Collectors.toList());
+                        public void filter(ClientRequestContext requestContext) throws IOException {
+                            List<Object> cookies = response.getCookies().values().stream()
+                                    .map(newCookie -> newCookie.toCookie()).collect(Collectors.toList());
                             requestContext.getHeaders().put("Cookie", cookies);
                         }
                     });
@@ -113,106 +101,76 @@ public class SleepIQImpl extends AbstractClient implements SleepIQ
     }
 
     @Override
-    public List<Bed> getBeds()
-    {
+    public List<Bed> getBeds() {
         return getSessionResponse(this::getBedsResponse).readEntity(BedsResponse.class).getBeds();
     }
 
-    protected Response getBedsResponse(Map<String, Object> data) throws LoginException
-    {
+    protected Response getBedsResponse(Map<String, Object> data) throws LoginException {
         LoginInfo login = login();
-        return getClient().target(config.getBaseUri())
-                          .path(Endpoints.bed())
-                          .queryParam(PARAM_KEY, login.getKey())
-                          .request(MediaType.APPLICATION_JSON_TYPE)
-                          .get();
+        return getClient().target(config.getBaseUri()).path(Endpoints.bed()).queryParam(PARAM_KEY, login.getKey())
+                .request(MediaType.APPLICATION_JSON_TYPE).get();
     }
 
     @Override
-    public List<Sleeper> getSleepers()
-    {
-        return getSessionResponse(this::getSleepersResponse).readEntity(SleepersResponse.class)
-                                                            .getSleepers();
+    public List<Sleeper> getSleepers() {
+        return getSessionResponse(this::getSleepersResponse).readEntity(SleepersResponse.class).getSleepers();
     }
 
-    protected Response getSleepersResponse(Map<String, Object> data) throws LoginException
-    {
+    protected Response getSleepersResponse(Map<String, Object> data) throws LoginException {
         LoginInfo login = login();
-        return getClient().target(config.getBaseUri())
-                          .path(Endpoints.sleeper())
-                          .queryParam(PARAM_KEY, login.getKey())
-                          .request(MediaType.APPLICATION_JSON_TYPE)
-                          .get();
+        return getClient().target(config.getBaseUri()).path(Endpoints.sleeper()).queryParam(PARAM_KEY, login.getKey())
+                .request(MediaType.APPLICATION_JSON_TYPE).get();
     }
 
     @Override
-    public FamilyStatus getFamilyStatus()
-    {
+    public FamilyStatus getFamilyStatus() {
         return getSessionResponse(this::getFamilyStatusResponse).readEntity(FamilyStatus.class);
     }
 
-    protected Response getFamilyStatusResponse(Map<String, Object> data) throws LoginException
-    {
+    protected Response getFamilyStatusResponse(Map<String, Object> data) throws LoginException {
         LoginInfo login = login();
-        return getClient().target(config.getBaseUri())
-                          .path(Endpoints.bed())
-                          .path(Endpoints.familyStatus())
-                          .queryParam(PARAM_KEY, login.getKey())
-                          .request(MediaType.APPLICATION_JSON_TYPE)
-                          .get();
+        return getClient().target(config.getBaseUri()).path(Endpoints.bed()).path(Endpoints.familyStatus())
+                .queryParam(PARAM_KEY, login.getKey()).request(MediaType.APPLICATION_JSON_TYPE).get();
     }
 
     @Override
-    public PauseMode getPauseMode(String bedId) throws BedNotFoundException
-    {
+    public PauseMode getPauseMode(String bedId) throws BedNotFoundException {
         Map<String, Object> data = new HashMap<>();
         data.put(DATA_BED_ID, bedId);
 
         Response response = getSessionResponse(this::getPauseModeResponse, data);
 
-        if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily()))
-        {
+        if (!Status.Family.SUCCESSFUL.equals(response.getStatusInfo().getFamily())) {
             throw new BedNotFoundException(response.readEntity(Failure.class));
         }
 
         return response.readEntity(PauseMode.class);
     }
 
-    protected Response getPauseModeResponse(Map<String, Object> data) throws LoginException
-    {
+    protected Response getPauseModeResponse(Map<String, Object> data) throws LoginException {
         LoginInfo login = login();
-        return getClient().target(config.getBaseUri())
-                          .path(Endpoints.bed())
-                          .path(data.get(DATA_BED_ID).toString())
-                          .path(Endpoints.pauseMode())
-                          .queryParam(PARAM_KEY, login.getKey())
-                          .request(MediaType.APPLICATION_JSON_TYPE)
-                          .get();
+        return getClient().target(config.getBaseUri()).path(Endpoints.bed()).path(data.get(DATA_BED_ID).toString())
+                .path(Endpoints.pauseMode()).queryParam(PARAM_KEY, login.getKey())
+                .request(MediaType.APPLICATION_JSON_TYPE).get();
     }
 
-    protected boolean isUnauthorized(Response response)
-    {
+    protected boolean isUnauthorized(Response response) {
         return Status.UNAUTHORIZED.getStatusCode() == response.getStatusInfo().getStatusCode();
     }
 
-    protected synchronized void resetLogin()
-    {
+    protected synchronized void resetLogin() {
         loginInfo = null;
     }
 
-    protected Response getSessionResponse(Request request)
-    {
+    protected Response getSessionResponse(Request request) {
         return getSessionResponse(request, Collections.emptyMap());
     }
 
-    protected Response getSessionResponse(Request request, Map<String, Object> data)
-    {
-        try
-        {
+    protected Response getSessionResponse(Request request, Map<String, Object> data) {
+        try {
             Response response = request.execute(data);
 
-            if (isUnauthorized(response))
-            {
+            if (isUnauthorized(response)) {
                 // session timed out
                 response.close();
                 resetLogin();
@@ -220,35 +178,27 @@ public class SleepIQImpl extends AbstractClient implements SleepIQ
             }
 
             return response;
-        }
-        catch (LoginException e)
-        {
+        } catch (LoginException e) {
             throw new RuntimeException(e.getMessage(), e);
         }
     }
 
     @Override
-    protected Client createClient()
-    {
-        ClientBuilder builder = ClientBuilder.newBuilder();
-
+    protected Client createClient() {
         // setup Gson (de)serialization
         GsonProvider<Object> gsonProvider = new GsonProvider<>(getGson());
-        builder.register(gsonProvider);
+        clientBuilder.register(gsonProvider);
 
         // turn on logging if requested
-        if (config.isLogging())
-        {
-            builder.register(new LoggingFilter(Logger.getLogger(SleepIQImpl.class.getName()),
-                                               true));
+        if (config.isLogging()) {
+            clientBuilder.register(new LoggingFilter(Logger.getLogger(SleepIQImpl.class.getName()), true));
         }
 
-        return builder.build();
+        return clientBuilder.build();
     }
 
     @FunctionalInterface
-    public static interface Request
-    {
+    public static interface Request {
         public Response execute(Map<String, Object> data) throws LoginException;
     }
 }
index 674e2ef7449d98dbb6ac976bbc0b78c02adb93b7..c6c8704861863e96af35f93693c95c0b8bf7b4d6 100644 (file)
 package org.openhab.binding.sleepiq.api.model;
 
 import java.time.Duration;
-import java.time.format.DateTimeParseException;
 import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-public class TimeSince
-{
+public class TimeSince {
     private static final Pattern PATTERN = Pattern.compile("(([0-9]+) d )?([0-9]{2}):([0-9]{2}):([0-9]{2})",
-                                                           Pattern.CASE_INSENSITIVE);
+            Pattern.CASE_INSENSITIVE);
 
     private Duration duration;
 
-    public Duration getDuration()
-    {
+    public Duration getDuration() {
         return duration;
     }
 
-    public void setDuration(Duration duration)
-    {
+    public void setDuration(Duration duration) {
         this.duration = duration == null ? null : duration.abs();
     }
 
-    public TimeSince withDuration(long days, long hours, long minutes, long seconds)
-    {
-        return withDuration(Duration.ofSeconds(TimeUnit.DAYS.toSeconds(days)
-                                               + TimeUnit.HOURS.toSeconds(hours)
-                                               + TimeUnit.MINUTES.toSeconds(minutes)
-                                               + seconds));
+    public TimeSince withDuration(long days, long hours, long minutes, long seconds) {
+        return withDuration(Duration.ofSeconds(TimeUnit.DAYS.toSeconds(days) + TimeUnit.HOURS.toSeconds(hours)
+                + TimeUnit.MINUTES.toSeconds(minutes) + seconds));
     }
 
-    public TimeSince withDuration(Duration duration)
-    {
+    public TimeSince withDuration(Duration duration) {
         setDuration(duration);
         return this;
     }
 
     @Override
-    public int hashCode()
-    {
+    public int hashCode() {
         final int prime = 31;
         int result = 1;
         result = prime * result + ((duration == null) ? 0 : duration.hashCode());
@@ -63,38 +54,29 @@ public class TimeSince
     }
 
     @Override
-    public boolean equals(Object obj)
-    {
-        if (this == obj)
-        {
+    public boolean equals(Object obj) {
+        if (this == obj) {
             return true;
         }
-        if (obj == null)
-        {
+        if (obj == null) {
             return false;
         }
-        if (!(obj instanceof TimeSince))
-        {
+        if (!(obj instanceof TimeSince)) {
             return false;
         }
-        TimeSince other = (TimeSince)obj;
-        if (duration == null)
-        {
-            if (other.duration != null)
-            {
+        TimeSince other = (TimeSince) obj;
+        if (duration == null) {
+            if (other.duration != null) {
                 return false;
             }
-        }
-        else if (!duration.equals(other.duration))
-        {
+        } else if (!duration.equals(other.duration)) {
             return false;
         }
         return true;
     }
 
     @Override
-    public String toString()
-    {
+    public String toString() {
         long totalDays = duration.toDays();
         long totalHours = duration.toHours();
         long totalMinutes = duration.toMinutes();
@@ -104,22 +86,19 @@ public class TimeSince
         long minutes = totalMinutes - TimeUnit.HOURS.toMinutes(totalHours);
         long seconds = totalSeconds - TimeUnit.MINUTES.toSeconds(totalMinutes);
 
-        if (totalDays > 0)
-        {
+        if (totalDays > 0) {
             return String.format("%d d %02d:%02d:%02d", totalDays, hours, minutes, seconds);
         }
 
         return String.format("%02d:%02d:%02d", hours, minutes, seconds);
     }
 
-    public static TimeSince parse(CharSequence text)
-    {
+    public static TimeSince parse(CharSequence text) {
         Objects.requireNonNull(text, "text");
 
         Matcher matcher = PATTERN.matcher(text);
-        if (!matcher.matches())
-        {
-            throw new DateTimeParseException("Text cannot be parsed", text, 0);
+        if (!matcher.matches()) {
+            return new TimeSince().withDuration(Duration.ZERO);
         }
 
         String dayMatch = matcher.group(2);
@@ -128,17 +107,10 @@ public class TimeSince
         String secondMatch = matcher.group(5);
 
         StringBuilder sb = new StringBuilder("P");
-        if (dayMatch != null)
-        {
+        if (dayMatch != null) {
             sb.append(dayMatch).append('D');
         }
-        sb.append('T')
-          .append(hourMatch)
-          .append('H')
-          .append(minuteMatch)
-          .append('M')
-          .append(secondMatch)
-          .append('S');
+        sb.append('T').append(hourMatch).append('H').append(minuteMatch).append('M').append(secondMatch).append('S');
 
         return new TimeSince().withDuration(Duration.parse(sb.toString()));
     }
index 67ff44666fa7cb7f83e18741620b9efe90cd159f..6717c178e63ca1b84d7d47a4d82fa59853a2ed3b 100644 (file)
@@ -20,6 +20,8 @@ import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import javax.ws.rs.client.ClientBuilder;
+
 import org.openhab.binding.sleepiq.internal.discovery.SleepIQBedDiscoveryService;
 import org.openhab.binding.sleepiq.internal.handler.SleepIQCloudHandler;
 import org.openhab.binding.sleepiq.internal.handler.SleepIQDualBedHandler;
@@ -32,7 +34,9 @@ import org.openhab.core.thing.binding.BaseThingHandlerFactory;
 import org.openhab.core.thing.binding.ThingHandler;
 import org.openhab.core.thing.binding.ThingHandlerFactory;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -49,8 +53,15 @@ public class SleepIQHandlerFactory extends BaseThingHandlerFactory {
 
     private final Logger logger = LoggerFactory.getLogger(SleepIQHandlerFactory.class);
 
+    private final ClientBuilder clientBuilder;
+
     private final Map<ThingUID, ServiceRegistration<?>> discoveryServiceReg = new HashMap<>();
 
+    @Activate
+    public SleepIQHandlerFactory(@Reference ClientBuilder clientBuilder) {
+        this.clientBuilder = clientBuilder;
+    }
+
     @Override
     public boolean supportsThingType(final ThingTypeUID thingTypeUID) {
         return SUPPORTED_THING_TYPE_UIDS.contains(thingTypeUID);
@@ -62,7 +73,7 @@ public class SleepIQHandlerFactory extends BaseThingHandlerFactory {
 
         if (SleepIQCloudHandler.SUPPORTED_THING_TYPE_UIDS.contains(thingTypeUID)) {
             logger.debug("Creating SleepIQ cloud thing handler");
-            SleepIQCloudHandler cloudHandler = new SleepIQCloudHandler((Bridge) thing);
+            SleepIQCloudHandler cloudHandler = new SleepIQCloudHandler((Bridge) thing, clientBuilder);
             registerBedDiscoveryService(cloudHandler);
             return cloudHandler;
         } else if (SleepIQDualBedHandler.SUPPORTED_THING_TYPE_UIDS.contains(thingTypeUID)) {
index 1b8a4bf558098ae0488f3b107a614a7134c1a663..1fcc2fb3650abe4d660bba8302e60203d4f19bac 100644 (file)
@@ -25,6 +25,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
+import javax.ws.rs.client.ClientBuilder;
+
 import org.openhab.binding.sleepiq.api.Configuration;
 import org.openhab.binding.sleepiq.api.LoginException;
 import org.openhab.binding.sleepiq.api.SleepIQ;
@@ -67,8 +69,11 @@ public class SleepIQCloudHandler extends ConfigStatusBridgeHandler {
 
     private SleepIQ cloud;
 
-    public SleepIQCloudHandler(final Bridge bridge) {
+    private ClientBuilder clientBuilder;
+
+    public SleepIQCloudHandler(final Bridge bridge, ClientBuilder clientBuilder) {
         super(bridge);
+        this.clientBuilder = clientBuilder;
     }
 
     @Override
@@ -100,6 +105,8 @@ public class SleepIQCloudHandler extends ConfigStatusBridgeHandler {
     /**
      * Create a new SleepIQ cloud service connection. If a connection already exists, it will be lost.
      *
+     * @param clientBuilder2
+     *
      * @throws LoginException if there is an error while authenticating to the service
      */
     private void createCloudConnection() throws LoginException {
@@ -109,7 +116,7 @@ public class SleepIQCloudHandler extends ConfigStatusBridgeHandler {
         logger.debug("Creating SleepIQ client");
         Configuration cloudConfig = new Configuration().withUsername(bindingConfig.username)
                 .withPassword(bindingConfig.password).withLogging(logger.isDebugEnabled());
-        cloud = SleepIQ.create(cloudConfig);
+        cloud = SleepIQ.create(cloudConfig, clientBuilder);
 
         logger.debug("Authenticating at the SleepIQ cloud service");
         cloud.login();