@@ -172,6 +172,115 @@ async Task SendTo(string state)
172
172
await SystemUtils . CleanUpStreamSystem ( system , stream ) . ConfigureAwait ( false ) ;
173
173
}
174
174
175
+ [ SkippableFact ]
176
+ public async void FilterShouldReturnOnlyOneChunkWithDeduplication ( )
177
+ {
178
+ SystemUtils . InitStreamSystemWithRandomStream ( out var system , out var stream ) ;
179
+ if ( ! AvailableFeaturesSingleton . Instance . PublishFilter )
180
+ {
181
+ throw new SkipException ( "broker does not support filter" ) ;
182
+ }
183
+
184
+ var deduplicatingProducer = await DeduplicatingProducer . Create (
185
+ new DeduplicatingProducerConfig ( system , stream , "my_ref" )
186
+ {
187
+ Filter = new ProducerFilter ( )
188
+ {
189
+ // define the producer filter
190
+ FilterValue = message => message . ApplicationProperties [ "state" ] . ToString ( ) ,
191
+ }
192
+ }
193
+ ) ;
194
+
195
+ const int ToSend = 50 ;
196
+
197
+ async Task SendTo ( string state , ulong start )
198
+ {
199
+ for ( var i = ( 0 + start ) ; i < ToSend + start ; i ++ )
200
+ {
201
+ var message = new Message ( Encoding . UTF8 . GetBytes ( $ "Message: { i } . State: { state } ") )
202
+ {
203
+ ApplicationProperties = new ApplicationProperties ( ) { [ "state" ] = state } ,
204
+ Properties = new Properties ( ) { GroupId = $ "group_{ i } " }
205
+ } ;
206
+ await deduplicatingProducer . Send ( i , message ) . ConfigureAwait ( false ) ;
207
+ }
208
+ }
209
+
210
+ await SendTo ( "Alabama" , 0 ) ;
211
+ await Task . Delay ( TimeSpan . FromSeconds ( 2 ) ) . ConfigureAwait ( false ) ;
212
+ await SendTo ( "New York" , ToSend ) ;
213
+ await Task . Delay ( TimeSpan . FromSeconds ( 2 ) ) . ConfigureAwait ( false ) ;
214
+
215
+ var testPassedAlabama = new TaskCompletionSource < int > ( ) ;
216
+ var consumedAlabama = new List < Message > ( ) ;
217
+ var consumerAlabama = await Consumer . Create ( new ConsumerConfig ( system , stream )
218
+ {
219
+ OffsetSpec = new OffsetTypeFirst ( ) ,
220
+
221
+ // This is mandatory for enabling the filter
222
+ Filter = new ConsumerFilter ( )
223
+ {
224
+ Values = new List < string > ( ) { "Alabama" } ,
225
+ PostFilter =
226
+ _ =>
227
+ true , // we don't apply any post filter here to be sure that the server is doing the filtering
228
+ MatchUnfiltered = true
229
+ } ,
230
+ MessageHandler = ( _ , _ , _ , message ) =>
231
+ {
232
+ consumedAlabama . Add ( message ) ;
233
+ if ( consumedAlabama . Count == ToSend )
234
+ {
235
+ testPassedAlabama . SetResult ( ToSend ) ;
236
+ }
237
+
238
+ return Task . CompletedTask ;
239
+ }
240
+ } ) . ConfigureAwait ( false ) ;
241
+ Assert . True ( testPassedAlabama . Task . Wait ( TimeSpan . FromSeconds ( 5 ) ) ) ;
242
+
243
+ Assert . Equal ( ToSend , consumedAlabama . Count ) ;
244
+
245
+ // check that only the messages from Alabama were
246
+ consumedAlabama . Where ( m => m . ApplicationProperties [ "state" ] . Equals ( "Alabama" ) ) . ToList ( ) . ForEach ( m =>
247
+ {
248
+ Assert . Equal ( "Alabama" , m . ApplicationProperties [ "state" ] ) ;
249
+ } ) ;
250
+
251
+ await consumerAlabama . Close ( ) . ConfigureAwait ( false ) ;
252
+ // let's reset
253
+ var consumedNY = new List < Message > ( ) ;
254
+
255
+ var consumerNY = await Consumer . Create ( new ConsumerConfig ( system , stream )
256
+ {
257
+ OffsetSpec = new OffsetTypeFirst ( ) ,
258
+
259
+ // This is mandatory for enabling the filter
260
+ Filter = new ConsumerFilter ( )
261
+ {
262
+ Values = new List < string > ( ) { "New York" } ,
263
+ PostFilter =
264
+ message => message . Properties . GroupId . ToString ( ) !
265
+ . Equals ( "group_55" ) , // we only want the message with group_55 ignoring the rest
266
+ // this filter is client side. We should have two messages with group_55
267
+ // One for the standard send and one for the batch send
268
+ MatchUnfiltered = true
269
+ } ,
270
+ MessageHandler = ( _ , _ , _ , message ) =>
271
+ {
272
+ consumedNY . Add ( message ) ;
273
+ return Task . CompletedTask ;
274
+ }
275
+ } ) . ConfigureAwait ( false ) ;
276
+
277
+ SystemUtils . Wait ( TimeSpan . FromSeconds ( 2 ) ) ;
278
+ Assert . Single ( consumedNY ) ;
279
+ Assert . Equal ( "group_55" , consumedNY [ 0 ] . Properties . GroupId ! ) ;
280
+ await consumerNY . Close ( ) . ConfigureAwait ( false ) ;
281
+ await SystemUtils . CleanUpStreamSystem ( system , stream ) . ConfigureAwait ( false ) ;
282
+ }
283
+
175
284
// This test is to test when there are errors on the filter functions
176
285
// producer side and consumer side.
177
286
// FilterValue and PostFilter are user's functions and can throw exceptions
@@ -249,7 +358,7 @@ await producer.Send(new Message(Encoding.UTF8.GetBytes("Message: " + i))
249
358
OffsetSpec = new OffsetTypeFirst ( ) ,
250
359
Filter = new ConsumerFilter ( )
251
360
{
252
- Values = new List < string > ( ) { "my_filter" } , // at this level we don't care about the filter value
361
+ Values = new List < string > ( ) { "my_filter" } , // at this level we don't care about the filter value
253
362
PostFilter =
254
363
message =>
255
364
{
0 commit comments