这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
18f30b5
opentelemtry for spring boot 3
saikatcse03 Apr 3, 2025
73dfadb
refactoring
saikatcse03 Apr 7, 2025
0f15676
fixed lint issues
saikatcse03 Apr 7, 2025
84560eb
refactoring
saikatcse03 Apr 8, 2025
7dbf4ee
Merge branch 'eugenp:master' into master
saikatcse03 Apr 8, 2025
34fb0d5
remove all deprecated code related to spring cloud sleuth
saikatcse03 Apr 8, 2025
a8ab29b
include version property
saikatcse03 Apr 8, 2025
03be93c
include version property
saikatcse03 Apr 8, 2025
0cb7cdb
Merge branch 'eugenp:master' into master
saikatcse03 May 8, 2025
4006d91
Merge branch 'eugenp:master' into master
saikatcse03 May 13, 2025
a6efe71
Merge branch 'eugenp:master' into master
saikatcse03 May 21, 2025
ac002d9
move spring-kafka article code to this module
saikatcse03 May 21, 2025
fafb7a7
remove code related to SASL article
saikatcse03 May 21, 2025
a96635b
Merge branch 'master' into master
saikatcse03 May 23, 2025
7c1d1d9
Merge branch 'eugenp:master' into master
saikatcse03 Jun 8, 2025
d4d63c0
Merge branch 'eugenp:master' into master
saikatcse03 Jun 12, 2025
25f5b23
sasl plaintext implemented
saikatcse03 Jun 14, 2025
b99e51a
refactor the sasl config and test
saikatcse03 Jun 15, 2025
1b12cc7
removed unrelated code
saikatcse03 Jun 17, 2025
c7aae98
removed unrelated code
saikatcse03 Jun 17, 2025
ca5eccb
removed unrelated code
saikatcse03 Jun 17, 2025
d996b27
Merge branch 'eugenp:master' into master
saikatcse03 Jun 17, 2025
ba232db
implement SASL Plain
saikatcse03 Jun 17, 2025
3c90a83
refactor the configs
saikatcse03 Jun 20, 2025
ca43dae
remove the lombok dependency and spring test
saikatcse03 Jun 21, 2025
ca4cd66
refactoring error fixes
saikatcse03 Jun 21, 2025
da1652b
fix indentation in jaas configs
saikatcse03 Jun 24, 2025
c4198aa
fix method typo
saikatcse03 Jun 24, 2025
0ab2599
Merge branch 'master' into BAEL-9070
theangrydev Jul 16, 2025
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
1 change: 0 additions & 1 deletion spring-kafka-4/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
Expand Down
24 changes: 24 additions & 0 deletions spring-kafka-4/src/main/java/com/baeldung/sasl/KafkaConsumer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.baeldung.sasl;

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class KafkaConsumer {

private static final Logger LOGGER = LoggerFactory.getLogger(KafkaConsumer.class);
public static final String TOPIC = "test-topic";
public final List<String> messages = new ArrayList<>();

@KafkaListener(topics = TOPIC)
public void receive(ConsumerRecord<String, String> consumerRecord) {
LOGGER.info("Received payload: '{}'", consumerRecord.toString());
messages.add(consumerRecord.value());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.baeldung.sasl;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class KafkaSaslApplication {

public static void main(String[] args) {
System.setProperty("spring.config.name", "application-sasl");
SpringApplication.run(KafkaSaslApplication.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.baeldung.saslplaintext;

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class KafkaConsumer {

private static final Logger LOGGER = LoggerFactory.getLogger(KafkaConsumer.class);
public static final String TOPIC = "test-topic";
public final List<String> messages = new ArrayList<>();

@KafkaListener(topics = TOPIC)
public void receive(ConsumerRecord<String, String> consumerRecord) {
LOGGER.info("Received payload: '{}'", consumerRecord.toString());
messages.add(consumerRecord.value());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.baeldung.saslplaintext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;

@Component
public class KafkaProducer {

private static final Logger LOGGER = LoggerFactory.getLogger(KafkaProducer.class);
private final KafkaTemplate<String, String> kafkaTemplate;

public KafkaProducer(KafkaTemplate<String, String> kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
}

public void sendMessage(String message, String topic) {
LOGGER.info("Producing message: {}", message);
kafkaTemplate.send(topic, "key", message)
.whenComplete((result, ex) -> {
if (ex == null) {
LOGGER.info("Message sent to topic: {}", message);
} else {
LOGGER.error("Failed to send message", ex);
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.baeldung.saslplaintext;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class KafkaSaslPlaintextApplication {

public static void main(String[] args) {
System.setProperty("spring.config.name", "application-sasl-plaintext");
SpringApplication.run(KafkaSaslPlaintextApplication.class, args);
}
}
16 changes: 16 additions & 0 deletions spring-kafka-4/src/main/resources/application-sasl-plaintext.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
spring:
kafka:
bootstrap-servers: localhost:9092
properties:
sasl.mechanism: PLAIN
sasl.jaas.config: >
org.apache.kafka.common.security.plain.PlainLoginModule required
username="user1"
password="user1-secret";
security:
protocol: SASL_PLAINTEXT
consumer:
group-id: test-group
auto-offset-reset: earliest
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
19 changes: 19 additions & 0 deletions spring-kafka-4/src/main/resources/application-sasl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
spring:
kafka:
bootstrap-servers: localhost:9092
properties:
sasl.mechanism: GSSAPI
sasl.jaas.config: >
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
keyTab="./src/test/resources/sasl/keytabs/client.keytab"
principal="client@BAELDUNG.COM"
serviceName="kafka";
security:
protocol: "SASL_PLAINTEXT"
consumer:
group-id: test
auto-offset-reset: earliest
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.baeldung.sasl;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = KafkaSaslApplication.class)
class SpringContextTest {

@Test
void whenSpringContextIsBootstrapped_thenNoExceptions() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.baeldung.saslplaintext;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.testcontainers.containers.DockerComposeContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

import java.io.File;
import java.time.Duration;
import java.util.UUID;

import static com.baeldung.saslplaintext.KafkaConsumer.TOPIC;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;

@Testcontainers
@ActiveProfiles("sasl-plaintext")
@SpringBootTest(classes = KafkaSaslPlaintextApplication.class)
class KafkaSaslPlaintextApplicationLiveTest {

private static final File KAFKA_COMPOSE_FILE = new File("src/test/resources/sasl-plaintext/docker-compose.yml");
private static final String KAFKA_SERVICE = "kafka";
private static final int SASL_PORT = 9092;

@Container
public DockerComposeContainer<?> container =
new DockerComposeContainer<>(KAFKA_COMPOSE_FILE)
.withExposedService(KAFKA_SERVICE, SASL_PORT, Wait.forListeningPort());

@Autowired
private KafkaProducer kafkaProducer;

@Autowired
private KafkaConsumer kafkaConsumer;

@Test
void givenSaslIsConfigured_whenProducerSendsMessageOverSasl_thenConsumerReceivesOverSasl() {
String message = UUID.randomUUID().toString();
kafkaProducer.sendMessage(message, TOPIC);

await().atMost(Duration.ofMinutes(2))
.untilAsserted(() -> assertThat(kafkaConsumer.messages).containsExactly(message));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
KafkaServer {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="admin"
password="admin-secret"
user_admin="admin-secret"
user_user1="user1-secret";
};

Client {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="zookeeper"
password="zookeeper-secret";
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Server {
org.apache.zookeeper.server.auth.DigestLoginModule required
username="zookeeper"
password="zookeeper-secret"
user_zookeeper="zookeeper-secret";
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
services:
zookeeper:
image: confluentinc/cp-zookeeper:7.6.6
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/zookeeper_jaas.conf"
volumes:
- ./config/zookeeper_jaas.conf:/etc/kafka/zookeeper_jaas.conf
ports:
- 2181

kafka:
image: confluentinc/cp-kafka:7.6.6
depends_on:
- zookeeper
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_LISTENERS: SASL_PLAINTEXT://0.0.0.0:9092
KAFKA_ADVERTISED_LISTENERS: SASL_PLAINTEXT://localhost:9092
KAFKA_INTER_BROKER_LISTENER_NAME: SASL_PLAINTEXT
KAFKA_SASL_ENABLED_MECHANISMS: PLAIN
KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: PLAIN
KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf"
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
volumes:
- ./config/kafka_server_jaas.conf:/etc/kafka/kafka_server_jaas.conf
ports:
- "9092:9092"
15 changes: 15 additions & 0 deletions spring-kafka-4/src/test/resources/sasl/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Use a minimal base image
FROM debian:bullseye

RUN apt-get update && \
apt-get install -y krb5-kdc krb5-admin-server krb5-user && \
rm -rf /var/lib/apt/lists/*

COPY config/krb5.conf /etc/krb5.conf
COPY setup_kdc.sh /setup_kdc.sh

RUN chmod +x /setup_kdc.sh

EXPOSE 88 749

CMD ["/setup_kdc.sh"]
1 change: 1 addition & 0 deletions spring-kafka-4/src/test/resources/sasl/config/kadm5.acl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*/admin@BAELDUNG.COM *
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
KafkaServer {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
keyTab="/etc/kafka/keytabs/kafka.keytab"
principal="kafka/localhost@BAELDUNG.COM"
serviceName="kafka";
};

Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
keyTab="/etc/kafka/keytabs/client.keytab"
principal="client@BAELDUNG.COM"
serviceName="kafka";
};
17 changes: 17 additions & 0 deletions spring-kafka-4/src/test/resources/sasl/config/krb5.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[libdefaults]
default_realm = BAELDUNG.COM
dns_lookup_realm = false
dns_lookup_kdc = false
forwardable = true
rdns = true

[realms]
BAELDUNG.COM = {
kdc = kdc
admin_server = kdc
}

[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
keyTab="/etc/kafka/keytabs/zookeeper.keytab"
principal="zookeeper/zookeeper.sasl_default@BAELDUNG.COM";
};
50 changes: 50 additions & 0 deletions spring-kafka-4/src/test/resources/sasl/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
services:

kdc:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./config:/etc/krb5kdc
- ./keytabs:/etc/krb5kdc/keytabs
- ./config/krb5.conf:/etc/krb5.conf
ports:
- "88:88/udp"

zookeeper:
image: confluentinc/cp-zookeeper:latest
container_name: zookeeper
hostname: localhost
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/zookeeper_jaas.conf"
volumes:
- ./config/zookeeper_jaas.conf:/etc/kafka/zookeeper_jaas.conf
- ./keytabs:/etc/kafka/keytabs
- ./config/krb5.conf:/etc/krb5.conf
ports:
- "2181:2181"

kafka:
image: confluentinc/cp-kafka:latest
container_name: kafka
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: GSSAPI
KAFKA_SASL_ENABLED_MECHANISMS: GSSAPI
KAFKA_LISTENERS: SASL_PLAINTEXT://:9092
KAFKA_ADVERTISED_LISTENERS: SASL_PLAINTEXT://localhost:9092
KAFKA_INTER_BROKER_LISTENER_NAME: SASL_PLAINTEXT
KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf"
KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
volumes:
- ./config/kafka_server_jaas.conf:/etc/kafka/kafka_server_jaas.conf
- ./keytabs:/etc/kafka/keytabs
- ./config/krb5.conf:/etc/krb5.conf
depends_on:
- zookeeper
- kdc
ports:
- 9092:9092
Loading