Add PollStatus to result of list targets via REST API (#1734)

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-05-22 11:02:21 +03:00
committed by GitHub
parent deb524d438
commit 7d62e81515
5 changed files with 50 additions and 31 deletions

View File

@@ -10,11 +10,18 @@
package org.eclipse.hawkbit.repository;
import java.io.Serializable;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Map;
import java.util.function.Function;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
import org.eclipse.hawkbit.repository.model.PollStatus;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidatorException;
import org.springframework.core.convert.ConversionFailedException;
@@ -142,4 +149,26 @@ public interface TenantConfigurationManagement {
*/
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ)
<T> T getGlobalConfigurationValue(String configurationKeyName, Class<T> propertyType);
// PreAuthorize for TENANT_CONFIGURATION_READ won't be applied but actually we want just read target
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_READ_TARGET)
default Function<Target, PollStatus> pollStatusResolver() {
final Duration pollTime = DurationHelper.formattedStringToDuration(
getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue());
final Duration overdueTime = DurationHelper.formattedStringToDuration(
getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class)
.getValue());
return target -> {
final Long lastTargetQuery = target.getLastTargetQuery();
if (lastTargetQuery == null) {
return null;
}
final LocalDateTime currentDate = LocalDateTime.now();
final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery),
ZoneId.systemDefault());
final LocalDateTime nextPollDate = lastPollDate.plus(pollTime);
final LocalDateTime overdueDate = nextPollDate.plus(overdueTime);
return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate);
};
}
}

View File

@@ -13,9 +13,12 @@ import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationPrope
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.USER_CONFIRMATION_ENABLED;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.model.PollStatus;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import java.io.Serializable;
import java.util.function.Function;
/**
* A collection of static helper methods for the tenant configuration
@@ -67,4 +70,8 @@ public final class TenantConfigHelper {
public boolean isConfirmationFlowEnabled() {
return getConfigValue(USER_CONFIRMATION_ENABLED, Boolean.class);
}
public Function<Target, PollStatus> pollStatusResolver() {
return tenantConfigurationManagement.pollStatusResolver();
}
}

View File

@@ -11,10 +11,6 @@ package org.eclipse.hawkbit.repository.jpa.model;
import java.io.Serial;
import java.net.URI;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -65,8 +61,6 @@ import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder;
import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.eclipse.persistence.annotations.CascadeOnDelete;
import org.eclipse.persistence.annotations.ConversionValue;
import org.eclipse.persistence.annotations.Convert;
@@ -361,24 +355,12 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw
*/
@Override
public PollStatus getPollStatus() {
// skip creating resolver
if (lastTargetQuery == null) {
return null;
}
return SystemSecurityContextHolder.getInstance().getSystemSecurityContext().runAsSystem(() -> {
final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagementHolder
.getInstance().getTenantConfigurationManagement()
.getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue());
final Duration overdueTime = DurationHelper.formattedStringToDuration(
TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement()
.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class)
.getValue());
final LocalDateTime currentDate = LocalDateTime.now();
final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery),
ZoneId.systemDefault());
final LocalDateTime nextPollDate = lastPollDate.plus(pollTime);
final LocalDateTime overdueDate = nextPollDate.plus(overdueTime);
return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate);
});
return TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement()
.pollStatusResolver().apply(this);
}
@Override

View File

@@ -18,6 +18,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.mgmt.json.model.MgmtMaintenanceWindow;
@@ -114,8 +115,8 @@ public final class MgmtTargetMapper {
return response;
}
static void addPollStatus(final Target target, final MgmtTarget targetRest) {
final PollStatus pollStatus = target.getPollStatus();
private static void addPollStatus(final Target target, final MgmtTarget targetRest, final Function<Target, PollStatus> pollStatusResolver) {
final PollStatus pollStatus = pollStatusResolver == null ? target.getPollStatus() : pollStatusResolver.apply(target);
if (pollStatus != null) {
final MgmtPollStatus pollStatusRest = new MgmtPollStatus();
pollStatusRest.setLastRequestAt(
@@ -139,8 +140,9 @@ public final class MgmtTargetMapper {
return Collections.emptyList();
}
final Function<Target, PollStatus> pollStatusResolver = configHelper.pollStatusResolver();
return new ResponseList<>(
targets.stream().map(target -> toResponse(target, configHelper)).collect(Collectors.toList()));
targets.stream().map(target -> toResponse(target, configHelper, pollStatusResolver)).collect(Collectors.toList()));
}
/**
@@ -150,7 +152,7 @@ public final class MgmtTargetMapper {
* the target
* @return the response
*/
public static MgmtTarget toResponse(final Target target, final TenantConfigHelper configHelper) {
public static MgmtTarget toResponse(final Target target, final TenantConfigHelper configHelper, final Function<Target, PollStatus> pollStatusResolver) {
if (target == null) {
return null;
}
@@ -198,6 +200,8 @@ public final class MgmtTargetMapper {
targetRest.add(
linkTo(methodOn(MgmtTargetRestApi.class).getTarget(target.getControllerId())).withSelfRel().expand());
addPollStatus(target, targetRest, pollStatusResolver == null ? configHelper.pollStatusResolver() : pollStatusResolver);
return targetRest;
}

View File

@@ -17,7 +17,6 @@ import java.util.Map.Entry;
import java.util.function.Function;
import java.util.stream.Collectors;
import jakarta.validation.Valid;
import jakarta.validation.ValidationException;
import lombok.extern.slf4j.Slf4j;
@@ -99,8 +98,7 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
public ResponseEntity<MgmtTarget> getTarget(@PathVariable("targetId") final String targetId) {
final Target findTarget = findTargetWithExceptionIfNotFound(targetId);
// to single response include poll status
final MgmtTarget response = MgmtTargetMapper.toResponse(findTarget, tenantConfigHelper);
MgmtTargetMapper.addPollStatus(findTarget, response);
final MgmtTarget response = MgmtTargetMapper.toResponse(findTarget, tenantConfigHelper, null);
MgmtTargetMapper.addTargetLinks(response);
return ResponseEntity.ok(response);
@@ -172,8 +170,7 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
}
final MgmtTarget response = MgmtTargetMapper.toResponse(updateTarget, tenantConfigHelper);
MgmtTargetMapper.addPollStatus(updateTarget, response);
final MgmtTarget response = MgmtTargetMapper.toResponse(updateTarget, tenantConfigHelper, null);
MgmtTargetMapper.addTargetLinks(response);
return ResponseEntity.ok(response);