Add timestamp to Actions (#2113)

* Add timestamp to Actions

Signed-off-by: Vasil Ilchev <Vasil.Ilchev@bosch.com>

* Add Timestamp to All Actions Feedback DDI/DMF

* After review

* Removed Action timestamp as we have timestamp in each ActionStatus so use that instead

* Unify to use everywhere System.currentTimeMillis()

* Add constructor w/o timestamp to DmfActionUpdateStatus

---------

Signed-off-by: Vasil Ilchev <Vasil.Ilchev@bosch.com>
Co-authored-by: vasilchev <vasil.ilchev@bosch.com>
This commit is contained in:
Vasil Ilchev
2024-12-04 09:53:10 +02:00
committed by GitHub
parent 58e427d1ea
commit b4215a9d76
17 changed files with 96 additions and 64 deletions

View File

@@ -37,7 +37,7 @@ public final class TimestampCalculator {
* @return <em>overdue_ts</em> in milliseconds since Unix epoch as long value
*/
public static long calculateOverdueTimestamp() {
return Instant.now().toEpochMilli() - getDurationForKey(TenantConfigurationKey.POLLING_TIME_INTERVAL).toMillis()
return System.currentTimeMillis() - getDurationForKey(TenantConfigurationKey.POLLING_TIME_INTERVAL).toMillis()
- getDurationForKey(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL).toMillis();
}

View File

@@ -10,7 +10,6 @@
package org.eclipse.hawkbit.repository.rsql;
import java.io.Serial;
import java.time.Instant;
import org.apache.commons.lang3.text.StrLookup;
import org.apache.commons.lang3.text.StrSubstitutor;
@@ -54,7 +53,7 @@ public class VirtualPropertyResolver extends StrLookup<String> implements Virtua
String resolved = null;
if ("now_ts".equalsIgnoreCase(rhs)) {
resolved = String.valueOf(Instant.now().toEpochMilli());
resolved = String.valueOf(System.currentTimeMillis());
} else if ("overdue_ts".equalsIgnoreCase(rhs)) {
resolved = String.valueOf(TimestampCalculator.calculateOverdueTimestamp());
}

View File

@@ -88,7 +88,7 @@ public class JpaActionManagement {
.orElseThrow(() -> new EntityNotFoundException(Action.class, actionId));
}
protected void onActionStatusUpdate(final Action.Status updatedActionStatus, final JpaAction action) {
protected void onActionStatusUpdate(final JpaActionStatus newActionStatus, final JpaAction action) {
// can be overwritten to intercept the persistence of the action status
}
@@ -165,7 +165,7 @@ public class JpaActionManagement {
assertActionStatusMessageQuota(actionStatus);
actionStatus.setAction(action);
onActionStatusUpdate(actionStatus.getStatus(), action);
onActionStatusUpdate(actionStatus, action);
actionStatusRepository.save(actionStatus);

View File

@@ -163,8 +163,8 @@ public class JpaConfirmationManagement extends JpaActionManagement implements Co
}
@Override
protected void onActionStatusUpdate(final Status updatedActionStatus, final JpaAction action) {
if (updatedActionStatus == Status.RUNNING && action.isActive()) {
protected void onActionStatusUpdate(final JpaActionStatus newActionStatus, final JpaAction action) {
if (newActionStatus.getStatus() == Status.RUNNING && action.isActive()) {
action.setStatus(Status.RUNNING);
}
}

View File

@@ -177,7 +177,9 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont
}
@Override
protected void onActionStatusUpdate(final Action.Status updatedActionStatus, final JpaAction action) {
protected void onActionStatusUpdate(final JpaActionStatus newActionStatus, final JpaAction action) {
final Action.Status updatedActionStatus = newActionStatus.getStatus();
final long occurredAt = newActionStatus.getOccurredAt();
switch (updatedActionStatus) {
case ERROR: {
final JpaTarget target = (JpaTarget) action.getTarget();
@@ -186,7 +188,7 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont
break;
}
case FINISHED: {
handleFinishedAndStoreInTargetStatus(action).ifPresent(this::requestControllerAttributes);
handleFinishedAndStoreInTargetStatus(occurredAt, action).ifPresent(this::requestControllerAttributes);
break;
}
case DOWNLOADED: {
@@ -865,33 +867,35 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont
* @return a present controllerId in case the attributes needs to be
* requested.
*/
private Optional<String> handleFinishedAndStoreInTargetStatus(final JpaAction action) {
private Optional<String> handleFinishedAndStoreInTargetStatus(final long occurredAt, final JpaAction action) {
final JpaTarget target = (JpaTarget) action.getTarget();
action.setActive(false);
action.setStatus(Status.FINISHED);
final JpaDistributionSet ds = (JpaDistributionSet) entityManager.merge(action.getDistributionSet());
if (target.getInstallationDate() == null || target.getInstallationDate() < occurredAt) {
final JpaDistributionSet ds = (JpaDistributionSet) entityManager.merge(action.getDistributionSet());
target.setInstalledDistributionSet(ds);
target.setInstallationDate(System.currentTimeMillis());
target.setInstalledDistributionSet(ds);
target.setInstallationDate(occurredAt);
// Target reported an installation of a DOWNLOAD_ONLY assignment, the
// assigned DS has to be adapted
// because the currently assigned DS can be unequal to the currently
// installed DS (the downloadOnly DS)
if (isDownloadOnly(action)) {
target.setAssignedDistributionSet((JpaDistributionSet) action.getDistributionSet());
// Target reported an installation of a DOWNLOAD_ONLY assignment, the
// assigned DS has to be adapted
// because the currently assigned DS can be unequal to the currently
// installed DS (the downloadOnly DS)
if (isDownloadOnly(action)) {
target.setAssignedDistributionSet((JpaDistributionSet) action.getDistributionSet());
}
// check if the assigned set is equal to the installed set (not
// necessarily the case as another update might be pending already).
if (target.getAssignedDistributionSet() != null
&& target.getAssignedDistributionSet().getId().equals(target.getInstalledDistributionSet().getId())) {
target.setUpdateStatus(TargetUpdateStatus.IN_SYNC);
}
targetRepository.save(target);
entityManager.detach(ds);
}
// check if the assigned set is equal to the installed set (not
// necessarily the case as another update might be pending already).
if (target.getAssignedDistributionSet() != null
&& target.getAssignedDistributionSet().getId().equals(target.getInstalledDistributionSet().getId())) {
target.setUpdateStatus(TargetUpdateStatus.IN_SYNC);
}
targetRepository.save(target);
entityManager.detach(ds);
return Optional.of(target.getControllerId());
}

View File

@@ -18,6 +18,8 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import jakarta.persistence.Access;
import jakarta.persistence.AccessType;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.ConstraintMode;
@@ -51,6 +53,7 @@ import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.springframework.data.annotation.CreatedDate;
/**
* JPA implementation of {@link Action}.
@@ -283,6 +286,7 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
return Optional.ofNullable(lastActionStatusCode);
}
@Override
public Optional<ZonedDateTime> getMaintenanceWindowStartTime() {
return MaintenanceScheduleHelper.getNextMaintenanceWindow(maintenanceWindowSchedule, maintenanceWindowDuration,

View File

@@ -89,7 +89,7 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
final DistributionSet installedSet = testdataFactory.createDistributionSet("another");
final Long lastTargetQueryNotOverdue = Instant.now().toEpochMilli();
final Long lastTargetQueryNotOverdue = System.currentTimeMillis();
final Long lastTargetQueryAlwaysOverdue = 0L;
final String targetDsAIdPref = "targ-A";
@@ -276,7 +276,7 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
void targetSearchWithOverdueFilterAndOrderByDistributionSet() {
final Long lastTargetQueryAlwaysOverdue = 0L;
final long lastTargetQueryNotOverdue = Instant.now().toEpochMilli();
final long lastTargetQueryNotOverdue = System.currentTimeMillis();
final Long[] overdueMix = { lastTargetQueryAlwaysOverdue, lastTargetQueryNotOverdue,
lastTargetQueryAlwaysOverdue, null, lastTargetQueryAlwaysOverdue };