From 7d62e81515e37339ff4dad5f97e8b00758ab1cd7 Mon Sep 17 00:00:00 2001 From: Avgustin Marinov Date: Wed, 22 May 2024 11:02:21 +0300 Subject: [PATCH] Add PollStatus to result of list targets via REST API (#1734) Signed-off-by: Marinov Avgustin --- .../TenantConfigurationManagement.java | 31 ++++++++++++++++++- .../hawkbit/utils/TenantConfigHelper.java | 7 +++++ .../repository/jpa/model/JpaTarget.java | 24 ++------------ .../mgmt/rest/resource/MgmtTargetMapper.java | 12 ++++--- .../rest/resource/MgmtTargetResource.java | 7 ++--- 5 files changed, 50 insertions(+), 31 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index 32ddeb021..b2256b4f1 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -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 getGlobalConfigurationValue(String configurationKeyName, Class 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 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); + }; + } } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/utils/TenantConfigHelper.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/utils/TenantConfigHelper.java index df145b10e..7997c72b1 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/utils/TenantConfigHelper.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/utils/TenantConfigHelper.java @@ -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 pollStatusResolver() { + return tenantConfigurationManagement.pollStatusResolver(); + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java index 300dee323..4f737a093 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -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 diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java index cfe5609e1..1e2005479 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java @@ -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 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 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 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; } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java index 0d1b294d7..94fb29c8d 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java @@ -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 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);