use of io.quarkus.smallrye.reactivemessaging.runtime.QuarkusMediatorConfiguration in project quarkus by quarkusio.
the class SmallRyeReactiveMessagingProcessor method build.
@BuildStep
@Record(STATIC_INIT)
public void build(SmallRyeReactiveMessagingRecorder recorder, RecorderContext recorderContext, BuildProducer<SyntheticBeanBuildItem> syntheticBeans, List<MediatorBuildItem> mediatorMethods, List<InjectedEmitterBuildItem> emitterFields, List<InjectedChannelBuildItem> channelFields, BuildProducer<GeneratedClassBuildItem> generatedClass, BuildProducer<ReflectiveClassBuildItem> reflectiveClass, ReactiveMessagingConfiguration conf) {
ClassOutput classOutput = new GeneratedClassGizmoAdaptor(generatedClass, true);
List<QuarkusMediatorConfiguration> mediatorConfigurations = new ArrayList<>(mediatorMethods.size());
List<WorkerConfiguration> workerConfigurations = new ArrayList<>();
List<EmitterConfiguration> emittersConfigurations = new ArrayList<>();
List<ChannelConfiguration> channelConfigurations = new ArrayList<>();
/*
* Go through the collected MediatorMethods and build up the corresponding MediaConfiguration
* This includes generating an invoker for each method
* The configuration will then be captured and used at static init time to push data into smallrye
*/
for (MediatorBuildItem mediatorMethod : mediatorMethods) {
MethodInfo methodInfo = mediatorMethod.getMethod();
BeanInfo bean = mediatorMethod.getBean();
if (methodInfo.hasAnnotation(BLOCKING) || methodInfo.hasAnnotation(SMALLRYE_BLOCKING) || methodInfo.hasAnnotation(TRANSACTIONAL)) {
// Just in case both annotation are used, use @Blocking value.
String poolName = Blocking.DEFAULT_WORKER_POOL;
// If the method is annotated with the SmallRye Reactive Messaging @Blocking, extract the worker pool name if any
if (methodInfo.hasAnnotation(ReactiveMessagingDotNames.BLOCKING)) {
AnnotationInstance blocking = methodInfo.annotation(ReactiveMessagingDotNames.BLOCKING);
poolName = blocking.value() == null ? Blocking.DEFAULT_WORKER_POOL : blocking.value().asString();
}
workerConfigurations.add(new WorkerConfiguration(methodInfo.declaringClass().toString(), methodInfo.name(), poolName));
}
try {
boolean isSuspendMethod = isSuspendMethod(methodInfo);
QuarkusMediatorConfiguration mediatorConfiguration = QuarkusMediatorConfigurationUtil.create(methodInfo, isSuspendMethod, bean, recorderContext, Thread.currentThread().getContextClassLoader(), conf.strict);
mediatorConfigurations.add(mediatorConfiguration);
String generatedInvokerName = generateInvoker(bean, methodInfo, isSuspendMethod, mediatorConfiguration, classOutput);
/*
* We need to register the invoker's constructor for reflection since it will be called inside smallrye.
* We could potentially lift this restriction with some extra CDI bean generation, but it's probably not worth
* it
*/
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, generatedInvokerName));
mediatorConfiguration.setInvokerClass((Class<? extends Invoker>) recorderContext.classProxy(generatedInvokerName));
} catch (IllegalArgumentException e) {
// needed to pass the TCK
throw new DeploymentException(e);
}
}
for (InjectedEmitterBuildItem it : emitterFields) {
emittersConfigurations.add(it.getEmitterConfig());
}
for (InjectedChannelBuildItem it : channelFields) {
channelConfigurations.add(it.getChannelConfig());
}
syntheticBeans.produce(SyntheticBeanBuildItem.configure(SmallRyeReactiveMessagingContext.class).supplier(recorder.createContext(mediatorConfigurations, workerConfigurations, emittersConfigurations, channelConfigurations)).done());
}
use of io.quarkus.smallrye.reactivemessaging.runtime.QuarkusMediatorConfiguration in project quarkus by quarkusio.
the class QuarkusMediatorConfigurationUtil method create.
public static QuarkusMediatorConfiguration create(MethodInfo methodInfo, boolean isSuspendMethod, BeanInfo bean, RecorderContext recorderContext, ClassLoader cl, boolean strict) {
Class[] parameterTypeClasses;
Class<?> returnTypeClass;
MediatorConfigurationSupport.GenericTypeAssignable genericReturnTypeAssignable;
if (isSuspendMethod) {
parameterTypeClasses = new Class[methodInfo.parameters().size() - 1];
for (int i = 0; i < methodInfo.parameters().size() - 1; i++) {
parameterTypeClasses[i] = load(methodInfo.parameters().get(i).name().toString(), cl);
}
// the generated invoker will always return a CompletionStage
// TODO: avoid hard coding this and use an SPI to communicate the info with the invoker generation code
returnTypeClass = CompletionStage.class;
genericReturnTypeAssignable = new JandexGenericTypeAssignable(determineReturnTypeOfSuspendMethod(methodInfo), cl);
} else {
parameterTypeClasses = new Class[methodInfo.parameters().size()];
for (int i = 0; i < methodInfo.parameters().size(); i++) {
parameterTypeClasses[i] = load(methodInfo.parameters().get(i).name().toString(), cl);
}
returnTypeClass = load(methodInfo.returnType().name().toString(), cl);
genericReturnTypeAssignable = new ReturnTypeGenericTypeAssignable(methodInfo, cl);
}
QuarkusMediatorConfiguration configuration = new QuarkusMediatorConfiguration();
MediatorConfigurationSupport mediatorConfigurationSupport = new MediatorConfigurationSupport(fullMethodName(methodInfo), returnTypeClass, parameterTypeClasses, genericReturnTypeAssignable, methodInfo.parameters().isEmpty() ? new AlwaysInvalidIndexGenericTypeAssignable() : new MethodParamGenericTypeAssignable(methodInfo, 0, cl));
if (strict) {
mediatorConfigurationSupport.strict();
}
configuration.setBeanId(bean.getIdentifier());
configuration.setMethodName(methodInfo.name());
String returnTypeName = returnTypeClass.getName();
configuration.setReturnType(recorderContext.classProxy(returnTypeName));
Class<?>[] parameterTypes = new Class[methodInfo.parameters().size()];
for (int i = 0; i < methodInfo.parameters().size(); i++) {
parameterTypes[i] = recorderContext.classProxy(methodInfo.parameters().get(i).name().toString());
}
configuration.setParameterTypes(parameterTypes);
// We need to extract the value of @Incoming and @Incomings (which contains an array of @Incoming)
List<String> incomingValues = new ArrayList<>(getValues(methodInfo, INCOMING));
incomingValues.addAll(getIncomingValues(methodInfo));
configuration.setIncomings(incomingValues);
String outgoingValue = getValue(methodInfo, OUTGOING);
configuration.setOutgoing(outgoingValue);
Shape shape = mediatorConfigurationSupport.determineShape(incomingValues, outgoingValue);
configuration.setShape(shape);
Acknowledgment.Strategy acknowledgment = mediatorConfigurationSupport.processSuppliedAcknowledgement(incomingValues, () -> {
AnnotationInstance instance = methodInfo.annotation(ACKNOWLEDGMENT);
if (instance != null) {
return Acknowledgment.Strategy.valueOf(instance.value().asEnum());
}
return null;
});
configuration.setAcknowledgment(acknowledgment);
MediatorConfigurationSupport.ValidationOutput validationOutput = mediatorConfigurationSupport.validate(shape, acknowledgment);
configuration.setProduction(validationOutput.getProduction());
configuration.setConsumption(validationOutput.getConsumption());
configuration.setIngestedPayloadType(validationOutput.getIngestedPayloadType());
if (validationOutput.getUseBuilderTypes()) {
configuration.setUseBuilderTypes(validationOutput.getUseBuilderTypes());
} else {
configuration.setUseBuilderTypes(false);
}
if (acknowledgment == null) {
acknowledgment = mediatorConfigurationSupport.processDefaultAcknowledgement(shape, validationOutput.getConsumption(), validationOutput.getProduction());
configuration.setAcknowledgment(acknowledgment);
}
configuration.setMerge(mediatorConfigurationSupport.processMerge(incomingValues, new Supplier<Merge.Mode>() {
@Override
public Merge.Mode get() {
AnnotationInstance instance = methodInfo.annotation(MERGE);
if (instance != null) {
AnnotationValue value = instance.value();
if (value == null) {
// the default value of @Merge
return Merge.Mode.MERGE;
}
return Merge.Mode.valueOf(value.asEnum());
}
return null;
}
}));
configuration.setBroadcastValue(mediatorConfigurationSupport.processBroadcast(outgoingValue, new Supplier<Integer>() {
@Override
public Integer get() {
AnnotationInstance instance = methodInfo.annotation(BROADCAST);
if (instance != null) {
AnnotationValue value = instance.value();
if (value == null) {
// the default value of @Broadcast
return 0;
}
return value.asInt();
}
return null;
}
}));
AnnotationInstance blockingAnnotation = methodInfo.annotation(BLOCKING);
AnnotationInstance smallryeBlockingAnnotation = methodInfo.annotation(SMALLRYE_BLOCKING);
AnnotationInstance transactionalAnnotation = methodInfo.annotation(TRANSACTIONAL);
if (blockingAnnotation != null || smallryeBlockingAnnotation != null || transactionalAnnotation != null) {
mediatorConfigurationSupport.validateBlocking(validationOutput);
configuration.setBlocking(true);
if (blockingAnnotation != null) {
AnnotationValue ordered = blockingAnnotation.value("ordered");
configuration.setBlockingExecutionOrdered(ordered == null || ordered.asBoolean());
String poolName;
if (blockingAnnotation.value() != null && !(poolName = blockingAnnotation.value().asString()).equals(Blocking.DEFAULT_WORKER_POOL)) {
configuration.setWorkerPoolName(poolName);
}
} else {
configuration.setBlockingExecutionOrdered(true);
}
}
return configuration;
}
Aggregations