Skip to content

Commit

Permalink
Merge branch hive/develop into hive/master
Browse files Browse the repository at this point in the history
- Fix "read only" bug introduced by immutable refactor.
- Fix bug in "easy-mode-operating" channel for hot water (would display "SCHEDULE" instead of "OFF"
  • Loading branch information
rbrownwsws committed May 1, 2020
1 parent 6d2432b commit 62fe145
Show file tree
Hide file tree
Showing 104 changed files with 1,635 additions and 1,443 deletions.
2 changes: 1 addition & 1 deletion bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@
<artifactId>org.openhab.binding.heos</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.hive</artifactId>
<version>${project.version}</version>
Expand Down
17 changes: 17 additions & 0 deletions bundles/org.openhab.binding.hive/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,27 @@
<version>3.1.13</version>
<scope>test</scope>
</dependency>

<!-- Nicer junit4 parameterized tests -->
<dependency>
<groupId>pl.pragmatists</groupId>
<artifactId>JUnitParams</artifactId>
<version>1.1.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<!-- Configure surefire to not trim stack traces -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<trimStackTrace>false</trimStackTrace>
</configuration>
</plugin>

<!-- Code coverage plugin -->
<plugin>
<groupId>org.jacoco</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
*/
package org.openhab.binding.hive.internal.client;

import java.net.URI;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
Expand All @@ -22,10 +20,8 @@
* @author Ross Brown - Initial contribution
*/
@NonNullByDefault
public final class ActionType extends SimpleValueTypeBase<URI> {
public static final ActionType GENERIC = new ActionType(URI.create("http://alertme.com/schema/json/configuration/configuration.device.action.generic.v1.json#"));
public enum ActionType {
GENERIC,

public ActionType(final URI actionType) {
super(actionType);
}
UNEXPECTED
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@
* @author Ross Brown - Initial contribution
*/
@NonNullByDefault
public final class AttributeName extends SimpleValueTypeBase<String> {
public static final AttributeName ATTRIBUTE_NAME_TARGET_HEAT_TEMPERATURE = new AttributeName("targetHeatTemperature");
public static final AttributeName ATTRIBUTE_NAME_MODE = new AttributeName("mode");
public enum AttributeName {
HEATING_THERMOSTAT_TARGET_HEAT_TEMPERATURE,
ON_OFF_DEVICE_MODE,
WATER_HEATER_HEATING_OPERATING_MODE,

public AttributeName(final String attributeName) {
super(attributeName);
}
UNEXPECTED
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,16 @@ public int intValue() {

@Override
public boolean equals(final @Nullable Object o) {
if (this == o)
if (this == o) {
return true;
if (o == null || getClass() != o.getClass())
}

if (o == null || this.getClass() != o.getClass()) {
return false;
BatteryLevel that = (BatteryLevel) o;
return value == that.value;
}

final BatteryLevel that = (BatteryLevel) o;
return this.value == that.value;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ public Instant getReportChangedTime() {
return this.reportChangedTime;
}

@Override
public SettableFeatureAttribute<T> withTargetValue(final @Nullable T targetValue) {
return DefaultFeatureAttribute.<T>builder()
.from(this)
.targetValue(targetValue)
.build();
}

public static <T> Builder<T> builder() {
return new Builder<>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@

import java.util.Objects;
import java.util.Set;
import java.util.function.Supplier;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.hive.internal.client.exception.HiveApiNotAuthorisedException;
import org.openhab.binding.hive.internal.client.exception.*;
import org.openhab.binding.hive.internal.client.repository.NodeRepository;
import org.openhab.binding.hive.internal.client.repository.SessionRepository;

Expand All @@ -29,10 +28,12 @@
*/
@NonNullByDefault
final class DefaultHiveClient implements HiveClient {
private static final int MAX_REAUTHENTICATION_ATTEMPTS = 1;

private final SessionAuthenticationManager authenticationManager;

private final Username username;
private final Password password;
private final String username;
private final String password;

private final SessionRepository sessionRepository;
private final NodeRepository nodeRepository;
Expand All @@ -42,20 +43,23 @@ final class DefaultHiveClient implements HiveClient {
/**
*
*
* @throws org.openhab.binding.hive.internal.client.exception.HiveApiAuthenticationException
* @throws HiveApiAuthenticationException
* If we failed to authenticate with the provided username and password.
*
* @throws org.openhab.binding.hive.internal.client.exception.HiveApiUnknownException
* @throws HiveApiUnknownException
* If something unexpected happens while communicating with the Hive
* API.
*
* @throws HiveClientResponseException
* If we don't understand the response the Hive API gave us.
*/
public DefaultHiveClient(
final SessionAuthenticationManager authenticationManager,
final Username username,
final Password password,
final String username,
final String password,
final SessionRepository sessionRepository,
final NodeRepository nodeRepository
) {
) throws HiveException {
Objects.requireNonNull(authenticationManager);
Objects.requireNonNull(sessionRepository);
Objects.requireNonNull(nodeRepository);
Expand All @@ -73,20 +77,20 @@ public DefaultHiveClient(

@Override
public void close() {
// TODO: Clean up
// No cleanup required.
}

/**
* Try to authenticate with the Hive API.
*
* @throws org.openhab.binding.hive.internal.client.exception.HiveApiAuthenticationException
* @throws HiveApiAuthenticationException
* If we failed to authenticate with the stored username and password.
*
* @throws org.openhab.binding.hive.internal.client.exception.HiveApiUnknownException
* @throws HiveApiUnknownException
* If something unexpected happens while communicating with the Hive
* API.
*/
private void authenticate() {
private void authenticate() throws HiveException {
this.authenticationManager.clearSession();

final Session session = this.sessionRepository.createSession(
Expand All @@ -98,16 +102,17 @@ private void authenticate() {
this.authenticationManager.setSession(session);
}

private <T> T makeAuthenticatedApiCall(final Supplier<T> apiCall) {
private <T> T makeAuthenticatedApiCall(final ApiCall<T> apiCall) throws HiveException {
// If we get a valid result return it.
// If we are not authorised check if session has expired, reauthenticate and try again.
// Otherwise let other exceptions bubble up.
boolean reauthenticated = false;
while (true) {
int reauthenticationCount = 0;
while (reauthenticationCount <= MAX_REAUTHENTICATION_ATTEMPTS) {
try {
return apiCall.get();
return apiCall.call();
} catch (final HiveApiNotAuthorisedException ex) {
if (reauthenticated || this.sessionRepository.isValidSession(this.authenticationManager.getSession())) {
if (reauthenticationCount == MAX_REAUTHENTICATION_ATTEMPTS
|| this.sessionRepository.isValidSession(this.authenticationManager.getSession())) {
// We are either not authorised for this resource or
// something has gone wrong with the client logic.
// Pass on the exception.
Expand All @@ -116,10 +121,12 @@ private <T> T makeAuthenticatedApiCall(final Supplier<T> apiCall) {
// Session seems to no longer be valid.
// Reauthenticate and try again.
authenticate();
reauthenticated = true;
reauthenticationCount++;
}
}
}

throw new IllegalStateException("Authentication failed and somehow I've escaped my trap.");
}

@Override
Expand All @@ -133,28 +140,33 @@ public UserId getUserId() {
}

@Override
public Set<Node> getAllNodes() {
public Set<Node> getAllNodes() throws HiveException {
return makeAuthenticatedApiCall(this.nodeRepository::getAllNodes);
}

@Override
public String getAllNodesJson() {
public String getAllNodesJson() throws HiveException {
return makeAuthenticatedApiCall(this.nodeRepository::getAllNodesJson);
}

@Override
public @Nullable Node getNode(final NodeId nodeId) {
public @Nullable Node getNode(final NodeId nodeId) throws HiveException {
Objects.requireNonNull(nodeId);

// N.B. Type parameter because Checker Framework needs a little help.
return this.<@Nullable Node>makeAuthenticatedApiCall(() -> this.nodeRepository.getNode(nodeId));
}

@Override
public @Nullable Node updateNode(final Node node) {
public @Nullable Node updateNode(final Node node) throws HiveException {
Objects.requireNonNull(node);

// N.B. Type parameter because Checker Framework needs a little help.
return this.<@Nullable Node>makeAuthenticatedApiCall(() -> this.nodeRepository.updateNode(node));
}

@FunctionalInterface
private interface ApiCall<T> {
T call() throws HiveException;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.hive.internal.client.exception.HiveException;
import org.openhab.binding.hive.internal.client.repository.DefaultNodeRepository;
import org.openhab.binding.hive.internal.client.repository.DefaultSessionRepository;
import org.openhab.binding.hive.internal.client.repository.NodeRepository;
Expand All @@ -37,10 +38,6 @@ public final class DefaultHiveClientFactory implements HiveClientFactory {
public DefaultHiveClientFactory(final HttpClient httpClient) {
Objects.requireNonNull(httpClient);

if (!httpClient.isStarted()) {
throw new IllegalArgumentException("The provided HttpClient is not started!");
}

this.requestFactory = new JettyHiveApiRequestFactory(
httpClient,
HiveApiConstants.DEFAULT_BASE_PATH,
Expand All @@ -50,9 +47,9 @@ public DefaultHiveClientFactory(final HttpClient httpClient) {
}

public HiveClient newClient(
final Username username,
final Password password
) {
final String username,
final String password
) throws HiveException {
Objects.requireNonNull(username);
Objects.requireNonNull(password);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
package org.openhab.binding.hive.internal.client;

import java.util.Objects;
import java.util.function.Function;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
Expand All @@ -36,9 +35,9 @@ private FeatureAttributeFactory() {

private static <F, T> void buildFeatureAttribute(
final DefaultFeatureAttribute.Builder<T> featureAttributeBuilder,
final Function<F, T> adapter,
final Adapter<F, T> adapter,
final FeatureAttributeDto<F> dto
) {
) throws HiveClientResponseException {
Objects.requireNonNull(featureAttributeBuilder);
Objects.requireNonNull(adapter);
Objects.requireNonNull(dto);
Expand Down Expand Up @@ -69,14 +68,14 @@ private static <F, T> void buildFeatureAttribute(
featureAttributeBuilder.reportReceivedTime(reportReceivedTime.asInstant());
}

public static <T> FeatureAttribute<T> getReadOnlyFromDto(final @Nullable FeatureAttributeDto<T> dto) {
return getReadOnlyFromDtoWithAdapter(Function.identity(), dto);
public static <T> FeatureAttribute<T> getReadOnlyFromDto(final @Nullable FeatureAttributeDto<T> dto) throws HiveClientResponseException {
return getReadOnlyFromDtoWithAdapter(Adapter.identity(), dto);
}

public static <F, T> FeatureAttribute<T> getReadOnlyFromDtoWithAdapter(
final Function<F, T> adapter,
final Adapter<F, T> adapter,
final @Nullable FeatureAttributeDto<F> dto
) {
) throws HiveClientResponseException {
if (dto == null) {
throw new HiveClientResponseException(FEATURE_ATTRIBUTE_NULL_MESSAGE);
}
Expand All @@ -92,14 +91,14 @@ public static <F, T> FeatureAttribute<T> getReadOnlyFromDtoWithAdapter(
return featureAttributeBuilder.build();
}

public static <T> SettableFeatureAttribute<T> getSettableFromDto(final @Nullable FeatureAttributeDto<T> dto) {
return getSettableFromDtoWithAdapter(Function.identity(), dto);
public static <T> SettableFeatureAttribute<T> getSettableFromDto(final @Nullable FeatureAttributeDto<T> dto) throws HiveClientResponseException {
return getSettableFromDtoWithAdapter(Adapter.identity(), dto);
}

public static <F, T> SettableFeatureAttribute<T> getSettableFromDtoWithAdapter(
final Function<F, T> adapter,
final Adapter<F, T> adapter,
final @Nullable FeatureAttributeDto<F> dto
) {
) throws HiveClientResponseException {
if (dto == null) {
throw new HiveClientResponseException(FEATURE_ATTRIBUTE_NULL_MESSAGE);
}
Expand All @@ -119,4 +118,13 @@ public static <F, T> SettableFeatureAttribute<T> getSettableFromDtoWithAdapter(

return featureAttributeBuilder.build();
}

@FunctionalInterface
public interface Adapter<F, T> {
T apply(F from) throws HiveClientResponseException;

static <T> Adapter<T, T> identity() {
return from -> from;
}
}
}
Loading

0 comments on commit 62fe145

Please sign in to comment.