Download presentation
Presentation is loading. Please wait.
Published byΙππόλυτος Ζερβός Modified over 6 years ago
1
Bring your favorite Kafka to Java EE with CDI
Ivan St. Ivanov
2
Who am I? @ivan_stefanov
3
Agenda Kafka Kafka portable
4
Showcase app User service Forum service Kafka User DB Forum DB
6
CDI primer @ApplicationScoped public class UserModificationObserver {
private KafkaProducer<String, String> kafkaProducer; public void userModified(User modifiedUser) { String record = modifiedUser.toJson().toString(); kafkaProducer.send(new ProducerRecord<>("user", record)); } }
7
CDI primer @ApplicationScoped public class UserModificationObserver {
private KafkaProducer<String, String> kafkaProducer; public void userModified(User modifiedUser) { String record = modifiedUser.toJson().toString(); kafkaProducer.send(new ProducerRecord<>("user", record)); } }
8
CDI primer @ApplicationScoped public class UserModificationObserver {
= "mykafkahost:9090") private KafkaProducer<String, String> kafkaProducer; public void userModified(User modifiedUser) { String record = modifiedUser.toJson().toString(); kafkaProducer.send(new ProducerRecord<>("user", record)); } }
9
CDI primer public @interface KafkaProducerConfig {
Class keyType() default String.class; Class valueType() default String.class; String bootstrapServers() default "localhost:9092"; }
10
CDI primer @ApplicationScoped public class KafkaProducerFactory {
public <K,V> KafkaProducer<K, V> createProducer( InjectionPoint injectionPoint) { KafkaProducerConfig annotation = injectionPoint .getAnnotated() .getAnnotation(KafkaProducerConfig.class); Properties producerProperties = new Properties(); producerProperties.setProperty( "bootstrap.servers", annotation.bootstrapServers()); // Set other props return new KafkaProducer<>(producerProperties); } }
11
CDI primer @ApplicationScoped public class UserModificationObserver {
= "mykafkahost:9090") private KafkaProducer<String, String> kafkaProducer; public void User modifiedUser) { String record = modifiedUser.toJson().toString(); kafkaProducer.send(new ProducerRecord<>("user", record)); } }
12
CDI primer public class KafkaUpdatesListener implements Runnable {
= "user") private KafkaConsumer<String, String> consumer; public void run() { while (continuePolling) { ConsumerRecords<String, String> records = consumer.poll(100); if (!records.isEmpty()) { // Update microservice storage } } }
13
But what if... Leave factories boilerplate to the framework
Leave polling updates to the framework Do it this way: public class UserModificationKafkaConsumer { = "user") public void listenForUsers( ConsumerRecord<String, String> record) { String userJson = record.value(); // Store the user in DB }
14
CDI extensions CDI magic Hook into the lifecycle
Override default behavior Portable across containers
15
CDI extension prerequisites
Implement javax.enterprise.inject.spi.Extension Observe events of interest Register service provider
16
Process Annotated Types
Before Bean Discovery Type discovery Process Annotated Types After Type Discovery
17
Type discovery Bean discovery Before Bean Discovery
Process Annotated Types After Type Discovery Bean discovery Process Injection Point Process Injection Target Process Bean Attributes Process Bean Process Producer Method / Field Process Observer Method After Bean Discovery After Deployment Validation
18
Type discovery Bean discovery Running Before Bean Discovery
Process Annotated Types After Type Discovery Bean discovery Process Injection Point Process Injection Target Process Bean Attributes Process Bean Process Producer Method / Field Process Observer Method After Bean Discovery After Deployment Validation Running
19
Type discovery Bean discovery Running Before shutdown
Before Bean Discovery Type discovery Process Annotated Types After Type Discovery Bean discovery Process Injection Point Process Injection Target Process Bean Attributes Process Bean Process Producer Method / Field Process Observer Method After Bean Discovery After Deployment Validation Running Before shutdown Before shutdown
20
Kafka CDI extension tasks
Register the factories and listener thread Create Kafka Consumer for methods Start polling consumers for changes methods when change happens
21
Type discovery Bean discovery Running Before shutdown
Before Bean Discovery Type discovery Process Annotated Types public void addKafkaSpecificTypes( BeforeBeanDiscovery bbd, BeanManager beanManager) { bbd.addAnnotatedType( beanManager.createAnnotatedType(KafkaProducerFactory.class)); bbd.addAnnotatedType( beanManager.createAnnotatedType(KafkaUpdatesListener.class)); } After Type Discovery Bean discovery Process Injection Point Process Injection Target Process Bean Attributes Process Bean Process Producer Method / Field Process Observer Method After Bean Discovery After Deployment Validation Running Before shutdown Before shutdown
22
Type discovery Bean discovery Running Before shutdown
Before Bean Discovery Type discovery Process Annotated Types After Type Discovery Bean discovery Process Injection Point public void collectConsumerMethods( ProcessAnnotatedType<?> pat) { pat.getAnnotatedType().getMethods().stream() .filter(m -> m.isAnnotationPresent(Consumes.class)) .forEach(m -> handleConsumerMethod(pat.getAnnotatedType(), m)); } Process Injection Target Process Bean Attributes Process Bean Process Producer Method / Field Process Observer Method After Bean Discovery After Deployment Validation Running Before shutdown Before shutdown
23
Type discovery Bean discovery Running Before shutdown
Before Bean Discovery Type discovery Process Annotated Types After Type Discovery Bean discovery Process Injection Point private void handleConsumerMethod(AnnotatedType<?> clazz, AnnotatedMethod<?> am) { List<AnnotatedParameter<?>> parameters = am.getParameters(); if (parameters.size() != 1) { errors.add(new IllegalArgumentException( methods should only have one parameter")); } else { consumerDescriptors.add(new KafkaConsumerDescriptor( clazz.getJavaClass(), am, am.getAnnotation(Consumes.class).topic())); } } Process Injection Target Process Bean Attributes Process Bean Process Producer Method / Field Process Observer Method After Bean Discovery After Deployment Validation Running Before shutdown Before shutdown
24
Type discovery Bean discovery Running Before shutdown
Before Bean Discovery Type discovery Process Annotated Types After Type Discovery public void AfterDeploymentValidation adv, BeanManager bm) { if (!errors.isEmpty()) { errors.forEach(adv::addDeploymentProblem); } else { KafkaUpdatesListener kafkaUpdatesListener = initializeListener(bm); startListener(kafkaUpdatesListener, adv); this.kafkaUpdatesListener = kafkaUpdatesListener; } } Bean discovery Process Injection Point Process Injection Target Process Bean Attributes Process Bean Process Producer Method / Field Process Observer Method After Bean Discovery After Deployment Validation Running Before shutdown Before shutdown
25
Type discovery Bean discovery Running Before shutdown
Before Bean Discovery Type discovery Process Annotated Types After Type Discovery Bean discovery Process Injection Point Process Injection Target Process Bean Attributes private KafkaUpdatesListener initializeListener(BeanManager bm) { Class<KafkaUpdatesListener> clazz = KafkaUpdatesListener.class; KafkaUpdatesListener reference = createBean(bm, clazz); consumerDescriptors.forEach(m -> addTopicToListen(m, reference)); return reference; } Process Bean Process Producer Method / Field Process Observer Method After Bean Discovery After Deployment Validation Running Before shutdown Before shutdown
26
Type discovery Bean discovery Running Before shutdown
Before Bean Discovery Type discovery Process Annotated Types After Type Discovery Bean discovery Process Injection Point Process Injection Target static Object createBean(BeanManager bm, Class<?> clazz) { Set<Bean<?>> listenerBeans = bm.getBeans(clazz); Bean<?> listenerBean = bm.resolve(listenerBeans); CreationalContext<?> creationalContext = bm.createCreationalContext(listenerBean); return bm.getReference(listenerBean, clazz, creationalContext); } Process Bean Attributes Process Bean Process Producer Method / Field Process Observer Method After Bean Discovery After Deployment Validation Running Before shutdown Before shutdown
27
Type discovery Bean discovery Running Before shutdown
Before Bean Discovery Type discovery Process Annotated Types After Type Discovery Bean discovery private void startListener(KafkaUpdatesListener kafkaUpdatesListener) { try { ExecutorService executorService = InitialContext.doLookup("java:comp/DefaultManagedExecutorService"); executorService.submit(kafkaUpdatesListener); } catch (NamingException e) { // Handle NamingException } } Process Injection Point Process Injection Target Process Bean Attributes Process Bean Process Producer Method / Field Process Observer Method After Bean Discovery After Deployment Validation Running Before shutdown Before shutdown
28
Type discovery Bean discovery Running Before shutdown
Before Bean Discovery Type discovery Process Annotated Types After Type Discovery Bean discovery Process Injection Point Process Injection Target Process Bean Attributes Process Bean Process Producer Method / Field Process Observer Method public void BeforeShutdown bsh) { kafkaUpdatesListener.stopPolling(); } After Bean Discovery After Deployment Validation Running Before shutdown Before shutdown
30
Wrap up CDI is powerful Extensions are portable
New features and improvements to add Create extensions for other libraries Evangelize
31
Resources The extension https://github.com/bgjug/kafka-cdi-extension
Showcase app Article by Antoine extensions/ Another Kafka CDI extension
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.