Rule の作成
この記事を読みながら
CreateRuleAsync というメソッドを使えば、ある topic の subscription に適応するルールを作成できます。
このルールを適応すれば、例えば以下のようなことが出来ます。
- ApplicationProperty の Shop の値が
test
となっている時、Message の ReplyTo をhoge
にする - Message の To が
fuga
の時に、ApplicationProperty の Shop の値を `` にする
など、Message のプロパティを書き換える事が出来ます。
こんなコードを書きます。
var a = new ServiceBusAdministrationClient(connectionString); await a.CreateRuleAsync("some-topic", "some-subscriptions", new CreateRuleOptions { Name = "StoreIsTestRule", Filter = new SqlRuleFilter("Store = 'test'"), Action = new SqlRuleAction("SET sys.ReplyTo = 'hoge'") });
すると Subscription に対して Rule が出来ます。
Fileter ってのがどの Message に対して Action を実行するかって条件を記述します。サンプルコードのように SQL Like に書くためのクラスが SqlRuleFilter です。
Store='test'
と書いてて Store
とは何ぞ?となるかもしれませんが、これは ApplicationProperty
内の値を示しています。Shop
とか書くと、ApplicationProperty
内の Shop
に対して条件をかけます。ネストされたプロパティに対しては、Shop.Name='Tokyo'
のように書くことが出来ます (配列は試してない)。
ApplicationProperty
だけでなく、システムプロパティにも条件は書けます。システムプロパティとは
- Subject
- State
- ReplyTo
などなどですね。詳しくはこちらの記事を参考にしてください。
これらに対して SQL を書くときは、sys
を先頭に付けます。なので sys.To='fuga'
のようにする必要があります。
同じく Filter を書くためのクラスには CorrelationRuleFilter というのもあります。こんな感じで書けますね。
var a = new ServiceBusAdministrationClient(connectionString); var fileter = new CorrelationRuleFilter(); fileter.ApplicationProperties.Add("Store", "Tokyo"); await a.CreateRuleAsync("etl-location-changed", "pub-make-location-content-sources", new CreateRuleOptions { Name = "StoreIsTestRule1", Filter = fileter, Action = new SqlRuleAction("SET Shop = 'hoge'") });
こちらの方が書き心地が良いかもしれません。
では実際に message を投げて Rule が適応されているのか見てみます。
await using var client = new ServiceBusClient(connectionString); await using var sender = client.CreateSender("some-topic"); var message = new ServiceBusMessage(); message.ApplicationProperties.Add("Store", "test"); await sender.SendMessageAsync(message); await using var receiver = client.CreateReceiver("some-subscriptions"); var messages = await receiver.ReceiveMessagesAsync(100, TimeSpan.FromMilliseconds(5)); foreach (var m in messages) { m.Dump(); await receiver.CompleteMessageAsync(m); }
すると受け取った message の ReplyTo にちゃんと hoge
と入っていました。面白いのが、ApplicationProperty
に適応された Rule が記録されていることです。Rule 名を同じ ApplicationProperty
をプログラムで追加してるとどうなるだろう?
後不思議だったのが、同じ MessageId の message が複数受信できたことです。今回の場合だと Rule が適応されていない Message
と適応されている Message
の 2 つが受信出来ました。同じ MessageId って複数存在しないと思ってたけどなんでだろう?
色々使える場面はあるのかもしれんけど、普段 ApplicationProperty
に値を積めないから想像がつかんなぁ。そもそも ApplicationProperty
を使いたい時とは。
書いてる途中で知ったんだけど、ServiceBusClient に CreateRuleManager ってメソッドがあって、これの戻り値でも同じように Rule の作成が出来そうだった。