Skip to content

Commit e4da514

Browse files
committed
fixed search and extended resume function
1 parent b00f4fc commit e4da514

File tree

8 files changed

+105
-5
lines changed

8 files changed

+105
-5
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## v2.1.2 - (2025-07-07)
4+
5+
### Bug fixes:
6+
- fixed search for exact values
7+
- extended resume function interface to modify the state
8+
39
## v2.1.0 - (2025-07-07)
410

511
### New features:

core/src/main/java/org/sterl/spring/persistent_tasks/shared/repository/TriggerRepository.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,16 @@ default Predicate buildSearch(
4040
final var predicate = new BooleanBuilder();
4141

4242
if (search.getSearch() != null) {
43-
final var value = StringHelper.applySearchWildCard(search.getSearch());
4443
Predicate pId;
45-
if (StringHelper.isSqlSearch(value)) {
44+
if (StringHelper.isSqlSearch(search.getSearch())) {
45+
final var value = StringHelper.applySearchWildCard(search.getSearch());
4646
pId = ExpressionUtils.anyOf(
4747
qData.key.id.like(value),
4848
qData.correlationId.like(value),
4949
qData.tag.like(value)
5050
);
5151
} else {
52+
final var value = search.getSearch();
5253
pId = ExpressionUtils.anyOf(
5354
qData.key.id.eq(value),
5455
qData.correlationId.eq(value),

core/src/main/java/org/sterl/spring/persistent_tasks/task/exception/CancelTaskException.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
public class CancelTaskException extends TaskException {
77
private static final long serialVersionUID = 1L;
8+
89
public CancelTaskException(String message, Throwable cause) {
910
super(message, cause);
1011
}

core/src/main/java/org/sterl/spring/persistent_tasks/task/exception/FailTaskNoRetryException.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
public class FailTaskNoRetryException extends TaskException {
77
private static final long serialVersionUID = 1L;
8+
89
public FailTaskNoRetryException(String message, Throwable cause) {
910
super(message, cause);
1011
}

core/src/main/java/org/sterl/spring/persistent_tasks/trigger/TriggerService.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.util.Collection;
66
import java.util.List;
77
import java.util.Optional;
8+
import java.util.function.Function;
89

910
import org.springframework.data.domain.Page;
1011
import org.springframework.data.domain.Pageable;
@@ -142,9 +143,7 @@ public <T extends Serializable> RunningTriggerEntity queue(TriggerRequest<T> tig
142143
}
143144

144145
/**
145-
* Will resume any found
146-
* @param trigger
147-
* @return
146+
* Will resume any found {@link RunningTriggerEntity} in state {@link TriggerStatus#AWAITING_SIGNAL}
148147
*/
149148
public Page<RunningTriggerEntity> resume(TriggerRequest<?> trigger) {
150149
if (trigger.key().getId() == null && trigger.correlationId() == null) {
@@ -153,6 +152,19 @@ public Page<RunningTriggerEntity> resume(TriggerRequest<?> trigger) {
153152
taskService.assertIsKnown(trigger.taskId());
154153
return editTrigger.resume(trigger);
155154
}
155+
156+
/**
157+
* Will resume first found {@link RunningTriggerEntity} in state {@link TriggerStatus#AWAITING_SIGNAL}
158+
* with the given search.
159+
*/
160+
public <T extends Serializable> Optional<RunningTriggerEntity> resumeOne(
161+
TriggerSearch search, Function<T, T> stateModifier) {
162+
if (search.getKeyId() == null && search.getCorrelationId() == null) {
163+
throw new IllegalArgumentException("Trigger ID or correlationId required to resume: "
164+
+ search);
165+
}
166+
return editTrigger.resumeOne(search, stateModifier);
167+
}
156168

157169
/**
158170
* If you changed your mind, cancel the persistentTask

core/src/main/java/org/sterl/spring/persistent_tasks/trigger/component/EditTriggerComponent.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.util.Collection;
66
import java.util.List;
77
import java.util.Optional;
8+
import java.util.function.Function;
89

910
import org.springframework.context.ApplicationEventPublisher;
1011
import org.springframework.data.domain.Page;
@@ -149,6 +150,29 @@ public Page<RunningTriggerEntity> resume(TriggerRequest<?> trigger) {
149150
return foundTriggers;
150151
}
151152

153+
/**
154+
* Resumes the first found trigger with the given
155+
* @param <T> state type
156+
* @param search search to run
157+
* @param stateModifier updates the state and should return the run
158+
* @return the updated trigger
159+
*/
160+
public <T extends Serializable> Optional<RunningTriggerEntity> resumeOne(
161+
TriggerSearch search, Function<T, T> stateModifier) {
162+
163+
search.setStatus(TriggerStatus.AWAITING_SIGNAL);
164+
var foundTriggers = readTrigger.searchTriggers(search, Pageable.ofSize(1));
165+
166+
foundTriggers.forEach(t -> {
167+
var newStart = stateModifier.apply((T)stateSerializer.deserialize(t.getData().getState()));
168+
t.getData().setState(stateSerializer.serialize(newStart));
169+
t.runAt(OffsetDateTime.now());
170+
publisher.publishEvent(new TriggerResumedEvent(t.getId(), t.copyData(), newStart));
171+
});
172+
173+
return foundTriggers.isEmpty() ? Optional.empty() : Optional.of(foundTriggers.getContent().get(0));
174+
}
175+
152176
public RunningTriggerEntity expireTrigger(RunningTriggerEntity t) {
153177
t.getData().setStatus(TriggerStatus.EXPIRED_SIGNAL);
154178
t.getData().setStart(null);

core/src/test/java/org/sterl/spring/persistent_tasks/trigger/TriggerServiceTest.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.sterl.spring.persistent_tasks.api.TaskId.TriggerBuilder;
2121
import org.sterl.spring.persistent_tasks.api.TriggerKey;
2222
import org.sterl.spring.persistent_tasks.api.TriggerRequest;
23+
import org.sterl.spring.persistent_tasks.api.TriggerSearch;
2324
import org.sterl.spring.persistent_tasks.api.TriggerStatus;
2425
import org.sterl.spring.persistent_tasks.history.repository.CompletedTriggerRepository;
2526
import org.sterl.spring.persistent_tasks.task.exception.CancelTaskException;
@@ -556,6 +557,47 @@ void testResumeWaitingTriggerForSignal() {
556557
assertThat(persistentTaskTestService.runNextTrigger()).isEmpty();
557558
}
558559

560+
@Test
561+
void testResumeWaitingTriggerWithFunction() {
562+
// GIVEN
563+
TaskId<String> taskId = taskService.replace("foo", asserts::info);
564+
subject.queue(taskId.newTrigger()
565+
.waitForSignal(OffsetDateTime.now().plusDays(1))
566+
.state("foo bar")
567+
.tag("aaa")
568+
.build());
569+
var triggerKey = subject.queue(taskId.newTrigger()
570+
.waitForSignal(OffsetDateTime.now().plusDays(1))
571+
.state("old state")
572+
.tag("aaa")
573+
.build()).getKey();
574+
assertThat(persistentTaskTestService.runNextTrigger()).isEmpty();
575+
576+
// WHEN
577+
var search = new TriggerSearch();
578+
search.setTag("aaa");
579+
search.setKeyId(triggerKey.getId());
580+
subject.resumeOne(search, s -> {
581+
return "Cool new State";
582+
});
583+
584+
// THEN
585+
var t = subject.get(triggerKey).get();
586+
assertThat(t.getData().getStatus()).isEqualTo(TriggerStatus.WAITING);
587+
assertThat(t.getData().getState()).isEqualTo(subject.getStateSerializer().serialize("Cool new State"));
588+
589+
// WHEN
590+
assertThat(persistentTaskTestService.runNextTrigger()).isPresent();
591+
592+
// THEN
593+
asserts.awaitValueOnce("Cool new State");
594+
asserts.assertMissing("old state");
595+
asserts.assertMissing("foo bar");
596+
assertThat(events.stream(TriggerResumedEvent.class).count()).isOne();
597+
// AND
598+
assertThat(persistentTaskTestService.runNextTrigger()).isEmpty();
599+
}
600+
559601
@Test
560602
void testAwaitForSignalTriggersInTimeoutWillNotRun() {
561603
// GIVEN

core/src/test/java/org/sterl/spring/persistent_tasks/trigger/api/TriggerResourceTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,19 @@ void testSearchById() {
9999
assertThat(response.getBody()).isNotNull();
100100
assertThat(response.getBody()).contains(key1.getId());
101101
assertThat(response.getBody()).doesNotContain(key2.getId());
102+
103+
// WHEN exact search, no wild card
104+
response = template.exchange(
105+
baseUrl + "?search=" + key1.getId(),
106+
HttpMethod.GET,
107+
null,
108+
String.class);
109+
110+
// THEN
111+
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
112+
assertThat(response.getBody()).isNotNull();
113+
assertThat(response.getBody()).contains(key1.getId());
114+
assertThat(response.getBody()).doesNotContain(key2.getId());
102115
}
103116

104117
@Test

0 commit comments

Comments
 (0)