Home > Mobile >  Execute docker command inside container from Java application
Execute docker command inside container from Java application

Time:06-26

I am running Kafka inside a container and would like to be able to run a simple command to change the number of partitions on a topic from Java application (Spring-Boot).

I have tried with ProcessBuilder but from what I have read any the error message I get I can´t do it thru processbuilder.

Instead I have tried to look in to Docker API but can´t understand / find any solution.

What I would like to do: run: docker exec -it kafka bash and then inside the Kafka container run: ./bin/kafka-topics.sh --alter --zookeeper zookeeper:2181 --topic topicName --partitions 5

Is their a simple way to do this?

CodePudding user response:

Where Kafka is running is not relevant to the question. You will only need it to be resolvable (use bootstrap-server, not deprecated zookeeper config)

The shell scripts are simply wrappers around existing Java classes that you can import and call in your own Java code, so you should not use ProcessBuilder or docker exec. You can also try defining a @Bean for NewTopic in your Spring config when using Spring-Kafka, but I'm not sure if changing the partition count in the config will actually send an alter request or will ignore the change for existing topics.

Keep in mind that you should not modify partition count for topics that are actively receiving data, so stop existing producers and consumers first.

CodePudding user response:

Solution was brought by @David Maze

You should be able to use the Kafka admin API to do this. You don't need to execute a command, you don't need debugging tools like docker exec to do it, and you don't need the unrestricted root-level permissions the Docker access would provide. – David Maze

It worked as a charm! Thank you!

I didn´t need to add more than this:

public static void changePartitions(String topicName, int numPartitions) {
    Properties props = new Properties();
    props.put("bootstrap.servers", "localhost:9094");
    AdminClient adminClient = AdminClient.create(props);

    Map<String, NewPartitions> newPartitionSet = new HashMap<>();
    newPartitionSet.put(topicName, NewPartitions.increaseTo(numPartitions));
    adminClient.createPartitions(newPartitionSet);
    adminClient.close();
}
  • Related