mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-25 14:55:55 +01:00
[hydrawise] Handle API auth changes (#16221)
* Handles a new condition where the service rejects a request as unauthorized, but really we just need to refresh our token after 60 seconds. Signed-off-by: Dan Cunningham <dan@digitaldan.com>
This commit is contained in:
parent
90480d0a10
commit
c8d2d4b171
@ -324,6 +324,8 @@ public class HydrawiseGraphQLClient {
|
||||
} catch (ExecutionException e) {
|
||||
// Hydrawise returns back a 40x status, but without a valid Realm , so jetty throws an exception,
|
||||
// this allows us to catch this in a callback and handle accordingly
|
||||
logger.debug("ExecutionException", e);
|
||||
logger.debug("ExecutionException {} {}", responseCode.get(), responseMessage);
|
||||
switch (responseCode.get()) {
|
||||
case 401:
|
||||
case 403:
|
||||
|
@ -62,6 +62,7 @@ public class HydrawiseAccountHandler extends BaseBridgeHandler implements Access
|
||||
* Minimum amount of time we can poll for updates
|
||||
*/
|
||||
private static final int MIN_REFRESH_SECONDS = 30;
|
||||
private static final int TOKEN_REFRESH_SECONDS = 60;
|
||||
private static final String BASE_URL = "https://app.hydrawise.com/api/v2/";
|
||||
private static final String AUTH_URL = BASE_URL + "oauth/access-token";
|
||||
private static final String CLIENT_SECRET = "zn3CrjglwNV1";
|
||||
@ -74,6 +75,7 @@ public class HydrawiseAccountHandler extends BaseBridgeHandler implements Access
|
||||
private @Nullable OAuthClientService oAuthService;
|
||||
private @Nullable HydrawiseGraphQLClient apiClient;
|
||||
private @Nullable ScheduledFuture<?> pollFuture;
|
||||
private @Nullable ScheduledFuture<?> tokenFuture;
|
||||
private @Nullable Customer lastData;
|
||||
private int refresh;
|
||||
|
||||
@ -102,6 +104,7 @@ public class HydrawiseAccountHandler extends BaseBridgeHandler implements Access
|
||||
public void dispose() {
|
||||
logger.debug("Handler disposed.");
|
||||
clearPolling();
|
||||
clearTokenRefresh();
|
||||
OAuthClientService oAuthService = this.oAuthService;
|
||||
if (oAuthService != null) {
|
||||
oAuthService.removeAccessTokenRefreshListener(this);
|
||||
@ -184,20 +187,40 @@ public class HydrawiseAccountHandler extends BaseBridgeHandler implements Access
|
||||
pollFuture = scheduler.scheduleWithFixedDelay(this::poll, initalDelay, refresh, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* The API will randomly reject a request with a 401 not authorized, waiting a min and refreshing the token usually
|
||||
* fixes it
|
||||
*/
|
||||
private synchronized void retryToken() {
|
||||
clearTokenRefresh();
|
||||
tokenFuture = scheduler.schedule(() -> {
|
||||
try {
|
||||
OAuthClientService oAuthService = this.oAuthService;
|
||||
if (oAuthService != null) {
|
||||
oAuthService.refreshToken();
|
||||
initPolling(0, MIN_REFRESH_SECONDS);
|
||||
}
|
||||
} catch (OAuthException | IOException | OAuthResponseException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
|
||||
}
|
||||
}, TOKEN_REFRESH_SECONDS, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops/clears this thing's polling future
|
||||
*/
|
||||
private void clearPolling() {
|
||||
ScheduledFuture<?> localFuture = pollFuture;
|
||||
if (isFutureValid(localFuture)) {
|
||||
if (localFuture != null) {
|
||||
localFuture.cancel(false);
|
||||
}
|
||||
}
|
||||
clearFuture(pollFuture);
|
||||
}
|
||||
|
||||
private boolean isFutureValid(@Nullable ScheduledFuture<?> future) {
|
||||
return future != null && !future.isCancelled();
|
||||
private void clearTokenRefresh() {
|
||||
clearFuture(tokenFuture);
|
||||
}
|
||||
|
||||
private void clearFuture(@Nullable final ScheduledFuture<?> future) {
|
||||
if (future != null) {
|
||||
future.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void poll() {
|
||||
@ -232,8 +255,10 @@ public class HydrawiseAccountHandler extends BaseBridgeHandler implements Access
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||
}
|
||||
} catch (HydrawiseAuthenticationException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
|
||||
logger.debug("Token has been rejected, will try to refresh token in {} secs: {}", TOKEN_REFRESH_SECONDS,
|
||||
e.getLocalizedMessage());
|
||||
clearPolling();
|
||||
retryToken();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user