Search in sources :

Example 1 with Acknowledgment

use of org.eclipse.microprofile.reactive.messaging.Acknowledgment 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;
}
Also used : MediatorConfigurationSupport(io.smallrye.reactive.messaging.providers.MediatorConfigurationSupport) Shape(io.smallrye.reactive.messaging.Shape) ArrayList(java.util.ArrayList) QuarkusMediatorConfiguration(io.quarkus.smallrye.reactivemessaging.runtime.QuarkusMediatorConfiguration) Merge(io.smallrye.reactive.messaging.annotations.Merge) Acknowledgment(org.eclipse.microprofile.reactive.messaging.Acknowledgment) AnnotationValue(org.jboss.jandex.AnnotationValue) Supplier(java.util.function.Supplier) AnnotationInstance(org.jboss.jandex.AnnotationInstance)

Example 2 with Acknowledgment

use of org.eclipse.microprofile.reactive.messaging.Acknowledgment in project optaplanner-quickstarts by kiegroup.

the class TimeTableResource method process.

@Incoming("solver_response")
@Acknowledgment(Acknowledgment.Strategy.POST_PROCESSING)
public void process(String solverResponseMessage) {
    SolverResponse solverResponse;
    try {
        solverResponse = objectMapper.readValue(solverResponseMessage, SolverResponse.class);
    } catch (JsonProcessingException ex) {
        throw new IllegalStateException("Unable to deserialize the solver response.", ex);
    }
    if (solverResponse.isSuccess()) {
        TimeTable timeTable = solverResponse.getTimeTable();
        timeTable.setSolverStatus(SolverStatus.NOT_SOLVING);
        timeTableRepository.update(timeTable);
    } else {
        timeTableRepository.get().setSolverStatus(SolverStatus.NOT_SOLVING);
        throw new IllegalStateException("Solving failed with exception class (" + solverResponse.getErrorInfo().getExceptionClassName() + ") and message (" + solverResponse.getErrorInfo().getExceptionMessage() + ").");
    }
}
Also used : SolverResponse(org.acme.schooltimetabling.message.SolverResponse) TimeTable(org.acme.schooltimetabling.domain.TimeTable) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) Incoming(org.eclipse.microprofile.reactive.messaging.Incoming) Acknowledgment(org.eclipse.microprofile.reactive.messaging.Acknowledgment)

Example 3 with Acknowledgment

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

the class MsgProcessingBean method betweenQueues.

/**
 * Example of resending message from one queue to another and logging the payload to DB in the process.
 *
 * @param msg received message
 * @return message to be sent
 */
@Incoming("from-queue-1")
@Outgoing("to-queue-2")
// Leave commit by ack to outgoing connector
@Acknowledgment(Acknowledgment.Strategy.NONE)
public CompletionStage<AqMessage<String>> betweenQueues(AqMessage<String> msg) {
    return CompletableFuture.supplyAsync(() -> {
        try {
            PreparedStatement statement = msg.getDbConnection().prepareStatement("INSERT INTO frank.message_log (message) VALUES (?)");
            statement.setString(1, msg.getPayload());
            statement.executeUpdate();
        } catch (SQLException e) {
            // Gets caught by messaging engine and translated to onError signal
            throw new RuntimeException("Error when saving message to log table.", e);
        }
        return msg;
    });
}
Also used : SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) Incoming(org.eclipse.microprofile.reactive.messaging.Incoming) Acknowledgment(org.eclipse.microprofile.reactive.messaging.Acknowledgment) Outgoing(org.eclipse.microprofile.reactive.messaging.Outgoing)

Example 4 with Acknowledgment

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

the class DefaultMediatorConfiguration method compute.

public void compute(List<Incoming> incomings, Outgoing outgoing, Blocking blocking) {
    if (incomings != null) {
        for (Incoming incoming : incomings) {
            if (Validation.isBlank(incoming.value())) {
                throw ex.illegalArgumentForAnnotationNullOrBlank("@Incoming", methodAsString());
            }
        }
    } else {
        incomings = Collections.emptyList();
    }
    if (outgoing != null && Validation.isBlank(outgoing.value())) {
        throw ex.illegalArgumentForAnnotationNullOrBlank("@Outgoing", methodAsString());
    }
    this.shape = this.mediatorConfigurationSupport.determineShape(incomings, outgoing);
    this.acknowledgment = this.mediatorConfigurationSupport.processSuppliedAcknowledgement(incomings, () -> {
        Acknowledgment annotation = method.getAnnotation(Acknowledgment.class);
        return annotation != null ? annotation.value() : null;
    });
    if (!incomings.isEmpty()) {
        this.incomingValues = incomings.stream().map(Incoming::value).collect(Collectors.toList());
    }
    if (outgoing != null) {
        this.outgoingValue = outgoing.value();
    }
    if (blocking != null) {
        this.isBlocking = true;
        this.isOrderedExecution = blocking.ordered();
        if (!blocking.value().equals(Blocking.DEFAULT_WORKER_POOL)) {
            this.workerPoolName = blocking.value();
        }
    }
    MediatorConfigurationSupport.ValidationOutput validationOutput = this.mediatorConfigurationSupport.validate(this.shape, this.acknowledgment);
    this.production = validationOutput.getProduction();
    this.consumption = validationOutput.getConsumption();
    if (validationOutput.getUseBuilderTypes()) {
        this.useBuilderTypes = validationOutput.getUseBuilderTypes();
    }
    if (this.acknowledgment == null) {
        this.acknowledgment = this.mediatorConfigurationSupport.processDefaultAcknowledgement(this.shape, this.consumption, this.production);
    }
    this.mergePolicy = this.mediatorConfigurationSupport.processMerge(incomings, () -> {
        Merge annotation = method.getAnnotation(Merge.class);
        return annotation != null ? annotation.value() : null;
    });
    this.broadcastValue = this.mediatorConfigurationSupport.processBroadcast(outgoing, () -> {
        Broadcast annotation = method.getAnnotation(Broadcast.class);
        return annotation != null ? annotation.value() : null;
    });
    if (this.isBlocking) {
        this.mediatorConfigurationSupport.validateBlocking(validationOutput);
    }
    ingestedPayloadType = validationOutput.getIngestedPayloadType();
}
Also used : Incoming(org.eclipse.microprofile.reactive.messaging.Incoming) Merge(io.smallrye.reactive.messaging.annotations.Merge) Broadcast(io.smallrye.reactive.messaging.annotations.Broadcast) Acknowledgment(org.eclipse.microprofile.reactive.messaging.Acknowledgment)

Example 5 with Acknowledgment

use of org.eclipse.microprofile.reactive.messaging.Acknowledgment in project himss_2021_sepsis_detection by redhat-na-ssa.

the class CommandConsumer method process.

@Incoming(RiskAssessmentUtils.COMMAND_CHANNEL)
// Ack message prior to message processing
@Acknowledgment(Acknowledgment.Strategy.PRE_PROCESSING)
public CompletionStage<Void> process(Message<String> message) throws JsonMappingException, JsonProcessingException {
    /*
        Message metadata consists of the following implementations:
          1) io.smallrye.reactive.messaging.kafka.impl.ce.DefaultIncomingKafkaCloudEventMetadata   :  only when "cloud-events=true" on channel
          2) io.smallrye.reactive.messaging.kafka.IncomingKafkaRecordMetadata
          3) io.smallrye.reactive.messaging.TracingMetadata
       */
    Optional<CloudEventMetadata> cloudEventMetadata = message.getMetadata(io.smallrye.reactive.messaging.kafka.impl.ce.DefaultIncomingKafkaCloudEventMetadata.class);
    if (cloudEventMetadata.isEmpty()) {
        log.warn("process() Incoming message is not a CloudEvent.");
        StringBuilder sBuilder = new StringBuilder("The following are the meta-data types:\n");
        Iterator metaIterator = message.getMetadata().iterator();
        while (metaIterator.hasNext()) {
            sBuilder.append(metaIterator.next() + "\n");
        }
        log.warn(sBuilder.toString());
        return CompletableFuture.completedFuture(null);
    }
    String type = cloudEventMetadata.get().getType();
    if (!RiskAssessmentUtils.MESSAGE_TYPE_COMMAND.equals(type)) {
        log.warn("process() message data type != " + RiskAssessmentUtils.MESSAGE_TYPE_COMMAND + "  : " + type);
        return CompletableFuture.completedFuture(null);
    }
    Map<String, String> dataNode = objectMapper.readValue(message.getPayload(), Map.class);
    if (dataNode == null)
        throw new RuntimeException("process() message payload must not be null");
    if (dataNode.get(RiskAssessmentUtils.CLOUD_EVENT_DATA) != null) {
        Object structuredJson = dataNode.get(RiskAssessmentUtils.CLOUD_EVENT_DATA);
        log.info("structuredJson = " + structuredJson.toString());
        dataNode = (Map<String, String>) structuredJson;
        log.warn("process() received a STRUCTURED Cloud Event");
    }
    String pNode = dataNode.get(RiskAssessmentUtils.PATIENT);
    if (pNode == null)
        throw new RuntimeException("CloudEvent payload does not include element: " + RiskAssessmentUtils.PATIENT);
    Patient patient = (Patient) fhirCtx.newJsonParser().parseResource(pNode);
    String srNode = dataNode.get(RiskAssessmentUtils.SEPSIS_RESPONSE);
    if (srNode == null)
        throw new RuntimeException("CloudEvent payload does not include element: " + RiskAssessmentUtils.SEPSIS_RESPONSE);
    String oNode = dataNode.get(RiskAssessmentUtils.OBSERVATION_ID);
    if (oNode == null)
        throw new RuntimeException("CloudEvent payload does not include element: " + RiskAssessmentUtils.OBSERVATION_ID);
    String cNode = dataNode.get(RiskAssessmentUtils.CORRELATION_KEY);
    if (cNode == null)
        throw new RuntimeException("CloudEvent payload does not include element: " + RiskAssessmentUtils.CORRELATION_KEY);
    raService.publishRiskAssessment(patient, srNode, oNode, cNode);
    return CompletableFuture.completedFuture(null);
}
Also used : Patient(org.hl7.fhir.r4.model.Patient) CloudEventMetadata(io.smallrye.reactive.messaging.ce.CloudEventMetadata) Iterator(java.util.Iterator) Incoming(org.eclipse.microprofile.reactive.messaging.Incoming) Acknowledgment(org.eclipse.microprofile.reactive.messaging.Acknowledgment)

Aggregations

Acknowledgment (org.eclipse.microprofile.reactive.messaging.Acknowledgment)8 Incoming (org.eclipse.microprofile.reactive.messaging.Incoming)7 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)2 Blocking (io.smallrye.reactive.messaging.annotations.Blocking)2 Broadcast (io.smallrye.reactive.messaging.annotations.Broadcast)2 Merge (io.smallrye.reactive.messaging.annotations.Merge)2 Outgoing (org.eclipse.microprofile.reactive.messaging.Outgoing)2 JsonNode (com.fasterxml.jackson.databind.JsonNode)1 Action (com.redhat.cloud.notifications.ingress.Action)1 AggregationCommand (com.redhat.cloud.notifications.models.AggregationCommand)1 Event (com.redhat.cloud.notifications.models.Event)1 EventType (com.redhat.cloud.notifications.models.EventType)1 Timer (io.micrometer.core.instrument.Timer)1 QuarkusMediatorConfiguration (io.quarkus.smallrye.reactivemessaging.runtime.QuarkusMediatorConfiguration)1 Shape (io.smallrye.reactive.messaging.Shape)1 CloudEventMetadata (io.smallrye.reactive.messaging.ce.CloudEventMetadata)1 MediatorConfigurationSupport (io.smallrye.reactive.messaging.providers.MediatorConfigurationSupport)1 PreparedStatement (java.sql.PreparedStatement)1 SQLException (java.sql.SQLException)1 ArrayList (java.util.ArrayList)1