Skip to content

Commit

Permalink
Fix Mqtt message address parsing (#214)
Browse files Browse the repository at this point in the history
  • Loading branch information
varunpuranik authored Aug 27, 2018
1 parent 38ac3f1 commit 2b09542
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,32 +86,38 @@ public bool TryBuildProtocolAddressFromEdgeHubMessage(string endPointUri, IMessa
/// of the <paramref name="message"/> argument - which here is an MQTT topic name - and
/// extracts features from it that it then uses to populate the <see cref="ProtocolGateway.Messaging.IMessage.Properties"/>
/// property.
/// Note: In case of multiple matches, this method uses the first topic. So the order in which the topics are defined matters.
/// </summary>
public bool TryParseProtocolMessagePropsFromAddress(IProtocolGatewayMessage message)
{
var uri = new Uri(message.Address, UriKind.Relative);
string address = message.Address;
var uri = new Uri(address, UriKind.Relative);
IList<IList<KeyValuePair<string, string>>> matches = this.inboundTable
.Select(template => template.Match(uri))
.Where(match => match.Count > 0)
.ToList();

if (matches.Count > 1)
{
this.logger.LogWarning($"Message address {message.Address} matches more than one topic. Picking first matching topic.");
}
else if (matches.Count == 0)
if (matches.Count == 0)
{
this.logger.LogWarning($"Message address {message.Address} does not match any topic.");
}
else
{
if (matches.Count > 1)
{
this.logger.LogDebug($"Message address {message.Address} matches more than one topic. Picking first matching topic.");
}

foreach (KeyValuePair<string, string> match in matches[0])
{
// If the template has a key called "params" then it contains all the properties set by the user on
// the sent message in query string format. So get the value and parse it.
if (match.Key == "params")
{
UrlEncodedDictionarySerializer.Deserialize(match.Value, 0, message.Properties);
if (!string.IsNullOrWhiteSpace(match.Value))
{
UrlEncodedDictionarySerializer.Deserialize(match.Value, 0, message.Properties);
}
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -528,5 +528,50 @@ public void TestTryParseAddressWithTailingSlashOptional()
Assert.Equal("bee", message2.Properties["b"]);
Assert.Equal("dee", message2.Properties["d"]);
}

[Fact]
public void TestTryParseAddressWithTailingSlashOptionalWithMultipleMatches()
{
IList<string> input = new List<string>
{
"a/{b}/c/{d}/{e}/",
"a/{b}/c/{d}/",
"a/{b}/c/",
"a/{b}/c/{d}/{e}",
"a/{b}/c/{d}",
"a/{b}/c"
};
var config = new MessageAddressConversionConfiguration(
input,
DontCareOutput
);
var converter = new MessageAddressConverter(config);

string address = "a/bee/c/";
ProtocolGatewayMessage message = new ProtocolGatewayMessage.Builder(Payload, address)
.Build();
bool status = converter.TryParseProtocolMessagePropsFromAddress(message);
Assert.True(status);
Assert.Equal(1, message.Properties.Count);
Assert.Equal("bee", message.Properties["b"]);

string address2 = "a/bee/c/dee/";
ProtocolGatewayMessage message2 = new ProtocolGatewayMessage.Builder(Payload, address2)
.Build();
bool status2 = converter.TryParseProtocolMessagePropsFromAddress(message2);
Assert.True(status2);
Assert.Equal(2, message2.Properties.Count);
Assert.Equal("bee", message2.Properties["b"]);
Assert.Equal("dee", message2.Properties["d"]);

string address3 = "a/bee/c/dee";
ProtocolGatewayMessage message3 = new ProtocolGatewayMessage.Builder(Payload, address3)
.Build();
bool status3 = converter.TryParseProtocolMessagePropsFromAddress(message3);
Assert.True(status2);
Assert.Equal(2, message2.Properties.Count);
Assert.Equal("bee", message2.Properties["b"]);
Assert.Equal("dee", message2.Properties["d"]);
}
}
}

0 comments on commit 2b09542

Please sign in to comment.