Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Multi-language docs examples for client configuration and method examples #836

Merged
merged 1 commit into from
Aug 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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[]
}