diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 5c2d1cf016b..cc4fdc293d0 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6ce793f21e8..94920145f34 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 83f2acfdc31..2fe81a7d95e 100755 --- a/gradlew +++ b/gradlew @@ -154,19 +154,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi @@ -175,14 +175,9 @@ save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=$(save "$@") +APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - exec "$JAVACMD" "$@" diff --git a/license-report.md b/license-report.md index bdeafa20e14..b5bb44402ee 100644 --- a/license-report.md +++ b/license-report.md @@ -1,6 +1,6 @@ -# Dependencies of `io.spine:spine-client:1.2.7` +# Dependencies of `io.spine:spine-client:1.2.8` ## Runtime 1. **Group:** com.google.api.grpc **Name:** proto-google-common-protos **Version:** 1.12.0 @@ -381,12 +381,12 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue Dec 03 17:19:27 EET 2019** 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 **Wed Dec 04 11:20:30 EET 2019** 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.2.7` +# Dependencies of `io.spine:spine-core:1.2.8` ## Runtime 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 @@ -743,12 +743,12 @@ This report was generated on **Tue Dec 03 17:19:27 EET 2019** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue Dec 03 17:19:27 EET 2019** 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 **Wed Dec 04 11:20:30 EET 2019** 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.2.7` +# Dependencies of `io.spine.tools:spine-model-assembler:1.2.8` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -1144,12 +1144,12 @@ This report was generated on **Tue Dec 03 17:19:27 EET 2019** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue Dec 03 17:19:28 EET 2019** 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 **Wed Dec 04 11:20:31 EET 2019** 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.2.7` +# Dependencies of `io.spine.tools:spine-model-verifier:1.2.8` ## Runtime 1. **Group:** aopalliance **Name:** aopalliance **Version:** 1.0 @@ -1699,12 +1699,12 @@ This report was generated on **Tue Dec 03 17:19:28 EET 2019** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue Dec 03 17:19:29 EET 2019** 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 **Wed Dec 04 11:20:31 EET 2019** 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.2.7` +# Dependencies of `io.spine:spine-server:1.2.8` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -2117,12 +2117,12 @@ This report was generated on **Tue Dec 03 17:19:29 EET 2019** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue Dec 03 17:19:29 EET 2019** 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 **Wed Dec 04 11:20:32 EET 2019** 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.2.7` +# Dependencies of `io.spine:spine-testutil-client:1.2.8` ## Runtime 1. **Group:** com.google.api.grpc **Name:** proto-google-common-protos **Version:** 1.12.0 @@ -2536,12 +2536,12 @@ This report was generated on **Tue Dec 03 17:19:29 EET 2019** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue Dec 03 17:19:30 EET 2019** 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 **Wed Dec 04 11:20:32 EET 2019** 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.2.7` +# Dependencies of `io.spine:spine-testutil-core:1.2.8` ## Runtime 1. **Group:** com.google.api.grpc **Name:** proto-google-common-protos **Version:** 1.12.0 @@ -2963,12 +2963,12 @@ This report was generated on **Tue Dec 03 17:19:30 EET 2019** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue Dec 03 17:19:30 EET 2019** 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 **Wed Dec 04 11:20:32 EET 2019** 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.2.7` +# Dependencies of `io.spine:spine-testutil-server:1.2.8` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -3466,4 +3466,4 @@ This report was generated on **Tue Dec 03 17:19:30 EET 2019** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue Dec 03 17:19:31 EET 2019** 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 **Wed Dec 04 11:20:33 EET 2019** 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 0dffa923d50..bb5703aed70 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.2.7 +1.2.8 2015 diff --git a/server/src/main/java/io/spine/server/event/model/EventHandlerMethod.java b/server/src/main/java/io/spine/server/event/model/EventHandlerMethod.java index bbf74c98e1b..dd880c471f5 100644 --- a/server/src/main/java/io/spine/server/event/model/EventHandlerMethod.java +++ b/server/src/main/java/io/spine/server/event/model/EventHandlerMethod.java @@ -20,22 +20,17 @@ package io.spine.server.event.model; -import com.google.protobuf.Message; -import io.spine.base.CommandMessage; import io.spine.base.EventMessage; import io.spine.server.model.AbstractHandlerMethod; import io.spine.server.model.DispatchKey; import io.spine.server.model.MethodParams; import io.spine.server.model.ParameterSpec; -import io.spine.server.type.CommandClass; import io.spine.server.type.EventClass; import io.spine.server.type.EventEnvelope; import io.spine.type.MessageClass; import java.lang.reflect.Method; -import static com.google.common.base.Preconditions.checkArgument; - /** * An abstract base for methods handling events. * @@ -45,52 +40,38 @@ * the type of the produced message classes */ public abstract class EventHandlerMethod> - extends AbstractHandlerMethod { + extends AbstractHandlerMethod + implements RejectionHandler { /** * Creates a new instance to wrap {@code method} on {@code target}. * - * @param method subscriber method + * @param method + * subscriber method */ EventHandlerMethod(Method method, ParameterSpec parameterSpec) { super(method, parameterSpec); } @Override - protected EventAcceptingMethodParams parameterSpec() { + public EventAcceptingMethodParams parameterSpec() { return (EventAcceptingMethodParams) super.parameterSpec(); } @Override public DispatchKey key() { - EventClass eventClass = messageClass(); - if (parameterSpec().acceptsCommand()) { - Class[] parameters = rawMethod().getParameterTypes(); - Class commandMessageClass = - castClass(parameters[1], CommandMessage.class); - CommandClass commandClass = CommandClass.from(commandMessageClass); - return new DispatchKey(eventClass.value(), null, commandClass.value()); - } else { - return super.key(); - } + return RejectionHandler.super.key(); } @Override public MethodParams params() { - if (parameterSpec().acceptsCommand()) { + if (RejectionHandler.super.handlesRejection()) { MethodParams result = MethodParams.of(rawMethod()); return result; } return super.params(); } - private static Class castClass(Class raw, Class targetBound) { - checkArgument(targetBound.isAssignableFrom(raw)); - @SuppressWarnings("unchecked") // Checked above. - Class result = (Class) raw; - return result; - } - /** * Ensures that the passed event matches the {@code external} attribute * of the method annotation. @@ -111,5 +92,4 @@ protected void checkAttributesMatch(EventEnvelope event) { .getExternal(); ensureExternalMatch(external); } - } diff --git a/server/src/main/java/io/spine/server/event/model/EventSubscriberMethod.java b/server/src/main/java/io/spine/server/event/model/EventSubscriberMethod.java index 50c20c6f0a7..a0ceb1dbec4 100644 --- a/server/src/main/java/io/spine/server/event/model/EventSubscriberMethod.java +++ b/server/src/main/java/io/spine/server/event/model/EventSubscriberMethod.java @@ -21,8 +21,11 @@ package io.spine.server.event.model; import com.google.errorprone.annotations.Immutable; +import io.spine.server.event.EventSubscriber; import io.spine.server.model.ArgumentFilter; +import io.spine.server.model.DispatchKey; import io.spine.server.model.ParameterSpec; +import io.spine.server.type.EmptyClass; import io.spine.server.type.EventEnvelope; import java.lang.reflect.Method; @@ -31,13 +34,25 @@ * A wrapper for an event subscriber method. */ @Immutable -public final class EventSubscriberMethod extends SubscriberMethod { +public final class EventSubscriberMethod extends SubscriberMethod + implements RejectionHandler { /** Creates a new instance. */ EventSubscriberMethod(Method method, ParameterSpec parameterSpec) { super(method, parameterSpec); } + @Override + public EventAcceptingMethodParams parameterSpec() { + return (EventAcceptingMethodParams) super.parameterSpec(); + } + + @Override + public DispatchKey key() { + DispatchKey dispatchKey = RejectionHandler.super.key(); + return applyFilter(dispatchKey); + } + @Override public ArgumentFilter createFilter() { ArgumentFilter result = ArgumentFilter.createFilter(rawMethod()); @@ -47,6 +62,6 @@ public ArgumentFilter createFilter() { @Override protected void checkAttributesMatch(EventEnvelope event) throws IllegalArgumentException { super.checkAttributesMatch(event); - ensureExternalMatch(event.context().getExternal()); + ensureExternalMatch(event.isExternal()); } } diff --git a/server/src/main/java/io/spine/server/event/model/RejectionDispatchKeys.java b/server/src/main/java/io/spine/server/event/model/RejectionDispatchKeys.java new file mode 100644 index 00000000000..3e4ba1ca3e9 --- /dev/null +++ b/server/src/main/java/io/spine/server/event/model/RejectionDispatchKeys.java @@ -0,0 +1,69 @@ +/* + * Copyright 2019, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.server.event.model; + +import io.spine.base.CommandMessage; +import io.spine.server.model.DispatchKey; +import io.spine.server.type.CommandClass; +import io.spine.server.type.EventClass; + +import java.lang.reflect.Method; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A helper utility class that allows creating {@link DispatchKey}s for rejection handling methods. + */ +final class RejectionDispatchKeys { + + /** Prevents instantiation of this utility class. **/ + private RejectionDispatchKeys() { + } + + /** + * Creates a new {@code DispatchKey} for a rejection handling method that accepts commands as + * a second parameter. + * + * @implSpec the developer is responsible for verifying that the method actually has a + * {@code CommandClass} type as a second parameter. + */ + static DispatchKey of(EventClass eventClass, Method rawMethod) { + checkNotNull(eventClass); + checkNotNull(rawMethod); + Class[] parameters = rawMethod.getParameterTypes(); + String methodName = rawMethod.getName(); + checkArgument(parameters.length >= 2, + "The method `%s` should have at least 2 parameters, but has `%s`.", + methodName, + parameters.length); + Class secondParameter = parameters[1]; + checkArgument(CommandMessage.class.isAssignableFrom(secondParameter), + "The method `%s` should have the second parameter assignable from `CommandMessage`, but has `%s`.", + methodName, + secondParameter); + @SuppressWarnings("unchecked") // checked above + Class commandMessageClass = + (Class) secondParameter; + CommandClass commandClass = CommandClass.from(commandMessageClass); + return new DispatchKey(eventClass.value(), null, commandClass.value()); + } +} diff --git a/server/src/main/java/io/spine/server/event/model/RejectionHandler.java b/server/src/main/java/io/spine/server/event/model/RejectionHandler.java new file mode 100644 index 00000000000..d98d186d040 --- /dev/null +++ b/server/src/main/java/io/spine/server/event/model/RejectionHandler.java @@ -0,0 +1,61 @@ +/* + * Copyright 2019, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.server.event.model; + +import com.google.errorprone.annotations.Immutable; +import io.spine.server.model.DispatchKey; +import io.spine.server.model.HandlerMethod; +import io.spine.server.type.EventClass; +import io.spine.server.type.EventEnvelope; +import io.spine.type.MessageClass; + +/** + * A handler method that may handle rejections. + */ +@Immutable +interface RejectionHandler> + extends HandlerMethod { + + /** + * Obtains the specification of parameters for this method. + */ + EventAcceptingMethodParams parameterSpec(); + + /** Tells whether the handler method is for a rejection. **/ + default boolean handlesRejection() { + return parameterSpec().acceptsCommand(); + } + + /** + * {@inheritDoc} + * + *

In case this method is declared to handle a rejection, a rejection-specific + * dispatch key is created. + */ + @Override + default DispatchKey key() { + if (handlesRejection()) { + DispatchKey dispatchKey = RejectionDispatchKeys.of(messageClass(), rawMethod()); + return dispatchKey; + } + return HandlerMethod.super.key(); + } +} diff --git a/server/src/main/java/io/spine/server/event/model/StateSubscriberMethod.java b/server/src/main/java/io/spine/server/event/model/StateSubscriberMethod.java index ad33dfc53f9..837a5f92751 100644 --- a/server/src/main/java/io/spine/server/event/model/StateSubscriberMethod.java +++ b/server/src/main/java/io/spine/server/event/model/StateSubscriberMethod.java @@ -30,6 +30,7 @@ import io.spine.core.BoundedContextName; import io.spine.logging.Logging; import io.spine.server.model.ArgumentFilter; +import io.spine.server.model.DispatchKey; import io.spine.server.model.Model; import io.spine.server.model.ParameterSpec; import io.spine.server.type.EventEnvelope; @@ -59,6 +60,12 @@ public final class StateSubscriberMethod extends SubscriberMethod implements Log checkExternal(); } + @Override + public DispatchKey key() { + DispatchKey typeBasedKey = super.key(); + return applyFilter(typeBasedKey); + } + private static Method checkNotFiltered(Method method) { ArgumentFilter filter = ArgumentFilter.createFilter(method); checkState(filter.acceptsAll(), @@ -95,7 +102,7 @@ protected Class rawMessageClass() { } @SuppressWarnings("TestOnlyProblems") - // Checks that the resulting context is not `AssumingTests` in production environment. + // Checks that the resulting context is not `AssumingTests` in production environment. private BoundedContextName contextOf(Class cls) { Model model = Model.inContextOf(cls); BoundedContextName name = model.contextName(); diff --git a/server/src/main/java/io/spine/server/event/model/SubscriberMethod.java b/server/src/main/java/io/spine/server/event/model/SubscriberMethod.java index 433498cec1b..4c1bedb1409 100644 --- a/server/src/main/java/io/spine/server/event/model/SubscriberMethod.java +++ b/server/src/main/java/io/spine/server/event/model/SubscriberMethod.java @@ -21,6 +21,7 @@ package io.spine.server.event.model; import com.google.errorprone.annotations.Immutable; +import io.spine.annotation.Internal; import io.spine.base.EventMessage; import io.spine.server.event.EventSubscriber; import io.spine.server.model.AbstractHandlerMethod; @@ -63,13 +64,16 @@ protected SubscriberMethod(Method method, ParameterSpec parameter super(method, parameterSpec); } - @Override - public DispatchKey key() { - DispatchKey typeBasedKey = super.key(); + /** + * Applies {@link #filter() filter} if a specific one is supplied. Otherwise returns the + * supplied {@code key}. + */ + @Internal + DispatchKey applyFilter(DispatchKey key) { ArgumentFilter filter = filter(); return filter.acceptsAll() - ? typeBasedKey - : typeBasedKey.withFilter(filter); + ? key + : key.withFilter(filter); } @Override @@ -98,7 +102,8 @@ public final ArgumentFilter filter() { *

It is assumed that the type of the event is correct and only the field filter should be * checked. * - * @param event the event to check + * @param event + * the event to check * @return {@code true} if this method can handle the given event, {@code false} otherwise */ final boolean canHandle(EventEnvelope event) { diff --git a/server/src/main/java/io/spine/server/model/HandlerMethod.java b/server/src/main/java/io/spine/server/model/HandlerMethod.java index 4d71b2dd756..9ebdcf45f51 100644 --- a/server/src/main/java/io/spine/server/model/HandlerMethod.java +++ b/server/src/main/java/io/spine/server/model/HandlerMethod.java @@ -139,6 +139,9 @@ default void ensureExternalMatch(boolean expectedValue) throws SignalOriginMisma } } + /** + * Creates a handler method dispatch key out of the {@linkplain #messageClass() message class}. + */ default DispatchKey key() { Class rawCls = messageClass().value(); return new DispatchKey(rawCls, null, null); diff --git a/server/src/test/java/io/spine/server/event/model/RejectionDispatchKeysTest.java b/server/src/test/java/io/spine/server/event/model/RejectionDispatchKeysTest.java new file mode 100644 index 00000000000..b19c25fb657 --- /dev/null +++ b/server/src/test/java/io/spine/server/event/model/RejectionDispatchKeysTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2019, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.server.event.model; + +import io.spine.model.contexts.projects.rejection.ProjectRejections.SigCannotCreateProject; +import io.spine.server.event.model.given.subscriber.RejectionSubscriber; +import io.spine.server.type.EventClass; +import io.spine.testing.UtilityClassTest; +import io.spine.testing.server.model.ModelTests; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Method; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@DisplayName("`RejectionDispatchKeys` should") +final class RejectionDispatchKeysTest extends UtilityClassTest { + + RejectionDispatchKeysTest() { + super(RejectionDispatchKeys.class); + } + + @SuppressWarnings("ResultOfMethodCallIgnored") + @Test + @DisplayName("create a valid key") + void createValidKey() { + assertDoesNotThrow(() -> { + Method method = ModelTests.getMethod(RejectionSubscriber.class, "rejectionWithCommand"); + RejectionDispatchKeys.of(EventClass.from(SigCannotCreateProject.class), method); + }); + assertDoesNotThrow(() -> { + Method method = ModelTests.getMethod(RejectionSubscriber.class, + "rejectionWithCommandAndCtx"); + RejectionDispatchKeys.of(EventClass.from(SigCannotCreateProject.class), method); + }); + } + + @SuppressWarnings("ResultOfMethodCallIgnored") + @Test + @DisplayName("not create keys for rejections without a cause") + void notCreateKeyForRejectionsWithoutCause() { + assertThrows(IllegalArgumentException.class, () -> { + Method method = ModelTests.getMethod(RejectionSubscriber.class, + "rejectionWithoutCommand"); + RejectionDispatchKeys.of(EventClass.from(SigCannotCreateProject.class), method); + }); + assertThrows(IllegalArgumentException.class, () -> { + Method method = ModelTests.getMethod(RejectionSubscriber.class, "rejectionWithCtx"); + RejectionDispatchKeys.of(EventClass.from(SigCannotCreateProject.class), method); + }); + } +} diff --git a/server/src/test/java/io/spine/server/event/model/given/subscriber/RejectionSubscriber.java b/server/src/test/java/io/spine/server/event/model/given/subscriber/RejectionSubscriber.java new file mode 100644 index 00000000000..1ddf66ba910 --- /dev/null +++ b/server/src/test/java/io/spine/server/event/model/given/subscriber/RejectionSubscriber.java @@ -0,0 +1,57 @@ +/* + * Copyright 2019, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.server.event.model.given.subscriber; + +import io.spine.core.CommandContext; +import io.spine.core.Subscribe; +import io.spine.model.contexts.projects.command.SigCreateProject; +import io.spine.model.contexts.projects.rejection.ProjectRejections.SigCannotCreateProject; +import io.spine.server.event.AbstractEventSubscriber; + +/** + * A subscriber that has Rejection events subscriptions. + */ +public final class RejectionSubscriber extends AbstractEventSubscriber { + + @Subscribe + void rejectionWithCommand(SigCannotCreateProject rejection, + SigCreateProject command) { + // do nothing. + } + + @Subscribe + void rejectionWithCommandAndCtx(SigCannotCreateProject rejection, + SigCreateProject cmd, + CommandContext ctx) { + // do nothing. + } + + @Subscribe + void rejectionWithoutCommand(SigCannotCreateProject rejection) { + // do nothing. + } + + @Subscribe + void rejectionWithCtx(SigCannotCreateProject rejection, + CommandContext ctx) { + // do nothing. + } +} diff --git a/server/src/test/java/io/spine/server/model/MethodScanTest.java b/server/src/test/java/io/spine/server/model/MethodScanTest.java index ef5f40b386a..8086d68b478 100644 --- a/server/src/test/java/io/spine/server/model/MethodScanTest.java +++ b/server/src/test/java/io/spine/server/model/MethodScanTest.java @@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableSetMultimap; import io.spine.server.event.model.SubscriberMethod; import io.spine.server.event.model.SubscriberSignature; +import io.spine.server.model.given.map.ARejectionSubscriber; import io.spine.server.model.given.map.FilteredSubscription; import io.spine.string.StringifierRegistry; import io.spine.string.Stringifiers; @@ -30,6 +31,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import static com.google.common.truth.Truth.assertThat; import static io.spine.server.model.MethodScan.findMethodsBy; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -53,4 +55,12 @@ void noFiltersInKeys() { map.keySet() .forEach(key -> assertEquals(key.withoutFilter(), key)); } + + @Test + @DisplayName("allow multiple subscriptions to the same rejection with different causes") + void multipleRejectionSubscriptions() { + ImmutableSetMultimap map = + findMethodsBy(ARejectionSubscriber.class, new SubscriberSignature()); + assertThat(map.keys()).hasSize(2); + } } diff --git a/server/src/test/java/io/spine/server/model/given/map/ARejectionSubscriber.java b/server/src/test/java/io/spine/server/model/given/map/ARejectionSubscriber.java new file mode 100644 index 00000000000..2020a3d3d2e --- /dev/null +++ b/server/src/test/java/io/spine/server/model/given/map/ARejectionSubscriber.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.server.model.given.map; + +import io.spine.core.Subscribe; +import io.spine.model.contexts.projects.command.SigCreateProject; +import io.spine.model.contexts.projects.command.SigStartProject; +import io.spine.model.contexts.projects.rejection.ProjectRejections; +import io.spine.server.event.AbstractEventSubscriber; + +public class ARejectionSubscriber extends AbstractEventSubscriber { + + @Subscribe + void handle2(ProjectRejections.SigCannotCreateProject rejection, SigCreateProject cmd) { + // do nothing. + } + + @Subscribe + void handle(ProjectRejections.SigCannotCreateProject rejection, SigStartProject cmd) { + // do nothing. + } +} diff --git a/version.gradle b/version.gradle index 9fc8129c101..e84a1cc4485 100644 --- a/version.gradle +++ b/version.gradle @@ -25,7 +25,7 @@ * as we want to manage the versions in a single source. */ -final def spineVersion = '1.2.7' +final def spineVersion = '1.2.8' ext { // The version of the modules in this project.