From ba3a08e56065a9910ba520efb19987c008487667 Mon Sep 17 00:00:00 2001 From: Stanislav Trailov Date: Fri, 27 Mar 2026 10:18:37 +0200 Subject: [PATCH] Add Target Poll Event in Service Events (#2981) * Add Target Poll Event in Service Events Signed-off-by: strailov * Target poll event to service event Signed-off-by: strailov --------- Signed-off-by: strailov --- .../service/TargetPollServiceEvent.java | 31 +++++++++++++++++++ .../org/eclipse/hawkbit/event/EventType.java | 2 ++ .../event/EventPublisherHolder.java | 7 ++++- .../jpa/JpaRepositoryConfiguration.java | 5 ++- .../event/remote/ServiceEventsTest.java | 12 ++++++- .../test/matcher/EventVerifier.java | 4 +++ 6 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/service/TargetPollServiceEvent.java diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/service/TargetPollServiceEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/service/TargetPollServiceEvent.java new file mode 100644 index 000000000..ebfdddbbc --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/service/TargetPollServiceEvent.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.hawkbit.repository.event.remote.service; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent; + +import java.io.Serial; + +/** + * Service event for {@link TargetPollEvent}. Event that needs single replica processing + */ +public class TargetPollServiceEvent extends AbstractServiceRemoteEvent { + + @Serial + private static final long serialVersionUID = 1L; + + @JsonCreator + public TargetPollServiceEvent(@JsonProperty("payload") TargetPollEvent remoteEvent) { + super(remoteEvent); + } + +} diff --git a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/event/EventType.java b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/event/EventType.java index 2ecb995f4..407927fb9 100644 --- a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/event/EventType.java +++ b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/event/EventType.java @@ -70,6 +70,7 @@ import org.eclipse.hawkbit.repository.event.remote.service.TargetAssignDistribut import org.eclipse.hawkbit.repository.event.remote.service.TargetAttributesRequestedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetCreatedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetDeletedServiceEvent; +import org.eclipse.hawkbit.repository.event.remote.service.TargetPollServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetUpdatedServiceEvent; /** @@ -181,6 +182,7 @@ public class EventType { TYPES.put(1005, CancelTargetAssignmentServiceEvent.class); TYPES.put(1008, ActionCreatedServiceEvent.class); TYPES.put(1009, ActionUpdatedServiceEvent.class); + TYPES.put(1010, TargetPollServiceEvent.class); } /** diff --git a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/event/EventPublisherHolder.java b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/event/EventPublisherHolder.java index aed15cca5..7e4dd05a1 100644 --- a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/event/EventPublisherHolder.java +++ b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/event/EventPublisherHolder.java @@ -20,6 +20,7 @@ import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent; import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent; +import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent; import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent; @@ -31,6 +32,7 @@ import org.eclipse.hawkbit.repository.event.remote.service.TargetAssignDistribut import org.eclipse.hawkbit.repository.event.remote.service.TargetAttributesRequestedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetCreatedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetDeletedServiceEvent; +import org.eclipse.hawkbit.repository.event.remote.service.TargetPollServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetUpdatedServiceEvent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -74,7 +76,8 @@ public final class EventPublisherHolder { CancelTargetAssignmentEvent.class, TargetAttributesRequestedEvent.class, ActionCreatedEvent.class, - ActionUpdatedEvent.class + ActionUpdatedEvent.class, + TargetPollEvent.class ); @Autowired @@ -181,6 +184,8 @@ public final class EventPublisherHolder { return new ActionCreatedServiceEvent(actionCreatedEvent); } else if (event instanceof ActionUpdatedEvent actionUpdatedEvent) { return new ActionUpdatedServiceEvent(actionUpdatedEvent); + } else if (event instanceof TargetPollEvent targetPollEvent) { + return new TargetPollServiceEvent(targetPollEvent); } return null; } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRepositoryConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRepositoryConfiguration.java index 4f48b5c79..0a81f1c84 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRepositoryConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRepositoryConfiguration.java @@ -45,6 +45,7 @@ import org.eclipse.hawkbit.repository.event.ApplicationEventFilter; import org.eclipse.hawkbit.repository.event.remote.EventEntityManager; import org.eclipse.hawkbit.repository.event.remote.EventEntityManagerHolder; import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent; +import org.eclipse.hawkbit.repository.event.remote.service.TargetPollServiceEvent; import org.eclipse.hawkbit.repository.jpa.acm.AccessController; import org.eclipse.hawkbit.repository.jpa.aspects.ExceptionMappingAspectHandler; import org.eclipse.hawkbit.repository.jpa.autocleanup.AutoActionCleanup; @@ -277,7 +278,9 @@ public class JpaRepositoryConfiguration { @Bean @ConditionalOnMissingBean ApplicationEventFilter applicationEventFilter(final RepositoryProperties repositoryProperties) { - return e -> e instanceof TargetPollEvent && !repositoryProperties.isPublishTargetPollEvent(); + return e -> + (e instanceof TargetPollEvent || e instanceof TargetPollServiceEvent) + && !repositoryProperties.isPublishTargetPollEvent(); } /** diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/ServiceEventsTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/ServiceEventsTest.java index a228c08b1..d0123c73c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/ServiceEventsTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/ServiceEventsTest.java @@ -28,6 +28,7 @@ import org.eclipse.hawkbit.repository.event.remote.service.TargetAssignDistribut import org.eclipse.hawkbit.repository.event.remote.service.TargetAttributesRequestedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetCreatedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetDeletedServiceEvent; +import org.eclipse.hawkbit.repository.event.remote.service.TargetPollServiceEvent; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Target; @@ -78,7 +79,8 @@ class ServiceEventsTest { CancelTargetAssignmentEvent.class, TargetAttributesRequestedEvent.class, ActionCreatedEvent.class, - ActionUpdatedEvent.class + ActionUpdatedEvent.class, + TargetPollEvent.class ); assertEquals(EventPublisherHolder.SERVICE_EVENTS, expected); } @@ -130,6 +132,14 @@ class ServiceEventsTest { verify(streamBridge).send(eq("group"), any(CancelTargetAssignmentServiceEvent.class)); } + @Test + void testTargetPollEventIsSent() { + TargetPollEvent event = new TargetPollEvent(); + publisher.publishEvent(event); + verify(streamBridge).send("fanout", event); + verify(streamBridge).send(eq("group"), any(TargetPollServiceEvent.class)); + } + private Action mockAction() { final Action actionMock = mock(Action.class); final Target targetMock = mock(Target.class); diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/EventVerifier.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/EventVerifier.java index fd9c86b66..dde05eb56 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/EventVerifier.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/EventVerifier.java @@ -38,6 +38,7 @@ import org.eclipse.hawkbit.repository.event.remote.RemoteTenantAwareEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent; import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent; +import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent; import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent; @@ -49,6 +50,7 @@ import org.eclipse.hawkbit.repository.event.remote.service.TargetAssignDistribut import org.eclipse.hawkbit.repository.event.remote.service.TargetAttributesRequestedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetCreatedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetDeletedServiceEvent; +import org.eclipse.hawkbit.repository.event.remote.service.TargetPollServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetUpdatedServiceEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationListener; @@ -180,6 +182,8 @@ public class EventVerifier extends AbstractTestExecutionListener { modifiedEvents.add(new DynamicExpect(ActionCreatedServiceEvent.class, event.count())); } else if (type.isAssignableFrom(ActionUpdatedEvent.class)) { modifiedEvents.add(new DynamicExpect(ActionUpdatedServiceEvent.class, event.count())); + } else if (type.isAssignableFrom(TargetPollEvent.class)) { + modifiedEvents.add(new DynamicExpect(TargetPollServiceEvent.class, event.count())); } }