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 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-sdkThen build the Maven project:
# make sure you are in the `java-sdk` directory.
mvn installThen, go into the examples directory:
cd examplesRun dapr init to initialize Dapr in Self-Hosted Mode if it's not already initialized.
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.
- Run the Kafka locally:
docker compose -f ./src/main/java/io/dapr/examples/bindings/http/docker-compose-single-kafka.yml up -d- Run
docker psto see the container running locally:
26966aaabd82 confluentinc/cp-kafka:7.4.4 "/etc/confluent/dock…" About a minute ago Up About a minute 9092/tcp, 0.0.0.0:29092->29092/tcp deploy-kafka-1
b95e7ad31707 confluentinc/cp-zookeeper:7.4.4 "/etc/confluent/dock…" 5 days ago Up 14 minutes 2888/tcp, 3888/tcp, 0.0.0.0:22181->2181/tcp deploy-zookeeper-1Click here for more information about the kafka broker server.
Dapr supports API token authentication to secure communication between Dapr and your application. When using input bindings, Dapr makes incoming calls to your app, and you can validate these requests using the APP_API_TOKEN.
For detailed implementation with gRPC interceptors, see the PubSub README App API Token Authentication section.
For HTTP-based apps, check the dapr-api-token header in incoming requests. For more details, see the Dapr App API Token Authentication documentation.
Quick setup:
# Export tokens before running the following `dapr run` commands.
export APP_API_TOKEN="your-app-api-token"
export DAPR_API_TOKEN="your-dapr-api-token"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 following command to run the Input Binding example:
dapr run --resources-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 3000The 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 the second is for objects to be persisted. The client publishes events using the 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.
Execute the following command to run the Output Binding example:
dapr run --resources-path ./components/bindings --app-id outputbinding -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.bindings.http.OutputBindingExampleOnce running, the OutputBindingExample should print the output as follows:
sending a class with message: Message #0
sending a plain string: Message #1
sending a class with message: Message #2
sending a plain string: Message #3Events have been sent.
Once running, the InputBindingExample should print the output as follows:
Received message through binding: {"message":"Message #0"}
Received message through binding: "Message #1"
Received message through binding: {"message":"Message #2"}
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 outputbindingFor 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 downFor more details on the Dapr Spring Boot integration, please refer to the Dapr Spring Boot Application implementation.