diff --git a/.github/workflows/publish-documentation.yml b/.github/workflows/publish-documentation.yml index 05c4b7df2..2f91cf336 100644 --- a/.github/workflows/publish-documentation.yml +++ b/.github/workflows/publish-documentation.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up JDK uses: actions/setup-java@v4 with: diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index a6c61c918..b9516c644 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up JDK uses: actions/setup-java@v4 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 537e00dda..0075af4f6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up JDK uses: actions/setup-java@v4 with: diff --git a/.github/workflows/sanity-check.yml b/.github/workflows/sanity-check.yml index dfc8073f9..f205cbbcd 100644 --- a/.github/workflows/sanity-check.yml +++ b/.github/workflows/sanity-check.yml @@ -14,9 +14,9 @@ jobs: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Checkout tls-gen - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: rabbitmq/tls-gen path: './tls-gen' diff --git a/.github/workflows/test-pr.yml b/.github/workflows/test-pr.yml index 36fdfcda7..dda07090b 100644 --- a/.github/workflows/test-pr.yml +++ b/.github/workflows/test-pr.yml @@ -10,9 +10,9 @@ jobs: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Checkout tls-gen - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: rabbitmq/tls-gen path: './tls-gen' diff --git a/.github/workflows/test-rabbitmq-alphas.yml b/.github/workflows/test-rabbitmq-alphas.yml index bfafd8fe8..d73c8f75f 100644 --- a/.github/workflows/test-rabbitmq-alphas.yml +++ b/.github/workflows/test-rabbitmq-alphas.yml @@ -18,9 +18,9 @@ jobs: - pivotalrabbitmq/rabbitmq:main-otp27 name: Test against ${{ matrix.rabbitmq-image }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Checkout tls-gen - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: rabbitmq/tls-gen path: './tls-gen' diff --git a/.github/workflows/test-supported-java-versions.yml b/.github/workflows/test-supported-java-versions.yml index 3cd9cbe3b..06a6e7508 100644 --- a/.github/workflows/test-supported-java-versions.yml +++ b/.github/workflows/test-supported-java-versions.yml @@ -17,9 +17,9 @@ jobs: version: '17' name: Test against Java ${{ matrix.distribution }} ${{ matrix.version }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Checkout tls-gen - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: rabbitmq/tls-gen path: './tls-gen' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 63b292505..fcf89e945 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,9 +11,9 @@ jobs: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Checkout tls-gen - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: rabbitmq/tls-gen path: './tls-gen' diff --git a/pom.xml b/pom.xml index 70cbe967f..ca47ebc66 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 com.rabbitmq.client amqp-client - 0.7.0 + 0.8.0-SNAPSHOT RabbitMQ AMQP 1.0 Java client The RabbitMQ AMQP 1.0 Java client library defines an API to access RabbitMQ with AMQP 1.0. @@ -35,23 +35,23 @@ https://github.com/rabbitmq/rabbitmq-amqp-java-client scm:git:git://github.com/rabbitmq/rabbitmq-amqp-java-client.git scm:git:https://github.com/rabbitmq/rabbitmq-amqp-java-client.git - v0.7.0 + HEAD UTF-8 true 1.7.36 - 4.2.3.Final + 4.2.4.Final 0.0.26.Final - 1.15.2 + 1.15.3 2.13.1 1.2.13 5.13.4 - 3.27.3 + 3.27.4 5.18.0 1.9.3 - 1.5.2 + 1.5.3 1.0.4 0.9.6 3.18.0 @@ -67,7 +67,7 @@ 2.46.1 1.28.0 4.9.3.2 - 4.9.3 + 4.9.4 3.2.1 3.2.8 3.2.0 diff --git a/src/main/qpid/org/apache/qpid/protonj2/client/SourceOptions.java b/src/main/qpid/org/apache/qpid/protonj2/client/SourceOptions.java index 0ade3a1c6..dd35f9438 100644 --- a/src/main/qpid/org/apache/qpid/protonj2/client/SourceOptions.java +++ b/src/main/qpid/org/apache/qpid/protonj2/client/SourceOptions.java @@ -19,8 +19,10 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import org.apache.qpid.protonj2.client.impl.ClientDeliveryState; +import org.apache.qpid.protonj2.types.DescribedType; /** * Options type that carries configuration for link Source types. @@ -99,6 +101,32 @@ public SourceOptions filters(Map filters) { return self(); } + /** + * Adds the given named filter into the map of filters (one will be created if not already set). + *

+ * If a previous filters {@link Map} was assigned this new filter instance will be assigned + * into that existing map, it is not cleared or reallocated. The descriptor should either be + * an Symbol or UnsignedLong that aligns with the filters definition being used. + * + * @param name + * The name to use when adding the described filter to the filters {@link Map}. + * @param descriptor + * The descriptor used for the {@link DescribedType} that will carry the filter. + * @param filter + * The filter value to assign to the filter {@link DescribedType}. + * + * @return this {@link SourceOptions} instance. + */ + public SourceOptions addFilter(String name, Object descriptor, Object filter) { + if (filters == null) { + filters = new HashMap<>(); + } + + filters.put(name, new FilterDescribedType(descriptor, filter)); + + return self(); + } + /** * @return the configured default outcome as a {@link DeliveryState} instance. */ @@ -139,4 +167,54 @@ public SourceOptions outcomes(DeliveryState.Type... outcomes) { SourceOptions self() { return this; } + + private static class FilterDescribedType implements DescribedType { + + private final Object descriptor; + private final Object described; + + public FilterDescribedType(Object descriptor, Object described) { + this.descriptor = descriptor; + this.described = described; + } + + @Override + public Object getDescriptor() { + return descriptor; + } + + @Override + public Object getDescribed() { + return this.described; + } + + @Override + public String toString() { + return "FilterDescribedType{ descriptor:" + descriptor + ", described:" + described + " }"; + } + + @Override + public int hashCode() { + return Objects.hash(described, descriptor); + } + + @Override + public boolean equals(Object target) { + if (this == target) { + return true; + } + + if (target == null) { + return false; + } + + if (!(target instanceof DescribedType)) { + return false; + } + + final DescribedType other = (DescribedType) target; + + return Objects.equals(descriptor, other.getDescriptor()) && Objects.equals(described, other.getDescribed()); + } + } } diff --git a/src/test/java/com/rabbitmq/client/amqp/docs/WebsiteDocumentation.java b/src/test/java/com/rabbitmq/client/amqp/docs/WebsiteDocumentation.java index 7e635f97c..97b6e9ef0 100644 --- a/src/test/java/com/rabbitmq/client/amqp/docs/WebsiteDocumentation.java +++ b/src/test/java/com/rabbitmq/client/amqp/docs/WebsiteDocumentation.java @@ -11,9 +11,10 @@ import com.rabbitmq.client.amqp.Publisher; import com.rabbitmq.client.amqp.impl.AmqpEnvironmentBuilder; -import java.nio.charset.StandardCharsets; import java.time.Duration; +import static java.nio.charset.StandardCharsets.UTF_8; + public class WebsiteDocumentation { void environment() { @@ -48,7 +49,7 @@ void publishing() { // create the message Message message = publisher - .message("hello".getBytes(StandardCharsets.UTF_8)) + .message("hello".getBytes(UTF_8)) .messageId(1L); // publish the message and deal with broker feedback @@ -326,4 +327,52 @@ void deactivateRecovery() { .activated(false) .connectionBuilder().build(); } + + void propertyFilterExpressions() { + Connection connection = null; + Consumer consumer = connection.consumerBuilder() + .stream().filter() + .userId("John".getBytes(UTF_8)) + .subject("&p:Order") + .property("region", "emea") + .stream().builder() + .queue("my-queue") + .messageHandler((ctx, msg ) -> { + // message processing + }) + .build(); + } + + void sqlFilterExpressions() { + Connection connection = null; + Consumer consumer = connection.consumerBuilder() + .stream().filter() + .sql("properties.user_id = 'John' AND " + + "properties.subject LIKE 'Order%' AND " + + "region = 'emea'") + .stream().builder() + .queue("my-queue") + .messageHandler((ctx, msg ) -> { + // message processing + }) + .build(); + } + + void combinedFilterExpressions() { + Connection connection = null; + Consumer consumer = connection.consumerBuilder() + .stream() + .filterValues("order.created") + .filter() + .sql("p.subject = 'order.created' AND " + + "p.creation_time > UTC() - 3600000 AND " + + "region IN ('AMER', 'EMEA', 'APJ') AND " + + "(h.priority > 4 OR price >= 99.99 OR premium_customer = TRUE)") + .stream().builder() + .queue("my-queue") + .messageHandler((ctx, msg ) -> { + // message processing + }) + .build(); + } }