in edge-hub/core/src/Microsoft.Azure.Devices.Edge.Hub.Core/TwinManager.cs [583:662]
async Task UpdateReportedPropertiesWithStoreSupportAsync(string id, IMessage reportedProperties)
{
try
{
using (await this.reportedPropertiesLock.LockAsync())
{
bool updatePatch;
bool cloudVerified = false;
IEntityStore<string, TwinInfo> twinStore = this.TwinStore.Expect(() => new InvalidOperationException("Missing twin store"));
Option<TwinInfo> info = await twinStore.Get(id);
// If the reported properties patch is not null, we will not attempt to write the reported
// properties to the cloud as we are still waiting for a connection established callback
// to sync the local reported properties with that of the cloud
updatePatch = info.Map(
(ti) =>
{
if (ti.ReportedPropertiesPatch.Count != 0)
{
Events.NeedsUpdateCachedReportedPropertiesPatch(id, ti.ReportedPropertiesPatch.Version);
return true;
}
else
{
return false;
}
}).GetOrElse(false);
TwinCollection reported = this.twinCollectionConverter.FromMessage(reportedProperties);
if (!updatePatch)
{
try
{
await this.SendReportedPropertiesToCloudProxy(id, reportedProperties);
Events.SentReportedPropertiesToCloud(id, reported.Version);
cloudVerified = true;
}
catch (Exception e)
{
Events.UpdateReportedToCloudException(id, e);
updatePatch = true;
}
}
if (!cloudVerified)
{
ValidateTwinProperties(JToken.Parse(reported.ToJson()), 1);
Events.ValidatedTwinPropertiesSuccess(id, reported.Version);
}
// Update the local twin's reported properties and swallow the exception if we failed
// to cache the twin
try
{
await this.ExecuteOnTwinStoreResultAsync(
id,
(t) => this.UpdateReportedPropertiesWhenTwinStoreHasTwinAsync(id, reported, cloudVerified),
() => this.UpdateReportedPropertiesWhenTwinStoreNeedsTwinAsync(id, reported, cloudVerified));
}
catch (TwinNotFoundException)
{
}
if (updatePatch)
{
// Update the collective patch of reported properties
await this.UpdateReportedPropertiesPatchAsync(
id,
new TwinInfo(null, reported) /* only used when twin was not previously cached */,
reported);
}
}
}
catch (Exception e)
{
Events.UpdateReportedPropertiesFailed(id, e);
throw; /* we only throw if we were unable to write to the db */
}
}