From 52ddda161675290c08b47d979ef039be9fb8b9b7 Mon Sep 17 00:00:00 2001 From: Lisa Jamen <31409174+ljamen@users.noreply.github.com> Date: Fri, 12 Aug 2022 10:52:07 -0400 Subject: [PATCH 1/3] doc updates for reactive messaging mp --- docs/mp/reactivemessaging/aq.adoc | 1 + docs/mp/reactivemessaging/introduction.adoc | 86 ++++++++++----------- docs/mp/reactivemessaging/jms.adoc | 1 + docs/mp/reactivemessaging/kafka.adoc | 1 + docs/mp/reactivemessaging/mock.adoc | 1 + 5 files changed, 46 insertions(+), 44 deletions(-) diff --git a/docs/mp/reactivemessaging/aq.adoc b/docs/mp/reactivemessaging/aq.adoc index 71a806e2495..f442ff4f3ce 100644 --- a/docs/mp/reactivemessaging/aq.adoc +++ b/docs/mp/reactivemessaging/aq.adoc @@ -24,6 +24,7 @@ :feature-name: AQ Connector :microprofile-bundle: false :rootdir: {docdir}/../.. +:h1-prefix: MP include::{rootdir}/includes/mp.adoc[] include::{rootdir}/includes/dependencies.adoc[] diff --git a/docs/mp/reactivemessaging/introduction.adoc b/docs/mp/reactivemessaging/introduction.adoc index bf224888eb0..b8091b47a01 100644 --- a/docs/mp/reactivemessaging/introduction.adoc +++ b/docs/mp/reactivemessaging/introduction.adoc @@ -16,7 +16,7 @@ /////////////////////////////////////////////////////////////////////////////// -= Reactive Messaging += Reactive Messaging MP :spec-name: MicroProfile Reactive Messaging :description: {spec-name} support in Helidon MP :keywords: helidon, mp, microprofile, messaging @@ -24,32 +24,25 @@ :feature-name: MicroProfile Reactive Messaging :microprofile-bundle: false :rootdir: {docdir}/../.. +:h1-prefix: MP + == Contents - <> - <> -- <> -- <> -- <> -- <> -- <> -- <> -- <> -- <> -- <> -- <> -- <> +- <> +- <> - <> +- <> == Overview -There is more to expect from the modern messaging than we got from old-fashioned Message Driven Beans, -blocking is not always favorable way to apply backpressure to the message source, actually is not the only way anymore. -Reactive messaging uses reactive streams as message channels, users can construct very effective pipelines for working -with the messages, or use messaging in the old-fashioned way. Similarly to the MDB's +Reactive messaging is vastly different from the older method of using message-driven beans. One significant difference is that blocking is no longer the only way to apply backpressure to the message source. +Reactive messaging uses reactive streams as message channels so you can construct very effective pipelines for working +with the messages or, if you prefer, you can continue to use older messaging methods. Like the message-driven beans, link:{microprofile-reactive-messaging-spec-url}[MicroProfile Reactive Messaging] uses CDI beans to produce, consume or process messages over Reactive Streams. -Such messaging bean is expected to be either in `ApplicationScoped` or `Dependent` scope. +These essaging beans are expected to be either `ApplicationScoped` or `Dependent` scoped. Messages are managed by methods annotated by `@Incoming` and `@Outgoing` and the invocation is always driven by message core - either at assembly time, or for every message coming from the stream. @@ -74,19 +67,21 @@ To include health checks for Messaging add the following dependency: ---- -== Channel +== Usage + +=== Channels -Reactive messaging uses named channels to connect always one source(upstream) with one consumer(downstream). -Each channel needs to have both ends connected otherwise container won't successfully start. +Reactive messaging uses named channels to connect one source (upstream) with one consumer (downstream). +Each channel needs to have both ends connected otherwise the container cannot successfully start. image::msg/channel.svg[Messaging Channel] Channels can be connected either to <> (1), <> (2) or <> (3) on the upstream side. And <> (4), <> (5) or <> (6) on the downstream. -=== Consuming method +==== Consuming method Consuming methods can be connected to the channel's downstream to consume the message coming through the channel. -Incoming annotation has one required attribute `value` that defines the channel name. +The incoming annotation has one required attribute `value` that defines the channel name. Consuming method can function in two ways: @@ -113,9 +108,9 @@ public Subscriber printMessage() { } ---- -=== Injected publisher +==== Injected publisher Directly injected publisher can be connected as a channel downstream, -we can consume the data from the channel by subscribing to it. +you can consume the data from the channel by subscribing to it. Helidon can inject following types of publishers: @@ -139,12 +134,12 @@ public MyBean(@Channel("example-channel-1") Multi multiChannel) { } ---- -=== Producing method +==== Producing method The annotation has one required attribute `value` that defines the link:{microprofile-reactive-messaging-spec-url}#_channel[channel] name. -Such annotated <> can function in two ways: +The annotated <> can function in two ways: * produce exactly one message to the stream connected to the link:{microprofile-reactive-messaging-spec-url}#_channel[channel] * prepare reactive stream's publisher and connect it to the link:{microprofile-reactive-messaging-spec-url}#_channel[channel] @@ -167,10 +162,10 @@ public Publisher printMessage() { } ---- -WARNING: Messaging methods are not meant to be invoked directly! +**Caution**: Messaging methods are not meant to be invoked directly! === Emitter -For sending messages from imperative code we can inject special channel source called emitter. +To send messages from imperative code, we can inject a special channel source called an emitter. Emitter can serve only as an upstream, source of the messages, for messaging channel. [source,java] @@ -188,9 +183,8 @@ public Response sendMessage(final String payload) { } ---- -Emitters as a source of messages for reactive channels needs to address possible backpressure from the downstream side -of the channel. In case there is not enough demand from the downstream we can configure best fitting strategy for our use-case -with annotation `@OnOverflow`. +Emitters, as a source of messages for reactive channels, need to address possible backpressure from the downstream side +of the channel. In case there is not enough demand from the downstream, you can configure a buffer size strategy using the `@OnOverflow` annotation. Additional overflow strategies are described below. .Overflow strategies |=== @@ -253,7 +247,7 @@ public String processMessage(String msg) { ---- === Connector -Messaging connector is an application scoped bean which implements one or both of following interfaces: +Messaging connector is an application-scoped bean that implements one or both of following interfaces: * `IncomingConnectorFactory` - connector can create an upstream publisher to produce messages to a channel * `OutgoingConnectorFactory` - connector can create a downstream subscriber to consume messages from a channel @@ -280,6 +274,8 @@ public class ExampleConnector implements IncomingConnectorFactory, OutgoingConne } ---- +== Configuration + Channel needs to be instructed to use connector as its upstream or downstream by configuration. [source,yaml] @@ -317,8 +313,8 @@ public void consume(String value) { > Consuming: bar ---- -When connector constructs publisher or subscriber for given channel, -it can access general connector configuration and channel specific properties merged together with +When the connector constructs a publisher or subscriber for a given channel, +it can access general connector configuration and channel-specific properties merged together with special synthetic property `channel-name`. image::msg/connector-config.svg[Connector config] @@ -397,10 +393,9 @@ public void consumeImplicitlyUnwrappedMessage(String value) { ---- === Acknowledgement -Message carries a callback for reception acknowledgement(ack) and negative acknowledgement(nack), -acknowledgement in messaging methods is possible manually by +Messages carry a callback for reception acknowledgement (ack) and negative acknowledgement (nack). An acknowledgement in messaging methods is possible manually by `org.eclipse.microprofile.reactive.messaging.Message#ack` or automatically according explicit -or implicit acknowledgement strategy by messaging core. Explicit strategy configuration is possible +or implicit acknowledgement strategy by the messaging core. Explicit strategy configuration is possible with `@Acknowledgment` annotation which has one required attribute `value` that expects the strategy type from enum `org.eclipse.microprofile.reactive.messaging.Acknowledgment.Strategy`. More information about supported signatures and implicit automatic acknowledgement can be found in specification @@ -524,15 +519,18 @@ every messaging channel to have its own probe. } ---- -WARNING: Due to the nack support are exceptions thrown in messaging methods NOT translated to error and cancel signals implicitly anymore - -== Upgrading to Messaging 3.0 -.Non-backward compatible changes: -* Exceptions thrown in messaging methods are not propagated as error or cancel signals to the stream(use `mp.messaging.helidon.propagate-errors=true` for backward compatible mode) - errors are propagated only to the upstream by `nack` functionality. -* Default acknowledgement strategies changed for selected signatures(all with Message as a parameter or return type) - See the specification issue link:{https://github.com/eclipse/microprofile-reactive-messaging/pull/97}[#97] +Caution: Due to the nack support are exceptions thrown in messaging methods NOT translated to error and cancel signals implicitly anymore == Reference * link:https://helidon.io/docs/v2/apidocs/io.helidon.microprofile.messaging/module-summary.html[Helidon MicroProfile Reactive Messaging] * link:{microprofile-reactive-messaging-spec-url}[MicroProfile Reactive Messaging Specification] -* link:https://github.com/eclipse/microprofile-reactive-messaging[MicroProfile Reactive Messaging on GitHub] \ No newline at end of file +* link:https://github.com/eclipse/microprofile-reactive-messaging[MicroProfile Reactive Messaging on GitHub] + +== Additional Information + +=== Upgrading to Messaging 3.0 +.Non-backward compatible changes: +* Exceptions thrown in messaging methods are not propagated as error or cancel signals to the stream(use `mp.messaging.helidon.propagate-errors=true` for backward compatible mode) - errors are propagated only to the upstream by `nack` functionality. +* Default acknowledgement strategies changed for selected signatures(all with Message as a parameter or return type) - See the specification issue link:{https://github.com/eclipse/microprofile-reactive-messaging/pull/97}[#97] + diff --git a/docs/mp/reactivemessaging/jms.adoc b/docs/mp/reactivemessaging/jms.adoc index 0db1896f558..1cfad832a10 100644 --- a/docs/mp/reactivemessaging/jms.adoc +++ b/docs/mp/reactivemessaging/jms.adoc @@ -24,6 +24,7 @@ :feature-name: JMS Connector :microprofile-bundle: false :rootdir: {docdir}/../.. +:h1-prefix: MP include::{rootdir}/includes/mp.adoc[] include::{rootdir}/includes/dependencies.adoc[] diff --git a/docs/mp/reactivemessaging/kafka.adoc b/docs/mp/reactivemessaging/kafka.adoc index 5a877d65bf5..cb37b53cce7 100644 --- a/docs/mp/reactivemessaging/kafka.adoc +++ b/docs/mp/reactivemessaging/kafka.adoc @@ -24,6 +24,7 @@ :feature-name: Reactive Kafka Connector :microprofile-bundle: false :rootdir: {docdir}/../.. +:h1-prefix: MP == Contents diff --git a/docs/mp/reactivemessaging/mock.adoc b/docs/mp/reactivemessaging/mock.adoc index 473603a47b2..dd191312cc9 100644 --- a/docs/mp/reactivemessaging/mock.adoc +++ b/docs/mp/reactivemessaging/mock.adoc @@ -24,6 +24,7 @@ :feature-name: Mock Connector :microprofile-bundle: false :rootdir: {docdir}/../.. +:h1-prefix: MP == Contents From 2cfa5dbe67c01da717b36e0416a40967e3f7f955 Mon Sep 17 00:00:00 2001 From: Lisa Jamen <31409174+ljamen@users.noreply.github.com> Date: Fri, 12 Aug 2022 13:31:02 -0400 Subject: [PATCH 2/3] doc updates to mp reactive messaging --- docs/mp/reactivemessaging/aq.adoc | 9 ++++----- docs/mp/reactivemessaging/introduction.adoc | 18 +++++++++++------ docs/mp/reactivemessaging/jms.adoc | 1 - docs/mp/reactivemessaging/kafka.adoc | 15 ++++++++------ docs/mp/reactivemessaging/mock.adoc | 22 ++++++++++++--------- 5 files changed, 38 insertions(+), 27 deletions(-) diff --git a/docs/mp/reactivemessaging/aq.adoc b/docs/mp/reactivemessaging/aq.adoc index f442ff4f3ce..ae553d71bec 100644 --- a/docs/mp/reactivemessaging/aq.adoc +++ b/docs/mp/reactivemessaging/aq.adoc @@ -24,7 +24,6 @@ :feature-name: AQ Connector :microprofile-bundle: false :rootdir: {docdir}/../.. -:h1-prefix: MP include::{rootdir}/includes/mp.adoc[] include::{rootdir}/includes/dependencies.adoc[] @@ -40,9 +39,9 @@ include::{rootdir}/includes/dependencies.adoc[] == Reactive Oracle Advanced Queueing Connector Connecting streams to Oracle AQ with Reactive Messaging couldn't be easier. -This connector extends Helidon's JMS connector with Oracle AQ's specific API. +This connector extends Helidon's JMS connector with Oracle's AQ-specific API. -=== Config +=== Configuration Connector name: `helidon-aq` @@ -73,7 +72,7 @@ will not be added to the durable subscription. Default value: `false` they share same JMS session and same JDBC connection as well. |=== -=== Configured JMS factory +=== Configured JMS Factory The simplest possible usage is leaving construction of AQjmsConnectionFactory to the connector. @@ -136,7 +135,7 @@ mp: === Injected JMS factory -In case you need more advanced setup, connector can work with injected AQjmsConnectionFactory +If you need more advanced configurations, connector can work with injected `AQjmsConnectionFactory`: [source,java] .Inject: diff --git a/docs/mp/reactivemessaging/introduction.adoc b/docs/mp/reactivemessaging/introduction.adoc index b8091b47a01..9773f0bc16c 100644 --- a/docs/mp/reactivemessaging/introduction.adoc +++ b/docs/mp/reactivemessaging/introduction.adoc @@ -24,8 +24,8 @@ :feature-name: MicroProfile Reactive Messaging :microprofile-bundle: false :rootdir: {docdir}/../.. -:h1-prefix: MP +include::{rootdir}/includes/mp.adoc[] == Contents @@ -37,7 +37,8 @@ - <> == Overview -Reactive messaging is vastly different from the older method of using message-driven beans. One significant difference is that blocking is no longer the only way to apply backpressure to the message source. +Reactive messaging offers a new way of processing messages that is different from the older method of using message-driven beans. One significant difference is that blocking is no longer the only way to apply backpressure to the message source. + Reactive messaging uses reactive streams as message channels so you can construct very effective pipelines for working with the messages or, if you prefer, you can continue to use older messaging methods. Like the message-driven beans, link:{microprofile-reactive-messaging-spec-url}[MicroProfile Reactive Messaging] @@ -69,6 +70,11 @@ To include health checks for Messaging add the following dependency: == Usage +- <> +- <> +- <> + + === Channels Reactive messaging uses named channels to connect one source (upstream) with one consumer (downstream). @@ -162,10 +168,10 @@ public Publisher printMessage() { } ---- -**Caution**: Messaging methods are not meant to be invoked directly! +WARNING: Messaging methods are not meant to be invoked directly! === Emitter -To send messages from imperative code, we can inject a special channel source called an emitter. +To send messages from imperative code, you can inject a special channel source called an emitter. Emitter can serve only as an upstream, source of the messages, for messaging channel. [source,java] @@ -198,7 +204,7 @@ of the channel. In case there is not enough demand from the downstream, you can |NONE |Messages are sent to downstream even if there is no demand. Backpressure is effectively ignored. |=== -=== Processing method +==== Processing method Such link:{microprofile-reactive-messaging-spec-url}#_method_consuming_and_producing[methods] acts as processors, consuming messages from one channel and producing to another. @@ -276,7 +282,7 @@ public class ExampleConnector implements IncomingConnectorFactory, OutgoingConne == Configuration -Channel needs to be instructed to use connector as its upstream or downstream by configuration. +The channel must be configured to use connector as its upstream or downstream. [source,yaml] .Example of channel to connector mapping config: diff --git a/docs/mp/reactivemessaging/jms.adoc b/docs/mp/reactivemessaging/jms.adoc index 1cfad832a10..0db1896f558 100644 --- a/docs/mp/reactivemessaging/jms.adoc +++ b/docs/mp/reactivemessaging/jms.adoc @@ -24,7 +24,6 @@ :feature-name: JMS Connector :microprofile-bundle: false :rootdir: {docdir}/../.. -:h1-prefix: MP include::{rootdir}/includes/mp.adoc[] include::{rootdir}/includes/dependencies.adoc[] diff --git a/docs/mp/reactivemessaging/kafka.adoc b/docs/mp/reactivemessaging/kafka.adoc index cb37b53cce7..4288178cc41 100644 --- a/docs/mp/reactivemessaging/kafka.adoc +++ b/docs/mp/reactivemessaging/kafka.adoc @@ -24,14 +24,16 @@ :feature-name: Reactive Kafka Connector :microprofile-bundle: false :rootdir: {docdir}/../.. -:h1-prefix: MP + +include::{rootdir}/includes/mp.adoc[] == Contents - <> +- <> - <> +- <> -include::{rootdir}/includes/mp.adoc[] include::{rootdir}/includes/dependencies.adoc[] [source,xml] @@ -43,7 +45,7 @@ include::{rootdir}/includes/dependencies.adoc[] ---- == Overview -Connecting streams to Kafka with Reactive Messaging couldn't be easier. +Connecting streams to Kafka with Reactive Messaging is easy to do. There is a standard Kafka client behind the scenes, all the link:{kafka-client-base-url}#producerconfigs[producer] and link:{kafka-client-base-url}#consumerconfigs[consumer] configs can be propagated through messaging config. @@ -115,7 +117,7 @@ topic is present on the same Kafka cluster. Serializers are derived from deserializers used for consumption `org.apache.kafka.common.serialization.StringDeserializer` > `org.apache.kafka.common.serialization.StringSerializer`. -In this ideal case only the name of error topic is needed. +Note that the name of the error topic is needed only in this case. [source,yaml] .Example of derived DLQ config: @@ -126,8 +128,7 @@ mp.messaging: nack-dlq: dql_topic_name ---- -In case custom connection is needed, all the usual producer configuration is possible -under the `nack-dlq` key. +If a custom connection is needed, then use the 'nack-dlq' key for all of the producer configuration. [source,yaml] .Example of custom DLQ config: @@ -157,6 +158,8 @@ mp.messaging: nack-log-only: true ---- +== Examples + Don't forget to check out the examples with pre-configured Kafka docker image, for easy testing: * {helidon-github-tree-url}/examples/messaging \ No newline at end of file diff --git a/docs/mp/reactivemessaging/mock.adoc b/docs/mp/reactivemessaging/mock.adoc index dd191312cc9..7184a9667f3 100644 --- a/docs/mp/reactivemessaging/mock.adoc +++ b/docs/mp/reactivemessaging/mock.adoc @@ -24,15 +24,15 @@ :feature-name: Mock Connector :microprofile-bundle: false :rootdir: {docdir}/../.. -:h1-prefix: MP + +include::{rootdir}/includes/mp.adoc[] == Contents - <> -- <> -- <> +- <> - <> -- <> +- <> == Overview Mock connector is a simple application scoped bean that can be used for emitting to a channel @@ -59,7 +59,11 @@ For injecting Mock Connector use `@TestConnector` qualifier: MockConnector mockConnector; ---- -=== Emitting data +== Usage +- <> +- <> + +=== Emitting Data .Emitting String values `a`, `b`, `c` [source,java] @@ -70,7 +74,7 @@ mockConnector ---- <1> Get incoming channel of given name and payload type -=== Asserting data +=== Asserting Data .Awaiting and asserting payloads with custom mapper [source,java] @@ -89,11 +93,11 @@ mockConnector |mock-data-type |java.lang.String| Type of the emitted initial data to be emitted |=== -== Helidon test with Mock Connector +== Helidon Test with Mock Connector Mock connector works great with built-in Helidon test support for -link:/{rootdir}/testing/testing.adoc[JUnit 5] or link:/{rootdir}/testing/testing-ng.adoc[Test NG]. +link:/{rootdir}/testing/testing.adoc[JUnit 5] or link:/{rootdir}/testing/testing-ng.adoc[TestNG]. -As Helidon test support makes a bean out of your test, you can inject MockConnector right in to it. +As Helidon test support makes a bean out of your test, you can inject MockConnector directly into it. [source,java] ---- From 119ba29a25405e93a07c3d6a94ed8b7e279dccea Mon Sep 17 00:00:00 2001 From: Lisa Jamen <31409174+ljamen@users.noreply.github.com> Date: Fri, 12 Aug 2022 13:58:24 -0400 Subject: [PATCH 3/3] doc updates to mp reactive messaging --- docs/mp/reactivemessaging/introduction.adoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/mp/reactivemessaging/introduction.adoc b/docs/mp/reactivemessaging/introduction.adoc index 9773f0bc16c..956f9030830 100644 --- a/docs/mp/reactivemessaging/introduction.adoc +++ b/docs/mp/reactivemessaging/introduction.adoc @@ -82,16 +82,16 @@ Each channel needs to have both ends connected otherwise the container cannot su image::msg/channel.svg[Messaging Channel] -Channels can be connected either to <> (1), <> (2) or <> (3) on the upstream side. And <> (4), <> (5) or <> (6) +Channels can be connected either to <> (1), <> (2) or <> (3) on the upstream side. And <> (4), <> (5) or <> (6) on the downstream. -==== Consuming method +==== Consuming Method Consuming methods can be connected to the channel's downstream to consume the message coming through the channel. The incoming annotation has one required attribute `value` that defines the channel name. Consuming method can function in two ways: -* consume every message coming from the stream connected to the <> - invoked per each message +* consume every message coming from the stream connected to the <> - invoked per each message * prepare reactive stream's subscriber and connect it to the channel - invoked only once during the channel construction [source,java] @@ -114,7 +114,7 @@ public Subscriber printMessage() { } ---- -==== Injected publisher +==== Injected Publisher Directly injected publisher can be connected as a channel downstream, you can consume the data from the channel by subscribing to it. @@ -140,7 +140,7 @@ public MyBean(@Channel("example-channel-1") Multi multiChannel) { } ---- -==== Producing method +==== Producing Method The annotation has one required attribute `value` that defines the link:{microprofile-reactive-messaging-spec-url}#_channel[channel] name. @@ -204,7 +204,7 @@ of the channel. In case there is not enough demand from the downstream, you can |NONE |Messages are sent to downstream even if there is no demand. Backpressure is effectively ignored. |=== -==== Processing method +==== Processing Method Such link:{microprofile-reactive-messaging-spec-url}#_method_consuming_and_producing[methods] acts as processors, consuming messages from one channel and producing to another.