use of com.rabbitmq.stream.Message in project rabbitmq-stream-java-client by rabbitmq.
the class SuperStreamUsage method producerCustomRoutingStrategy.
void producerCustomRoutingStrategy() {
Environment environment = Environment.builder().build();
// tag::producer-custom-routing-strategy[]
AtomicLong messageCount = new AtomicLong(0);
RoutingStrategy routingStrategy = (message, metadata) -> {
List<String> partitions = metadata.partitions();
String stream = partitions.get((int) messageCount.getAndIncrement() % partitions.size());
return Collections.singletonList(stream);
};
Producer producer = environment.producerBuilder().stream("invoices").routing(// <1>
null).strategy(// <2>
routingStrategy).producerBuilder().build();
// end::producer-custom-routing-strategy[]
}
use of com.rabbitmq.stream.Message in project rabbitmq-stream-java-client by rabbitmq.
the class AmqpInteroperabilityTest method publishToStreamQueueConsumeFromStream.
@ParameterizedTest
@MethodSource("codecs")
void publishToStreamQueueConsumeFromStream(Codec codec) throws Exception {
int messageCount = 10_000;
ConnectionFactory connectionFactory = new ConnectionFactory();
Date timestamp = new Date();
Supplier<Stream<PropertiesTestConfiguration>> propertiesTestConfigurations = () -> Stream.of(ptc(b -> b.appId("application id"), m -> assertThat(m.getApplicationProperties().get("x-basic-app-id")).isEqualTo("application id")), ptc(b -> b.contentEncoding("content encoding"), m -> assertThat(m.getProperties().getContentEncoding()).isEqualTo("content encoding")), ptc(b -> b.contentType("content type"), m -> assertThat(m.getProperties().getContentType()).isEqualTo("content type")), ptc(b -> b.correlationId("correlation id"), m -> assertThat(m.getProperties().getCorrelationIdAsString()).isEqualTo("correlation id")), ptc(b -> b.deliveryMode(2), m -> assertThat(m.getMessageAnnotations().get("x-basic-delivery-mode")).isEqualTo(UnsignedByte.valueOf("2"))), ptc(b -> b.expiration(String.valueOf(60_000)), m -> assertThat(m.getMessageAnnotations().get("x-basic-expiration")).isEqualTo(String.valueOf(60_000))), ptc(b -> b.messageId("message id"), m -> assertThat(m.getProperties().getMessageIdAsString()).isEqualTo("message id")), ptc(b -> b.priority(5), m -> assertThat(m.getMessageAnnotations().get("x-basic-priority")).isEqualTo(UnsignedByte.valueOf("5"))), ptc(b -> b.replyTo("reply to"), m -> assertThat(m.getProperties().getReplyTo()).isEqualTo("reply to")), ptc(b -> b.timestamp(timestamp), m -> assertThat(m.getProperties().getCreationTime()).isEqualTo((timestamp.getTime() / 1000) * // in seconds in 091, in ms in 1.0, so losing some
1000)), // precision
ptc(b -> b.type("the type"), m -> assertThat(m.getApplicationProperties().get("x-basic-type")).isEqualTo("the type")), ptc(b -> b.userId("guest"), m -> assertThat(m.getProperties().getUserId()).isEqualTo("guest".getBytes(UTF8))));
Supplier<Stream<HeaderTestConfiguration>> headerApplicationPropertiesTestConfigurations = () -> Stream.of(htc(h -> h.put("long.string", LongStringHelper.asLongString("long string")), ap -> assertThat(ap.get("long.string")).isEqualTo("long string")), htc(h -> h.put("short.string", "short string"), ap -> assertThat(ap.get("short.string")).isEqualTo("short string")), htc(h -> h.put("long", Long.MAX_VALUE - 1), ap -> assertThat(ap.get("long")).isEqualTo(Long.MAX_VALUE - 1)), htc(h -> h.put("byte", Byte.MAX_VALUE - 1), ap -> assertThat(ap.get("byte")).isEqualTo(Byte.MAX_VALUE - 1)), htc(h -> h.put("integer", Integer.MAX_VALUE - 1), ap -> assertThat(ap.get("integer")).isEqualTo(Integer.MAX_VALUE - 1)), htc(h -> h.put("double", Double.MAX_VALUE - 1), ap -> assertThat(ap.get("double")).isEqualTo(Double.MAX_VALUE - 1)), htc(h -> h.put("float", Float.MAX_VALUE - 1), ap -> assertThat(ap.get("float")).isEqualTo(Float.MAX_VALUE - 1)), htc(h -> h.put("boolean", Boolean.FALSE), ap -> assertThat(ap.get("boolean")).isEqualTo(Boolean.FALSE)), htc(h -> h.put("binary", "hello".getBytes(UTF8)), ap -> assertThat(ap.get("binary")).isEqualTo("hello".getBytes(UTF8))), htc(h -> h.put("timestamp", timestamp), ap -> assertThat(ap.get("timestamp")).isEqualTo((timestamp.getTime() / 1000) * // in seconds in 091, in ms in 1.0, so losing some
1000)));
try (Connection amqpConnection = connectionFactory.newConnection()) {
Channel c = amqpConnection.createChannel();
c.confirmSelect();
Map<String, Object> headers = new HashMap<>();
headerApplicationPropertiesTestConfigurations.get().forEach(configuration -> configuration.headerValue.accept(headers));
AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
propertiesTestConfigurations.get().forEach(configuration -> configuration.builder.accept(builder));
AMQP.BasicProperties properties = builder.headers(headers).build();
for (int i = 0; i < messageCount; i++) {
c.basicPublish("", stream, properties, ("amqp " + i).getBytes(UTF8));
}
c.waitForConfirmsOrDie(10_000);
}
CountDownLatch consumedLatch = new CountDownLatch(messageCount);
Set<String> messageBodies = ConcurrentHashMap.newKeySet(messageCount);
Set<Message> messages = ConcurrentHashMap.newKeySet(messageCount);
Client client = cf.get(new Client.ClientParameters().codec(codec).chunkListener((client1, subscriptionId, offset, messageCount1, dataSize) -> client1.credit(subscriptionId, 1)).messageListener((subscriptionId, offset, chunkTimestamp, message) -> {
messages.add(message);
messageBodies.add(new String(message.getBodyAsBinary(), UTF8));
consumedLatch.countDown();
}));
client.subscribe(b(1), stream, OffsetSpecification.first(), 10);
assertThat(consumedLatch.await(10, SECONDS)).isTrue();
assertThat(messageBodies).hasSize(messageCount);
IntStream.range(0, messageCount).forEach(i -> assertThat(messageBodies.contains("amqp " + i)).isTrue());
Message message = messages.iterator().next();
propertiesTestConfigurations.get().forEach(c -> c.assertion.accept(message));
assertThat(message.getMessageAnnotations().get("x-exchange")).isEqualTo("");
assertThat(message.getMessageAnnotations().get("x-routing-key")).isEqualTo(stream);
headerApplicationPropertiesTestConfigurations.get().forEach(c -> c.assertion.accept(message.getApplicationProperties()));
}
use of com.rabbitmq.stream.Message in project rabbitmq-stream-java-client by rabbitmq.
the class AmqpInteroperabilityTest method publishToStreamConsumeFromStreamQueue.
@ParameterizedTest
@MethodSource("codecs")
void publishToStreamConsumeFromStreamQueue(Codec codec, TestInfo info) {
int messageCount = 1_000;
ConnectionFactory connectionFactory = new ConnectionFactory();
Date timestamp = new Date();
UUID messageIdUuid = UUID.randomUUID();
UUID correlationIdUuid = UUID.randomUUID();
Supplier<Stream<MessageOperation>> testMessageOperations = () -> Stream.of(mo(mb -> {
mb.properties().messageId("the message ID");
mb.properties().correlationId("the correlation ID");
}, d -> {
assertThat(d.getProperties().getMessageId()).isEqualTo("the message ID");
assertThat(d.getProperties().getCorrelationId()).isEqualTo("the correlation ID");
}), mo(mb -> {
mb.properties().messageId(// larger than 091 shortstr
StringUtils.repeat("*", 300));
mb.properties().correlationId(// larger than 091 shortstr
StringUtils.repeat("*", 300));
}, d -> {
assertThat(d.getProperties().getMessageId()).isNull();
assertThat(d.getProperties().getCorrelationId()).isNull();
assertThat(d.getProperties().getHeaders()).containsEntry("x-message-id", LongStringHelper.asLongString(StringUtils.repeat("*", 300))).containsEntry("x-correlation-id", LongStringHelper.asLongString(StringUtils.repeat("*", 300)));
}), mo(mb -> {
mb.properties().messageId(messageIdUuid);
mb.properties().correlationId(correlationIdUuid);
}, d -> {
assertThat(d.getProperties().getMessageId()).isEqualTo(messageIdUuid.toString());
assertThat(d.getProperties().getCorrelationId()).isEqualTo(correlationIdUuid.toString());
assertThat(d.getProperties().getHeaders()).containsEntry("x-message-id-type", LongStringHelper.asLongString("uuid")).containsEntry("x-correlation-id-type", LongStringHelper.asLongString("uuid"));
}), mo(mb -> {
mb.properties().messageId(10);
mb.properties().correlationId(20);
}, d -> {
assertThat(d.getProperties().getMessageId()).isEqualTo("10");
assertThat(d.getProperties().getCorrelationId()).isEqualTo("20");
assertThat(d.getProperties().getHeaders()).containsEntry("x-message-id-type", LongStringHelper.asLongString("ulong")).containsEntry("x-correlation-id-type", LongStringHelper.asLongString("ulong"));
}), mo(mb -> {
mb.properties().messageId("the message ID".getBytes(UTF8));
mb.properties().correlationId("the correlation ID".getBytes(UTF8));
}, d -> {
assertThat(Base64.getDecoder().decode(d.getProperties().getMessageId())).isEqualTo("the message ID".getBytes(UTF8));
assertThat(Base64.getDecoder().decode(d.getProperties().getCorrelationId())).isEqualTo("the correlation ID".getBytes(UTF8));
assertThat(d.getProperties().getHeaders()).containsEntry("x-message-id-type", LongStringHelper.asLongString("binary")).containsEntry("x-correlation-id-type", LongStringHelper.asLongString("binary"));
}), mo(mb -> {
mb.properties().messageId(StringUtils.repeat("a", 300).getBytes(// larger than 091 shortstr
UTF8));
mb.properties().correlationId(StringUtils.repeat("b", 300).getBytes(// larger than 091 shortstr
UTF8));
}, d -> {
assertThat(d.getProperties().getMessageId()).isNull();
assertThat(d.getProperties().getCorrelationId()).isNull();
assertThat(d.getProperties().getHeaders()).containsEntry("x-message-id", LongStringHelper.asLongString(StringUtils.repeat("a", 300).getBytes(UTF8))).containsEntry("x-correlation-id", LongStringHelper.asLongString(StringUtils.repeat("b", 300).getBytes(UTF8)));
}));
testMessageOperations.get().forEach(testMessageOperation -> {
CountDownLatch confirmLatch = new CountDownLatch(messageCount);
Client client = cf.get(new Client.ClientParameters().codec(codec).publishConfirmListener((publisherId, publishingId) -> confirmLatch.countDown()));
String s = streamName(info);
Client.Response response = client.create(s);
assertThat(response.isOk()).isTrue();
Supplier<Stream<MessageOperation>> messageOperations = () -> Stream.of(mo(mb -> mb.properties().userId("the user ID".getBytes(UTF8)), d -> assertThat(d.getProperties().getUserId()).isEqualTo("the user ID")), mo(mb -> mb.properties().to("the to address"), d -> {
}), mo(mb -> mb.properties().subject("the subject"), d -> {
}), mo(mb -> mb.properties().replyTo("the reply to address"), d -> assertThat(d.getProperties().getReplyTo()).isEqualTo("the reply to address")), mo(mb -> mb.properties().contentType("the content type"), d -> assertThat(d.getProperties().getContentType()).isEqualTo("the content type")), mo(mb -> mb.properties().contentEncoding("the content encoding"), d -> assertThat(d.getProperties().getContentEncoding()).isEqualTo("the content encoding")), mo(mb -> mb.properties().absoluteExpiryTime(timestamp.getTime() + 1000), d -> {
}), mo(mb -> mb.properties().creationTime(timestamp.getTime()), d -> assertThat(d.getProperties().getTimestamp().getTime()).isEqualTo((timestamp.getTime() / 1000) * // in seconds in 091, in ms in 1.0, so losing
1000)), mo(mb -> mb.properties().groupId("the group ID"), d -> {
}), mo(mb -> mb.properties().groupSequence(10), d -> {
}), mo(mb -> mb.properties().replyToGroupId("the reply to group ID"), d -> {
}), mo(mb -> mb.applicationProperties().entry("byte", Byte.MAX_VALUE), d -> assertThat(d.getProperties().getHeaders()).containsEntry("byte", Byte.MAX_VALUE)), mo(mb -> mb.applicationProperties().entry("short", Short.MAX_VALUE), d -> assertThat(d.getProperties().getHeaders()).containsEntry("short", Short.MAX_VALUE)), mo(mb -> mb.applicationProperties().entry("integer", Integer.MAX_VALUE), d -> assertThat(d.getProperties().getHeaders()).containsEntry("integer", Integer.MAX_VALUE)), mo(mb -> mb.applicationProperties().entry("long", Long.MAX_VALUE), d -> assertThat(d.getProperties().getHeaders()).containsEntry("long", Long.MAX_VALUE)), mo(mb -> mb.applicationProperties().entry("string", "a string"), d -> assertThat(d.getProperties().getHeaders()).containsEntry("string", LongStringHelper.asLongString("a string"))), mo(mb -> mb.applicationProperties().entryTimestamp("timestamp", timestamp.getTime()), d -> assertThat(d.getProperties().getHeaders()).containsEntry("timestamp", new Date((timestamp.getTime() / 1000) * 1000))), mo(mb -> mb.applicationProperties().entry("boolean", Boolean.TRUE), d -> assertThat(d.getProperties().getHeaders()).containsEntry("boolean", Boolean.TRUE)), mo(mb -> mb.applicationProperties().entry("float", 3.14f), d -> assertThat(d.getProperties().getHeaders()).containsEntry("float", 3.14f)), mo(mb -> mb.applicationProperties().entry("binary", "hello".getBytes(UTF8)), d -> assertThat(d.getProperties().getHeaders()).containsEntry("binary", "hello".getBytes(UTF8))));
client.declarePublisher(b(1), null, s);
IntStream.range(0, messageCount).forEach(i -> {
MessageBuilder messageBuilder = client.messageBuilder();
messageBuilder.addData(("stream " + i).getBytes(UTF8));
testMessageOperation.messageBuilderConsumer.accept(messageBuilder);
messageOperations.get().forEach(messageOperation -> messageOperation.messageBuilderConsumer.accept(messageBuilder));
client.publish(b(1), Collections.singletonList(messageBuilder.build()));
});
try (Connection c = connectionFactory.newConnection()) {
assertThat(confirmLatch.await(10, SECONDS)).isTrue();
Channel ch = c.createChannel();
ch.basicQos(200);
CountDownLatch consumedLatch = new CountDownLatch(messageCount);
Set<String> messageBodies = ConcurrentHashMap.newKeySet(messageCount);
Set<Delivery> messages = ConcurrentHashMap.newKeySet(messageCount);
ch.basicConsume(s, false, Collections.singletonMap("x-stream-offset", 0), (consumerTag, message) -> {
messages.add(message);
messageBodies.add(new String(message.getBody(), UTF8));
consumedLatch.countDown();
ch.basicAck(message.getEnvelope().getDeliveryTag(), false);
}, consumerTag -> {
});
assertThat(consumedLatch.await(10, SECONDS)).isTrue();
assertThat(messageBodies).hasSize(messageCount);
IntStream.range(0, messageCount).forEach(i -> assertThat(messageBodies.contains("stream " + i)).isTrue());
Delivery message = messages.iterator().next();
assertThat(message.getEnvelope().getExchange()).isEmpty();
assertThat(message.getEnvelope().getRoutingKey()).isEqualTo(s);
assertThat(message.getProperties().getHeaders()).containsKey("x-stream-offset");
testMessageOperation.deliveryConsumer.accept(message);
messageOperations.get().forEach(messageOperation -> messageOperation.deliveryConsumer.accept(message));
} catch (Exception e) {
throw new RuntimeException(e);
}
response = client.delete(s);
assertThat(response.isOk()).isTrue();
});
}
use of com.rabbitmq.stream.Message in project rabbitmq-stream-java-client by rabbitmq.
the class CodecsTest method publishingIdShouldBeSetOnMessageIfSetOnMessageBuilder.
@ParameterizedTest
@MethodSource("messageBuilders")
void publishingIdShouldBeSetOnMessageIfSetOnMessageBuilder(MessageBuilder builder) {
Message message = builder.publishingId(42).build();
assertThat(message.hasPublishingId()).isTrue();
assertThat(message.getPublishingId()).isEqualTo(42);
}
use of com.rabbitmq.stream.Message in project rabbitmq-stream-java-client by rabbitmq.
the class CodecsTest method supportAmqpValueBody.
@ParameterizedTest
@MethodSource("codecs")
void supportAmqpValueBody(Codec codec) {
Function<Object, Message> encodeDecode = content -> {
org.apache.qpid.proton.message.Message nativeMessage = org.apache.qpid.proton.message.Message.Factory.create();
nativeMessage.setBody(new AmqpValue(content));
QpidProtonAmqpMessageWrapper wrapper = new QpidProtonAmqpMessageWrapper(true, 1L, nativeMessage);
EncodedMessage encoded = new QpidProtonCodec().encode(wrapper);
byte[] encodedData = new byte[encoded.getSize()];
System.arraycopy(encoded.getData(), 0, encodedData, 0, encoded.getSize());
Message decodedMessage = codec.decode(encodedData);
return decodedMessage;
};
Message m1 = encodeDecode.apply("hello".getBytes(StandardCharsets.UTF_8));
assertThat(m1.getBodyAsBinary()).asString(StandardCharsets.UTF_8).isEqualTo("hello");
Message m2 = encodeDecode.apply("a string is not an array of byte");
assertThatThrownBy(() -> m2.getBodyAsBinary()).isInstanceOf(IllegalStateException.class);
}
Aggregations