Add api sugar for mono gets mono

- While this doesn't change underlying behaviour, add sendEventCollect
  method which takes a mono and returns a mono as list of results.
- Add some notes to docs why this is like this, aka having regions
  returns multiple results.
- Fixes #922
This commit is contained in:
Janne Valkealahti
2021-03-13 15:32:16 +00:00
parent adce03c2e4
commit 341d57e48f
11 changed files with 103 additions and 8 deletions

View File

@@ -12,7 +12,9 @@ include::samples/DocsMigrationTests.java[tags=snippetA]
We're now solely working on a spring `Message` and reactor `Mono` and `Flux` classes.
You can send a `Mono` of a `Message` and receive back a `Flux` of `StateMachineEventResult`.
Remember that nothing happens until you subscribe to this `Flux`. More about
this returned value, see <<sm-triggers-statemachineeventresult>>.
this returned value, see <<sm-triggers-statemachineeventresult>>. Method `sendEventCollect`
is just a syntactic sugar to pass in a `Mono` and get a `Mono` which wraps
results as a list.
====
[source,java,indent=0]

View File

@@ -20,6 +20,20 @@ include::samples/DocsConfigurationSampleTests.java[tags=snippetO]
----
====
Whether you send one event or multiple events, result is always a sequence
of results. This is so because in a presence multiple reqions, results will
come back from multiple machines in those regions. This is shown
with method `sendEventCollect` which gives a list of results. Method
itself is a just a syntactic sugar collecting `Flux` as list. If there is
just one region, this list contains one result.
====
[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetO3]
----
====
IMPORTANT: Nothing happens until returned flux is subscribed. See more about it from
<<sm-triggers-statemachineeventresult>>.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.springframework.statemachine.ensemble;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import java.util.function.Function;
@@ -121,6 +122,11 @@ public class DistributedStateMachine<S, E> extends LifecycleObjectSupport implem
return delegate.sendEvent(event.map(addMachineIdentifier()));
}
@Override
public Mono<List<StateMachineEventResult<S, E>>> sendEventCollect(Mono<Message<E>> event) {
return delegate.sendEventCollect(event.map(addMachineIdentifier()));
}
@Override
public Flux<StateMachineEventResult<S, E>> sendEvents(Flux<Message<E>> events) {
return delegate.sendEvents(events.map(addMachineIdentifier()));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.springframework.statemachine.region;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import org.springframework.messaging.Message;
@@ -115,6 +116,16 @@ public interface Region<S, E> extends StateMachineReactiveLifecycle {
*/
Flux<StateMachineEventResult<S, E>> sendEvent(Mono<Message<E>> event);
/**
* Send a {@link Mono} of event and return a {@link Mono} of collected
* {@link StateMachineEventResult}s as a list. Events are consumed after
* returned results are consumed.
*
* @param event the event
* @return the event results
*/
Mono<List<StateMachineEventResult<S, E>>> sendEventCollect(Mono<Message<E>> event);
/**
* Gets the current {@link State}.
*

View File

@@ -249,6 +249,11 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
return event.flatMapMany(e -> handleEvent(e));
}
@Override
public Mono<List<StateMachineEventResult<S, E>>> sendEventCollect(Mono<Message<E>> event) {
return event.flatMapMany(e -> handleEvent(e)).collectList();
}
@Override
protected void onInit() throws Exception {
super.onInit();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019-2020 the original author or authors.
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -254,6 +254,30 @@ public class ReactiveTests extends AbstractStateMachineTests {
assertThat(machine.getState().getIds()).containsExactlyInAnyOrder(TestStates.S11, TestStates.S20);
}
@SuppressWarnings("unchecked")
@Test
public void testRegionsAsCollect() {
context.register(Config4.class);
context.refresh();
assertThat(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE)).isTrue();
StateMachine<TestStates,TestEvents> machine =
context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, StateMachine.class);
assertThat(machine).isNotNull();
verifyStart(machine);
assertThat(machine.getState().getIds()).containsExactlyInAnyOrder(TestStates.S10, TestStates.S20);
StepVerifier.create(machine.sendEventCollect(asMono(TestEvents.E1)))
.assertNext(r -> {
assertThat(r).hasSize(2);
assertThat(r).filteredOnAssertions(er -> assertThat(er.getResultType()).isSameAs(ResultType.ACCEPTED)).hasSize(1);
assertThat(r).filteredOnAssertions(er -> assertThat(er.getResultType()).isSameAs(ResultType.DENIED)).hasSize(1);
})
.expectComplete()
.verify();
assertThat(machine.getState().getIds()).containsExactlyInAnyOrder(TestStates.S11, TestStates.S20);
}
@Configuration
@EnableStateMachine
static class Config1 extends EnumStateMachineConfigurerAdapter<TestStates, TestEvents> {

View File

@@ -152,6 +152,11 @@ public class StateMachineAccessTests {
return null;
}
@Override
public Mono<List<StateMachineEventResult<String, String>>> sendEventCollect(Mono<Message<String>> event) {
return null;
}
@Override
public Flux<StateMachineEventResult<String, String>> sendEvents(Flux<Message<String>> events) {
return null;

View File

@@ -18,6 +18,7 @@ package org.springframework.statemachine.docs;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.StaticListableBeanFactory;
@@ -615,10 +616,21 @@ public class DocsConfigurationSampleTests extends AbstractStateMachineTests {
stateMachine.sendEvents(Flux.just(message1, message2));
results.subscribe();
// end::snippetO2[]
}
void signalMachine3() {
// tag::snippetO3[]
Message<String> message1 = MessageBuilder
.withPayload("E1")
.build();
Mono<List<StateMachineEventResult<String, String>>> results =
stateMachine.sendEventCollect(Mono.just(message1));
results.subscribe();
// end::snippetO3[]
}
}
// tag::snippetP[]

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019 the original author or authors.
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
*/
package org.springframework.statemachine.docs;
import java.util.List;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
@@ -33,6 +35,8 @@ public class DocsMigrationTests {
Flux<StateMachineEventResult<S, E>> sendEvent(Mono<Message<E>> event);
Flux<StateMachineEventResult<S, E>> sendEvents(Flux<Message<E>> events);
Mono<List<StateMachineEventResult<S, E>>> sendEventCollect(Mono<Message<E>> event);
// end::snippetA[]
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
@@ -203,6 +204,12 @@ public class StateContextExpressionMethodsTests {
return null;
}
@Override
public Mono<List<StateMachineEventResult<SpelStates, SpelEvents>>> sendEventCollect(
Mono<Message<SpelEvents>> event) {
return null;
}
@Override
public Flux<StateMachineEventResult<SpelStates, SpelEvents>> sendEvents(Flux<Message<SpelEvents>> events) {
return null;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -739,6 +739,11 @@ public class ZookeeperStateMachineEnsembleTests extends AbstractZookeeperTests {
return null;
}
@Override
public Mono<List<StateMachineEventResult<String, String>>> sendEventCollect(Mono<Message<String>> event) {
return null;
}
@Override
public Flux<StateMachineEventResult<String, String>> sendEvents(Flux<Message<String>> events) {
return null;