in dotnet/src/Azure.Iot.Operations.Protocol/MqttTopicProcessor.cs [77:165]
public static PatternValidity ValidateTopicPattern(
string? pattern,
IReadOnlyDictionary<string, string>? tokenMap,
bool requireReplacement,
out string errMsg,
out string? errToken,
out string? errReplacement)
{
errToken = null;
errReplacement = null;
if (string.IsNullOrEmpty(pattern))
{
errMsg = "MQTT topic pattern must not be empty";
return PatternValidity.InvalidPattern;
}
if (pattern.StartsWith('$'))
{
errMsg = "MQTT topic pattern starts with reserved character '$'";
return PatternValidity.InvalidPattern;
}
foreach (string level in pattern.Split('/'))
{
if (level.Length == 0)
{
errMsg = "MQTT topic pattern contains empty level";
return PatternValidity.InvalidPattern;
}
bool isToken = level.StartsWith('{') && level.EndsWith('}');
if (isToken)
{
string token = level[1..^1];
if (token.Length == 0)
{
errMsg = "Token in MQTT topic pattern is empty";
return PatternValidity.InvalidPattern;
}
else if (ContainsInvalidChar(token))
{
errMsg = $"Token '{level}' in MQTT topic pattern contains invalid character";
return PatternValidity.InvalidPattern;
}
else if (tokenMap == null)
{
if (requireReplacement)
{
errMsg = $"Token '{level}' in MQTT topic pattern, but no replacement map value provided";
errToken = token;
return PatternValidity.MissingReplacement;
}
}
else
{
string? replacement = null;
bool hasReplacement = tokenMap != null && tokenMap.TryGetValue(token, out replacement);
if (!hasReplacement)
{
if (requireReplacement)
{
errMsg = $"Token '{level}' in MQTT topic pattern, but key '{token}' not found in replacement map";
errToken = token;
return PatternValidity.MissingReplacement;
}
}
else if (hasReplacement && !IsValidReplacement(replacement))
{
errMsg = $"Token '{level}' in MQTT topic pattern has resident replacement value '{replacement}' that is not valid";
errToken = token;
errReplacement = replacement;
return PatternValidity.InvalidResidentReplacement;
}
}
}
else
{
if (ContainsInvalidChar(level))
{
errMsg = $"Level '{level}' in MQTT topic pattern contains invalid character";
return PatternValidity.InvalidPattern;
}
}
}
errMsg = string.Empty;
return PatternValidity.Valid;
}