Search in sources :

Example 1 with MediatorBuildItem

use of io.quarkus.smallrye.reactivemessaging.deployment.items.MediatorBuildItem 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());
}
Also used : InjectedChannelBuildItem(io.quarkus.smallrye.reactivemessaging.deployment.items.InjectedChannelBuildItem) BeanInfo(io.quarkus.arc.processor.BeanInfo) ArrayList(java.util.ArrayList) ChannelConfiguration(io.smallrye.reactive.messaging.providers.extension.ChannelConfiguration) GeneratedClassGizmoAdaptor(io.quarkus.deployment.GeneratedClassGizmoAdaptor) EmitterConfiguration(io.smallrye.reactive.messaging.EmitterConfiguration) MediatorBuildItem(io.quarkus.smallrye.reactivemessaging.deployment.items.MediatorBuildItem) QuarkusMediatorConfiguration(io.quarkus.smallrye.reactivemessaging.runtime.QuarkusMediatorConfiguration) WorkerConfiguration(io.quarkus.smallrye.reactivemessaging.runtime.WorkerConfiguration) ClassOutput(io.quarkus.gizmo.ClassOutput) InjectedEmitterBuildItem(io.quarkus.smallrye.reactivemessaging.deployment.items.InjectedEmitterBuildItem) MethodInfo(org.jboss.jandex.MethodInfo) DeploymentException(javax.enterprise.inject.spi.DeploymentException) SmallRyeReactiveMessagingContext(io.quarkus.smallrye.reactivemessaging.runtime.SmallRyeReactiveMessagingRecorder.SmallRyeReactiveMessagingContext) AnnotationInstance(org.jboss.jandex.AnnotationInstance) ReflectiveClassBuildItem(io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem) BuildStep(io.quarkus.deployment.annotations.BuildStep) Record(io.quarkus.deployment.annotations.Record)

Example 2 with MediatorBuildItem

use of io.quarkus.smallrye.reactivemessaging.deployment.items.MediatorBuildItem in project quarkus by quarkusio.

the class WiringProcessor method extractComponents.

@BuildStep
void extractComponents(BeanDiscoveryFinishedBuildItem beanDiscoveryFinished, TransformedAnnotationsBuildItem transformedAnnotations, BuildProducer<ChannelBuildItem> appChannels, BuildProducer<MediatorBuildItem> mediatorMethods, BuildProducer<InjectedEmitterBuildItem> emitters, BuildProducer<InjectedChannelBuildItem> channels, BuildProducer<ValidationPhaseBuildItem.ValidationErrorBuildItem> validationErrors, BuildProducer<ConfigDescriptionBuildItem> configDescriptionBuildItemBuildProducer) {
    Map<String, AnnotationInstance> emitterFactories = new HashMap<>();
    // We need to collect all business methods annotated with @Incoming/@Outgoing first
    for (BeanInfo bean : beanDiscoveryFinished.beanStream().classBeans()) {
        // TODO: add support for inherited business methods
        // noinspection OptionalGetWithoutIsPresent
        AnnotationInstance emitterFactory = transformedAnnotations.getAnnotation(bean.getTarget().get(), ReactiveMessagingDotNames.EMITTER_FACTORY_FOR);
        if (emitterFactory != null) {
            emitterFactories.put(emitterFactory.value().asClass().name().toString(), emitterFactory);
        }
        for (MethodInfo method : bean.getTarget().get().asClass().methods()) {
            // @Incoming is repeatable
            AnnotationInstance incoming = transformedAnnotations.getAnnotation(method, ReactiveMessagingDotNames.INCOMING);
            AnnotationInstance incomings = transformedAnnotations.getAnnotation(method, ReactiveMessagingDotNames.INCOMINGS);
            AnnotationInstance outgoing = transformedAnnotations.getAnnotation(method, ReactiveMessagingDotNames.OUTGOING);
            AnnotationInstance blocking = transformedAnnotations.getAnnotation(method, BLOCKING);
            if (incoming != null || incomings != null || outgoing != null) {
                handleMethodAnnotatedWithIncoming(appChannels, validationErrors, configDescriptionBuildItemBuildProducer, method, incoming);
                handleMethodAnnotationWithIncomings(appChannels, validationErrors, configDescriptionBuildItemBuildProducer, method, incomings);
                handleMethodAnnotationWithOutgoing(appChannels, validationErrors, configDescriptionBuildItemBuildProducer, method, outgoing);
                if (WiringHelper.isSynthetic(method)) {
                    continue;
                }
                mediatorMethods.produce(new MediatorBuildItem(bean, method));
                LOGGER.debugf("Found mediator business method %s declared on %s", method, bean);
            } else if (blocking != null) {
                validationErrors.produce(new ValidationPhaseBuildItem.ValidationErrorBuildItem(new DeploymentException("@Blocking used on " + method + " which has no @Incoming or @Outgoing annotation")));
            }
        }
    }
    for (InjectionPointInfo injectionPoint : beanDiscoveryFinished.getInjectionPoints()) {
        Optional<AnnotationInstance> broadcast = WiringHelper.getAnnotation(transformedAnnotations, injectionPoint, ReactiveMessagingDotNames.BROADCAST);
        Optional<AnnotationInstance> channel = WiringHelper.getAnnotation(transformedAnnotations, injectionPoint, ReactiveMessagingDotNames.CHANNEL);
        Optional<AnnotationInstance> legacyChannel = WiringHelper.getAnnotation(transformedAnnotations, injectionPoint, ReactiveMessagingDotNames.LEGACY_CHANNEL);
        String injectionType = injectionPoint.getRequiredType().name().toString();
        AnnotationInstance emitterType = emitterFactories.get(injectionType);
        boolean isLegacyEmitter = injectionPoint.getRequiredType().name().equals(ReactiveMessagingDotNames.LEGACY_EMITTER);
        if (emitterType != null) {
            if (isLegacyEmitter) {
                // Deprecated Emitter from SmallRye (emitter, channel and on overflow have been added to the spec)
                handleEmitter(transformedAnnotations, appChannels, emitters, validationErrors, injectionPoint, emitterType, broadcast, legacyChannel, ReactiveMessagingDotNames.LEGACY_ON_OVERFLOW);
            } else {
                // New emitter from the spec, or Mutiny emitter
                handleEmitter(transformedAnnotations, appChannels, emitters, validationErrors, injectionPoint, emitterType, broadcast, channel, ReactiveMessagingDotNames.ON_OVERFLOW);
            }
        } else {
            if (channel.isPresent()) {
                handleChannelInjection(appChannels, channels, channel.get());
            }
            if (legacyChannel.isPresent()) {
                handleChannelInjection(appChannels, channels, legacyChannel.get());
            }
        }
    }
}
Also used : MediatorBuildItem(io.quarkus.smallrye.reactivemessaging.deployment.items.MediatorBuildItem) InjectionPointInfo(io.quarkus.arc.processor.InjectionPointInfo) HashMap(java.util.HashMap) BeanInfo(io.quarkus.arc.processor.BeanInfo) MethodInfo(org.jboss.jandex.MethodInfo) DeploymentException(javax.enterprise.inject.spi.DeploymentException) AnnotationInstance(org.jboss.jandex.AnnotationInstance) BuildStep(io.quarkus.deployment.annotations.BuildStep)

Aggregations

BeanInfo (io.quarkus.arc.processor.BeanInfo)2 BuildStep (io.quarkus.deployment.annotations.BuildStep)2 MediatorBuildItem (io.quarkus.smallrye.reactivemessaging.deployment.items.MediatorBuildItem)2 DeploymentException (javax.enterprise.inject.spi.DeploymentException)2 AnnotationInstance (org.jboss.jandex.AnnotationInstance)2 MethodInfo (org.jboss.jandex.MethodInfo)2 InjectionPointInfo (io.quarkus.arc.processor.InjectionPointInfo)1 GeneratedClassGizmoAdaptor (io.quarkus.deployment.GeneratedClassGizmoAdaptor)1 Record (io.quarkus.deployment.annotations.Record)1 ReflectiveClassBuildItem (io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem)1 ClassOutput (io.quarkus.gizmo.ClassOutput)1 InjectedChannelBuildItem (io.quarkus.smallrye.reactivemessaging.deployment.items.InjectedChannelBuildItem)1 InjectedEmitterBuildItem (io.quarkus.smallrye.reactivemessaging.deployment.items.InjectedEmitterBuildItem)1 QuarkusMediatorConfiguration (io.quarkus.smallrye.reactivemessaging.runtime.QuarkusMediatorConfiguration)1 SmallRyeReactiveMessagingContext (io.quarkus.smallrye.reactivemessaging.runtime.SmallRyeReactiveMessagingRecorder.SmallRyeReactiveMessagingContext)1 WorkerConfiguration (io.quarkus.smallrye.reactivemessaging.runtime.WorkerConfiguration)1 EmitterConfiguration (io.smallrye.reactive.messaging.EmitterConfiguration)1 ChannelConfiguration (io.smallrye.reactive.messaging.providers.extension.ChannelConfiguration)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1