All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.microprofile.reactive.messaging.Message Maven / Gradle / Ivy

/*
 * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.eclipse.microprofile.reactive.messaging;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * A message envelope.
 * 

* Messaging providers may provide their own sub classes of this type, in order to allow messaging provider specific * information to be passed to and from applications. *

* * @param * The type of the message payload. */ public interface Message { /** * Create a message with the given payload. * * @param payload * The payload. * @param * The type of payload * @return A message with the given payload, and a no-op ack function. */ static Message of(T payload) { return () -> payload; } /** * Create a message with the given payload and ack function. * * @param payload * The payload. * @param ack * The ack function, this will be invoked when the returned messages {@link #ack()} method is invoked. * @param * the type of payload * @return A message with the given payload and ack function. */ static Message of(T payload, Supplier> ack) { return new Message() { @Override public T getPayload() { return payload; } @Override public Supplier> getAck() { return ack; } }; } /** * Create a message with the given payload, ack and nack functions. * * @param payload * The payload. * @param ack * The ack function, this will be invoked when the returned messages {@link #ack()} method is invoked. * @param nack * The negative-ack function, this will be invoked when the returned messages {@link #nack(Throwable)} * method is invoked. * @param * the type of payload * @return A message with the given payload, ack and nack functions. */ static Message of(T payload, Supplier> ack, Function> nack) { return new Message() { @Override public T getPayload() { return payload; } @Override public Supplier> getAck() { return ack; } @Override public Function> getNack() { return nack; } }; } /** * Creates a new instance of {@link Message} with the specified payload. The ack/nack functions are taken from the * current {@link Message}. * * @param payload * the new payload. * @param

* the type of the new payload * @return the new instance of {@link Message} */ default

Message

withPayload(P payload) { return Message.of(payload, getAck(), getNack()); } /** * Creates a new instance of {@link Message} with the given acknowledgement supplier. The payload, and nack function * are taken from the current {@link Message}. * * @param ack * the positive-acknowledgement function * @return the new instance of {@link Message} */ default Message withAck(Supplier> ack) { return Message.of(getPayload(), ack, getNack()); } /** * Creates a new instance of {@link Message} with the given negative-acknowledgement function. The payload and * acknowledgment are taken from the current {@link Message}. * * @param nack * the negative-acknowledgement function * @return the new instance of {@link Message} */ default Message withNack(Function> nack) { return Message.of(getPayload(), getAck(), nack); } /** * @return The payload for this message. */ T getPayload(); /** * Acknowledge this message. * * @return a completion stage completed when the message is acknowledged. If the acknowledgement fails, the * completion stage propagates the failure. */ default CompletionStage ack() { Supplier> ack = getAck(); if (ack == null) { return CompletableFuture.completedFuture(null); } else { return ack.get(); } } /** * @return the supplier used to retrieve the acknowledgement {@link CompletionStage}. */ default Supplier> getAck() { return () -> CompletableFuture.completedFuture(null); } /** * @return the function used to retrieve the negative-acknowledgement asynchronous function. */ default Function> getNack() { return reason -> CompletableFuture.completedFuture(null); } /** * Acknowledge negatively this message. nack is used to indicate that the processing of a message * failed with the reason passed as the parameter. * * @param reason * the reason of the nack, must not be {@code null} * @return a completion stage completed when the message is negative-acknowledgement has completed. If the negative * acknowledgement fails, the completion stage propagates the failure. */ default CompletionStage nack(Throwable reason) { if (reason == null) { throw new IllegalArgumentException("The reason must not be `null`"); } Function> nack = getNack(); if (nack == null) { return CompletableFuture.completedFuture(null); } else { return nack.apply(reason); } } /** * Returns an object of the specified type to allow access to the connector-specific {@link Message} implementation, * and other classes. For example, a Kafka connector could implement this method to allow unwrapping to a specific * Kafka message implementation, or to {@code ConsumerRecord} and {@code ProducerRecord}. If the {@link Message} * implementation does not support the target class, an {@link IllegalArgumentException} should be raised. * * The default implementation tries to cast the current {@link Message} instance to the target class. When * a connector provides its own {@link Message} implementation, it should override this method to support specific * types. * * @param unwrapType * the class of the object to be returned, must not be {@code null} * @param * the target type * @return an instance of the specified class * @throws IllegalArgumentException * if the current {@link Message} instance does not support the call */ default C unwrap(Class unwrapType) { if (unwrapType == null) { throw new IllegalArgumentException("The target class must not be `null`"); } try { return unwrapType.cast(this); } catch (ClassCastException e) { throw new IllegalArgumentException("Cannot unwrap an instance of " + this.getClass().getName() + " to " + unwrapType.getName(), e); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy