Skip to content

Commit

Permalink
[sleepiq] Use constructor injection for ClientBuilder (openhab#11700)
Browse files Browse the repository at this point in the history
Fixes openhab#11696

Signed-off-by: Mark Hilbush <mark@hilbush.com>
  • Loading branch information
mhilbush committed Dec 5, 2021
1 parent e59cd9d commit 48c9b5a
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 161 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

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;
Expand All @@ -29,8 +31,7 @@
*
* @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
Expand Down Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@
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";
Expand All @@ -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);
}
});
Expand All @@ -113,142 +101,104 @@ public void filter(ClientRequestContext requestContext) throws IOException
}

@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();
response = request.execute(data);
}

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;
}
}
Loading

0 comments on commit 48c9b5a

Please sign in to comment.