use of io.micronaut.configuration.kafka.annotation.KafkaClient in project micronaut-kafka by micronaut-projects.
the class KafkaProducerFactory method getProducer.
/**
* Creates a new {@link KafkaProducer} for the given configuration.
*
* @param injectionPoint The injection point used to create the bean
* @param producerConfiguration An optional producer configuration
* @param <K> The key type
* @param <V> The value type
* @return The consumer
*/
@Bean
@Any
public <K, V> Producer<K, V> getProducer(@Nullable InjectionPoint<KafkaProducer<K, V>> injectionPoint, @Nullable @Parameter AbstractKafkaProducerConfiguration<K, V> producerConfiguration) {
if (injectionPoint == null) {
if (producerConfiguration != null) {
Optional<Serializer<K>> keySerializer = producerConfiguration.getKeySerializer();
Optional<Serializer<V>> valueSerializer = producerConfiguration.getValueSerializer();
Properties config = producerConfiguration.getConfig();
if (keySerializer.isPresent() && valueSerializer.isPresent()) {
Serializer<K> ks = keySerializer.get();
Serializer<V> vs = valueSerializer.get();
return new KafkaProducer<>(config, ks, vs);
} else if (keySerializer.isPresent() || valueSerializer.isPresent()) {
throw new ConfigurationException("Both the [keySerializer] and [valueSerializer] must be set when setting either");
} else {
return new KafkaProducer<>(config);
}
} else {
throw new ConfigurationException("No Kafka configuration specified when using direct instantiation");
}
}
Argument<?> argument;
if (injectionPoint instanceof FieldInjectionPoint) {
argument = ((FieldInjectionPoint<?, ?>) injectionPoint).asArgument();
} else if (injectionPoint instanceof ArgumentInjectionPoint) {
argument = ((ArgumentInjectionPoint<?, ?>) injectionPoint).getArgument();
} else {
throw new ConfigurationException("Cannot directly retrieve KafkaProducer instances. Use @Inject or constructor injection");
}
Argument<?> k = argument.getTypeVariable("K").orElse(null);
Argument<?> v = argument.getTypeVariable("V").orElse(null);
if (k == null || v == null) {
throw new ConfigurationException("@KafkaClient used on type missing generic argument values for Key and Value: " + injectionPoint);
}
final String id = injectionPoint.getAnnotationMetadata().stringValue(KafkaClient.class).orElse(null);
return getKafkaProducer(id, null, k, v, false);
}
use of io.micronaut.configuration.kafka.annotation.KafkaClient in project micronaut-kafka by micronaut-projects.
the class KafkaClientIntroductionAdvice method intercept.
@SuppressWarnings("unchecked")
@Override
public final Object intercept(MethodInvocationContext<Object, Object> context) {
if (context.hasAnnotation(KafkaClient.class)) {
if (!context.hasAnnotation(KafkaClient.class)) {
throw new IllegalStateException("No @KafkaClient annotation present on method: " + context);
}
ProducerState producerState = getProducer(context);
InterceptedMethod interceptedMethod = InterceptedMethod.of(context);
try {
Argument<?> returnType = interceptedMethod.returnTypeValue();
if (Argument.OBJECT_ARGUMENT.equalsType(returnType)) {
returnType = Argument.of(RecordMetadata.class);
}
switch(interceptedMethod.resultType()) {
case COMPLETION_STAGE:
CompletableFuture<Object> completableFuture = returnCompletableFuture(context, producerState, returnType);
return interceptedMethod.handleResult(completableFuture);
case PUBLISHER:
Flux<Object> returnFlowable = returnPublisher(context, producerState, returnType);
return interceptedMethod.handleResult(returnFlowable);
case SYNCHRONOUS:
return returnSynchronous(context, producerState);
default:
return interceptedMethod.unsupported();
}
} catch (Exception e) {
return interceptedMethod.handleException(e);
}
} else {
// can't be implemented so proceed
return context.proceed();
}
}
use of io.micronaut.configuration.kafka.annotation.KafkaClient in project micronaut-kafka by micronaut-projects.
the class KafkaClientIntroductionAdvice method buildSendFluxForReactiveValue.
private Flux<Object> buildSendFluxForReactiveValue(MethodInvocationContext<Object, Object> context, ProducerState producerState, Argument<?> returnType, Object value) {
Flux<?> valueFlowable = Flux.from(Publishers.convertPublisher(value, Publisher.class));
Class<?> javaReturnType = returnType.getType();
if (Iterable.class.isAssignableFrom(javaReturnType)) {
returnType = returnType.getFirstTypeVariable().orElse(Argument.OBJECT_ARGUMENT);
}
boolean transactional = producerState.transactional;
Producer<?, ?> kafkaProducer = producerState.kafkaProducer;
if (transactional) {
LOG.trace("Beginning transaction for producer: {}", producerState.transactionalId);
kafkaProducer.beginTransaction();
}
Argument<?> finalReturnType = returnType;
Flux<Object> sendFlowable = valueFlowable.flatMap(o -> {
ProducerRecord record = buildProducerRecord(context, producerState, o);
LOG.trace("@KafkaClient method [{}] Sending producer record: {}", context, record);
return producerSend(kafkaProducer, record).map(metadata -> convertResult(metadata, finalReturnType, o, producerState.bodyArgument)).onErrorMap(e -> wrapException(context, e));
});
if (transactional) {
sendFlowable = addTransactionalProcessing(producerState, sendFlowable);
}
if (producerState.maxBlock != null) {
sendFlowable = sendFlowable.timeout(producerState.maxBlock);
}
return sendFlowable;
}
Aggregations