Skip to content

Commit 38a738b

Browse files
author
Azure IoT Builder
committed
Merge commit '53de2f2a802a63a2cb55dc9c118f1b30827134a8' into HEAD
2 parents 3ce92e1 + 53de2f2 commit 38a738b

File tree

9 files changed

+284
-33
lines changed

9 files changed

+284
-33
lines changed

device/Microsoft.Azure.Devices.Client/Common/WebApi/CustomHeaderConstants.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,26 @@ static class CustomHeaderConstants
6767
/// </summary>
6868
public const string Ack = "iothub-ack";
6969

70+
/// <summary>
71+
/// [Optional] Used to specify the schema of the message content.
72+
/// </summary>
73+
public const string MessageSchema = "iothub-messageschema";
74+
75+
/// <summary>
76+
/// [Optional] Custom date property set by the originator of the message.
77+
/// </summary>
78+
public const string CreationTimeUtc = "iothub-creationtimeutc";
79+
80+
/// <summary>
81+
/// [Optional] Used to specify the content encoding type of the message.
82+
/// </summary>
83+
public const string ContentEncoding = "iothub-contentencoding";
84+
85+
/// <summary>
86+
/// [Optional] Used to specify the content type of the message.
87+
/// </summary>
88+
public const string ContentType = "iothub-contenttype";
89+
7090
/// <summary>
7191
/// The lock token of the retrieved message
7292
/// </summary>

device/Microsoft.Azure.Devices.Client/Message.cs

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-

2-
3-
// Copyright (c) Microsoft. All rights reserved.
1+
// Copyright (c) Microsoft. All rights reserved.
42
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
53

64
namespace Microsoft.Azure.Devices.Client
@@ -363,6 +361,86 @@ public string UserId
363361
/// For incoming messages, contains the Mqtt topic that the message arrived on
364362
/// </summary>
365363
internal string MqttTopicName { get; set; }
364+
365+
/// <summary>
366+
/// Used to specify the schema of the message content.
367+
/// </summary>
368+
public string MessageSchema
369+
{
370+
get
371+
{
372+
#if NETMF
373+
return this.GetSystemProperty(MessageSystemPropertyNames.MessageSchema) as string ?? string.Empty;
374+
#else
375+
return this.GetSystemProperty<string>(MessageSystemPropertyNames.MessageSchema);
376+
#endif
377+
}
378+
379+
set
380+
{
381+
this.SystemProperties[MessageSystemPropertyNames.MessageSchema] = value;
382+
}
383+
}
384+
385+
/// <summary>
386+
/// Custom date property set by the originator of the message.
387+
/// </summary>
388+
public DateTimeT CreationTimeUtc
389+
{
390+
get
391+
{
392+
#if NETMF
393+
return (DateTime)(this.GetSystemProperty(MessageSystemPropertyNames.CreationTimeUtc) ?? DateTime.MinValue);
394+
#else
395+
return this.GetSystemProperty<DateTimeT>(MessageSystemPropertyNames.CreationTimeUtc);
396+
#endif
397+
}
398+
399+
set
400+
{
401+
this.SystemProperties[MessageSystemPropertyNames.CreationTimeUtc] = value;
402+
}
403+
}
404+
405+
/// <summary>
406+
/// Used to specify the content type of the message.
407+
/// </summary>
408+
public string ContentType
409+
{
410+
get
411+
{
412+
#if NETMF
413+
return this.GetSystemProperty(MessageSystemPropertyNames.ContentType) as string ?? string.Empty;
414+
#else
415+
return this.GetSystemProperty<string>(MessageSystemPropertyNames.ContentType);
416+
#endif
417+
}
418+
419+
set
420+
{
421+
this.SystemProperties[MessageSystemPropertyNames.ContentType] = value;
422+
}
423+
}
424+
425+
/// <summary>
426+
/// Used to specify the content encoding type of the message.
427+
/// </summary>
428+
public string ContentEncoding
429+
{
430+
get
431+
{
432+
#if NETMF
433+
return this.GetSystemProperty(MessageSystemPropertyNames.ContentEncoding) as string ?? string.Empty;
434+
#else
435+
return this.GetSystemProperty<string>(MessageSystemPropertyNames.ContentEncoding);
436+
#endif
437+
}
438+
439+
set
440+
{
441+
this.SystemProperties[MessageSystemPropertyNames.ContentEncoding] = value;
442+
}
443+
}
366444

367445
/// <summary>
368446
/// Gets the dictionary of user properties which are set when user send the data.

device/Microsoft.Azure.Devices.Client/MessageConverter.cs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ public static void UpdateMessageHeaderAndProperties(AmqpMessage amqpMessage, Mes
4444

4545
data.CorrelationId = amqpMessage.Properties.CorrelationId != null ? amqpMessage.Properties.CorrelationId.ToString() : null;
4646
data.UserId = amqpMessage.Properties.UserId.Array != null ? Encoding.UTF8.GetString(amqpMessage.Properties.UserId.Array, 0 /*index*/, amqpMessage.Properties.UserId.Array.Length) : null;
47+
48+
if (!string.IsNullOrWhiteSpace(amqpMessage.Properties.ContentType.Value))
49+
{
50+
data.ContentType = amqpMessage.Properties.ContentType.Value;
51+
}
52+
53+
if (!string.IsNullOrWhiteSpace(amqpMessage.Properties.ContentEncoding.Value))
54+
{
55+
data.ContentEncoding = amqpMessage.Properties.ContentEncoding.Value;
56+
}
4757
}
4858

4959
if ((sections & SectionFlag.MessageAnnotations) != 0)
@@ -89,6 +99,12 @@ public static void UpdateMessageHeaderAndProperties(AmqpMessage amqpMessage, Mes
8999
case MessageSystemPropertyNames.Operation:
90100
data.SystemProperties[pair.Key.ToString()] = stringObject;
91101
break;
102+
case MessageSystemPropertyNames.MessageSchema:
103+
data.MessageSchema = stringObject;
104+
break;
105+
case MessageSystemPropertyNames.CreationTimeUtc:
106+
data.CreationTimeUtc = DateTime.Parse(stringObject);
107+
break;
92108
default:
93109
data.Properties[pair.Key.ToString()] = stringObject;
94110
break;
@@ -144,10 +160,30 @@ public static void UpdateAmqpMessageHeadersAndProperties(AmqpMessage amqpMessage
144160
amqpMessage.ApplicationProperties = new ApplicationProperties();
145161
}
146162

147-
object deliveryAckSetting;
148-
if (data.SystemProperties.TryGetValue(MessageSystemPropertyNames.Ack, out deliveryAckSetting))
163+
object propertyValue;
164+
if (data.SystemProperties.TryGetValue(MessageSystemPropertyNames.Ack, out propertyValue))
165+
{
166+
amqpMessage.ApplicationProperties.Map["iothub-ack"] = (string)propertyValue;
167+
}
168+
169+
if (data.SystemProperties.TryGetValue(MessageSystemPropertyNames.MessageSchema, out propertyValue))
170+
{
171+
amqpMessage.ApplicationProperties.Map[MessageSystemPropertyNames.MessageSchema] = (string)propertyValue;
172+
}
173+
174+
if (data.SystemProperties.TryGetValue(MessageSystemPropertyNames.CreationTimeUtc, out propertyValue))
175+
{
176+
amqpMessage.ApplicationProperties.Map[MessageSystemPropertyNames.CreationTimeUtc] = ((DateTime)propertyValue).ToString("o"); // Convert to string that complies with ISO 8601
177+
}
178+
179+
if (data.SystemProperties.TryGetValue(MessageSystemPropertyNames.ContentType, out propertyValue))
180+
{
181+
amqpMessage.Properties.ContentType = (string)propertyValue;
182+
}
183+
184+
if (data.SystemProperties.TryGetValue(MessageSystemPropertyNames.ContentEncoding, out propertyValue))
149185
{
150-
amqpMessage.ApplicationProperties.Map["iothub-ack"] = (string)deliveryAckSetting;
186+
amqpMessage.Properties.ContentEncoding = (string)propertyValue;
151187
}
152188

153189
if (copyUserProperties && data.Properties.Count > 0)

device/Microsoft.Azure.Devices.Client/MessageSystemPropertyNames.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,13 @@ static class MessageSystemPropertyNames
2626
public const string Operation = "iothub-operation";
2727

2828
public const string Ack = "iothub-ack";
29+
30+
public const string MessageSchema = "iothub-message-schema";
31+
32+
public const string CreationTimeUtc = "iothub-creation-time-utc";
33+
34+
public const string ContentEncoding = "iothub-content-encoding";
35+
36+
public const string ContentType = "iothub-content-type";
2937
}
3038
}

device/Microsoft.Azure.Devices.Client/Transport/HttpTransportHandler.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ sealed class HttpTransportHandler : TransportHandler
3535
{ MessageSystemPropertyNames.Operation, CustomHeaderConstants.Operation },
3636
{ MessageSystemPropertyNames.To, CustomHeaderConstants.To },
3737
{ MessageSystemPropertyNames.UserId, CustomHeaderConstants.UserId },
38+
{ MessageSystemPropertyNames.MessageSchema, CustomHeaderConstants.MessageSchema },
39+
{ MessageSystemPropertyNames.CreationTimeUtc, CustomHeaderConstants.CreationTimeUtc },
40+
{ MessageSystemPropertyNames.ContentType, CustomHeaderConstants.ContentType },
41+
{ MessageSystemPropertyNames.ContentEncoding, CustomHeaderConstants.ContentEncoding }
3842
};
3943

4044
readonly IHttpClientHelper httpClientHelper;
@@ -150,7 +154,8 @@ public override Task SendEventAsync(Message message, CancellationToken cancellat
150154
var customHeaders = new Dictionary<string, string>(message.SystemProperties.Count + message.Properties.Count);
151155
foreach (var property in message.SystemProperties)
152156
{
153-
customHeaders.Add(MapMessageProperties2HttpHeaders[property.Key], property.Value.ToString());
157+
string strValue = property.Value is DateTime ? ((DateTime)property.Value).ToString("o") : property.Value.ToString();
158+
customHeaders.Add(MapMessageProperties2HttpHeaders[property.Key], strValue);
154159
}
155160

156161
foreach (var property in message.Properties)

device/Microsoft.Azure.Devices.Client/Transport/Mqtt/Util.cs

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,32 +37,23 @@ static class IotHubWirePropertyNames
3737
public const string MessageId = "$.mid";
3838
public const string To = "$.to";
3939
public const string UserId = "$.uid";
40+
public const string MessageSchema = "$.schema";
41+
public const string CreationTimeUtc = "$.ctime";
42+
public const string ContentType = "$.ct";
43+
public const string ContentEncoding = "$.ce";
4044
}
41-
42-
static class MessageSystemPropertyNames
43-
{
44-
public const string MessageId = "message-id";
45-
46-
public const string To = "to";
47-
48-
public const string ExpiryTimeUtc = "absolute-expiry-time";
49-
50-
public const string CorrelationId = "correlation-id";
51-
52-
public const string UserId = "user-id";
53-
54-
public const string Operation = "iothub-operation";
55-
56-
public const string Ack = "iothub-ack";
57-
}
58-
45+
5946
static readonly Dictionary<string, string> ToSystemPropertiesMap = new Dictionary<string, string>
6047
{
6148
{IotHubWirePropertyNames.AbsoluteExpiryTime, MessageSystemPropertyNames.ExpiryTimeUtc},
6249
{IotHubWirePropertyNames.CorrelationId, MessageSystemPropertyNames.CorrelationId},
6350
{IotHubWirePropertyNames.MessageId, MessageSystemPropertyNames.MessageId},
6451
{IotHubWirePropertyNames.To, MessageSystemPropertyNames.To},
6552
{IotHubWirePropertyNames.UserId, MessageSystemPropertyNames.UserId},
53+
{IotHubWirePropertyNames.MessageSchema, MessageSystemPropertyNames.MessageSchema},
54+
{IotHubWirePropertyNames.CreationTimeUtc, MessageSystemPropertyNames.CreationTimeUtc},
55+
{IotHubWirePropertyNames.ContentType, MessageSystemPropertyNames.ContentType},
56+
{IotHubWirePropertyNames.ContentEncoding, MessageSystemPropertyNames.ContentEncoding},
6657
{MessageSystemPropertyNames.Operation, MessageSystemPropertyNames.Operation},
6758
{MessageSystemPropertyNames.Ack, MessageSystemPropertyNames.Ack}
6859
};
@@ -74,6 +65,10 @@ static class MessageSystemPropertyNames
7465
{MessageSystemPropertyNames.MessageId, IotHubWirePropertyNames.MessageId},
7566
{MessageSystemPropertyNames.To, IotHubWirePropertyNames.To},
7667
{MessageSystemPropertyNames.UserId, IotHubWirePropertyNames.UserId},
68+
{MessageSystemPropertyNames.MessageSchema, IotHubWirePropertyNames.MessageSchema},
69+
{MessageSystemPropertyNames.CreationTimeUtc, IotHubWirePropertyNames.CreationTimeUtc},
70+
{MessageSystemPropertyNames.ContentType, IotHubWirePropertyNames.ContentType},
71+
{MessageSystemPropertyNames.ContentEncoding, IotHubWirePropertyNames.ContentEncoding},
7772
{MessageSystemPropertyNames.Operation, MessageSystemPropertyNames.Operation},
7873
{MessageSystemPropertyNames.Ack, MessageSystemPropertyNames.Ack}
7974
};
@@ -272,7 +267,8 @@ static object ConvertToSystemProperty(KeyValuePair<string, string> property)
272267
{
273268
return property.Value;
274269
}
275-
if (property.Key == IotHubWirePropertyNames.AbsoluteExpiryTime)
270+
if (property.Key == IotHubWirePropertyNames.AbsoluteExpiryTime ||
271+
property.Key == IotHubWirePropertyNames.CreationTimeUtc)
276272
{
277273
return DateTime.ParseExact(property.Value, "o", CultureInfo.InvariantCulture);
278274
}

service/Microsoft.Azure.Devices/Message.cs

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ public DeliveryAcknowledgement Ack
193193
}
194194
set
195195
{
196-
string valueToSet = null;
196+
string valueToSet;
197197

198198
switch (value)
199199
{
@@ -295,6 +295,70 @@ public string UserId
295295
}
296296
}
297297

298+
/// <summary>
299+
/// Used to specify the schema of the message content.
300+
/// </summary>
301+
public string MessageSchema
302+
{
303+
get
304+
{
305+
return this.GetSystemProperty<string>(MessageSystemPropertyNames.MessageSchema);
306+
}
307+
308+
set
309+
{
310+
this.SystemProperties[MessageSystemPropertyNames.MessageSchema] = value;
311+
}
312+
}
313+
314+
/// <summary>
315+
/// Custom date property set by the originator of the message.
316+
/// </summary>
317+
public DateTime CreationTimeUtc
318+
{
319+
get
320+
{
321+
return this.GetSystemProperty<DateTime>(MessageSystemPropertyNames.CreationTimeUtc);
322+
}
323+
324+
set
325+
{
326+
this.SystemProperties[MessageSystemPropertyNames.CreationTimeUtc] = value;
327+
}
328+
}
329+
330+
/// <summary>
331+
/// Used to specify the content type of the message.
332+
/// </summary>
333+
public string ContentType
334+
{
335+
get
336+
{
337+
return this.GetSystemProperty<string>(MessageSystemPropertyNames.ContentType);
338+
}
339+
340+
set
341+
{
342+
this.SystemProperties[MessageSystemPropertyNames.ContentType] = value;
343+
}
344+
}
345+
346+
/// <summary>
347+
/// Used to specify the content encoding type of the message.
348+
/// </summary>
349+
public string ContentEncoding
350+
{
351+
get
352+
{
353+
return this.GetSystemProperty<string>(MessageSystemPropertyNames.ContentEncoding);
354+
}
355+
356+
set
357+
{
358+
this.SystemProperties[MessageSystemPropertyNames.ContentEncoding] = value;
359+
}
360+
}
361+
298362
/// <summary>
299363
/// Gets the dictionary of user properties which are set when user send the data.
300364
/// </summary>
@@ -360,7 +424,7 @@ public Message Clone()
360424
};
361425
}
362426

363-
foreach (var systemProperty in this.SystemProperties)
427+
foreach (KeyValuePair<string, object> systemProperty in this.SystemProperties)
364428
{
365429
// MessageId would already be there.
366430
if (message.SystemProperties.ContainsKey(systemProperty.Key))
@@ -373,7 +437,7 @@ public Message Clone()
373437
}
374438
}
375439

376-
foreach (var property in this.Properties)
440+
foreach (KeyValuePair<string, string> property in this.Properties)
377441
{
378442
message.Properties.Add(property);
379443
}
@@ -427,7 +491,7 @@ public byte[] GetBytes()
427491
if ((listStream = this.bodyStream as BufferListStream) != null)
428492
{
429493
// We can trust Amqp bufferListStream.Length;
430-
byte[] bytes = new byte[listStream.Length];
494+
var bytes = new byte[listStream.Length];
431495
listStream.Read(bytes, 0, bytes.Length);
432496
return bytes;
433497
}

0 commit comments

Comments
 (0)