Skip to content

Commit

Permalink
Merge pull request #1402 from SpineEventEngine/integration-bus-feature
Browse files Browse the repository at this point in the history
Enable IntegrationBroker dispatch events regardless of registration order of subscribing and publishing BCs
  • Loading branch information
yevhenii-nadtochii authored Oct 21, 2021
2 parents 2cfad47 + 8bf4de1 commit 3893bf1
Showing 38 changed files with 584 additions and 1,122 deletions.
2 changes: 1 addition & 1 deletion .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 16 additions & 16 deletions license-report.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@


# Dependencies of `io.spine:spine-client:1.7.7-SNAPSHOT.0`
# Dependencies of `io.spine:spine-client:1.7.7-SNAPSHOT.2`

## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -399,12 +399,12 @@
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Sep 28 16:46:52 EEST 2021** 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 **Thu Oct 21 16:54:26 EEST 2021** 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.7.7-SNAPSHOT.0`
# Dependencies of `io.spine:spine-core:1.7.7-SNAPSHOT.2`

## Runtime
1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
@@ -763,12 +763,12 @@ This report was generated on **Tue Sep 28 16:46:52 EEST 2021** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Sep 28 16:46:52 EEST 2021** 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 **Thu Oct 21 16:54:26 EEST 2021** 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.7.7-SNAPSHOT.0`
# Dependencies of `io.spine.tools:spine-model-assembler:1.7.7-SNAPSHOT.2`

## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -1162,12 +1162,12 @@ This report was generated on **Tue Sep 28 16:46:52 EEST 2021** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Sep 28 16:46:52 EEST 2021** 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 **Thu Oct 21 16:54:27 EEST 2021** 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.7.7-SNAPSHOT.0`
# Dependencies of `io.spine.tools:spine-model-verifier:1.7.7-SNAPSHOT.2`

## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -1627,12 +1627,12 @@ This report was generated on **Tue Sep 28 16:46:52 EEST 2021** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Sep 28 16:46:53 EEST 2021** 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 **Thu Oct 21 16:54:27 EEST 2021** 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.7.7-SNAPSHOT.0`
# Dependencies of `io.spine:spine-server:1.7.7-SNAPSHOT.2`

## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -2039,12 +2039,12 @@ This report was generated on **Tue Sep 28 16:46:53 EEST 2021** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Sep 28 16:46:53 EEST 2021** 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 **Thu Oct 21 16:54:27 EEST 2021** 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.7.7-SNAPSHOT.0`
# Dependencies of `io.spine:spine-testutil-client:1.7.7-SNAPSHOT.2`

## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -2493,12 +2493,12 @@ This report was generated on **Tue Sep 28 16:46:53 EEST 2021** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Sep 28 16:46:54 EEST 2021** 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 **Thu Oct 21 16:54:29 EEST 2021** 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.7.7-SNAPSHOT.0`
# Dependencies of `io.spine:spine-testutil-core:1.7.7-SNAPSHOT.2`

## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -2947,12 +2947,12 @@ This report was generated on **Tue Sep 28 16:46:54 EEST 2021** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Sep 28 16:46:55 EEST 2021** 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 **Thu Oct 21 16:54:30 EEST 2021** 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.7.7-SNAPSHOT.0`
# Dependencies of `io.spine:spine-testutil-server:1.7.7-SNAPSHOT.2`

## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -3445,4 +3445,4 @@ This report was generated on **Tue Sep 28 16:46:55 EEST 2021** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Tue Sep 28 16:46:57 EEST 2021** 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 **Thu Oct 21 16:54:32 EEST 2021** 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).
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ all modules and does not describe the project structure per-subproject.

<groupId>io.spine</groupId>
<artifactId>spine-core-java</artifactId>
<version>1.7.7-SNAPSHOT.0</version>
<version>1.7.7-SNAPSHOT.2</version>

<inceptionYear>2015</inceptionYear>

18 changes: 14 additions & 4 deletions server/src/main/java/io/spine/server/BoundedContext.java
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@
*/
package io.spine.server;

import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.spine.annotation.Internal;
import io.spine.base.EntityState;
import io.spine.core.BoundedContextName;
@@ -482,7 +483,7 @@ public final InternalAccess internalAccess() {
* Provides access to features of {@link BoundedContext} used internally by the framework.
*/
@Internal
public class InternalAccess {
public final class InternalAccess {

/** Prevents instantiation from outside. */
private InternalAccess() {
@@ -491,28 +492,37 @@ private InternalAccess() {
/**
* Registers the passed repository.
*
* @return this instance of {@code InternalAccess} for call chaining
* @see BoundedContext#register(Repository)
*/
public void register(Repository<?, ?> repository) {
@CanIgnoreReturnValue
public InternalAccess register(Repository<?, ?> repository) {
self().register(checkNotNull(repository));
return this;
}

/**
* Registers the passed command dispatcher.
*
* @return this instance of {@code InternalAccess} for call chaining
* @see BoundedContext#registerCommandDispatcher(CommandDispatcher)
*/
public void registerCommandDispatcher(CommandDispatcher dispatcher) {
@CanIgnoreReturnValue
public InternalAccess registerCommandDispatcher(CommandDispatcher dispatcher) {
self().registerCommandDispatcher(checkNotNull(dispatcher));
return this;
}

/**
* Registers the passed event dispatcher.
*
* @return this instance of {@code InternalAccess} for call chaining
* @see BoundedContext#registerEventDispatcher(EventDispatcher)
*/
public void registerEventDispatcher(EventDispatcher dispatcher) {
@CanIgnoreReturnValue
public InternalAccess registerEventDispatcher(EventDispatcher dispatcher) {
self().registerEventDispatcher(dispatcher);
return this;
}

/**
2 changes: 1 addition & 1 deletion server/src/main/java/io/spine/server/ContextAware.java
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@
import static com.google.common.base.Preconditions.checkState;

/**
* An structural part of a Bounded Context which is aware of the other parts.
* A structural part of a Bounded Context which is aware of the other parts.
*/
@Internal
public interface ContextAware {
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@

/**
* Base routines for the {@linkplain Subscriber#addObserver(StreamObserver)}
* subscriber observers}.
* subscriber observers.
*/
@SPI
public abstract class AbstractChannelObserver implements StreamObserver<ExternalMessage>, Logging {
Original file line number Diff line number Diff line change
@@ -73,7 +73,7 @@ void unregister(Class<? extends Message> messageClass) {
* the given class.
*
* <p>The created dispatcher is serving as a listener, notifying the {@code IntegrationBroker}
* of the messages, that are requested by the collaborators outside of this bounded context.
* of the messages, that are requested by the collaborators outside this bounded context.
*
* @param messageClass
* the class of message to be dispatched by the created dispatcher
Original file line number Diff line number Diff line change
@@ -87,13 +87,27 @@ static ExternalMessage of(RequestForExternalMessages request, BoundedContextName
checkNotNull(request);
checkNotNull(origin);

String idString = Identifier.newUuid();
ExternalMessage result = of(StringValue.newBuilder()
.setValue(idString)
.build(),
request,
origin);
return result;
return of(generateMessageId(), request, origin);
}

/**
* Wraps the instance of {@link ExternalMessagesSourceAvailable} into an {@code ExternalMessage}.
*
* @param notification the notification to wrap
* @param origin the name of a bounded context in which the notification was created
* @return the external message wrapping the given notification
*/
static ExternalMessage of(ExternalMessagesSourceAvailable notification, BoundedContextName origin) {
checkNotNull(notification);
checkNotNull(origin);

return of(generateMessageId(), notification, origin);
}

private static StringValue generateMessageId() {
return StringValue.newBuilder()
.setValue(Identifier.newUuid())
.build();
}

private static ExternalMessage of(Message messageId,
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@
* (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.integration;

import com.google.common.collect.HashMultimap;
@@ -32,30 +33,23 @@
import io.spine.core.BoundedContextName;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static io.spine.protobuf.AnyPacker.unpack;
import static java.util.Collections.synchronizedSet;

/**
* An observer, which reacts to the configuration update messages sent by
* external entities (such as {@code IntegrationBroker}s of other bounded contexts).
* Reacts on {@code RequestForExternalMessages} sent by other parties (usually Bounded Contexts)
* in a multi-component environment.
*
* @see #handle(ExternalMessage)
*/
final class ConfigurationChangeObserver
final class ExternalNeedsObserver
extends AbstractChannelObserver
implements AutoCloseable {

private final IntegrationBroker broker;
private final BoundedContextName boundedContextName;
private final BusAdapter adapter;

/**
* Names of Bounded Contexts already known to this observer.
*
* <p>If a context is unknown, the observer publishes a {@code RequestForExternalMessages}.
*/
private final Set<BoundedContextName> knownContexts = synchronizedSet(new HashSet<>());
private final BusAdapter bus;

/**
* Current set of message type URLs, requested by other parties via sending the
@@ -65,38 +59,28 @@ final class ConfigurationChangeObserver
private final Multimap<ExternalMessageType, BoundedContextName> requestedTypes =
HashMultimap.create();

ConfigurationChangeObserver(IntegrationBroker broker,
BoundedContextName boundedContextName,
BusAdapter adapter) {
super(boundedContextName, RequestForExternalMessages.class);
this.broker = broker;
this.boundedContextName = boundedContextName;
this.adapter = adapter;
this.knownContexts.add(boundedContextName);
ExternalNeedsObserver(BoundedContextName context, BusAdapter bus) {
super(context, RequestForExternalMessages.class);
this.boundedContextName = context;
this.bus = bus;
}

/**
* Handles the {@code RequestForExternalMessages} by creating local publishers for the requested
* types.
*
* <p>If the request originates from a previously unknown Bounded Context,
* {@linkplain IntegrationBroker#notifyOthers() publishes} the types requested by the current
* Context, since they may be unknown to the new Context.
*
* @param value
* {@link RequestForExternalMessages} form another Bounded Context
* Unpacks {@code RequestForExternalMessages} from the passed {@code ExternalMessage} and
* handles it by creating local publishers for the requested types and dismissing types
* that are no longer needed.
*/
@Override
public void handle(ExternalMessage value) {
RequestForExternalMessages request = unpack(value.getOriginalMessage(),
RequestForExternalMessages.class);
BoundedContextName origin = value.getBoundedContextName();
addNewSubscriptions(request.getRequestedMessageTypeList(), origin);
clearStaleSubscriptions(request.getRequestedMessageTypeList(), origin);
if (!knownContexts.contains(origin)) {
knownContexts.add(origin);
broker.notifyOthers();
}
public void handle(ExternalMessage message) {
BoundedContextName origin = message.getBoundedContextName();
RequestForExternalMessages request = unpack(
message.getOriginalMessage(),
RequestForExternalMessages.class
);

List<ExternalMessageType> externalTypes = request.getRequestedMessageTypeList();
addNewSubscriptions(externalTypes, origin);
clearStaleSubscriptions(externalTypes, origin);
}

private void addNewSubscriptions(Iterable<ExternalMessageType> types,
@@ -116,7 +100,7 @@ private void addNewSubscriptions(Iterable<ExternalMessageType> types,

private void registerInAdapter(ExternalMessageType newType) {
Class<? extends Message> messageClass = newType.asMessageClass();
adapter.register(messageClass);
bus.register(messageClass);
}

private void clearStaleSubscriptions(Collection<ExternalMessageType> types,
@@ -139,7 +123,7 @@ private void clearStaleSubscriptions(Collection<ExternalMessageType> types,

private void unregisterInAdapter(ExternalMessageType itemForRemoval) {
Class<? extends Message> messageClass = itemForRemoval.asMessageClass();
adapter.unregister(messageClass);
bus.unregister(messageClass);
}

private Set<ExternalMessageType> findStale(Collection<ExternalMessageType> types,
Loading

0 comments on commit 3893bf1

Please sign in to comment.