Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import third-party events #1152

Merged
merged 51 commits into from
Sep 4, 2019
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
ac42ada
Fix Javadoc wrapping
dmdashenkov Aug 29, 2019
f4772e8
Remove empty line
dmdashenkov Aug 29, 2019
843424b
Remove empty line
dmdashenkov Aug 29, 2019
d4a368d
Outline event import API
dmdashenkov Aug 29, 2019
0de37a8
Implement funnels posing events into a bounded context
dmdashenkov Aug 30, 2019
d1cf0d6
Merge branch 'master' into import-3d-party-events
dmdashenkov Aug 30, 2019
94f5874
Update config
dmdashenkov Aug 30, 2019
4e4805b
Fix typos
dmdashenkov Aug 30, 2019
c84972b
Simplify EventFunnels
dmdashenkov Aug 30, 2019
83e2d39
Mark `TestEventFactory` as visible for testing
dmdashenkov Aug 30, 2019
8e159d3
Add test env for event funnel tests
dmdashenkov Aug 30, 2019
9c25007
Re-enable tests
dmdashenkov Aug 30, 2019
7c34cb9
Add tests for importing events into an aggregate
dmdashenkov Aug 30, 2019
35701ee
Re-enable and fix a test
dmdashenkov Aug 30, 2019
e97c8d1
Fix test domain
dmdashenkov Aug 31, 2019
83a9195
Add error logging
dmdashenkov Aug 31, 2019
5a0a67a
Add a test for importing external events
dmdashenkov Aug 31, 2019
c2fea8f
Add more tests for EventFunnel
dmdashenkov Aug 31, 2019
39fa1ab
Add tests for multitenancy
dmdashenkov Aug 31, 2019
5ef8dc4
Document new API
dmdashenkov Aug 31, 2019
8bec505
Fix a test
dmdashenkov Aug 31, 2019
7b1c966
Update report
dmdashenkov Aug 31, 2019
2cecbf7
Merge branch 'master' into import-3d-party-events
dmdashenkov Sep 2, 2019
7386d35
Update config
dmdashenkov Sep 2, 2019
be3b949
Add doc for test env
dmdashenkov Sep 2, 2019
3da6d17
Delete EventFunnel API and introduce ThirdPartyContext
dmdashenkov Sep 2, 2019
67ed608
Remove `Outside` context name
dmdashenkov Sep 2, 2019
405f676
Make ThirdPartyContext detached from a specific tenant
dmdashenkov Sep 2, 2019
d8e7007
Avoid storing external events twice
dmdashenkov Sep 2, 2019
aa0f693
Turn off all system features for `ThirdPartyContext`
dmdashenkov Sep 2, 2019
1ea31f1
Document ThirdPartyContext
dmdashenkov Sep 2, 2019
9bd7599
Improve doc
dmdashenkov Sep 2, 2019
8894d6c
Clean up
dmdashenkov Sep 2, 2019
bf08008
Add more tests
dmdashenkov Sep 2, 2019
48766d7
Extract document ID
dmdashenkov Sep 2, 2019
d92a6b8
Reset server env after each test
dmdashenkov Sep 3, 2019
b340993
Improve doc
dmdashenkov Sep 3, 2019
8288e6c
Add required precondition checks.
dmdashenkov Sep 4, 2019
0e26690
Delegate event creation to `EventFactory`
dmdashenkov Sep 4, 2019
708dc0b
Add a test for checking that a HandlerMap does not contain duplicates
dmdashenkov Sep 4, 2019
9bdc2ba
Throw a ModelError if the HandlerMap is corrupted
dmdashenkov Sep 4, 2019
b39f53b
Rename `notifyOfCurrentNeeds` to `introduceSelf`
dmdashenkov Sep 4, 2019
5da84f0
Swap params in `ThirdPartyContext.emittedEvent`
dmdashenkov Sep 4, 2019
0fc181b
Change version to 1.0.7-SNAPSHOT
dmdashenkov Sep 4, 2019
922e81e
Use test env types instead of exposing internal API for tests
dmdashenkov Sep 4, 2019
0c93249
Simplify method count check
dmdashenkov Sep 4, 2019
32f37a6
List all methods in the error message
dmdashenkov Sep 4, 2019
aaae84e
Change version to 1.0.6-SNAPSHOT
dmdashenkov Sep 4, 2019
300197b
Add instructions to the error message
dmdashenkov Sep 4, 2019
cb400a3
Remove redundant copying
dmdashenkov Sep 4, 2019
e0f85cb
Improve naming in `IntegrationBus`
dmdashenkov Sep 4, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .idea/dictionaries/common.xml

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

13 changes: 10 additions & 3 deletions .idea/inspectionProfiles/Project_Default.xml

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

16 changes: 8 additions & 8 deletions license-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Sun Sep 01 13:04:20 EEST 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 Sep 04 11:10:23 EEST 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).



Expand Down Expand Up @@ -865,7 +865,7 @@ This report was generated on **Sun Sep 01 13:04:20 EEST 2019** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Sun Sep 01 13:04:20 EEST 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 Sep 04 11:10:24 EEST 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).



Expand Down Expand Up @@ -1321,7 +1321,7 @@ This report was generated on **Sun Sep 01 13:04:20 EEST 2019** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Sun Sep 01 13:04:21 EEST 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 Sep 04 11:10:25 EEST 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).



Expand Down Expand Up @@ -1939,7 +1939,7 @@ This report was generated on **Sun Sep 01 13:04:21 EEST 2019** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Sun Sep 01 13:04:22 EEST 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 Sep 04 11:10:26 EEST 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).



Expand Down Expand Up @@ -2461,7 +2461,7 @@ This report was generated on **Sun Sep 01 13:04:22 EEST 2019** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Sun Sep 01 13:04:23 EEST 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 Sep 04 11:10:27 EEST 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).



Expand Down Expand Up @@ -2993,7 +2993,7 @@ This report was generated on **Sun Sep 01 13:04:23 EEST 2019** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Sun Sep 01 13:04:23 EEST 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 Sep 04 11:10:28 EEST 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).



Expand Down Expand Up @@ -3533,7 +3533,7 @@ This report was generated on **Sun Sep 01 13:04:23 EEST 2019** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Sun Sep 01 13:04:24 EEST 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 Sep 04 11:10:28 EEST 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).



Expand Down Expand Up @@ -4119,4 +4119,4 @@ This report was generated on **Sun Sep 01 13:04:24 EEST 2019** using [Gradle-Lic
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.


This report was generated on **Sun Sep 01 13:04:25 EEST 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 Sep 04 11:10:29 EEST 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).
30 changes: 28 additions & 2 deletions server/src/main/java/io/spine/server/BoundedContextBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import io.spine.server.event.EventDispatcher;
import io.spine.server.event.EventEnricher;
import io.spine.server.integration.IntegrationBus;
import io.spine.server.security.Security;
import io.spine.server.stand.Stand;
import io.spine.server.tenant.TenantIndex;
import io.spine.server.type.CommandEnvelope;
Expand Down Expand Up @@ -100,7 +101,7 @@ public final class BoundedContextBuilder implements Logging {
private final Collection<Repository<?, ?>> repositories = new ArrayList<>();

/**
* Prevents direct instantiation.
* Creates a new builder with the given spec.
*
* @param spec
* the context spec for the built context
Expand All @@ -112,10 +113,12 @@ public final class BoundedContextBuilder implements Logging {
}

/**
* Prevents direct instantiation.
* Creates a new builder with the given spec and system features.
*
* @param spec
* the context spec for the built context
* @param systemFeatures
* system feature flags; can be changed later via {@link #systemFeatures()}
* @see BoundedContext#singleTenant
* @see BoundedContext#multitenant
*/
Expand Down Expand Up @@ -145,6 +148,29 @@ public static BoundedContextBuilder assumingTests() {
return assumingTests(false);
}

/**
* Creates a new builder for a Bounded Context which does not store its events.
*
* <p>Such a Bounded Context should not be used general case. This method throws
* a {@link SecurityException} if called outside the framework core. Please use static factory
* methods in {@link BoundedContext} to create an instance of builder.
*/
@Internal
public static BoundedContextBuilder notStoringEvents(String name, boolean multitenant) {
checkNotNull(name);
Security.allowOnlyFrameworkServer();

ContextSpec spec = multitenant
? multitenant(name)
: singleTenant(name);
BoundedContextBuilder builder = new BoundedContextBuilder(spec.notStoringEvents());
builder.systemFeatures()
.forgetEvents()
.disableAggregateQuerying()
.disableCommandLog();
return builder;
}

/**
* Obtains the context spec.
*/
Expand Down
1 change: 0 additions & 1 deletion server/src/main/java/io/spine/server/aggregate/Apply.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,3 @@
*/
boolean allowImport() default false;
}

Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import io.spine.server.type.EventEnvelope;
import io.spine.type.TypeName;

import static io.spine.core.EventValidationError.UNSUPPORTED_EVENT_VALUE;
import static io.spine.server.event.EventException.eventTypeAttribute;
import static java.lang.String.format;

Expand Down Expand Up @@ -71,7 +72,7 @@ private static Error unsupportedImportEvent(Message eventMessage, String errorMe
Error result = Error
.newBuilder()
.setType(UnsupportedImportEventException.class.getName())
.setCode(-1)
.setCode(UNSUPPORTED_EVENT_VALUE)
.setMessage(errorMessage)
.putAllAttributes(eventTypeAttribute(eventMessage))
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
*
* <p>An entity column can be of any type. Most common types are already supported if an existing
* implementation of the {@link io.spine.server.storage.Storage Spine Storage} is used.
* However, their behavior can be overriden using {@link ColumnTypeRegistry}.
* However, their behavior can be overridden using {@link ColumnTypeRegistry}.
*
* <p>To handle column types not supported by default implement the {@link ColumnType}
* interface, register it in a {@link ColumnTypeRegistry} and pass the instance of the registry
Expand Down
3 changes: 2 additions & 1 deletion server/src/main/java/io/spine/server/event/EventBus.java
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ protected EventEnvelope toEnvelope(Event message) {
public EventStore eventStore() {
checkNotNull(
eventStore,
"`EventStore` is not initialized. Please call `EventBus.init(BoundedContext)`."
"`EventStore` is not initialized. " +
"Please call `EventBus.registerWith(BoundedContext)`."
);
return eventStore;
}
Expand Down
19 changes: 19 additions & 0 deletions server/src/main/java/io/spine/server/event/EventFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.google.protobuf.Timestamp;
import io.spine.base.EventMessage;
import io.spine.base.RejectionMessage;
import io.spine.core.ActorContext;
import io.spine.core.Event;
import io.spine.core.EventContext;
import io.spine.core.EventId;
Expand Down Expand Up @@ -73,6 +74,24 @@ public static EventFactory on(MessageEnvelope origin, Any producerId) {
return new EventFactory(eventOrigin, producerId);
}

/**
* Creates a new event factory for producing events to be imported into a Bounced Context.
*
* @param actorContext
* the description of the actor who imports the events
* @param producerId
* the ID of the system which produced the events
* @return new event factory
*/
public static EventFactory forImport(ActorContext actorContext, Any producerId) {
checkNotNull(actorContext);
checkNotNull(producerId);
checkValid(actorContext);

EventOrigin origin = EventOrigin.forImport(actorContext);
return new EventFactory(origin, producerId);
}

/**
* Creates an event for the passed event message.
*
Expand Down
4 changes: 2 additions & 2 deletions server/src/main/java/io/spine/server/event/React.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
* <ul>
* <li>be annotated with {@link React @React};
* <li>have package-private visibility;
* <li>accept an event message (derived from {@link io.spine.base.EventMessage
* EventMessage}) as the first parameter;
* <li>accept an event message (derived from {@link io.spine.base.EventMessage EventMessage})
* as the first parameter;
* <li>return an event message derived from {@link io.spine.base.EventMessage Message}
* <strong>or</strong> several event messages returned as an {@code Iterable}.
* </ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ abstract class EventAcceptingSignature<H extends HandlerMethod<?, ?, EventEnvelo

/**
* This field is also is used by {@link SubscriberSignature} to avoid repeated scanning in
* the overriden {@link #paramSpecs()}.
* the overridden {@link #paramSpecs()}.
*/
static final ImmutableSet<EventAcceptingMethodParams>
PARAM_SPEC = ImmutableSet.copyOf(EventAcceptingMethodParams.values());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package io.spine.server.event.model;

import com.google.common.collect.ImmutableSet;
import io.spine.annotation.Internal;
import io.spine.base.EventMessage;
import io.spine.server.event.React;
import io.spine.server.model.ParameterSpec;
Expand All @@ -32,12 +33,13 @@
/**
* The signature of {@link EventReactorMethod}.
*/
final class EventReactorSignature extends EventAcceptingSignature<EventReactorMethod> {
@Internal
public final class EventReactorSignature extends EventAcceptingSignature<EventReactorMethod> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we hide this class back?


private static final ImmutableSet<Class<?>>
RETURN_TYPES = ImmutableSet.of(EventMessage.class, Iterable.class, Optional.class);

EventReactorSignature() {
public EventReactorSignature() {
super(React.class);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ final class ConfigurationChangeObserver extends AbstractChannelObserver implemen
* types.
*
* <p>If the request originates from a previously unknown Bounded Context,
* {@linkplain IntegrationBus#notifyOfCurrentNeeds() publishes} the needs of current context,
* {@linkplain IntegrationBus#introduceSelf() publishes} the needs of current context,
* since they may be unknown to the new context.
*
* @param value {@link RequestForExternalMessages} form another Bounded Context
Expand All @@ -89,7 +89,7 @@ public void handle(ExternalMessage value) {
clearStaleSubscriptions(request.getRequestedMessageTypeList(), origin);
if (!knownContexts.contains(origin)) {
knownContexts.add(origin);
integrationBus.notifyOfCurrentNeeds();
integrationBus.introduceSelf();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't sound right. The bus is already introduced to the system. It's the new context which introduces itself. Or, if you want the bus to do the job the method should be named differently.

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,13 @@ private void notifyOfUpdatedNeeds() {
}

/**
* Notifies other parts of the application about the types requested by this integration bus.
* Notifies other Bounded Contexts of the application about the types requested by this Context.
*
* <p>Sends out an instance of {@linkplain RequestForExternalMessages
* request for external messages} for that purpose.
* <p>The {@code IntegrationBus} sends a {@link RequestForExternalMessages}. The request
* triggers other Contexts to send their requests. As the result, all the Contexts know about
* the needs of all the Contexts.
*/
void notifyOfCurrentNeeds() {
void introduceSelf() {
configurationBroadcast.send();
}

Expand Down
Loading