skip to Main Content

I’m trying to construct an Azure ServiceBus Subscription Rule that will have either a correlation filter or sql filter depending on the length of param’s subjectFilter array property. I tried this using if with union, based on this answer. However, it looks like the object is constructed with all properties. For example, the sql filter errors with "At least one system or user property must be set for a correlation filter."

Here’s my code (simplified).

  • The copy variable contains properties to use for each subscription name and filterProperties, with defines a filterType and is used as the base properties object.
  • It also declares a separate object for the sqlFilterProperties and correlationFilterProperties, respectively.
  • Either the sqlFilterProperties or correlationFilterProperties object should be unioned with the filterProperties to construct the complete properties.
{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "resourceName": {
            "type": "string"
        },
        "topics": {
            "type": "array"
        },
        "subscriptionName": {
            "type": "string"
        }
    },
    "variables": {
        "apiVersion": "2018-01-01-preview",
        "copy": [
            {
                "name": "subscriptions",
                "count": "[length(parameters('topics'))]",
                "input": {
                    "name": "[concat(parameters('resourceName'), '/', parameters('topics')[copyIndex('subscriptions')].name, '/', parameters('subscriptionName'))]",
                    "filterProperties": {
                        "filterType": "[if(greater(length(parameters('topics')[copyIndex('subscriptions')].subjectFilter),1),'sqlFilter','correlationFilter')]"
                    },
                    "sqlFilterProperties": {
                        "sqlFilter": {
                            "sqlExpression": "[concat('sys.subject in (''',join(parameters('topics')[copyIndex('subscriptions')].subjectFilter,''','''), ''')')]",
                            "requiresPreprocessing": false
                        }
                    },
                    "correlationFilterProperties": {
                        "correlationFilter": {
                            "subject": "[parameters('topics')[copyIndex('subscriptions')].subjectFilter[0]]",
                            "requiresPreprocessing": false
                        }
                    }
                }
            }
        ]
    },
    "resources": [
        {
            "type": "Microsoft.ServiceBus/namespaces/topics/subscriptions/rules",
            "apiVersion": "[variables('apiVersion')]",
            "copy": {
                "name": "subscriptionFilters",
                "count": "[length(parameters('topics'))]"
            },
            "name": "[concat(variables('subscriptions')[copyIndex()].name, '/subject')]",
            "properties": "[union(variables('subscriptions')[copyIndex()].filterProperties, if(startsWith(variables('subscriptions')[copyIndex()].filterProperties.filterType, 'sql'), variables('subscriptions')[copyIndex()].sqlFilterProperties, variables('subscriptions')[copyIndex()].correlationFilterProperties) )]"
        }
    ]
}

2

Answers


  1. Chosen as BEST ANSWER

    I got this answer from Microsoft through a support ticket. The problem is subject metadata property is actually called label when creating filters. (In C# it is called Subject.) So simply changing the sqlExpression to use sys.Label and the correlationFilter properties to use Label solved the problem.

    See docs

    https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-messages-payloads

    https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.servicebus.message.label?view=azure-dotnet


  2. Rather than using the union method directly, you can conditionally assign the filter properties based on the filter type. Compare the filter type with 'correlationFilter' or 'sqlFilter' using the equals function.

    You can make the changes listed below to your code and try deployment once again.

    "correlationFilter":  "[if(equals(variables('subscriptions')[copyIndex()].filterProperties.filterType, 'correlationFilter'), variables('subscriptions')[copyIndex()].correlationFilterProperties.correlationFilter)]",  
    "sqlFilter":  "[if(equals(variables('subscriptions')[copyIndex()].filterProperties.filterType, 'sqlFilter'), variables('subscriptions')[copyIndex()].sqlFilterProperties.sqlFilter)]"
    

    Alternatively, you can also use system properties like (ContentType, Label, MessageId, ReplyTo) and user-defined values to filter, when you use the CorrelationRuleFilter default constructor. Use the IDictionary string, object> property Properties to supply user-defined properties for the correlation filter as detailed here.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search