In this sample, we'll create two java applications: an output binding application and an input binding application, using Dapr Java SDK. This sample includes two applications:
- InputBindingExample (Initializes the Dapr Spring boot application client)
- OutputBindingExample (pushes the event message)
Visit this link for more information about Dapr and bindings concepts.
In this example, the component used is Kafka but others are also available.
Visit this link for more information about binding implementations.
- Dapr and Dapr Cli.
- Java JDK 11 (or greater):
- Apache Maven version 3.x.
Clone this repository:
git clone https://github.com/dapr/java-sdk.git
cd java-sdk
Then build the Maven project:
# make sure you are in the `java-sdk` directory.
mvn install
Then, go into the examples directory:
cd examples
Before getting into the application code, follow these steps in order to set up a local instance of Kafka. This is needed for the local instances. Steps are:
- To run container locally run:
docker-compose -f ./src/main/java/io/dapr/examples/bindings/http/docker-compose-single-kafka.yml up -d
- Run
docker ps
to see the container running locally:
342d3522ca14 kafka-docker_kafka "start-kafka.sh" 14 hours ago Up About
a minute 0.0.0.0:9092->9092/tcp kafka-docker_kafka_1
0cd69dbe5e65 wurstmeister/zookeeper "/bin/sh -c '/usr/sb…" 8 days ago Up About
a minute 22/tcp, 2888/tcp, 3888/tcp, 0.0.0.0:2181->2181/tcp kafka-docker_zookeeper_1
Click here for more information about the kafka broker server.
The input binding sample uses the Spring Boot´s DaprApplication class for initializing the InputBindingController
. In InputBindingExample.java
file, you will find the InputBindingExample
class and the main
method. See the code snippet below:
public class InputBindingExample {
public static void main(String[] args) throws Exception {
///..
// If port string is not valid, it will throw an exception.
int port = Integer.parseInt(cmd.getOptionValue("port"));
// Start Dapr's callback endpoint.
DaprApplication.start(port);
}
///...
}
DaprApplication.start()
Method will run an Spring Boot application that registers the InputBindingController
, which exposes the actual handling of the event message as a POST request. The Dapr's sidecar is the one that performs the actual call to this controller, based on the binding features and the output binding action.
@RestController
public class InputBindingController {
@PostMapping(path = "/bindingSample")
public Mono<Void> handleInputBinding(@RequestBody(required = false) byte[] body) {
return Mono.fromRunnable(() ->
System.out.println("Received message through binding: " + (body == null ? "" : new String(body))));
}
}
Execute the follow script in order to run the Input Binding example:
dapr run --components-path ./components/bindings --app-id inputbinding --app-port 3000 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.bindings.http.InputBindingExample -p 3000
The output binding application is a simple java class with a main method that uses the Dapr Client to invoke binding.
In the OutputBindingExample.java
file, you will find the OutputBindingExample
class, containing the main method. The main method declares a Dapr Client using the DaprClientBuilder
class. Notice that this builder gets two serializer implementations in the constructor: One is for Dapr's sent and recieved objects, and second is for objects to be persisted. The client publishes events using invokeBinding
method. The Dapr client is also within a try-with-resource block to properly close the client at the end. See the code snippet below:
public class OutputBindingExample{
///...
static final String BINDING_NAME = "sample123";
static final String BINDING_OPERATION = "create";
///...
public static void main(String[] args) throws Exception {
try (DaprClient client = new DaprClientBuilder().build()) {
int count = 0;
while (!Thread.currentThread().isInterrupted()) {
String message = "Message #" + (count);
// On even number, send class message
if (count % 2 == 0) {
// This is an example of sending data in a user-defined object. The input binding will receive:
// {"message":"hello"}
MyClass myClass = new MyClass();
myClass.message = message;
System.out.println("sending a class with message: " + myClass.message);
client.invokeBinding(BINDING_NAME, BINDING_OPERATION, myClass).block();
} else {
System.out.println("sending a plain string: " + message);
client.invokeBinding(BINDING_NAME, BINDING_OPERATION, message).block();
}
count++;
try {
Thread.sleep((long) (10000 * Math.random()));
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
System.out.println("Done.");
}
}
///...
}
This example binds two events: A user-defined data object (using the myClass
object as parameter) and a simple string using the same invokeBinding
method.
Use the follow command to execute the Output Binding example:
dapr run --components-path ./components/bindings --app-id outputbinding -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.bindings.http.OutputBindingExample
Once running, the OutputBindingExample should print the output as follows:
== APP == sending a class with message: Message #0
== APP == sending a plain string: Message #1
== APP == sending a class with message: Message #2
== APP == sending a plain string: Message #3
Events have been sent.
Once running, the InputBindingExample should print the output as follows:
== APP == Received message through binding: {"message":"Message #0"}
== APP == Received message through binding: "Message #1"
== APP == Received message through binding: {"message":"Message #2"}
== APP == Received message through binding: "Message #3"
Events have been retrieved from the binding.
To stop both apps, press CTRL+C
or run:
dapr stop --app-id inputbinding
dapr stop --app-id outputbinding
For bringing down the kafka cluster that was started in the beginning, run
docker-compose -f ./src/main/java/io/dapr/examples/bindings/http/docker-compose-single-kafka.yml down
For more details on Dapr Spring Boot integration, please refer to Dapr Spring Boot Application implementation.