Skip to content

Commit

Permalink
[improve][test] Add integration test for entry filters (#17396)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andras Beni authored Sep 16, 2022
1 parent bfbe381 commit 4ba219d
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.pulsar.tests.integration.plugins;

import java.util.regex.Pattern;
import org.apache.bookkeeper.mledger.Entry;
import org.apache.pulsar.broker.service.plugin.EntryFilter;
import org.apache.pulsar.broker.service.plugin.FilterContext;
import org.apache.pulsar.common.api.proto.KeyValue;

public class PatternEntryFilter implements EntryFilter {

public static final String FILTER_PATTERN = "entry_filter_pattern";
public static final String FILTER_PROPERTY = "filter_property";

@Override
public FilterResult filterEntry(Entry entry, FilterContext context) {
Pattern p = getPattern(context);
String value = getMessagePropertyValue(context);
if (p == null || value == null || p.matcher(value).matches()) {
return FilterResult.ACCEPT;
}
return FilterResult.REJECT;
}

private Pattern getPattern(FilterContext context) {
String subscriptionRegex = context.getSubscription().getSubscriptionProperties().get(FILTER_PATTERN);
if (subscriptionRegex == null) {
return null;
}
return Pattern.compile(subscriptionRegex);
}

private String getMessagePropertyValue(FilterContext context) {
return context.getMsgMetadata().getPropertiesList().stream()
.filter(kv -> FILTER_PROPERTY.equals(kv.getKey()))
.map(KeyValue::getValue)
.findFirst().orElse(null);
}

@Override
public void close() {
// Nothing to do here
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#

name: pattern_filter
description: Regex pattern based entry filter
entryFilterClass: org.apache.pulsar.tests.integration.plugins.PatternEntryFilter
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ protected String getPartitionedTopic(String topicPrefix, boolean isPersistent, i
"Received duplicate message " + currentReceived.getValue());
}
}
assertEquals(messagesReceived.size(), messagesToReceive);
assertEquals(messagesToReceive, messagesReceived.size());
}

protected <T> void receiveMessagesCheckDuplicate
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.pulsar.tests.integration.plugins;

import static org.testng.Assert.assertNotNull;
import lombok.Cleanup;
import org.apache.pulsar.client.api.Consumer;
import org.apache.pulsar.client.api.ConsumerBuilder;
import org.apache.pulsar.client.api.MessageId;
import org.apache.pulsar.client.api.Producer;
import org.apache.pulsar.client.api.PulsarClient;
import org.apache.pulsar.client.api.Schema;
import org.apache.pulsar.client.api.SubscriptionInitialPosition;
import org.apache.pulsar.client.api.SubscriptionType;
import org.apache.pulsar.tests.integration.messaging.TopicMessagingBase;
import org.testng.annotations.Test;
import java.util.Collections;
import java.util.function.Supplier;

public class TestEntryFilters extends TopicMessagingBase {

private static final String PREFIX = "PULSAR_PREFIX_";

@Override
public void setupCluster() throws Exception {
brokerEnvs.put(PREFIX + "entryFilterNames", "pattern_filter");
brokerEnvs.put(PREFIX + "entryFiltersDirectory", "/pulsar/examples");
super.setupCluster();
}

@Test(dataProvider = "ServiceUrls")
public void test(Supplier<String> serviceUrlSupplier) throws Exception {
String serviceUrl = serviceUrlSupplier.get();

final String topicName = getNonPartitionedTopic("filtered-topic", true);
@Cleanup
final PulsarClient client = PulsarClient.builder()
.serviceUrl(serviceUrl)
.build();

String evenPattern = "^[a-z]+-\\d*[02468]$";

@Cleanup
final Producer<String> producer = client.newProducer(Schema.STRING)
.topic(topicName)
.enableBatching(false)
.producerName("producer")
.create();
int messagesToSend = 20;
for (int i = 0; i < messagesToSend; i++) {
String messageValue = producer.getProducerName() + "-" + i;
MessageId messageId = producer.newMessage()
.value(messageValue)
.property("filter_property", messageValue)
.send();
assertNotNull(messageId);
}

try (Consumer<String> consumer = createConsumer(client, topicName, evenPattern)) {
receiveMessagesCheckOrderAndDuplicate(Collections.singletonList(consumer), messagesToSend / 2);

}
try(Consumer<String> consumer = createConsumer(client, topicName, null)) {
receiveMessagesCheckOrderAndDuplicate(Collections.singletonList(consumer), messagesToSend);

}
}

private Consumer<String> createConsumer(
PulsarClient client, String topicName, String filterPattern) throws Exception {
ConsumerBuilder<String> builder = client.newConsumer(Schema.STRING)
.topic(topicName)
.subscriptionName(randomName(8))
.subscriptionType(SubscriptionType.Exclusive)
.subscriptionInitialPosition(SubscriptionInitialPosition.Earliest);
if (filterPattern != null) {
builder.subscriptionProperties(Collections.singletonMap("entry_filter_pattern", filterPattern));
}
return builder.subscribe();
}

}
1 change: 1 addition & 0 deletions tests/integration/src/test/resources/pulsar-plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<classes>
<class name="org.apache.pulsar.tests.integration.plugins.TestProtocolHandlers" />
<class name="org.apache.pulsar.tests.integration.plugins.TestAdditionalServlets" />
<class name="org.apache.pulsar.tests.integration.plugins.TestEntryFilters" />
</classes>
</test>
</suite>

0 comments on commit 4ba219d

Please sign in to comment.