Skip to content

Commit

Permalink
Multi-language docs examples for client configuration and method exam…
Browse files Browse the repository at this point in the history
…ples (#836)
  • Loading branch information
wetted authored Aug 24, 2023
1 parent 535aba8 commit 15c234f
Show file tree
Hide file tree
Showing 17 changed files with 264 additions and 55 deletions.
6 changes: 2 additions & 4 deletions src/main/docs/guide/kafkaClient/kafkaClientConfiguration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ Any property in the link:{kafkaapi}/org/apache/kafka/clients/producer/ProducerCo
To configure different properties for each client, you should set a `@KafkaClient` id using the annotation:

.Using a Client ID
[source,java]
----
@KafkaClient("product-client")
----

snippet::io.micronaut.kafka.docs.producer.config.ClientIdClient[tags="annotation"]

This serves 2 purposes. Firstly it sets the value of the `client.id` setting used to build the `Producer`. Secondly, it allows you to apply per producer configuration in `application.yml`:

Expand Down
62 changes: 11 additions & 51 deletions src/main/docs/guide/kafkaClient/kafkaClientMethods.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,16 @@ The Kafka key can be specified by providing a parameter annotated with `@KafkaKe

The value to send is resolved by selecting the argument annotated with https://docs.micronaut.io/latest/api/io/micronaut/messaging/annotation/MessageBody.html[@MessageBody], otherwise the first argument with no specific binding annotation is used. For example:

[source,java]
----
@Topic("my-products")
void sendProduct(@KafkaKey String brand, String name);
----

snippet::io.micronaut.kafka.docs.producer.methods.ProductClient[tags=key,indents=0]

The method above will use the parameter `brand` as the key and the parameter `name` as the value.

=== Including Message Headers

There are a number of ways you can include message headers. One way is to annotate an argument with the https://docs.micronaut.io/latest/api/io/micronaut/messaging/annotation/MessageHeader.html[@MessageHeader] annotation and include a value when calling the method:

[source,java]
----
@Topic("my-products")
void sendProduct(
@KafkaKey String brand,
String name,
@MessageHeader("My-Header") String myHeader);
----
snippet::io.micronaut.kafka.docs.producer.methods.ProductClient[tags=messageheader,indents=0]

The example above will include the value of the `myHeader` argument as a header called `My-Header`.

Expand All @@ -40,26 +30,14 @@ If the `my.application.token` is not set then an error will occur creating the c
It is also possible to pass `Collection<Header>` or `Headers` object as method arguments as seen below.

.Collection<Header> Argument
[source,java]
----
@Topic("my-bicycles")
void sendBicycle(
@KafkaKey String brand,
String model,
Collection<Header> headers);
----

snippet::io.micronaut.kafka.docs.producer.methods.ProductClient[tags=collectionheaders,indents=0]

https://javadoc.io/doc/org.apache.kafka/kafka-clients/latest/org/apache/kafka/common/header/Header.html[Kafka Header Javadocs]

.Headers Argument
[source,java]
----
@Topic("my-bicycles")
void sendBicycle(
@KafkaKey String brand,
String model,
Headers headers);
----

snippet::io.micronaut.kafka.docs.producer.methods.ProductClient[tags=kafkaheaders,indents=0]

https://javadoc.io/doc/org.apache.kafka/kafka-clients/latest/org/apache/kafka/common/header/Headers.html[Kafka Headers Javadocs]

Expand All @@ -74,37 +52,19 @@ The following sections cover possible method signatures and behaviour:

==== Single Value and Return Type

[source,java]
----
Single<Book> sendBook(
@KafkaKey String author,
Single<Book> book
);
----
snippet::io.micronaut.kafka.docs.producer.methods.BookClient[tags=single,indents=0]

The implementation will return a rx:Single[] that when subscribed to will subscribe to the passed rx:Single[] and send the emitted item as a `ProducerRecord` emitting the item again if successful or an error otherwise.

==== Flowable Value and Return Type

[source,java]
----
Flowable<Book> sendBooks(
@KafkaKey String author,
Flowable<Book> book
);
----
snippet::io.micronaut.kafka.docs.producer.methods.BookClient[tags=flowable,indents=0]

The implementation will return a rx:Flowable[] that when subscribed to will subscribe to the passed rx:Flowable[] and for each emitted item will send a `ProducerRecord` emitting the item again if successful or an error otherwise.

==== Flowable Value and Return Type
==== Flux Value and Return Type

[source,java]
----
Flux<RecordMetadata> sendBooks(
@KafkaKey String author,
Flux<Book> book
);
----
snippet::io.micronaut.kafka.docs.producer.methods.BookClient[tags=flux,indents=0]

The implementation will return a Reactor `Flux` that when subscribed to will subscribe to the passed `Flux` and for each emitted item will send a `ProducerRecord` emitting the resulting Kafka `RecordMetadata` if successful or an error otherwise.

Expand Down
1 change: 1 addition & 0 deletions test-suite-groovy/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ plugins {
dependencies {
testImplementation(platform(mn.micronaut.core.bom))
testCompileOnly(mn.micronaut.inject.groovy)
testImplementation(mn.micronaut.messaging)
testImplementation(mnSerde.micronaut.serde.jackson)
testImplementation(libs.testcontainers.kafka)
testImplementation(mnTest.micronaut.test.spock)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.micronaut.kafka.docs.producer.config

import io.micronaut.configuration.kafka.annotation.KafkaClient
import io.micronaut.context.annotation.Requires

@Requires(property = 'spec.name', value = 'ClientIdClientTest')
// tag::annotation[]
@KafkaClient('product-client')
// end::annotation[]
interface ClientIdClient {
// define client API
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.micronaut.kafka.docs.producer.methods

import groovy.transform.Canonical

@Canonical
class Book {
String title
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.micronaut.kafka.docs.producer.methods

import io.micronaut.configuration.kafka.annotation.KafkaClient
import io.micronaut.configuration.kafka.annotation.KafkaKey
import io.micronaut.configuration.kafka.annotation.Topic
import io.micronaut.context.annotation.Requires
import io.reactivex.Flowable
import io.reactivex.Single
import org.apache.kafka.clients.producer.RecordMetadata
import reactor.core.publisher.Flux

@Requires(property = 'spec.name', value = 'BookClientTest')
@KafkaClient('product-client')
interface BookClient {

// tag::single[]
@Topic('my-books')
Single<Book> sendBook(@KafkaKey String author, Single<Book> book);
// end::single[]

// tag::flowable[]
@Topic('my-books')
Flowable<Book> sendBooks(@KafkaKey String author, Flowable<Book> book);
// end::flowable[]

// tag::flux[]
@Topic('my-books')
Flux<RecordMetadata> sendBooks(@KafkaKey String author, Flux<Book> book);
// end::flux[]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.micronaut.kafka.docs.producer.methods

import io.micronaut.configuration.kafka.annotation.KafkaClient
import io.micronaut.configuration.kafka.annotation.KafkaKey
import io.micronaut.configuration.kafka.annotation.Topic
import io.micronaut.context.annotation.Requires
import io.micronaut.messaging.annotation.MessageHeader
import org.apache.kafka.common.header.Header
import org.apache.kafka.common.header.Headers

@Requires(property = 'spec.name', value = 'ProductClientTest')
@KafkaClient('product-client')
interface ProductClient {

// tag::key[]
@Topic('my-products')
void sendProduct(@KafkaKey String brand, String name)
// end::key[]

// tag::messageheader[]
@Topic('my-products')
void sendProduct(@KafkaKey String brand, String name, @MessageHeader('My-Header') String myHeader)
// end::messageheader[]

// tag::collectionheaders[]
@Topic('my-bicycles')
void sendBicycle(@KafkaKey String brand, String model, Collection<Header> headers)
// end::collectionheaders[]

// tag::kafkaheaders[]
@Topic('my-bicycles')
void sendBicycle(@KafkaKey String brand, String model, Headers headers)
// end::kafkaheaders[]
}
1 change: 1 addition & 0 deletions test-suite-kotlin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ plugins {
dependencies {
kaptTest(platform(mn.micronaut.core.bom))
kaptTest(mn.micronaut.inject.java)
testImplementation(mn.micronaut.messaging)
testImplementation(mnSerde.micronaut.serde.jackson)
testImplementation(libs.testcontainers.kafka)
testImplementation(mnTest.micronaut.test.junit5)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.micronaut.kafka.docs.producer.config

import io.micronaut.configuration.kafka.annotation.KafkaClient
import io.micronaut.context.annotation.Requires

@Requires(property = "spec.name", value = "ClientIdClientTest")
// tag::annotation[]
@KafkaClient("product-client")
// end::annotation[]
interface ClientIdClient {
// define client API
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package io.micronaut.kafka.docs.producer.methods

data class Book(val title: String)
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.micronaut.kafka.docs.producer.methods

import io.micronaut.configuration.kafka.annotation.KafkaClient
import io.micronaut.configuration.kafka.annotation.KafkaKey
import io.micronaut.configuration.kafka.annotation.Topic
import io.micronaut.context.annotation.Requires
import io.reactivex.Flowable
import io.reactivex.Single
import org.apache.kafka.clients.producer.RecordMetadata
import reactor.core.publisher.Flux

@Requires(property = "spec.name", value = "BookClientTest")
@KafkaClient("product-client")
interface BookClient {

// tag::single[]
@Topic("my-books")
fun sendBook(@KafkaKey author: String, book: Single<Book>): Single<Book>
// end::single[]

// tag::flowable[]
@Topic("my-books")
fun sendBooks(@KafkaKey author: String, book: Flowable<Book>): Flowable<Book>
// end::flowable[]

// tag::flux[]
@Topic("my-books")
fun sendBooks(@KafkaKey author: String, book: Flux<Book>): Flux<RecordMetadata>
// end::flux[]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.micronaut.kafka.docs.producer.methods

import io.micronaut.configuration.kafka.annotation.KafkaClient
import io.micronaut.configuration.kafka.annotation.KafkaKey
import io.micronaut.configuration.kafka.annotation.Topic
import io.micronaut.context.annotation.Requires
import io.micronaut.messaging.annotation.MessageHeader
import org.apache.kafka.common.header.Header
import org.apache.kafka.common.header.Headers

@Requires(property = "spec.name", value = "ProductClientTest")
@KafkaClient("product-client")
interface ProductClient {

// tag::key[]
@Topic("my-products")
fun sendProduct(@KafkaKey brand: String, name: String)
// end::key[]

// tag::messageheader[]
@Topic("my-products")
fun sendProduct(@KafkaKey brand: String, name: String, @MessageHeader("My-Header") myHeader: String)
// end::messageheader[]

// tag::collectionheaders[]
@Topic("my-bicycles")
fun sendBicycle(@KafkaKey brand: String, model: String, headers: Collection<Header>)
// end::collectionheaders[]

// tag::kafkaheaders[]
@Topic("my-bicycles")
fun sendBicycle(@KafkaKey brand: String, model: String, headers: Headers)
// end::kafkaheaders[]
}
1 change: 1 addition & 0 deletions test-suite/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ plugins {
dependencies {
testAnnotationProcessor(platform(mn.micronaut.core.bom))
testAnnotationProcessor(mn.micronaut.inject.java)
testImplementation(mn.micronaut.messaging)
testImplementation(mnSerde.micronaut.serde.jackson)
testImplementation(libs.testcontainers.kafka)
testImplementation(mnTest.micronaut.test.junit5)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.micronaut.kafka.docs.producer.config;

import io.micronaut.configuration.kafka.annotation.KafkaClient;
import io.micronaut.context.annotation.Requires;

@Requires(property = "spec.name", value = "ClientIdClientTest")
// tag::annotation[]
@KafkaClient("product-client")
// end::annotation[]
public interface ClientIdClient {
// define client API
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.micronaut.kafka.docs.producer.methods;

import io.micronaut.serde.annotation.Serdeable;

@Serdeable
public record Book(String title) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.micronaut.kafka.docs.producer.methods;

import io.micronaut.configuration.kafka.annotation.KafkaClient;
import io.micronaut.configuration.kafka.annotation.KafkaKey;
import io.micronaut.configuration.kafka.annotation.Topic;
import io.micronaut.context.annotation.Requires;
import io.reactivex.Flowable;
import io.reactivex.Single;
import org.apache.kafka.clients.producer.RecordMetadata;
import reactor.core.publisher.Flux;

@Requires(property = "spec.name", value = "BookClientTest")
@KafkaClient("product-client")
public interface BookClient {

// tag::single[]
@Topic("my-books")
Single<Book> sendBook(@KafkaKey String author, Single<Book> book);
// end::single[]

// tag::flowable[]
@Topic("my-books")
Flowable<Book> sendBooks(@KafkaKey String author, Flowable<Book> book);
// end::flowable[]

// tag::flux[]
@Topic("my-books")
Flux<RecordMetadata> sendBooks(@KafkaKey String author, Flux<Book> book);
// end::flux[]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.micronaut.kafka.docs.producer.methods;

import io.micronaut.configuration.kafka.annotation.KafkaClient;
import io.micronaut.configuration.kafka.annotation.KafkaKey;
import io.micronaut.configuration.kafka.annotation.Topic;
import io.micronaut.context.annotation.Requires;
import io.micronaut.messaging.annotation.MessageHeader;
import org.apache.kafka.common.header.Header;
import org.apache.kafka.common.header.Headers;

import java.util.Collection;

@Requires(property = "spec.name", value = "ProductClientTest")
@KafkaClient("product-client")
public interface ProductClient {

// tag::key[]
@Topic("my-products")
void sendProduct(@KafkaKey String brand, String name);
// end::key[]

// tag::messageheader[]
@Topic("my-products")
void sendProduct(@KafkaKey String brand, String name, @MessageHeader("My-Header") String myHeader);
// end::messageheader[]

// tag::collectionheaders[]
@Topic("my-bicycles")
void sendBicycle(@KafkaKey String brand, String model, Collection<Header> headers);
// end::collectionheaders[]

// tag::kafkaheaders[]
@Topic("my-bicycles")
void sendBicycle(@KafkaKey String brand, String model, Headers headers);
// end::kafkaheaders[]
}

0 comments on commit 15c234f

Please sign in to comment.