tag:github.com,2008:https://github.com/SpineEventEngine/core-java/releasesRelease notes from core-java2024-05-28T15:49:37Ztag:github.com,2008:Repository/38311906/v1.9.12024-05-28T18:05:22Z1.9.1<p>This is a minor release bringing a quality-of-life improvement, basing on Spine's real world usage.</p>
<h4><code>EnvSetting</code> utility (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="2319392852" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1550" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1550/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1550">#1550</a>)</h4>
<p>The <code>EnvSetting</code> is a tool that allows configuring the value that may differ per environment type.</p>
<p>Previously it was an internal utility, but now it is available for all Spine-based projects.</p>
<p>Usage example:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" EnvSetting<UserReader> setting = new EnvSetting<>();
setting.use(projectsUserReader(), Production.class)
.use(localUserReader(), Local.class)
.use(testsUserReader(), Tests.class);
// ...
// The instance is returned according to the current `Environment` type.
final UserReader reader = setting.value(); "><pre> <span class="pl-smi">EnvSetting</span><<span class="pl-smi">UserReader</span>> <span class="pl-s1">setting</span> = <span class="pl-k">new</span> <span class="pl-smi">EnvSetting</span><>();
<span class="pl-s1">setting</span>.<span class="pl-en">use</span>(<span class="pl-en">projectsUserReader</span>(), <span class="pl-smi">Production</span>.<span class="pl-k">class</span>)
.<span class="pl-en">use</span>(<span class="pl-en">localUserReader</span>(), <span class="pl-smi">Local</span>.<span class="pl-k">class</span>)
.<span class="pl-en">use</span>(<span class="pl-en">testsUserReader</span>(), <span class="pl-smi">Tests</span>.<span class="pl-k">class</span>);
<span class="pl-c">// ...</span>
<span class="pl-c">// The instance is returned according to the current `Environment` type.</span>
<span class="pl-k">final</span> <span class="pl-smi">UserReader</span> <span class="pl-s1">reader</span> = <span class="pl-s1">setting</span>.<span class="pl-en">value</span>(); </pre></div>
<p>In addition to making this class <code>public</code>, some changes were made to it comparing to its internal version:</p>
<ul>
<li>introduced method chaining for a more fluent and convenient API (as shown in the example);</li>
<li>added a public endpoint to access the value configured for the current environment type;</li>
<li>API is made thread-safe, allowing concurrent read operations while ensuring exclusive access for write operations to maintain data integrity.</li>
</ul>
<h4>Migration</h4>
<p>This release is fully compatible with <code>core-java</code> libraries 1.9.0. No special migration steps required.</p>Artem-Semenov-devtag:github.com,2008:Repository/38311906/v1.9.02023-05-20T13:50:10Z1.9.0<p>This is part of Spine 1.9.0 release.</p>
<p>This update brings a number of API changes, and also addresses several known issues.</p>
<h3>Breaking changes</h3>
<p>The API of the <code>ShardedWorkRegistry</code> has been changed.</p>
<p>In particular, a new <code>PickUpOutcome pickUp(ShardIndex index, NodeId node)</code> method is introduced. Note, it returns an explicit result instead of <code>Optional</code>, as previously. This outcome contains either of two:</p>
<ul>
<li><code>ShardSessionRecord</code> — meaning that the shard is picked successfully,</li>
<li><code>ShardAlreadyPickedUp</code> — a message that contains a <code>WorkerID</code> of the worker who owns the session at the moment, and the <code>Timestamp</code> when the shard was picked. This outcome means the session cannot be obtained as it's already picked.</li>
</ul>
<p>Also, there is a new <code>void release(ShardSessionRecord session)</code> method that releases the passed session.</p>
<p>Here is a summary of code changes for those using <code>ShardedWorkRegistry</code>:</p>
<p>Before:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Optional<ShardProcessingSession> session = workRegistry.pickUp(index, currentNode);
if (session.isPresent()) { // Check if shard is picked.
// ...
session.get().complete(); // Release shard.
}"><pre><span class="pl-smi">Optional</span><<span class="pl-smi">ShardProcessingSession</span>> <span class="pl-s1">session</span> = <span class="pl-s1">workRegistry</span>.<span class="pl-en">pickUp</span>(<span class="pl-s1">index</span>, <span class="pl-s1">currentNode</span>);
<span class="pl-k">if</span> (<span class="pl-s1">session</span>.<span class="pl-en">isPresent</span>()) { <span class="pl-c">// Check if shard is picked.</span>
<span class="pl-c">// ...</span>
<span class="pl-s1">session</span>.<span class="pl-en">get</span>().<span class="pl-en">complete</span>(); <span class="pl-c">// Release shard.</span>
}</pre></div>
<p>After:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="PickUpOutcome outcome = workRegistry.pickUp(index, currentNode);
if (outcome.hasSession()) { // Check if shard is picked
// ...
workRegistry.release(outcome.getSession()); // Release shard.
}"><pre><span class="pl-smi">PickUpOutcome</span> <span class="pl-s1">outcome</span> = <span class="pl-s1">workRegistry</span>.<span class="pl-en">pickUp</span>(<span class="pl-s1">index</span>, <span class="pl-s1">currentNode</span>);
<span class="pl-k">if</span> (<span class="pl-s1">outcome</span>.<span class="pl-en">hasSession</span>()) { <span class="pl-c">// Check if shard is picked</span>
<span class="pl-c">// ...</span>
<span class="pl-s1">workRegistry</span>.<span class="pl-en">release</span>(<span class="pl-s1">outcome</span>.<span class="pl-en">getSession</span>()); <span class="pl-c">// Release shard.</span>
}</pre></div>
<p>Also, the new API allows getting the <code>WorkerId</code> of the worker who owns the session in case if the shard is already picked by someone else and the <code>Timestamp</code> when the shard was picked:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="PickUpOutcome outcome = workRegistry.pickUp(index, currentNode);
if (outcome.hasAlreadyPickedBy()) {
WorkerId worker = outcome.getAlreadyPicked().getWorker();
Timestamp whenPicked = outcome.getAlreadyPicked().getWhenPicked();
// ...
}"><pre><span class="pl-smi">PickUpOutcome</span> <span class="pl-s1">outcome</span> = <span class="pl-s1">workRegistry</span>.<span class="pl-en">pickUp</span>(<span class="pl-s1">index</span>, <span class="pl-s1">currentNode</span>);
<span class="pl-k">if</span> (<span class="pl-s1">outcome</span>.<span class="pl-en">hasAlreadyPickedBy</span>()) {
<span class="pl-smi">WorkerId</span> <span class="pl-s1">worker</span> = <span class="pl-s1">outcome</span>.<span class="pl-en">getAlreadyPicked</span>().<span class="pl-en">getWorker</span>();
<span class="pl-smi">Timestamp</span> <span class="pl-s1">whenPicked</span> = <span class="pl-s1">outcome</span>.<span class="pl-en">getAlreadyPicked</span>().<span class="pl-en">getWhenPicked</span>();
<span class="pl-c">// ...</span>
}</pre></div>
<h3>Other changes</h3>
<ul>
<li><strong>Custom <code>Executor</code> for <code>SystemSettings</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1208461157" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1448" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1448/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1448">#1448</a>).</strong></li>
</ul>
<p>Now, <code>SystemSettings</code> allows customizing an <code>Executor</code> to post the system events in parallel. This provides an opportunity to improve the control over the available CPU resources on a server instance.</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var builder = BoundedContextBuilder.assumingTests();
var executor = ...;
builder.systemSettings()
.enableParallelPosting()
.useCustomExecutor(executor);"><pre><span class="pl-smi">var</span> <span class="pl-s1">builder</span> = <span class="pl-smi">BoundedContextBuilder</span>.<span class="pl-en">assumingTests</span>();
<span class="pl-smi">var</span> <span class="pl-s1">executor</span> = ...;
<span class="pl-s1">builder</span>.<span class="pl-en">systemSettings</span>()
.<span class="pl-en">enableParallelPosting</span>()
.<span class="pl-en">useCustomExecutor</span>(<span class="pl-s1">executor</span>);</pre></div>
<ul>
<li><strong>Customization of gRPC <code>Server</code> via <code>GrpcContainer</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1276698406" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1454" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1454/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1454">#1454</a>).</strong></li>
</ul>
<p>It is now possible to access an underlying instance of <code>Server</code>'s builder when configuring the <code>GrpcContainer</code>:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="GrpcContainer.atPort(1654)
// `server` is an instance of `io.grpc.ServerBuilder`.
.withServer((server) -> server.maxInboundMessageSize(16_000_000))
// ...
.build();"><pre><span class="pl-smi">GrpcContainer</span>.<span class="pl-en">atPort</span>(<span class="pl-c1">1654</span>)
<span class="pl-c">// `server` is an instance of `io.grpc.ServerBuilder`.</span>
.<span class="pl-en">withServer</span>((<span class="pl-s1">server</span>) -> <span class="pl-s1">server</span>.<span class="pl-en">maxInboundMessageSize</span>(<span class="pl-c1">16_000_000</span>))
<span class="pl-c">// ...</span>
.<span class="pl-en">build</span>();</pre></div>
<p>This API is <strong>experimental</strong> and may change in future versions of Spine.</p>
<ul>
<li><strong>Thorough copying of Bounded Contexts by <code>BlackBoxContext</code>'s builder (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1443789271" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1495" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1495/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1495">#1495</a>).</strong></li>
</ul>
<p>Previously, the<code> BlackBoxContext</code> instances were built on top of <code>BoundedContextBuilder</code>s by copying the internals of the latter builder. However, not all of the parts were copied properly.</p>
<p>This release improves the copying by including more pieces from the source <code>BoundedContextBuilder</code>. In particular, all changes made to <code>BoundedContextBuilder.systemSettings()</code> are now transferred as well.</p>
<ul>
<li><strong>Custom handlers for failed delivery of a signal (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1463356878" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1496" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1496/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1496">#1496</a>).</strong></li>
</ul>
<p>Now, the Delivery API allows to subscribe for any failures which occur during the reception of each signal. Additionally, end-users may now choose the way to handle the reception failures in terms of action in respect to the InboxMessage of interest.</p>
<p>Out-of-the-box, end-users are provided with two options:</p>
<ul>
<li>mark the <code>InboxMessage</code> as delivered — so that it does not block further delivery of messages;</li>
<li>repeat the dispatching of <code>InboxMessage</code> in a synchronous manner.</li>
</ul>
<p>Alternatively, end-users may implement their own way of handling the reception failure.</p>
<p>The corresponding functionality is provided via the API of <code>DeliveryMonitor</code>:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="public final class MarkFailureDelivered extends DeliveryMonitor {
/**
* In case the reception of the {@code InboxMessage} failed,
* mark it as {@code DELIVERED} anyway.
*/
@Override
public FailedReception.Action onReceptionFailure(FailedReception reception) {
//// Error details are available as well:
// InboxMessage msg = reception.message();
// Error error = reception.error();
// notifyOf(msg, error);
return reception.markDelivered();
}
}
// ...
// Plugging the monitor into the Delivery:
DeliveryMonitor monitor = new MarkFailureDelivered();
Delivery delivery = Delivery.newBuilder()
.setMonitor(monitor)
// ...
.build();
ServerEnvironment
.when(MyEnvironment.class)
.use(delivery);"><pre><span class="pl-k">public</span> <span class="pl-k">final</span> <span class="pl-k">class</span> <span class="pl-smi">MarkFailureDelivered</span> <span class="pl-k">extends</span> <span class="pl-smi">DeliveryMonitor</span> {
<span class="pl-c">/**</span>
<span class="pl-c"> * In case the reception of the {@code InboxMessage} failed,</span>
<span class="pl-c"> * mark it as {@code DELIVERED} anyway.</span>
<span class="pl-c"> */</span>
<span class="pl-c1">@</span><span class="pl-c1">Override</span>
<span class="pl-k">public</span> <span class="pl-smi">FailedReception</span>.<span class="pl-smi">Action</span> <span class="pl-en">onReceptionFailure</span>(<span class="pl-smi">FailedReception</span> <span class="pl-s1">reception</span>) {
<span class="pl-c">//// Error details are available as well:</span>
<span class="pl-c">// InboxMessage msg = reception.message();</span>
<span class="pl-c">// Error error = reception.error();</span>
<span class="pl-c">// notifyOf(msg, error);</span>
<span class="pl-k">return</span> <span class="pl-s1">reception</span>.<span class="pl-en">markDelivered</span>();
}
}
<span class="pl-c">// ...</span>
<span class="pl-c">// Plugging the monitor into the Delivery:</span>
<span class="pl-smi">DeliveryMonitor</span> <span class="pl-s1">monitor</span> = <span class="pl-k">new</span> <span class="pl-smi">MarkFailureDelivered</span>();
<span class="pl-smi">Delivery</span> <span class="pl-s1">delivery</span> = <span class="pl-smi">Delivery</span>.<span class="pl-en">newBuilder</span>()
.<span class="pl-en">setMonitor</span>(<span class="pl-s1">monitor</span>)
<span class="pl-c">// ...</span>
.<span class="pl-en">build</span>();
<span class="pl-smi">ServerEnvironment</span>
.<span class="pl-en">when</span>(<span class="pl-smi">MyEnvironment</span>.<span class="pl-k">class</span>)
.<span class="pl-en">use</span>(<span class="pl-s1">delivery</span>);</pre></div>
<p>By default, <code>InboxMessages</code> are marked as DELIVERED in case of failure of their reception.</p>
<ul>
<li><strong>Prohibit calling <code>state()</code> from from <code>@Apply</code>-ers (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1567957371" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1501" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1501/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1501">#1501</a>).</strong></li>
</ul>
<p>It is now not possible to call <code>Aggregate.state()</code> from <code>@Apply</code>-ers. Previously, it was possible, but as discovered from real-world cases, such a functionality is prone to logical errors. End-users must use <code>Aggregate.builder()</code> instead.</p>
<ul>
<li><strong>Fix delivering signals to aggregate <code>Mirror</code>s in a multi-Bounded Context environment (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1570056706" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1502" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1502/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1502">#1502</a>).</strong></li>
</ul>
<p>Previously, when several Bounded Contexts had their <code>Aggregate</code>s "visible" (i.e. exposed via <code>Mirror</code>), the delivery mechanism was confused with multiple <code>Mirror</code> entity types which technically were distinct, but at the same time had exactly the same Type URL. Such a use-cases led to failures when <code>Aggregate</code> state on read-side is updated by the framework code.</p>
<p>This release alters Type URLs, under which Mirror projections register themselves in <code>Delivery</code>. The new type URL value includes the name of the Bounded Context — which makes this type URL invalid in terms of type discovery, but addresses the issue.</p>
<ul>
<li><strong>Importing domain events from 3rd-party contexts properly in multi-tenant environments (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1574066081" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1503" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1503/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1503">#1503</a>).</strong></li>
</ul>
<p>Previously, in a multi-tenant application, the imported events were dispatched in a straightforward manner, without specifying the <code>TenantId</code> in the dispatching context. Now, this issue is resolved.</p>
<ul>
<li><strong>Allow subscribers to receive a notification once an Entity stops matching the subscription criteria (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1611363625" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1504" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1504/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1504">#1504</a>).</strong></li>
</ul>
<p>Starting this release, clients of gRPC Subscription API will start receiving updates once entities previously included into some subscription as matching, are modified and no longer pass the subscription criteria.</p>
<p>In particular, this will always be the case if an Entity becomes archived or deleted.</p>
<p>The new endpoint is available for Spine client under <code>whenNoLongerMatching()</code> DSL, and is a part of Client's request API:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" Client client = client();
client
/* ... */
.subscribeTo(Task.class)
.observe((task) -> { /* ... */ })
.whenNoLongerMatching(TaskId.class, (idOfNonMatchingEntity) -> { /* ... */})
.post();"><pre> <span class="pl-smi">Client</span> <span class="pl-s1">client</span> = <span class="pl-en">client</span>();
<span class="pl-s1">client</span>
<span class="pl-c">/* ... */</span>
.<span class="pl-en">subscribeTo</span>(<span class="pl-smi">Task</span>.<span class="pl-k">class</span>)
.<span class="pl-en">observe</span>((<span class="pl-s1">task</span>) -> { <span class="pl-c">/* ... */</span> })
.<span class="pl-en">whenNoLongerMatching</span>(<span class="pl-smi">TaskId</span>.<span class="pl-k">class</span>, (<span class="pl-s1">idOfNonMatchingEntity</span>) -> { <span class="pl-c">/* ... */</span>})
.<span class="pl-en">post</span>();</pre></div>
<ul>
<li><strong>More granularity into <code>Shard</code> pick-up results (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1645318004" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1505" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1505/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1505">#1505</a>).</strong></li>
</ul>
<p>In this release we start to distinguish the shard pick-up results. In particular, it is now possible to find out the reason of an unsuccessful shard pick-up. In particular, there may be some runtime issues, or a shard may already be picked-up by another worker.</p>
<p>Two new API endpoints were added to the <code>DeliveryMonitor</code> to provide end-users with some control over such cases:</p>
<ul>
<li><code>FailedPickUp.Action onShardAlreadyPicked(AlreadyPickedUp failure)</code></li>
</ul>
<p>Invoked if the shared is already picked by another worker. The callback provides some insights into the pick-up failure, such as ID of the worker currently holding the shard, and <code>Timestamp</code> of the moment when the shard was picked by it.</p>
<p>It is also required to return an action to take in relation to this case. By default, an action silently accepting this scenario is returned. End-users may implement their own means, e.g. retrying the pick-up attempt:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="final class MyDeliveryMonitor extends DeliveryMonitor {
...
@Override
public FailedPickUp.Action onShardAlreadyPicked(AlreadyPickedUp failure) {
return failure.retry();
}
...
}"><pre><span class="pl-k">final</span> <span class="pl-k">class</span> <span class="pl-smi">MyDeliveryMonitor</span> <span class="pl-k">extends</span> <span class="pl-smi">DeliveryMonitor</span> {
...
<span class="pl-c1">@</span><span class="pl-c1">Override</span>
<span class="pl-k">public</span> <span class="pl-smi">FailedPickUp</span>.<span class="pl-smi">Action</span> <span class="pl-en">onShardAlreadyPicked</span>(<span class="pl-smi">AlreadyPickedUp</span> <span class="pl-s1">failure</span>) {
<span class="pl-k">return</span> <span class="pl-s1">failure</span>.<span class="pl-en">retry</span>();
}
...
}</pre></div>
<ul>
<li><code>FailedPickUp.Action onShardPickUpFailure(RuntimeFailure failure)</code></li>
</ul>
<p>This method is invoked if the shard could not be picked for some runtime technical reason. This method receives the <code>ShardIndex</code> of the shard that could not be picked, and the instance of the occurred <code>Exception</code>. It also requires to return an action to handle this case. By default, such failures are just rethrown as <code>RuntimeException</code>s, but end-users may choose to retry the pick-up:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="final class MyDeliveryMonitor extends DeliveryMonitor {
...
@Override
public FailedPickUp.Action onShardPickUpFailure(RuntimeFailure failure) {
return failure.retry();
}
...
}"><pre><span class="pl-k">final</span> <span class="pl-k">class</span> <span class="pl-smi">MyDeliveryMonitor</span> <span class="pl-k">extends</span> <span class="pl-smi">DeliveryMonitor</span> {
...
<span class="pl-c1">@</span><span class="pl-c1">Override</span>
<span class="pl-k">public</span> <span class="pl-smi">FailedPickUp</span>.<span class="pl-smi">Action</span> <span class="pl-en">onShardPickUpFailure</span>(<span class="pl-smi">RuntimeFailure</span> <span class="pl-s1">failure</span>) {
<span class="pl-k">return</span> <span class="pl-s1">failure</span>.<span class="pl-en">retry</span>();
}
...
}</pre></div>
<ul>
<li><strong>A build-in <code>Sample</code> type providing the generation of sample Proto messages was improved in relation to generation more humane <code>String</code> values (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1676978223" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1506" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1506/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1506">#1506</a>).</strong></li>
</ul>armioltag:github.com,2008:Repository/38311906/v1.8.22022-06-20T12:04:24Z1.8.2<p>This is a maintenance release of Spine core libraries. It extends the existing API, primarily focusing on adding new configuration knobs.</p>
<p>In particular, these changes were made since the last release:</p>
<ul>
<li>
<p><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1176691919" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1443" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1443/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1443">#1443</a>: Expand the <code>io.spine.server.Server</code> API to allow to:</p>
<ul>
<li>obtain the Query, Subscription, and Command services after the <code>Server</code> is built;</li>
<li>add extra gRPC services to the same server.</li>
</ul>
</li>
<li>
<p><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1208461157" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1448" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1448/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1448">#1448</a>: Allow supplying <code>Executor</code> for <code>SystemWriteSide</code>.</p>
</li>
<li>
<p><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1276698406" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1454" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1454/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1454">#1454</a>: Allow to configure the underlying gRPC server via <code>GrpcContainer</code> API.</p>
</li>
</ul>
<p>No breaking changes to the existing API were made.</p>armioltag:github.com,2008:Repository/38311906/v1.8.02021-12-16T10:06:33Z1.8.0<p>This release brings numerous fixes, updates to API and performance improvements.</p>
<h2>Breaking Changes</h2>
<ul>
<li>
<p>Instead of <code>NodeId</code>, <code>ShardSessionRecord</code> now uses <code>WorkerId</code> to indicate who is currently processing which shard.</p>
<p>Thus, all shard processing sessions should be completed before the migration.</p>
<p>Please see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1078679636" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1433" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1433/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1433">#1433</a> for details.</p>
</li>
</ul>
<h2>API Changes</h2>
<ul>
<li>
<p>Made <code>BlackBoxContext</code> implement <code>Closeable</code> (as addition of <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1026592173" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1402" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1402/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1402">#1402</a>).</p>
</li>
<li>
<p><code>BlackBoxContext</code> API has been extended to provide an instance of <code>Client</code> linked to the context under the test.</p>
<p>It makes possible to use <code>Client</code> in tests, for example:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="BlackBoxContext context = BlackBoxContext.from(...);
ClientRequest clientRequest = context.client().asGuest();
assertThat(clientRequest.select(ProjectView.class).run())
.hasSize(0);
clientRequest.command(createProject()).postAndForget();
assertThat(clientRequest.select(ProjectView.class).run())
.hasSize(1);"><pre><span class="pl-smi">BlackBoxContext</span> <span class="pl-s1">context</span> = <span class="pl-smi">BlackBoxContext</span>.<span class="pl-en">from</span>(...);
<span class="pl-smi">ClientRequest</span> <span class="pl-s1">clientRequest</span> = <span class="pl-s1">context</span>.<span class="pl-en">client</span>().<span class="pl-en">asGuest</span>();
<span class="pl-en">assertThat</span>(<span class="pl-s1">clientRequest</span>.<span class="pl-en">select</span>(<span class="pl-smi">ProjectView</span>.<span class="pl-k">class</span>).<span class="pl-en">run</span>())
.<span class="pl-en">hasSize</span>(<span class="pl-c1">0</span>);
<span class="pl-s1">clientRequest</span>.<span class="pl-en">command</span>(<span class="pl-en">createProject</span>()).<span class="pl-en">postAndForget</span>();
<span class="pl-en">assertThat</span>(<span class="pl-s1">clientRequest</span>.<span class="pl-en">select</span>(<span class="pl-smi">ProjectView</span>.<span class="pl-k">class</span>).<span class="pl-en">run</span>())
.<span class="pl-en">hasSize</span>(<span class="pl-c1">1</span>);</pre></div>
<p>Please note, that provided <code>Client</code> would inherit <code>TenantId</code> from <code>BlackBoxContext</code>, but would NOT inherit <code>UserId</code> and <code>ZoneId</code>.</p>
<p>Check <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1035385099" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1407" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1407/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1407">#1407</a> for details.</p>
</li>
<li>
<p>Made API calls for the conditional settings of <code>ServerEnvironment</code> "lazy".</p>
<p>Previously, ServerEnvironment provided two kinds of API calls for the conditional settings:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" ServerEnvironment.when(Staging.class)
// This call is handy when `myStorageFactory` is already available.
.use(myStorageFactory)
ServerEnvironment.when(PreProduction.class)
// And this one looks lazy, so that it is only executed when and _if_ requested.
.use((env) -> createMySqlStorage())"><pre> <span class="pl-smi">ServerEnvironment</span>.<span class="pl-en">when</span>(<span class="pl-smi">Staging</span>.<span class="pl-k">class</span>)
<span class="pl-c">// This call is handy when `myStorageFactory` is already available.</span>
.<span class="pl-en">use</span>(<span class="pl-s1">myStorageFactory</span>)
<span class="pl-smi">ServerEnvironment</span>.<span class="pl-en">when</span>(<span class="pl-smi">PreProduction</span>.<span class="pl-k">class</span>)
<span class="pl-c">// And this one looks lazy, so that it is only executed when and _if_ requested.</span>
.<span class="pl-en">use</span>((<span class="pl-s1">env</span>) -> <span class="pl-en">createMySqlStorage</span>())</pre></div>
<p>However, in fact, there was no "lazy" behavior, which caused numerous workarounds to actually postpone the initialization of environment-specific settings until they start to make sense.</p>
<p>This release addresses the issue by making the behavior truly "lazy" (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1057086804" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1421" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1421/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1421">#1421</a>).</p>
</li>
</ul>
<h2>Fixes</h2>
<ul>
<li>
<p>Enabled <code>IntegrationBroker</code> dispatch events regardless of registration order of subscribing and publishing Bounded Contexts (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1026592173" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1402" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1402/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1402">#1402</a>).</p>
</li>
<li>
<p>Transformation of an Entity's state during <code>Migration</code> has been changed so that the <code>newState</code> completely overwrites the old one within the migration transaction (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1034419684" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1405" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1405/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1405">#1405</a>).</p>
</li>
<li>
<p>The internals of <code>IntegrationBroker</code> were made more thread-safe (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1060429228" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1423" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1423/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1423">#1423</a>).</p>
</li>
<li>
<p><code>SubscriptionService</code> now properly locates the Bounded Context when subscribing to events produced by standalone producers, such as descendants of <code>AbstractCommandHandler</code> or <code>AbstractEventReactor</code> (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1060429228" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1423" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1423/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1423">#1423</a>).</p>
</li>
</ul>
<h2>Performance</h2>
<ul>
<li>Improved Catch-up caching (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1035384152" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1406" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1406/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1406">#1406</a> for details).</li>
</ul>yevhenii-nadtochiitag:github.com,2008:Repository/38311906/v1.7.62021-09-28T13:39:31Z1.7.6<p>This is another patch release of Spine 1.x. It addresses some issues and inconveniences operating the Projection catch-up.</p>
<ul>
<li>It is now not possible to start the catch-up for Aggregate's <code>MirrorProjection</code> — as such projections are built from system events only, and their catch-up makes not much sense.</li>
<li>The run-time of catch-up is made more stable, taking into account the experience of exploring this feature in production use cases.</li>
</ul>armioltag:github.com,2008:Repository/38311906/v1.7.52021-09-13T09:43:04Z1.7.5<p>This is a patch release of Spine 1.x. It follows up on the production use of Spine libraries and brings a few requested improvements.</p>
<ul>
<li>The integration with gRPC server has been improved for better results in dealing with heavy-duty subscriptions.</li>
<li><code>BlackBoxContext</code> API has been extended with a few endpoints to test for the positive outcomes.</li>
</ul>
<p>Additionally, several improvements of <code>config</code> scripts were brought to this version.</p>
<p><a href="https://github.com/SpineEventEngine/core-java/compare/v1.7.0...v1.7.5">Compare</a> v1.7.0 and v1.7.5.</p>armioltag:github.com,2008:Repository/38311906/latest-v12021-07-26T20:02:36Zlatest-v1<p>Synchronize the calls subscription observer (underlying `ServerCallIm…</p>armioltag:github.com,2008:Repository/38311906/v1.7.02020-12-14T15:59:40Z1.7.0<p>This release brings numerous API improvements, as well as fixes and infrastructure updates to the framework.</p>
<h2>Breaking Changes</h2>
<ol>
<li>
<p>The <code>BlackBoxContext</code>-based tests now fail if a runtime exception was thrown within the signal handlers.</p>
<p>In order to address <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="728121790" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1314" data-hovercard-type="issue" data-hovercard-url="/SpineEventEngine/core-java/issues/1314/hovercard" href="https://github.com/SpineEventEngine/core-java/issues/1314">#1314</a>, we've decided to enforce the fail-fast approach within the BBC tests done in <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="745811450" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1322" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1322/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1322">#1322</a>. From now on, if a test case had any runtime exceptions thrown from signal handlers the test is failed by the BBC. While it may be a breaking change for some, we believe it worth fixing such issues right away than hiding them under the carpet.</p>
<p>If one requires to fall back to the previous behavior, the BBC instance can be configured using the newly introduced <code>tolerateFailures</code> method.</p>
</li>
<li>
<p>The <code>grand_origin</code> field is no longer set to a default instance for the signal <code>Origin</code> if no grand origin is present (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="758673601" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1341" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1341/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1341">#1341</a> for details).</p>
</li>
<li>
<p>The <code>ServerEnvironment</code> API is improved and changed as a result of the <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="728179743" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1315" data-hovercard-type="issue" data-hovercard-url="/SpineEventEngine/core-java/issues/1315/hovercard" href="https://github.com/SpineEventEngine/core-java/issues/1315">#1315</a> and related discussions in a series of PRs (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="746906178" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1327" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1327/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1327">#1327</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="747717573" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1331" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1331/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1331">#1331</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="754500748" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1336" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1336/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1336">#1336</a>).</p>
<p>The previously deprecated <code>configure...()</code> API is removed in favor of the new fluent <code>when().use()</code> API.</p>
<p>So now, instead of smth like this:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ServerEnvironment.use(productionStorageFactory, Production.class)
.use(testingStorageFactory, Tests.class)
.use(memoizingTracerFactory, Production.class)"><pre><span class="pl-smi">ServerEnvironment</span>.<span class="pl-en">use</span>(<span class="pl-s1">productionStorageFactory</span>, <span class="pl-smi">Production</span>.<span class="pl-k">class</span>)
.<span class="pl-en">use</span>(<span class="pl-s1">testingStorageFactory</span>, <span class="pl-smi">Tests</span>.<span class="pl-k">class</span>)
.<span class="pl-en">use</span>(<span class="pl-s1">memoizingTracerFactory</span>, <span class="pl-smi">Production</span>.<span class="pl-k">class</span>)</pre></div>
<p>One should use the following snippet:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ServerEnvironment.when(Production.class)
.use(productionStorageFactory)
.use(memoizingTracerFactory);
ServerEnvironment.when(Tests.class)
.use(testingStorageFactory);"><pre><span class="pl-smi">ServerEnvironment</span>.<span class="pl-en">when</span>(<span class="pl-smi">Production</span>.<span class="pl-k">class</span>)
.<span class="pl-en">use</span>(<span class="pl-s1">productionStorageFactory</span>)
.<span class="pl-en">use</span>(<span class="pl-s1">memoizingTracerFactory</span>);
<span class="pl-smi">ServerEnvironment</span>.<span class="pl-en">when</span>(<span class="pl-smi">Tests</span>.<span class="pl-k">class</span>)
.<span class="pl-en">use</span>(<span class="pl-s1">testingStorageFactory</span>);</pre></div>
</li>
</ol>
<h2>API Changes</h2>
<ol>
<li>
<p><code>Change</code> type validation requirements are relaxed for primitive type changes.</p>
<p>The <code>new_value</code> field is no longer a required one for <code>StringChange</code> and <code>BytesChange</code> types. See <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="721586393" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1307" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1307/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1307">#1307</a> for details.</p>
</li>
<li>
<p>Introduced simplified <code>unicast()</code> methods in the <code>EventRouting</code>.</p>
<p>The new <code>unicast()</code> API allows simplifying and prettifying the even routing for the cases where a singular ID is used.</p>
<p>Now, instead of smth like this:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" @OverridingMethodsMustInvokeSuper
@Override
protected void setupEventRouting(EventRouting<AirportId> routing) {
super.setupEventRouting(routing);
routing.route(FlightScheduled.class, (e, ctx)-> EventRoute.withId(e.getAirport()));
}"><pre> <span class="pl-c1">@</span><span class="pl-c1">OverridingMethodsMustInvokeSuper</span>
<span class="pl-c1">@</span><span class="pl-c1">Override</span>
<span class="pl-k">protected</span> <span class="pl-smi">void</span> <span class="pl-en">setupEventRouting</span>(<span class="pl-smi">EventRouting</span><<span class="pl-smi">AirportId</span>> <span class="pl-s1">routing</span>) {
<span class="pl-en">super</span>.<span class="pl-en">setupEventRouting</span>(<span class="pl-s1">routing</span>);
<span class="pl-s1">routing</span>.<span class="pl-en">route</span>(<span class="pl-smi">FlightScheduled</span>.<span class="pl-k">class</span>, (<span class="pl-s1">e</span>, <span class="pl-s1">ctx</span>)-> <span class="pl-smi">EventRoute</span>.<span class="pl-en">withId</span>(<span class="pl-s1">e</span>.<span class="pl-en">getAirport</span>()));
}</pre></div>
<p>One can use the following API:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" @OverridingMethodsMustInvokeSuper
@Override
protected void setupEventRouting(EventRouting<AirportId> routing) {
super.setupEventRouting(routing);
routing.unicast(FlightScheduled.class, FlightScheduled::getAirport)
}"><pre> <span class="pl-c1">@</span><span class="pl-c1">OverridingMethodsMustInvokeSuper</span>
<span class="pl-c1">@</span><span class="pl-c1">Override</span>
<span class="pl-k">protected</span> <span class="pl-smi">void</span> <span class="pl-en">setupEventRouting</span>(<span class="pl-smi">EventRouting</span><<span class="pl-smi">AirportId</span>> <span class="pl-s1">routing</span>) {
<span class="pl-en">super</span>.<span class="pl-en">setupEventRouting</span>(<span class="pl-s1">routing</span>);
<span class="pl-s1">routing</span>.<span class="pl-en">unicast</span>(<span class="pl-smi">FlightScheduled</span>.<span class="pl-k">class</span>, <span class="pl-smi">FlightScheduled</span>::<span class="pl-s1">getAirport</span>)
}</pre></div>
<p>To find out more details on the new API please check <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="728588762" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1317" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1317/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1317">#1317</a>.</p>
</li>
<li>
<p>Added <code>localDate</code> and <code>localDateTime</code> helpers to the <code>WithTime</code> interface.</p>
<p>This feature allows accessing <code>localDate</code> and <code>localDateTime</code> methods from within all the signals. From now on, if one requires a Java <code>LocalDate</code> or <code>LocalDateTime</code> instances over the Protobuf <code>Timestamp</code> or Java <code>Instant</code> that were previously available for signals, they may use the new API to simplify such a conversion and access to the signals <code>timestamp</code> field.</p>
<p>See <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="741965655" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1319" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1319/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1319">#1319</a> for additional details.</p>
</li>
</ol>
<h2>Fixes</h2>
<ol>
<li>
<p>Improved multitenant delivery support by ensuring the tenant is properly propagated within the delivery (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="723302681" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1308" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1308/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1308">#1308</a>).</p>
</li>
<li>
<p>Fixed a typo in the <code>io.spine.client.Client</code> <code>shutdownTimeout</code> method (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="756123252" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1339" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1339/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1339">#1339</a>).</p>
</li>
<li>
<p>Fixed dispatching of rejections caused by a particular command (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="740077212" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1318" data-hovercard-type="issue" data-hovercard-url="/SpineEventEngine/core-java/issues/1318/hovercard" href="https://github.com/SpineEventEngine/core-java/issues/1318">#1318</a> and <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="761367333" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1343" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1343/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1343">#1343</a>).</p>
</li>
</ol>
<h2>Infrastructure</h2>
<ol>
<li>The libraries now do not use <code>implementation</code> for compile-only annotations like <code>errorprone</code> annotations but use the newly <a href="https://docs.gradle.org/6.7.1/release-notes.html#new-dependency-management-features" rel="nofollow">introduced</a> <code>compileOnlyApi</code> configuration for such dependencies (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="756285200" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1340" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1340/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1340">#1340</a>).</li>
</ol>
<p><a href="https://github.com/SpineEventEngine/core-java/compare/v1.6.0...v1.7.0">Compare</a> v1.6.0 and v1.7.0.</p>yuri-sergiichuktag:github.com,2008:Repository/38311906/v1.6.02020-09-14T12:40:43Z1.6.0<p>This release brings numerous API improvements, as well as fixes and infrastructure updates to the framework.</p>
<h2>API changes</h2>
<h3>Client</h3>
<ol>
<li>The ability to <code>postAndForget()</code> a command is added to the <code>Client</code>. This method should be called when the user does not care about events/rejections produced by a command.<br>
The previously used <code>post()</code> method is reserved for cases when one or more event types are actually observed by the client. The value returned by <code>post()</code> can no longer be ignored [<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="679145465" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1292" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1292/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1292">#1292</a>].</li>
<li>Event subscriptions are now more flexible, allowing to subscribe to events produced by non-entity objects (e.g. <code>AbstractEventReactor</code>) as well as events not explicitly declared in any <code>BoundedContext</code> [<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="591932979" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1258" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1258/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1258">#1258</a>].</li>
<li>The <code>Client</code> is extended with methods to handle streaming and server errors when executing requests [<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="609939093" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1270" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1270/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1270">#1270</a>].</li>
</ol>
<h3>Server</h3>
<ol>
<li>The custom environments support is introduced [<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="620905171" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1274" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1274/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1274">#1274</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="681026507" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1293" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1293/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1293">#1293</a>].<br>
The <code>Environment</code> now exposes API to register user-defined environment types and to determine which one is enabled at any given moment of time. See the <a href="https://github.com/SpineEventEngine/base/releases/tag/v1.6.0">release notes</a> of <code>base</code>.<br>
The <code>ServerEnvironment</code> allows to configure environment-dependent values, as follows: </li>
</ol>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="StorageFactory factory = InMemoryStorageFactory.newInstance();
ServerEnvironment.instance()
.use(factory, Tests.class); "><pre><span class="pl-smi">StorageFactory</span> <span class="pl-s1">factory</span> = <span class="pl-smi">InMemoryStorageFactory</span>.<span class="pl-en">newInstance</span>();
<span class="pl-smi">ServerEnvironment</span>.<span class="pl-en">instance</span>()
.<span class="pl-en">use</span>(<span class="pl-s1">factory</span>, <span class="pl-smi">Tests</span>.<span class="pl-k">class</span>); </pre></div>
<p>The Spine framework provides two environments out of the box: <code>Production</code> and <code>Tests</code>.</p>
<ol start="2">
<li><strong>Breaking change:</strong> Most of the <code>@Internal</code> methods of <code>BoundedContext</code> moved to its internal class <code>InternalAccess</code> instance of which is available via the <code>internalAccess()</code> method.<br>
The method is available only to the server-side framework code.</li>
<li>Delivery API is extended with a factory method which allows to create asynchronous version of local <code>Delivery</code> [<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="603319458" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1265" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1265/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1265">#1265</a>].</li>
<li>The <code>Pair</code> can now be created from an already existing <code>Optional</code> [<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="690442780" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1296" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1296/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1296">#1296</a>].</li>
<li>The proper support to the <code>CommandBus</code> filters which throw rejections is added [<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="688023754" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1295" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1295/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1295">#1295</a>].</li>
</ol>
<h3>Model</h3>
<ol>
<li>The <code>@External</code> annotation is introduced to mark the handler method parameters of an external origin. It replaces the previously used for this purpose <code>(external = true)</code> attribute of <code>@Subscribe</code>, <code>@React</code>, and <code>@Command</code> annotation. The attribute is deprecated [<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="608333124" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1269" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1269/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1269">#1269</a>].</li>
<li><code>(set_once)</code> constraint in entity states is no longer ignored [<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="607764603" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1268" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1268/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1268">#1268</a>].</li>
<li><code>@ByField</code> is deprecated in favour of <code>@Where</code> [<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="609939093" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1270" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1270/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1270">#1270</a>].</li>
</ol>
<h3>Logging</h3>
<ol>
<li>The <code>DiagnosticLog</code> messages are made more detailed [<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="597411490" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1262" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1262/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1262">#1262</a>].</li>
<li>The standard framework exceptions are expanded with more info [<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="587839245" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1255" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1255/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1255">#1255</a>].</li>
</ol>
<h3>Testing</h3>
<p>Various quality-of-life changes are introduced for the testing API.</p>
<p>See <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="581884867" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1249" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1249/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1249">#1249</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="583159860" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1251" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1251/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1251">#1251</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="583838630" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1252" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1252/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1252">#1252</a>, and <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="595189699" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1261" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1261/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1261">#1261</a> for details.</p>
<p>Some of the testing API changes are breaking. They include:</p>
<ol>
<li><code>BlackBoxBoundedContext</code> is renamed to <code>BlackBoxContext</code>.</li>
<li>Outdated <code>Verify</code>-based API is removed.</li>
<li><code>BlackBoxContext</code> no longer exposes <code>eventBus()</code> and <code>commandBus()</code>.</li>
<li>The <code>BlackBoxContext.subscribeTo(Topic)</code> semantics changed. See <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="581884867" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1249" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1249/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1249">#1249</a>.</li>
<li>Simplified combinations of <code>UserId</code> and <code>ZoneId</code> parameters of <code>BlackBoxContext</code>.</li>
</ol>
<h2>Fixes</h2>
<p>The <code>Migration</code> logic is fixed to properly support entity state updates [<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="691423762" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1298" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1298/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1298">#1298</a>].</p>
<h2>Infrastructure</h2>
<p>The project build scripts are migrated to Kotlin [<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="626465139" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1278" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1278/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1278">#1278</a>].</p>dmitrykuzmintag:github.com,2008:Repository/38311906/v1.5.02020-03-08T14:38:04Z1.5.0<p>This major update of the library brings a number of new features and performance improvements.</p>
<ul>
<li>Projections now support an automated run-time catch-up (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="547480974" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1221" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1221/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1221">#1221</a>).</li>
<li>The client API was made less error-prone by enforcing the strong typing for the columns and properties of Entities and Events. The list of the model fields is generated as Java code by the Spine compiler at build-time (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="556488404" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1229" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1229/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1229">#1229</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="576288064" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1246" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1246/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1246">#1246</a>).</li>
<li>A data migration API is now available for <code>ProcessManager</code>s and <code>Projection</code>s. It automates the process of updating the existing data upon the changes in the domain model (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="572937780" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1241" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1241/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1241">#1241</a>).</li>
<li>The logging records made from within the Entity handlers now print the full signature of the called method (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="573945403" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1242" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1242/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1242">#1242</a>).</li>
<li>It is now possible to specify an actor when composing a test scenario with <code>BlackBoxBoundedContext</code> API (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="573945403" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1242" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1242/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1242">#1242</a>).</li>
<li><code>CommandBus</code> is no longer responsible for validating the first field of the transmitted <code>Command</code>s; instead, this is a job of the <code>Repository</code> for the target <code>Entity</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="576238643" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1245" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1245/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1245">#1245</a>).</li>
</ul>
<p>The API of <code>InboxMessage</code> has been changed so that any of the existing <code>InboxMessage</code>s become incompatible (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="572175689" data-permission-text="Title is private" data-url="https://github.com/SpineEventEngine/core-java/issues/1239" data-hovercard-type="pull_request" data-hovercard-url="/SpineEventEngine/core-java/pull/1239/hovercard" href="https://github.com/SpineEventEngine/core-java/pull/1239">#1239</a>). Please make sure to deliver the messages from all of your production <code>Inbox</code>es prior to updating to the new version.</p>
<p>Also, a number of minor improvements and issues were addressed. Please see the list of closed pull requests for more details.</p>armiol