Search in sources :

Example 1 with Connector

use of org.eclipse.microprofile.reactive.messaging.spi.Connector in project smallrye-reactive-messaging by smallrye.

the class ConnectorAttributeProcessor method process.

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    if (invoked) {
        return true;
    }
    invoked = true;
    Set<? extends Element> annotated = roundEnv.getElementsAnnotatedWith(ConnectorAttributes.class);
    Set<? extends Element> others = roundEnv.getElementsAnnotatedWith(ConnectorAttribute.class);
    Set<Element> all = new LinkedHashSet<>();
    all.addAll(annotated);
    all.addAll(others);
    for (Element annotatedElement : all) {
        String className = annotatedElement.toString();
        Connector connector = getConnector(annotatedElement);
        ConnectorAttributes annotation = annotatedElement.getAnnotation(ConnectorAttributes.class);
        ConnectorAttribute[] attributes;
        if (annotation == null) {
            attributes = new ConnectorAttribute[] { annotatedElement.getAnnotation(ConnectorAttribute.class) };
        } else {
            attributes = annotation.value();
        }
        List<ConnectorAttribute> incomingAttributes = new ArrayList<>();
        List<ConnectorAttribute> outgoingAttributes = new ArrayList<>();
        List<ConnectorAttribute> commonAttributes = new ArrayList<>();
        for (ConnectorAttribute attribute : attributes) {
            addAttributeToList(commonAttributes, attribute, ConnectorAttribute.Direction.INCOMING_AND_OUTGOING);
            addAttributeToList(incomingAttributes, attribute, ConnectorAttribute.Direction.INCOMING);
            addAttributeToList(outgoingAttributes, attribute, ConnectorAttribute.Direction.OUTGOING);
        }
        validate(commonAttributes);
        validate(incomingAttributes);
        validate(outgoingAttributes);
        ConfigurationClassWriter classWriter = new ConfigurationClassWriter(processingEnv);
        ConfigurationDocWriter asciidocWriter = new ConfigurationDocWriter(processingEnv);
        ConfigurationMarkdownDocWriter markdownWriter = new ConfigurationMarkdownDocWriter(processingEnv);
        try {
            classWriter.generateAllClasses(connector, className, commonAttributes, incomingAttributes, outgoingAttributes);
            asciidocWriter.generate(connector, commonAttributes, incomingAttributes, outgoingAttributes);
            markdownWriter.generate(connector, commonAttributes, incomingAttributes, outgoingAttributes);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    return true;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Connector(org.eclipse.microprofile.reactive.messaging.spi.Connector) ConnectorAttribute(io.smallrye.reactive.messaging.annotations.ConnectorAttribute) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) IOException(java.io.IOException) ConnectorAttributes(io.smallrye.reactive.messaging.annotations.ConnectorAttributes)

Example 2 with Connector

use of org.eclipse.microprofile.reactive.messaging.spi.Connector in project helidon by oracle.

the class ChannelRouter method registerConnectorFactory.

/**
 * Register connector bean, can be recognized as a bean implementing
 * {@link org.eclipse.microprofile.reactive.messaging.spi.IncomingConnectorFactory}
 * or {@link org.eclipse.microprofile.reactive.messaging.spi.OutgoingConnectorFactory}
 * or both with annotation {@link org.eclipse.microprofile.reactive.messaging.spi.Connector}.
 *
 * @param bean connector bean
 */
void registerConnectorFactory(Bean<?> bean) {
    Class<?> beanType = bean.getBeanClass();
    Connector annotation = beanType.getAnnotation(Connector.class);
    if (IncomingConnectorFactory.class.isAssignableFrom(beanType) && null != annotation) {
        incomingConnectorFactoryList.add(bean);
    }
    if (OutgoingConnectorFactory.class.isAssignableFrom(beanType) && null != annotation) {
        outgoingConnectorFactoryList.add(bean);
    }
}
Also used : Connector(org.eclipse.microprofile.reactive.messaging.spi.Connector) OutgoingConnectorFactory(org.eclipse.microprofile.reactive.messaging.spi.OutgoingConnectorFactory) IncomingConnectorFactory(org.eclipse.microprofile.reactive.messaging.spi.IncomingConnectorFactory)

Example 3 with Connector

use of org.eclipse.microprofile.reactive.messaging.spi.Connector in project smallrye-reactive-messaging by smallrye.

the class RabbitMQConnector method getSubscriberBuilder.

/**
 * Creates a <em>channel</em> for the given configuration. The channel's configuration is associated with a
 * specific {@code connector}, using the {@link Connector} qualifier's parameter indicating a key to
 * which {@link org.eclipse.microprofile.reactive.messaging.Outgoing} to use.
 * <p>
 * Note that the connection to the <em>transport</em> or <em>broker</em> is generally postponed until the
 * subscription.
 *
 * @param config the configuration, never {@code null}, must contain the {@link #CHANNEL_NAME_ATTRIBUTE}
 *        attribute.
 * @return the created {@link SubscriberBuilder}, must not be {@code null}.
 * @throws IllegalArgumentException if the configuration is invalid.
 * @throws NoSuchElementException if the configuration does not contain an expected attribute.
 */
@Override
public SubscriberBuilder<? extends Message<?>, Void> getSubscriberBuilder(final Config config) {
    final RabbitMQConnectorOutgoingConfiguration oc = new RabbitMQConnectorOutgoingConfiguration(config);
    outgoingChannelStatus.put(oc.getChannel(), ChannelStatus.INITIALISING);
    // Create a client
    final RabbitMQClient client = RabbitMQClientHelper.createClient(this, oc, clientOptions, credentialsProviders);
    final ConnectionHolder holder = new ConnectionHolder(client, oc, getVertx());
    final Uni<RabbitMQPublisher> getSender = holder.getOrEstablishConnection().onItem().call(connection -> establishExchange(connection, oc)).onItem().transformToUni(connection -> Uni.createFrom().item(RabbitMQPublisher.create(getVertx(), connection, new RabbitMQPublisherOptions().setReconnectAttempts(oc.getReconnectAttempts()).setReconnectInterval(ofSeconds(oc.getReconnectInterval()).toMillis()).setMaxInternalQueueSize(oc.getMaxOutgoingInternalQueueSize().orElse(Integer.MAX_VALUE))))).onItem().call(RabbitMQPublisher::start).invoke(s -> {
        // Add the channel in the opened state
        outgoingChannelStatus.put(oc.getChannel(), ChannelStatus.CONNECTED);
    }).onFailure().invoke(t -> outgoingChannelStatus.put(oc.getChannel(), ChannelStatus.NOT_CONNECTED)).onFailure().recoverWithNull().memoize().indefinitely().onCancellation().invoke(() -> outgoingChannelStatus.put(oc.getChannel(), ChannelStatus.NOT_CONNECTED));
    // Set up a sender based on the publisher we established above
    final RabbitMQMessageSender processor = new RabbitMQMessageSender(oc, getSender);
    subscriptions.add(processor);
    // Return a SubscriberBuilder
    return ReactiveStreams.<Message<?>>builder().via(processor).onError(t -> {
        log.error(oc.getChannel(), t);
        outgoingChannelStatus.put(oc.getChannel(), ChannelStatus.NOT_CONNECTED);
    }).ignore();
}
Also used : RabbitMQPublisher(io.vertx.mutiny.rabbitmq.RabbitMQPublisher) Arrays(java.util.Arrays) HealthReport(io.smallrye.reactive.messaging.health.HealthReport) RabbitMQConsumer(io.vertx.mutiny.rabbitmq.RabbitMQConsumer) INCOMING(io.smallrye.reactive.messaging.annotations.ConnectorAttribute.Direction.INCOMING) INCOMING_AND_OUTGOING(io.smallrye.reactive.messaging.annotations.ConnectorAttribute.Direction.INCOMING_AND_OUTGOING) Reception(javax.enterprise.event.Reception) Map(java.util.Map) Observes(javax.enterprise.event.Observes) Connector(org.eclipse.microprofile.reactive.messaging.spi.Connector) JsonObject(io.vertx.core.json.JsonObject) Any(javax.enterprise.inject.Any) Instance(javax.enterprise.inject.Instance) ExecutionHolder(io.smallrye.reactive.messaging.providers.connectors.ExecutionHolder) RabbitMQAutoAck(io.smallrye.reactive.messaging.rabbitmq.ack.RabbitMQAutoAck) ConnectorAttribute(io.smallrye.reactive.messaging.annotations.ConnectorAttribute) RabbitMQExceptions.ex(io.smallrye.reactive.messaging.rabbitmq.i18n.RabbitMQExceptions.ex) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) RabbitMQPublisher(io.vertx.mutiny.rabbitmq.RabbitMQPublisher) SubscriberBuilder(org.eclipse.microprofile.reactive.streams.operators.SubscriberBuilder) Config(org.eclipse.microprofile.config.Config) Collectors(java.util.stream.Collectors) Priority(javax.annotation.Priority) List(java.util.List) CredentialsProvider(com.rabbitmq.client.impl.CredentialsProvider) PostConstruct(javax.annotation.PostConstruct) ApplicationScoped(javax.enterprise.context.ApplicationScoped) PublisherBuilder(org.eclipse.microprofile.reactive.streams.operators.PublisherBuilder) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) OutgoingConnectorFactory(org.eclipse.microprofile.reactive.messaging.spi.OutgoingConnectorFactory) RabbitMQReject(io.smallrye.reactive.messaging.rabbitmq.fault.RabbitMQReject) BroadcastProcessor(io.smallrye.mutiny.operators.multi.processors.BroadcastProcessor) RabbitMQLogging.log(io.smallrye.reactive.messaging.rabbitmq.i18n.RabbitMQLogging.log) RabbitMQClient(io.vertx.mutiny.rabbitmq.RabbitMQClient) Duration.ofSeconds(java.time.Duration.ofSeconds) HealthReporter(io.smallrye.reactive.messaging.health.HealthReporter) Multi(io.smallrye.mutiny.Multi) Uni(io.smallrye.mutiny.Uni) Inject(javax.inject.Inject) RabbitMQAck(io.smallrye.reactive.messaging.rabbitmq.ack.RabbitMQAck) BeforeDestroyed(javax.enterprise.context.BeforeDestroyed) TracingUtils(io.smallrye.reactive.messaging.rabbitmq.tracing.TracingUtils) OUTGOING(io.smallrye.reactive.messaging.annotations.ConnectorAttribute.Direction.OUTGOING) RabbitMQAccept(io.smallrye.reactive.messaging.rabbitmq.fault.RabbitMQAccept) QueueOptions(io.vertx.rabbitmq.QueueOptions) RabbitMQPublisherOptions(io.vertx.rabbitmq.RabbitMQPublisherOptions) NoSuchElementException(java.util.NoSuchElementException) IncomingConnectorFactory(org.eclipse.microprofile.reactive.messaging.spi.IncomingConnectorFactory) ReactiveStreams(org.eclipse.microprofile.reactive.streams.operators.ReactiveStreams) RabbitMQOptions(io.vertx.rabbitmq.RabbitMQOptions) RabbitMQAckHandler(io.smallrye.reactive.messaging.rabbitmq.ack.RabbitMQAckHandler) Message(org.eclipse.microprofile.reactive.messaging.Message) RabbitMQFailStop(io.smallrye.reactive.messaging.rabbitmq.fault.RabbitMQFailStop) Subscription(org.reactivestreams.Subscription) Vertx(io.vertx.mutiny.core.Vertx) RabbitMQFailureHandler(io.smallrye.reactive.messaging.rabbitmq.fault.RabbitMQFailureHandler) RabbitMQClient(io.vertx.mutiny.rabbitmq.RabbitMQClient) RabbitMQPublisherOptions(io.vertx.rabbitmq.RabbitMQPublisherOptions)

Example 4 with Connector

use of org.eclipse.microprofile.reactive.messaging.spi.Connector in project smallrye-reactive-messaging by smallrye.

the class RabbitMQConnector method getPublisherBuilder.

/**
 * Creates a <em>channel</em> for the given configuration. The channel's configuration is associated with a
 * specific {@code connector}, using the {@link Connector} qualifier's parameter indicating a key to
 * which {@link IncomingConnectorFactory} to use.
 *
 * <p>
 * Note that the connection to the <em>transport</em> or <em>broker</em> is generally postponed until the
 * subscription occurs.
 *
 * @param config the configuration, must not be {@code null}, must contain the {@link #CHANNEL_NAME_ATTRIBUTE}
 *        attribute.
 * @return the created {@link PublisherBuilder}, will not be {@code null}.
 * @throws IllegalArgumentException if the configuration is invalid.
 * @throws NoSuchElementException if the configuration does not contain an expected attribute.
 */
@Override
public PublisherBuilder<? extends Message<?>> getPublisherBuilder(final Config config) {
    final RabbitMQConnectorIncomingConfiguration ic = new RabbitMQConnectorIncomingConfiguration(config);
    incomingChannelStatus.put(ic.getChannel(), ChannelStatus.INITIALISING);
    // Create a client
    final RabbitMQClient client = RabbitMQClientHelper.createClient(this, ic, clientOptions, credentialsProviders);
    final ConnectionHolder holder = new ConnectionHolder(client, ic, getVertx());
    final RabbitMQFailureHandler onNack = createFailureHandler(ic);
    final RabbitMQAckHandler onAck = createAckHandler(ic);
    // Ensure we set the queue up
    Uni<RabbitMQClient> uniQueue = holder.getOrEstablishConnection().onItem().call(connection -> establishQueue(connection, ic)).onItem().call(connection -> establishDLQ(connection, ic)).onItem().invoke(connection -> incomingChannelStatus.put(ic.getChannel(), ChannelStatus.CONNECTED));
    // Once the queue is set up, set yp a consumer
    final Integer interval = ic.getReconnectInterval();
    final Integer attempts = ic.getReconnectAttempts();
    Multi<? extends Message<?>> multi = uniQueue.onItem().transformToUni(connection -> client.basicConsumer(ic.getQueueName(), new QueueOptions().setAutoAck(ic.getAutoAcknowledgement()).setMaxInternalQueueSize(ic.getMaxIncomingInternalQueueSize()).setKeepMostRecent(ic.getKeepMostRecent()))).onItem().transformToMulti(consumer -> getStreamOfMessages(consumer, holder, ic, onNack, onAck)).plug(m -> {
        if (attempts > 0) {
            return m.onFailure().invoke(log::retrieveMessagesRetrying).onFailure().retry().withBackOff(ofSeconds(1), ofSeconds(interval)).atMost(attempts).onFailure().invoke(t -> {
                incomingChannelStatus.put(ic.getChannel(), ChannelStatus.NOT_CONNECTED);
                log.retrieveMessagesNoMoreRetrying(t);
            });
        }
        return m;
    });
    if (Boolean.TRUE.equals(ic.getBroadcast())) {
        multi = multi.broadcast().toAllSubscribers();
    }
    return ReactiveStreams.fromPublisher(multi);
}
Also used : Arrays(java.util.Arrays) HealthReport(io.smallrye.reactive.messaging.health.HealthReport) RabbitMQConsumer(io.vertx.mutiny.rabbitmq.RabbitMQConsumer) INCOMING(io.smallrye.reactive.messaging.annotations.ConnectorAttribute.Direction.INCOMING) INCOMING_AND_OUTGOING(io.smallrye.reactive.messaging.annotations.ConnectorAttribute.Direction.INCOMING_AND_OUTGOING) Reception(javax.enterprise.event.Reception) Map(java.util.Map) Observes(javax.enterprise.event.Observes) Connector(org.eclipse.microprofile.reactive.messaging.spi.Connector) JsonObject(io.vertx.core.json.JsonObject) Any(javax.enterprise.inject.Any) Instance(javax.enterprise.inject.Instance) ExecutionHolder(io.smallrye.reactive.messaging.providers.connectors.ExecutionHolder) RabbitMQAutoAck(io.smallrye.reactive.messaging.rabbitmq.ack.RabbitMQAutoAck) ConnectorAttribute(io.smallrye.reactive.messaging.annotations.ConnectorAttribute) RabbitMQExceptions.ex(io.smallrye.reactive.messaging.rabbitmq.i18n.RabbitMQExceptions.ex) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) RabbitMQPublisher(io.vertx.mutiny.rabbitmq.RabbitMQPublisher) SubscriberBuilder(org.eclipse.microprofile.reactive.streams.operators.SubscriberBuilder) Config(org.eclipse.microprofile.config.Config) Collectors(java.util.stream.Collectors) Priority(javax.annotation.Priority) List(java.util.List) CredentialsProvider(com.rabbitmq.client.impl.CredentialsProvider) PostConstruct(javax.annotation.PostConstruct) ApplicationScoped(javax.enterprise.context.ApplicationScoped) PublisherBuilder(org.eclipse.microprofile.reactive.streams.operators.PublisherBuilder) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) OutgoingConnectorFactory(org.eclipse.microprofile.reactive.messaging.spi.OutgoingConnectorFactory) RabbitMQReject(io.smallrye.reactive.messaging.rabbitmq.fault.RabbitMQReject) BroadcastProcessor(io.smallrye.mutiny.operators.multi.processors.BroadcastProcessor) RabbitMQLogging.log(io.smallrye.reactive.messaging.rabbitmq.i18n.RabbitMQLogging.log) RabbitMQClient(io.vertx.mutiny.rabbitmq.RabbitMQClient) Duration.ofSeconds(java.time.Duration.ofSeconds) HealthReporter(io.smallrye.reactive.messaging.health.HealthReporter) Multi(io.smallrye.mutiny.Multi) Uni(io.smallrye.mutiny.Uni) Inject(javax.inject.Inject) RabbitMQAck(io.smallrye.reactive.messaging.rabbitmq.ack.RabbitMQAck) BeforeDestroyed(javax.enterprise.context.BeforeDestroyed) TracingUtils(io.smallrye.reactive.messaging.rabbitmq.tracing.TracingUtils) OUTGOING(io.smallrye.reactive.messaging.annotations.ConnectorAttribute.Direction.OUTGOING) RabbitMQAccept(io.smallrye.reactive.messaging.rabbitmq.fault.RabbitMQAccept) QueueOptions(io.vertx.rabbitmq.QueueOptions) RabbitMQPublisherOptions(io.vertx.rabbitmq.RabbitMQPublisherOptions) NoSuchElementException(java.util.NoSuchElementException) IncomingConnectorFactory(org.eclipse.microprofile.reactive.messaging.spi.IncomingConnectorFactory) ReactiveStreams(org.eclipse.microprofile.reactive.streams.operators.ReactiveStreams) RabbitMQOptions(io.vertx.rabbitmq.RabbitMQOptions) RabbitMQAckHandler(io.smallrye.reactive.messaging.rabbitmq.ack.RabbitMQAckHandler) Message(org.eclipse.microprofile.reactive.messaging.Message) RabbitMQFailStop(io.smallrye.reactive.messaging.rabbitmq.fault.RabbitMQFailStop) Subscription(org.reactivestreams.Subscription) Vertx(io.vertx.mutiny.core.Vertx) RabbitMQFailureHandler(io.smallrye.reactive.messaging.rabbitmq.fault.RabbitMQFailureHandler) RabbitMQAckHandler(io.smallrye.reactive.messaging.rabbitmq.ack.RabbitMQAckHandler) RabbitMQClient(io.vertx.mutiny.rabbitmq.RabbitMQClient) RabbitMQFailureHandler(io.smallrye.reactive.messaging.rabbitmq.fault.RabbitMQFailureHandler) RabbitMQLogging.log(io.smallrye.reactive.messaging.rabbitmq.i18n.RabbitMQLogging.log) QueueOptions(io.vertx.rabbitmq.QueueOptions)

Example 5 with Connector

use of org.eclipse.microprofile.reactive.messaging.spi.Connector in project smallrye-reactive-messaging by smallrye.

the class ConfigurationDocWriterTest method test.

@Test
public void test() throws IOException {
    ProcessingEnvironment pe = mock(ProcessingEnvironment.class);
    ConfigurationDocWriter writer = new ConfigurationDocWriter(pe);
    List<ConnectorAttribute> attributes = new ArrayList<>();
    attributes.add(new ConnectorAttributeLiteral("a", "desc-a", "string", true, ConnectorAttribute.Direction.INCOMING));
    attributes.add(new ConnectorAttributeLiteral("b", "desc-b", "int", false, ConnectorAttribute.Direction.INCOMING));
    attributes.add(new ConnectorAttributeLiteral("c", "desc-c", "boolean", true, ConnectorAttribute.Direction.INCOMING).setAlias("alias-c"));
    attributes.add(new ConnectorAttributeLiteral("d", "desc-d", "string", false, ConnectorAttribute.Direction.INCOMING).setDefaultValue("d"));
    attributes.add(new ConnectorAttributeLiteral("e", "desc-e", "string", false, ConnectorAttribute.Direction.INCOMING).setDefaultValue("e").setAlias("alias-e"));
    attributes.add(new ConnectorAttributeLiteral("f", "desc-f", "string", true, ConnectorAttribute.Direction.INCOMING).setAlias("alias-f"));
    Connector connector = ConnectorLiteral.of("my-connector");
    ByteArrayOutputStream boas = new ByteArrayOutputStream();
    try (PrintWriter pw = new PrintWriter(boas)) {
        writer.generateDocumentation(connector, "Incoming", attributes, Collections.emptyList(), pw);
        pw.flush();
    }
    String content = boas.toString("UTF-8");
    assertThat(content).isNotEmpty();
    boas = new ByteArrayOutputStream();
    try (PrintWriter pw = new PrintWriter(boas)) {
        writer.generateDocumentation(connector, "Outgoing", attributes, Collections.emptyList(), pw);
        pw.flush();
    }
    content = boas.toString("UTF-8");
    assertThat(content).isNotEmpty();
}
Also used : Connector(org.eclipse.microprofile.reactive.messaging.spi.Connector) ConnectorAttribute(io.smallrye.reactive.messaging.annotations.ConnectorAttribute) ArrayList(java.util.ArrayList) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ProcessingEnvironment(javax.annotation.processing.ProcessingEnvironment) PrintWriter(java.io.PrintWriter) Test(org.junit.jupiter.api.Test)

Aggregations

Connector (org.eclipse.microprofile.reactive.messaging.spi.Connector)5 ConnectorAttribute (io.smallrye.reactive.messaging.annotations.ConnectorAttribute)4 CredentialsProvider (com.rabbitmq.client.impl.CredentialsProvider)2 Multi (io.smallrye.mutiny.Multi)2 Uni (io.smallrye.mutiny.Uni)2 BroadcastProcessor (io.smallrye.mutiny.operators.multi.processors.BroadcastProcessor)2 INCOMING (io.smallrye.reactive.messaging.annotations.ConnectorAttribute.Direction.INCOMING)2 INCOMING_AND_OUTGOING (io.smallrye.reactive.messaging.annotations.ConnectorAttribute.Direction.INCOMING_AND_OUTGOING)2 OUTGOING (io.smallrye.reactive.messaging.annotations.ConnectorAttribute.Direction.OUTGOING)2 HealthReport (io.smallrye.reactive.messaging.health.HealthReport)2 HealthReporter (io.smallrye.reactive.messaging.health.HealthReporter)2 ExecutionHolder (io.smallrye.reactive.messaging.providers.connectors.ExecutionHolder)2 RabbitMQAck (io.smallrye.reactive.messaging.rabbitmq.ack.RabbitMQAck)2 RabbitMQAckHandler (io.smallrye.reactive.messaging.rabbitmq.ack.RabbitMQAckHandler)2 RabbitMQAutoAck (io.smallrye.reactive.messaging.rabbitmq.ack.RabbitMQAutoAck)2 RabbitMQAccept (io.smallrye.reactive.messaging.rabbitmq.fault.RabbitMQAccept)2 RabbitMQFailStop (io.smallrye.reactive.messaging.rabbitmq.fault.RabbitMQFailStop)2 RabbitMQFailureHandler (io.smallrye.reactive.messaging.rabbitmq.fault.RabbitMQFailureHandler)2 RabbitMQReject (io.smallrye.reactive.messaging.rabbitmq.fault.RabbitMQReject)2 RabbitMQExceptions.ex (io.smallrye.reactive.messaging.rabbitmq.i18n.RabbitMQExceptions.ex)2