diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 59ead256874..2185ef6d5e7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@ How to contribute ================== Thank you for wanting to contribute to Spine. The following links will help you get started: - * [Wiki home][wiki-home] — the home of the developer's documentation. + * [Wiki home][wiki-home] — the home of the framework developer's documentation. * [Getting started with Spine in Java][quick-start] — this guide will walk you through a minimal client-server “Hello World!” application in Java. * [Introduction][docs-intro] — this section of the Spine Documentation will help you understand @@ -9,20 +9,19 @@ Thank you for wanting to contribute to Spine. The following links will help you Pull requests ------------- -A work on an improvement starts from creating an issue which describes a bug or a feature you -intend to fix. The issue will be used for communications on the proposed improvements. If code -changes are going to be introduced, the issue would also have a link to corresponding Pull Request. +The work on an improvement starts with creating an issue that describes a bug or a feature. The issue will be used for communications on the proposed improvements. +If code changes are going to be introduced, the issue should also have a link to the corresponding Pull Request. Code contributions should: * Be accompanied by tests. - * Be licensed Apache 2.0 with the appropriate copyright header for each file. + * Be licensed under the Apache v2.0 license with the appropriate copyright header for each file. * Formatted according to the code style. See [Wiki home][wiki-home] for the links to style guides of the programming languages used in the framework. Contributor License Agreement ----------------------------- Contributions to the code of Spine Event Engine framework and its libraries must be accompanied by -Contributor License Agreement. +Contributor License Agreement (CLA). * If you are an individual writing original source code and you're sure you own the intellectual property, then you'll need to sign an individual CLA. diff --git a/client/src/main/java/io/spine/client/CommandRequest.java b/client/src/main/java/io/spine/client/CommandRequest.java index 7286485a319..f57e8c45715 100644 --- a/client/src/main/java/io/spine/client/CommandRequest.java +++ b/client/src/main/java/io/spine/client/CommandRequest.java @@ -171,13 +171,27 @@ public CommandRequest onServerError(ServerErrorHandler handler) { * client code "knows" how many of them it expects. Also, some events may not arrive * because of communication or business logic reasons. That's why the returned * subscriptions should be cancelled by the client code when it no longer needs it. + * @see #postAndForget() */ - @CanIgnoreReturnValue public ImmutableSet post() { PostOperation op = new PostOperation(); return op.perform(); } + /** + * Posts the command without subscribing to events that may be generated during + * the command handling. + * + * @throws IllegalStateException + * if {@link #observe(Class, EventConsumer)} or {@link #observe(Class, Consumer)} were + * called in the command request configuration chain before calling this method + * @see #post() + */ + public void postAndForget() throws IllegalStateException { + PostOperation op = new PostOperation(); + op.performWithoutSubscriptions(); + } + @VisibleForTesting CommandMessage message() { return message; @@ -201,9 +215,41 @@ private PostOperation() { } private ImmutableSet perform() { + if (consumers.isEmpty()) { + throw newIllegalStateException( + "No event subscriptions were requested prior to calling `post()`." + + " If you intend to receive events please call `observe()`" + + " before `post()`." + + " Or, if you subscribe to events or projections elsewhere," + + " please use `postAndForget()`." + ); + } subscribeToEvents(); Ack ack = client().post(command); Status status = ack.getStatus(); + return handleStatus(status); + } + + private void performWithoutSubscriptions() { + if (!consumers.isEmpty()) { + throw newIllegalStateException( + "Subscriptions to events were requested. Please call `post()` instead." + ); + } + Ack ack = client().post(command); + Status status = ack.getStatus(); + handleStatus(status); + } + + private void subscribeToEvents() { + Client client = client(); + this.subscriptions = subscribe(client, command, consumers, streamingErrorHandler()); + client.subscriptions() + .addAll(subscriptions); + } + + @CanIgnoreReturnValue + private ImmutableSet handleStatus(Status status) { switch (status.getStatusCase()) { case OK: return Optional.ofNullable(subscriptions) @@ -224,21 +270,13 @@ private ImmutableSet perform() { } } - private void subscribeToEvents() { - Client client = client(); - this.subscriptions = subscribe(client, command, consumers, streamingErrorHandler()); - checkNotNull(subscriptions); - client.subscriptions() - .addAll(subscriptions); - } - /** * Cancels the passed subscriptions to events because the command could not be posted. * */ private void cancelVoidSubscriptions() { - Subscriptions activeSubscriptions = client().subscriptions(); if (subscriptions != null) { + Subscriptions activeSubscriptions = client().subscriptions(); subscriptions.forEach(activeSubscriptions::cancel); } } diff --git a/client/src/main/java/io/spine/client/EventsAfterCommand.java b/client/src/main/java/io/spine/client/EventsAfterCommand.java index 3234b05622f..447bd674a00 100644 --- a/client/src/main/java/io/spine/client/EventsAfterCommand.java +++ b/client/src/main/java/io/spine/client/EventsAfterCommand.java @@ -29,6 +29,7 @@ import io.spine.core.EventContext; import io.spine.core.UserId; import io.spine.logging.Logging; +import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import static com.google.common.base.Preconditions.checkNotNull; @@ -47,7 +48,7 @@ final class EventsAfterCommand implements Logging { private final Command command; private final MultiEventConsumers consumers; - static ImmutableSet + static @NonNull ImmutableSet subscribe(Client client, Command command, MultiEventConsumers consumers, diff --git a/client/src/main/java/io/spine/client/MultiEventConsumers.java b/client/src/main/java/io/spine/client/MultiEventConsumers.java index fd683910ff9..7237b01036c 100644 --- a/client/src/main/java/io/spine/client/MultiEventConsumers.java +++ b/client/src/main/java/io/spine/client/MultiEventConsumers.java @@ -63,8 +63,17 @@ ImmutableSet> eventTypes() { return map.keySet(); } + /** + * Returns {@code true} if no event consumers were collected, {@code false} otherwise. + */ + boolean isEmpty() { + boolean result = eventTypes().isEmpty(); + return result; + } + /** Obtains all the consumers grouped by type of consumed events. */ ImmutableMap, StreamObserver> toObservers() { + @SuppressWarnings("ConstantConditions") // `null` values are prevented when gathering. Map, StreamObserver> observers = Maps.transformValues(map, EventConsumers::toObserver); return ImmutableMap.copyOf(observers); diff --git a/client/src/main/java/io/spine/client/Subscriptions.java b/client/src/main/java/io/spine/client/Subscriptions.java index a5415ddabd5..ceb538403f8 100644 --- a/client/src/main/java/io/spine/client/Subscriptions.java +++ b/client/src/main/java/io/spine/client/Subscriptions.java @@ -22,6 +22,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableSet; import com.google.common.flogger.FluentLogger; +import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.protobuf.Message; import io.grpc.ManagedChannel; import io.grpc.stub.StreamObserver; @@ -34,7 +35,6 @@ import io.spine.logging.Logging; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.Collection; import java.util.HashSet; import java.util.Optional; import java.util.Set; @@ -172,7 +172,7 @@ Subscription subscribeTo(Topic topic, StreamObserver obse } /** Adds all the passed subscriptions. */ - void addAll(Collection newSubscriptions) { + void addAll(Iterable newSubscriptions) { newSubscriptions.forEach(this::add); } @@ -188,6 +188,7 @@ private void add(Subscription s) { * * @return {@code true} if the subscription was previously made */ + @CanIgnoreReturnValue public boolean cancel(Subscription s) { checkNotNull(s); boolean isActive = items.contains(s); diff --git a/license-report.md b/license-report.md index f5a2b03bc0a..f800f3111c6 100644 --- a/license-report.md +++ b/license-report.md @@ -1,6 +1,6 @@ -# Dependencies of `io.spine:spine-client:1.5.20` +# Dependencies of `io.spine:spine-client:1.5.24` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -324,6 +324,7 @@ 1. **Group:** org.jacoco **Name:** org.jacoco.report **Version:** 0.8.5 * **POM License: Eclipse Public License 2.0** - [https://www.eclipse.org/legal/epl-2.0/](https://www.eclipse.org/legal/epl-2.0/) +1. **Group:** org.junit **Name:** junit-bom **Version:** 5.6.2 **No license information found** 1. **Group:** org.junit.jupiter **Name:** junit-jupiter-api **Version:** 5.6.2 * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) @@ -405,12 +406,12 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri Jun 19 14:07:39 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Fri Aug 14 14:46:46 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-core:1.5.20` +# Dependencies of `io.spine:spine-core:1.5.24` ## Runtime 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 @@ -694,6 +695,7 @@ This report was generated on **Fri Jun 19 14:07:39 EEST 2020** using [Gradle-Lic 1. **Group:** org.jacoco **Name:** org.jacoco.report **Version:** 0.8.5 * **POM License: Eclipse Public License 2.0** - [https://www.eclipse.org/legal/epl-2.0/](https://www.eclipse.org/legal/epl-2.0/) +1. **Group:** org.junit **Name:** junit-bom **Version:** 5.6.2 **No license information found** 1. **Group:** org.junit.jupiter **Name:** junit-jupiter-api **Version:** 5.6.2 * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) @@ -775,12 +777,12 @@ This report was generated on **Fri Jun 19 14:07:39 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri Jun 19 14:07:40 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Fri Aug 14 14:46:46 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-model-assembler:1.5.20` +# Dependencies of `io.spine.tools:spine-model-assembler:1.5.24` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -1099,6 +1101,7 @@ This report was generated on **Fri Jun 19 14:07:40 EEST 2020** using [Gradle-Lic 1. **Group:** org.jacoco **Name:** org.jacoco.report **Version:** 0.8.5 * **POM License: Eclipse Public License 2.0** - [https://www.eclipse.org/legal/epl-2.0/](https://www.eclipse.org/legal/epl-2.0/) +1. **Group:** org.junit **Name:** junit-bom **Version:** 5.6.2 **No license information found** 1. **Group:** org.junit.jupiter **Name:** junit-jupiter-api **Version:** 5.6.2 * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) @@ -1180,12 +1183,12 @@ This report was generated on **Fri Jun 19 14:07:40 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri Jun 19 14:07:40 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Fri Aug 14 14:46:47 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-model-verifier:1.5.20` +# Dependencies of `io.spine.tools:spine-model-verifier:1.5.24` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -1570,6 +1573,7 @@ This report was generated on **Fri Jun 19 14:07:40 EEST 2020** using [Gradle-Lic * **POM License: Eclipse Public License version 1.0** - [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html) * **POM License: Public Domain** - [http://repository.jboss.org/licenses/cc0-1.0.txt](http://repository.jboss.org/licenses/cc0-1.0.txt) +1. **Group:** org.junit **Name:** junit-bom **Version:** 5.6.2 **No license information found** 1. **Group:** org.junit-pioneer **Name:** junit-pioneer **Version:** 0.4.2 * **POM Project URL:** [https://github.com/junit-pioneer/junit-pioneer](https://github.com/junit-pioneer/junit-pioneer) * **POM License: The MIT License** - [https://github.com/junit-pioneer/junit-pioneer/blob/master/LICENSE](https://github.com/junit-pioneer/junit-pioneer/blob/master/LICENSE) @@ -1655,12 +1659,12 @@ This report was generated on **Fri Jun 19 14:07:40 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri Jun 19 14:07:41 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Fri Aug 14 14:46:47 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-server:1.5.20` +# Dependencies of `io.spine:spine-server:1.5.24` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -1996,6 +2000,7 @@ This report was generated on **Fri Jun 19 14:07:41 EEST 2020** using [Gradle-Lic 1. **Group:** org.jacoco **Name:** org.jacoco.report **Version:** 0.8.5 * **POM License: Eclipse Public License 2.0** - [https://www.eclipse.org/legal/epl-2.0/](https://www.eclipse.org/legal/epl-2.0/) +1. **Group:** org.junit **Name:** junit-bom **Version:** 5.6.2 **No license information found** 1. **Group:** org.junit.jupiter **Name:** junit-jupiter-api **Version:** 5.6.2 * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) @@ -2077,12 +2082,12 @@ This report was generated on **Fri Jun 19 14:07:41 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri Jun 19 14:07:42 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Fri Aug 14 14:46:47 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-testutil-client:1.5.20` +# Dependencies of `io.spine:spine-testutil-client:1.5.24` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -2215,6 +2220,7 @@ This report was generated on **Fri Jun 19 14:07:42 EEST 2020** using [Gradle-Lic 1. **Group:** org.hamcrest **Name:** hamcrest-core **Version:** 1.3 * **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php) +1. **Group:** org.junit **Name:** junit-bom **Version:** 5.6.2 **No license information found** 1. **Group:** org.junit.jupiter **Name:** junit-jupiter-api **Version:** 5.6.2 * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) @@ -2454,6 +2460,7 @@ This report was generated on **Fri Jun 19 14:07:42 EEST 2020** using [Gradle-Lic 1. **Group:** org.jacoco **Name:** org.jacoco.report **Version:** 0.8.5 * **POM License: Eclipse Public License 2.0** - [https://www.eclipse.org/legal/epl-2.0/](https://www.eclipse.org/legal/epl-2.0/) +1. **Group:** org.junit **Name:** junit-bom **Version:** 5.6.2 **No license information found** 1. **Group:** org.junit.jupiter **Name:** junit-jupiter-api **Version:** 5.6.2 * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) @@ -2535,12 +2542,12 @@ This report was generated on **Fri Jun 19 14:07:42 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri Jun 19 14:07:44 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Fri Aug 14 14:46:49 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-testutil-core:1.5.20` +# Dependencies of `io.spine:spine-testutil-core:1.5.24` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -2673,6 +2680,7 @@ This report was generated on **Fri Jun 19 14:07:44 EEST 2020** using [Gradle-Lic 1. **Group:** org.hamcrest **Name:** hamcrest-core **Version:** 1.3 * **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php) +1. **Group:** org.junit **Name:** junit-bom **Version:** 5.6.2 **No license information found** 1. **Group:** org.junit.jupiter **Name:** junit-jupiter-api **Version:** 5.6.2 * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) @@ -2920,6 +2928,7 @@ This report was generated on **Fri Jun 19 14:07:44 EEST 2020** using [Gradle-Lic 1. **Group:** org.jacoco **Name:** org.jacoco.report **Version:** 0.8.5 * **POM License: Eclipse Public License 2.0** - [https://www.eclipse.org/legal/epl-2.0/](https://www.eclipse.org/legal/epl-2.0/) +1. **Group:** org.junit **Name:** junit-bom **Version:** 5.6.2 **No license information found** 1. **Group:** org.junit.jupiter **Name:** junit-jupiter-api **Version:** 5.6.2 * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) @@ -3001,12 +3010,12 @@ This report was generated on **Fri Jun 19 14:07:44 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri Jun 19 14:07:45 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Fri Aug 14 14:46:50 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-testutil-server:1.5.20` +# Dependencies of `io.spine:spine-testutil-server:1.5.24` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -3139,6 +3148,7 @@ This report was generated on **Fri Jun 19 14:07:45 EEST 2020** using [Gradle-Lic 1. **Group:** org.hamcrest **Name:** hamcrest-core **Version:** 1.3 * **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php) +1. **Group:** org.junit **Name:** junit-bom **Version:** 5.6.2 **No license information found** 1. **Group:** org.junit.jupiter **Name:** junit-jupiter-api **Version:** 5.6.2 * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) @@ -3422,6 +3432,7 @@ This report was generated on **Fri Jun 19 14:07:45 EEST 2020** using [Gradle-Lic 1. **Group:** org.jacoco **Name:** org.jacoco.report **Version:** 0.8.5 * **POM License: Eclipse Public License 2.0** - [https://www.eclipse.org/legal/epl-2.0/](https://www.eclipse.org/legal/epl-2.0/) +1. **Group:** org.junit **Name:** junit-bom **Version:** 5.6.2 **No license information found** 1. **Group:** org.junit.jupiter **Name:** junit-jupiter-api **Version:** 5.6.2 * **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) * **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html) @@ -3503,4 +3514,4 @@ This report was generated on **Fri Jun 19 14:07:45 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri Jun 19 14:07:48 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file +This report was generated on **Fri Aug 14 14:46:51 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/pom.xml b/pom.xml index 886cc359469..eea537e584a 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ all modules and does not describe the project structure per-subproject. io.spine spine-core-java -1.5.21 +1.5.24 2015 @@ -70,25 +70,25 @@ all modules and does not describe the project structure per-subproject. io.spine spine-base - 1.5.19 + 1.5.23 compile io.spine spine-time - 1.5.19 + 1.5.21 compile io.spine.tools spine-model-compiler - 1.5.19 + 1.5.23 compile io.spine.tools spine-plugin-base - 1.5.19 + 1.5.23 compile @@ -130,25 +130,25 @@ all modules and does not describe the project structure per-subproject. io.spine spine-testlib - 1.5.19 + 1.5.23 test io.spine spine-testutil-time - 1.5.19 + 1.5.21 test io.spine.tools spine-mute-logging - 1.5.19 + 1.5.23 test io.spine.tools spine-plugin-testlib - 1.5.19 + 1.5.23 test @@ -204,12 +204,12 @@ all modules and does not describe the project structure per-subproject. io.spine.tools spine-javadoc-filter - 1.5.19 + 1.5.23 io.spine.tools spine-protoc-plugin - 1.5.19 + 1.5.23 net.sourceforge.pmd diff --git a/server/src/test/java/io/spine/client/ClientTest.java b/server/src/test/java/io/spine/client/ClientTest.java index b861f914edf..8ea6623d1f9 100644 --- a/server/src/test/java/io/spine/client/ClientTest.java +++ b/server/src/test/java/io/spine/client/ClientTest.java @@ -177,7 +177,7 @@ void byId() { .build(); client.asGuest() .command(command) - .post(); + .postAndForget(); ImmutableList users = client.onBehalfOf(user) .select(ActiveUsers.class) diff --git a/server/src/test/java/io/spine/client/CommandRequestTest.java b/server/src/test/java/io/spine/client/CommandRequestTest.java index 8a36b3df5ac..41d2b05b95d 100644 --- a/server/src/test/java/io/spine/client/CommandRequestTest.java +++ b/server/src/test/java/io/spine/client/CommandRequestTest.java @@ -45,6 +45,7 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; @MuteLogging @@ -78,139 +79,182 @@ protected ImmutableList contexts() { return ImmutableList.of(ClientTestContext.users()); } - @Test - @DisplayName("deliver an event to a consumer") - void eventConsumer() { - commandRequest.observe(UserLoggedIn.class, counter::add) - .observe(UserAccountCreated.class, counter::add) - .post(); - assertThat(counter.containsAll(UserLoggedIn.class, UserAccountCreated.class)) - .isTrue(); - } - - @Test - @DisplayName("deliver an event and its context to a consumer") - void eventAndContextConsumer() { - commandRequest.observe(UserLoggedIn.class, (e, c) -> counter.add(e)) - .observe(UserAccountCreated.class, (e, c) -> counter.add(e)) - .post(); - assertThat(counter.containsAll(UserLoggedIn.class, UserAccountCreated.class)) - .isTrue(); - } - - @Test - @DisplayName("deliver a rejection to its consumers") - void rejections() { - // Post the command so that the user is logged in. We are not interested in events here. - commandRequest.post(); - // Now post the command again, expecting the rejection. - commandRequest.observe(UserAlreadyLoggedIn.class, counter::add) - .post(); - - assertThat(counter.contains(UserAlreadyLoggedIn.class)) - .isTrue(); - } - @Nested - @DisplayName("Allow setting custom streaming error handler") - class CustomStreamingErrorHandler { + @DisplayName("Allow posting without subscriptions") + class NoSubscriptions { @Test - @DisplayName("rejecting `null`") - void rejectingNull() { - assertThrows(NullPointerException.class, () -> commandRequest.onStreamingError(null)); + @DisplayName("Rejecting when a subscription was made") + void illegalUse() { + commandRequest.observe(UserLoggedIn.class, counter::add); + assertThrows( + IllegalStateException.class, + () -> commandRequest.postAndForget() + ); + } + + @Test + @DisplayName("Delivering no events") + void noEvents() { + assertDoesNotThrow(() -> commandRequest.postAndForget()); } } @Nested - @DisplayName("Allow setting custom consumer error handler") - class CustomConsumerErrorHandler { + @DisplayName("Deliver") + class OfDelivery { - private boolean handlerInvoked; - private @Nullable Throwable passedThrowable; - - @BeforeEach - void setup() { - handlerInvoked = false; - passedThrowable = null; + @Test + @DisplayName("an event to a consumer") + void eventConsumer() { + commandRequest.observe(UserLoggedIn.class, counter::add) + .observe(UserAccountCreated.class, counter::add) + .post(); + assertDelivered(UserLoggedIn.class, UserAccountCreated.class); } @Test - @DisplayName("rejecting `null`") - void rejectingNull() { - assertThrows(NullPointerException.class, () -> commandRequest.onConsumingError(null)); + @DisplayName("an event and its context to a consumer") + void eventAndContextConsumer() { + commandRequest.observe(UserLoggedIn.class, (e, c) -> counter.add(e)) + .observe(UserAccountCreated.class, (e, c) -> counter.add(e)) + .post(); + assertDelivered(UserLoggedIn.class, UserAccountCreated.class); } @Test - @DisplayName("invoking the handler when a consumer fails") - void invocation() { - ConsumerErrorHandler handler = (c, th) -> { - handlerInvoked = true; - passedThrowable = th; - }; - RuntimeException exception = new RuntimeException("Consumer-generated error."); - - commandRequest.onConsumingError(handler) - .observe(UserLoggedIn.class, e -> { - throw exception; - }) + @DisplayName("a rejection to its consumers") + void rejections() { + // Post the command so that the user is logged in. We are not interested in events here. + commandRequest.postAndForget(); + // Now post the command again, expecting the rejection. + commandRequest.observe(UserAlreadyLoggedIn.class, counter::add) .post(); - assertThat(handlerInvoked) + assertDelivered(UserAlreadyLoggedIn.class); + } + + @SafeVarargs + private final void assertDelivered(Class... classes) { + assertThat(counter.containsAll(classes)) .isTrue(); - assertThat(passedThrowable) - .isEqualTo(exception); } } + @Test + @DisplayName("Suggest `postAndForget()` call if no subscriptions were made") + void noSubscriptions() { + assertThrows( + IllegalStateException.class, + () -> commandRequest.post() + ); + } + @Nested - @DisplayName("Allow setting custom posting error handler") - class CustomServerErrorHandler { + @DisplayName("Support custom error handler for") + class OfErrorHandler { - private @Nullable Message postedMessage; - private @Nullable Error returnedError; + @Nested + @DisplayName("streaming error") + class CustomStreamingErrorHandler { - @BeforeEach - void setup() { - postedMessage = null; - returnedError = null; + @Test + @DisplayName("rejecting `null`") + void rejectingNull() { + assertThrows(NullPointerException.class, () -> commandRequest.onStreamingError(null)); + } } - @Test - @DisplayName("rejecting `null`") - void rejectingNull() { - assertThrows(NullPointerException.class, () -> commandRequest.onServerError(null)); + @Nested + @DisplayName("consumer error") + class CustomConsumerErrorHandler { + + private boolean handlerInvoked; + private @Nullable Throwable passedThrowable; + + @BeforeEach + void setup() { + handlerInvoked = false; + passedThrowable = null; + } + + @Test + @DisplayName("rejecting `null`") + void rejectingNull() { + assertThrows(NullPointerException.class, () -> commandRequest.onConsumingError(null)); + } + + @Test + @DisplayName("invoking the handler when a consumer fails") + void invocation() { + ConsumerErrorHandler handler = (c, th) -> { + handlerInvoked = true; + passedThrowable = th; + }; + RuntimeException exception = new RuntimeException("Consumer-generated error."); + + commandRequest.onConsumingError(handler) + .observe(UserLoggedIn.class, e -> { + throw exception; + }) + .post(); + + assertThat(handlerInvoked) + .isTrue(); + assertThat(passedThrowable) + .isEqualTo(exception); + } } - @Test - @DisplayName("invoking handler when an invalid command posted") - void invocation() { - ServerErrorHandler handler = (message, error) -> { - postedMessage = message; - returnedError = error; - }; - - UnsupportedCommand commandMessage = UnsupportedCommand - .newBuilder() - .setUser(GivenUserId.generated()) - .build(); - CommandRequest request = - client().asGuest() - .command(commandMessage) - .onServerError(handler); - request.post(); - - assertThat(returnedError) - .isNotNull(); - assertThat(postedMessage) - .isInstanceOf(Command.class); - Command expected = Command - .newBuilder() - .setMessage(AnyPacker.pack(commandMessage)) - .build(); - assertThat(postedMessage) - .comparingExpectedFieldsOnly() - .isEqualTo(expected); + @Nested + @DisplayName("posting error") + class CustomServerErrorHandler { + + private @Nullable Message postedMessage; + private @Nullable Error returnedError; + + @BeforeEach + void setup() { + postedMessage = null; + returnedError = null; + } + + @Test + @DisplayName("rejecting `null`") + void rejectingNull() { + assertThrows(NullPointerException.class, () -> commandRequest.onServerError(null)); + } + + @Test + @DisplayName("invoking handler when an invalid command posted") + void invocation() { + ServerErrorHandler handler = (message, error) -> { + postedMessage = message; + returnedError = error; + }; + + UnsupportedCommand commandMessage = UnsupportedCommand + .newBuilder() + .setUser(GivenUserId.generated()) + .build(); + CommandRequest request = + client().asGuest() + .command(commandMessage) + .onServerError(handler); + request.postAndForget(); + + assertThat(returnedError) + .isNotNull(); + assertThat(postedMessage) + .isInstanceOf(Command.class); + Command expected = Command + .newBuilder() + .setMessage(AnyPacker.pack(commandMessage)) + .build(); + assertThat(postedMessage) + .comparingExpectedFieldsOnly() + .isEqualTo(expected); + } } } } diff --git a/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java b/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java index e43e3ef3f15..1e01b956fe8 100644 --- a/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java +++ b/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java @@ -85,7 +85,7 @@ void observeEventMessage() { .subscribeToEvent(UserLoggedIn.class) .observe(counter::add) .post(); - commandRequest.post(); + commandRequest.postAndForget(); assertThat(counter.contains(UserLoggedIn.class)) .isTrue(); @@ -113,7 +113,7 @@ void subscribeWithFiltering() { rememberedContext = c; }) .post(); - commandRequest.post(); + commandRequest.postAndForget(); } @Test diff --git a/version.gradle.kts b/version.gradle.kts index 7df954d300b..f276dd5c548 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -25,6 +25,6 @@ * as we want to manage the versions in a single source. */ -val spineBaseVersion: String by extra("1.5.21") +val spineBaseVersion: String by extra("1.5.23") val spineTimeVersion: String by extra("1.5.21") -val versionToPublish: String by extra("1.5.23") +val versionToPublish: String by extra("1.5.24")