private async Task ReportRebootCmdStatus(RebootCmdDataContract.ResponseValue status, string rebootCmdTime) { Logger.Log("ReportRebootCmdStatus() invoked.", LoggingLevel.Verbose); RebootCmdDataContract.ReportedProperties reportedProperties = new RebootCmdDataContract.ReportedProperties(status); await _deviceManagementClient.ReportPropertiesAsync(PropertySectionName, reportedProperties.ToJsonObject()); StatusSection statusSection = new StatusSection(StatusSection.StateType.Completed); await _deviceManagementClient.ReportStatusAsync(PropertySectionName, statusSection); }
private Task <string> UsoClientCmdAsyncHandler(string jsonParam) { Logger.Log("UsoClientCmdAsync() invoked by direct method.", LoggingLevel.Verbose); InternalUsoClientCmdAsync(jsonParam).FireAndForget(); // Will do its own error reporting. StatusSection status = new StatusSection(StatusSection.StateType.Pending); return(Task.FromResult <string>(status.AsJsonObject().ToString())); }
private Task <string> DoClearReportedProperties(string jsonParam) { Logger.Log("ClearReportedPropertiesHandler() invoked by direct method.", LoggingLevel.Verbose); _deviceManagementClient.ClearReportedProperties().FireAndForget(); StatusSection status = new StatusSection(StatusSection.StateType.Pending); return(Task.FromResult <string>(status.AsJsonObject().ToString())); }
private Task <string> ReportAllDevicePropertiesMethodHandler(string jsonParam) { Logger.Log("Handling direct method " + CommonDataContract.ReportAllAsync + " ...", LoggingLevel.Verbose); ReportAllDeviceProperties().FireAndForget(); StatusSection status = new StatusSection(StatusSection.StateType.Pending); return(Task.FromResult <string>(status.AsJsonObject().ToString())); }
private async Task ReportAllDeviceProperties() { Logger.Log("Reporting all device properties to device twin...", LoggingLevel.Information); Logger.Log("Querying device state...", LoggingLevel.Information); JObject windowsObj = new JObject(); foreach (var handler in this._desiredPropertyMap.Values) { StatusSection statusSection = new StatusSection(StatusSection.StateType.Pending); await ReportStatusAsync(handler.PropertySectionName, statusSection); // TODO: how do we ensure that only Reported=yes sections report results? try { windowsObj[handler.PropertySectionName] = await handler.GetReportedPropertyAsync(); statusSection.State = StatusSection.StateType.Completed; Logger.Log(statusSection.ToString(), LoggingLevel.Information); await ReportStatusAsync(handler.PropertySectionName, statusSection); } catch (Error e) { statusSection.State = StatusSection.StateType.Failed; statusSection.TheError = e; Logger.Log(statusSection.ToString(), LoggingLevel.Error); await ReportStatusAsync(handler.PropertySectionName, statusSection); } catch (Exception e) { statusSection.State = StatusSection.StateType.Failed; statusSection.TheError = new Error(ErrorSubSystem.Unknown, e.HResult, e.Message); Logger.Log(statusSection.ToString(), LoggingLevel.Error); await ReportStatusAsync(handler.PropertySectionName, statusSection); } } Dictionary <string, object> collection = new Dictionary <string, object>(); collection[DMJSonConstants.DTWindowsIoTNameSpace] = windowsObj; Debug.WriteLine($"Report properties: {collection[DMJSonConstants.DTWindowsIoTNameSpace].ToString()}"); _deviceTwin.ReportProperties(collection).FireAndForget(); }
// IClientHandlerCallBack.ReportStatusAsync public async Task ReportStatusAsync(string sectionName, StatusSection statusSubSection) { // We always construct an object and set a property inside it. // This way, we do not overwrite what's already in there. // Set the status to refreshing... JObject refreshingValue = new JObject(); refreshingValue.Add(statusSubSection.AsJsonPropertyRefreshing()); await ReportPropertiesAsync(sectionName, refreshingValue); // Set the status to the actual status... JObject actualValue = new JObject(); actualValue.Add(statusSubSection.AsJsonProperty()); await ReportPropertiesAsync(sectionName, actualValue); }
private async Task InternalStartDmAppStoreUpdateAsync(string jsonParamString) { Logger.Log("InternalStartDmAppStoreUpdateAsync() invoked.", LoggingLevel.Verbose); await Helpers.EnsureErrorsLogged(_deviceManagementClient, PropertySectionName, async() => { // Report to the device twin StatusSection status = new StatusSection(StatusSection.StateType.Pending); await _deviceManagementClient.ReportStatusAsync(PropertySectionName, status); StoreContext context = StoreContext.GetDefault(); // Check for updates... string lastCheck = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssZ"); await ReportResponse(DmAppStoreUpdateDataContract.JSonChecking, lastCheck); IReadOnlyList <StorePackageUpdate> updates = await context.GetAppAndOptionalStorePackageUpdatesAsync(); if (updates.Count == 0) { await ReportResponse(DmAppStoreUpdateDataContract.JSonNoUpdates, lastCheck); return; } // Download and install the updates... IAsyncOperationWithProgress <StorePackageUpdateResult, StorePackageUpdateStatus> downloadOperation = context.RequestDownloadAndInstallStorePackageUpdatesAsync(updates); await ReportResponse(DmAppStoreUpdateDataContract.JsonDownloadingAndInstalling, lastCheck); // Wait for completion... StorePackageUpdateResult result = await downloadOperation.AsTask(); string resultString = result.OverallState == StorePackageUpdateState.Completed ? DmAppStoreUpdateDataContract.JsonInstalled : DmAppStoreUpdateDataContract.JsonFailed; await ReportResponse(resultString, lastCheck); // Report to the device twin status.State = StatusSection.StateType.Completed; await _deviceManagementClient.ReportStatusAsync(PropertySectionName, status); }); }
private async Task InternalUsoClientCmdAsync(string jsonParamString) { Logger.Log("InternalUsoClientCmdAsync() invoked.", LoggingLevel.Verbose); await Helpers.EnsureErrorsLogged(_deviceManagementClient, PropertySectionName, async() => { StatusSection status = new StatusSection(StatusSection.StateType.Pending); await _deviceManagementClient.ReportStatusAsync(PropertySectionName, status); // Parse json parameters var resetParams = JsonConvert.DeserializeObject <UsoClientCmdDataContract.CmdParams>(jsonParamString); // Construct request var request = new UsoClientCmdRequest(); request.cmd = resetParams.cmd; // Send the request var response = await _systemConfiguratorProxy.SendCommandAsync(request); await ReportCmdStatus(UsoClientCmdDataContract.JsonScheduled); }); }
public static async Task EnsureErrorsLogged(IClientHandlerCallBack _callback, string sectionName, Func <Task> action) { try { await action(); } catch (Error ex) { StatusSection status = new StatusSection(StatusSection.StateType.Failed, ex); Logger.Log(status.ToString(), LoggingLevel.Error); await _callback.ReportStatusAsync(sectionName, status); } catch (Exception ex) { Error e = new Error(ErrorSubSystem.Unknown, ex.HResult, ex.Message); StatusSection status = new StatusSection(StatusSection.StateType.Failed, e); Logger.Log(status.ToString(), LoggingLevel.Error); await _callback.ReportStatusAsync(sectionName, status); } }
private async Task InternalRebootCmdAsync(string rebootCmdTime) { Logger.Log("InternalRebootCmdAsync(" + rebootCmdTime + ") invoked.", LoggingLevel.Verbose); StatusSection status = new StatusSection(StatusSection.StateType.Pending); await _deviceManagementClient.ReportStatusAsync(PropertySectionName, status); var response = await IsRebootAllowedBySystem(); if (response != RebootCmdDataContract.ResponseValue.Allowed) { await ReportRebootCmdStatus(response, rebootCmdTime); return; } response = await IsRebootAllowedByApp(); if (response != RebootCmdDataContract.ResponseValue.Allowed) { await ReportRebootCmdStatus(response, rebootCmdTime); return; } { var request = new ImmediateRebootRequest(); request.lastRebootCmdTime = rebootCmdTime; await this._systemConfiguratorProxy.SendCommandAsync(request); response = RebootCmdDataContract.ResponseValue.Scheduled; await ReportRebootCmdStatus(response, rebootCmdTime); return; } }
public async Task <string> Invoke(string arg) { Debug.WriteLine($"Executing direct method: {this._methodName}"); try { return(await _method(arg)); } catch (Error ex) { StatusSection status = new StatusSection(StatusSection.StateType.Failed, ex); Logger.Log(status.ToString(), LoggingLevel.Error); return(status.AsJsonObject().ToString()); } catch (Exception ex) { Error e = new Error(Message.ErrorSubSystem.Unknown, ex.HResult, ex.Message); StatusSection status = new StatusSection(StatusSection.StateType.Failed, e); Logger.Log(status.ToString(), LoggingLevel.Error); return(status.AsJsonObject().ToString()); } }
private async Task ApplyDesiredStateAsync(long version, JObject windowsPropValue, bool forceFullTwinUpdate) { Logger.Log(string.Format("Applying {0} node desired state for version {1} ...", DMJSonConstants.DTWindowsIoTNameSpace, version), LoggingLevel.Verbose); try { // Only one set of updates at a time... await _desiredPropertiesLock.WaitAsync(); // If we force a full twin update OR // we haven't processed any updates yet OR // we missed a version ... // Then, get all of the twin's properties if (forceFullTwinUpdate || _lastDesiredPropertyVersion == -1 || version > (_lastDesiredPropertyVersion + 1)) { Dictionary <string, object> desiredProperties = await this._deviceTwin.GetDesiredPropertiesAsync(); ExtractInfoFromDesiredProperties(desiredProperties, out version, out windowsPropValue); } else if (version <= _lastDesiredPropertyVersion) { // If this version is older (or the same) than the last we processed ... // Then, skip this update return; } _lastDesiredPropertyVersion = version; if (windowsPropValue == null) { // Nothing to apply. return; } foreach (var sectionProp in windowsPropValue.Children().OfType <JProperty>()) { // Handle any dependencies first List <IClientPropertyDependencyHandler> handlers; if (this._desiredPropertyDependencyMap.TryGetValue(sectionProp.Name, out handlers)) { handlers.ForEach((handler) => { try { Debug.WriteLine($"{sectionProp.Name} = {sectionProp.Value.ToString()}"); if (sectionProp.Value is JObject) { handler.OnDesiredPropertyDependencyChange(sectionProp.Name, (JObject)sectionProp.Value); } } catch (Exception e) { Debug.WriteLine($"Exception caught while handling desired property - {sectionProp.Name}"); Debug.WriteLine(e); throw; } }); } } foreach (var sectionProp in windowsPropValue.Children().OfType <JProperty>()) { // If we've been told to stop, we should not process any desired properties... if (_lastCommandStatus == CommandStatus.PendingDMAppRestart) { break; } IClientPropertyHandler handler; if (this._desiredPropertyMap.TryGetValue(sectionProp.Name, out handler)) { StatusSection statusSection = new StatusSection(StatusSection.StateType.Pending); await ReportStatusAsync(sectionProp.Name, statusSection); try { Debug.WriteLine($"{sectionProp.Name} = {sectionProp.Value.ToString()}"); if (sectionProp.Value is JValue && sectionProp.Value.Type == JTokenType.String && (string)sectionProp.Value == "refreshing") { continue; } _lastCommandStatus = await handler.OnDesiredPropertyChange(sectionProp.Value); statusSection.State = StatusSection.StateType.Completed; await ReportStatusAsync(sectionProp.Name, statusSection); } catch (Error e) { statusSection.State = StatusSection.StateType.Failed; statusSection.TheError = e; Logger.Log(statusSection.ToString(), LoggingLevel.Error); await ReportStatusAsync(sectionProp.Name, statusSection); } catch (Exception e) { statusSection.State = StatusSection.StateType.Failed; statusSection.TheError = new Error(ErrorSubSystem.Unknown, e.HResult, e.Message); Logger.Log(statusSection.ToString(), LoggingLevel.Error); await ReportStatusAsync(sectionProp.Name, statusSection); } } } } finally { this._desiredPropertiesLock.Release(); } }