/// <inheritdoc/> public Task <byte[]> InvokeAsync(byte[] payload, string contentType) { object task; try { object[] inputs; if (_methodParams.Length == 1) { var data = JsonConvertEx.DeserializeObject( Encoding.UTF8.GetString(payload), _methodParams[0].ParameterType); inputs = new[] { data }; } else { var data = (JObject)JToken.Parse(Encoding.UTF8.GetString(payload)); inputs = _methodParams.Select(param => { if (data.TryGetValue(param.Name, StringComparison.InvariantCultureIgnoreCase, out var value)) { return(value.ToObject(param.ParameterType)); } return(param.HasDefaultValue ? param.DefaultValue : null); }).ToArray(); } task = _controllerMethod.Invoke(_controller, inputs); } catch (Exception e) { task = Task.FromException(e); } return((Task <byte[]>)_methodTaskContinuation.Invoke(this, new[] { task })); }
/// <summary> /// Create deployment for a fleet of devices identified by /// the target condition and given the desired name. /// </summary> /// <param name="factory"></param> /// <param name="name"></param> /// <param name="condition"></param> /// <param name="deploymentJson"></param> /// <returns></returns> public static IEdgeDeployment CreateFromDeploymentJson( this IEdgeDeploymentFactory factory, string name, string condition, string deploymentJson) { return(factory.Create(name, condition, 0, JsonConvertEx.DeserializeObject <ConfigurationContentModel>(deploymentJson))); }
/// <summary> /// helper to invoke service /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="R"></typeparam> /// <param name="service"></param> /// <param name="registration"></param> /// <param name="request"></param> /// <returns></returns> private async Task <R> CallServiceOnSupervisor <T, R>(string service, EndpointRegistrationModel registration, T request) { if (registration == null) { throw new ArgumentNullException(nameof(registration)); } if (registration.Endpoint == null) { throw new ArgumentNullException(nameof(registration.Endpoint)); } if (string.IsNullOrEmpty(registration.SupervisorId)) { throw new ArgumentNullException(nameof(registration.SupervisorId)); } var sw = Stopwatch.StartNew(); var deviceId = SupervisorModelEx.ParseDeviceId(registration.SupervisorId, out var moduleId); var result = await _client.CallMethodAsync(deviceId, moduleId, service, JsonConvertEx.SerializeObject(new { endpoint = registration.Endpoint, request })); _logger.Debug("Calling supervisor service '{service}' on {deviceId}/{moduleId} " + "took {elapsed} ms and returned {result}!", service, deviceId, moduleId, sw.ElapsedMilliseconds, result); return(JsonConvertEx.DeserializeObject <R>(result)); }
protected void TestDeploymentManifestAndJson3() { var fixture = new Fixture(); var customization = new SupportMutableValueTypesCustomization(); customization.Customize(fixture); var modules = fixture.CreateMany <EdgeDeploymentModuleModel>(30).ToList(); var routes = fixture.CreateMany <EdgeDeploymentRouteModel>(10).ToList(); for (var i = 0; i < routes.Count; i++) { routes[i].To = modules[i].Name; routes[i].From = modules[i + 10].Name; } var deployment1 = new EdgeDeploymentBase(Log.Logger); deployment1.WithManifest(new EdgeDeploymentManifestModel { Modules = modules, Routes = routes }); var json1 = deployment1.ToString(); var deployment2 = new EdgeDeploymentBase( JsonConvertEx.DeserializeObject <ConfigurationContentModel>(json1), Log.Logger); var config1 = JsonConvertEx.DeserializeObject <ConfigurationContentModel>( json1); var config2 = JsonConvertEx.DeserializeObject <ConfigurationContentModel>( deployment2.ToString()); Assert.True(JToken.DeepEquals(JToken.FromObject(config1), JToken.FromObject(config2))); }
/// <summary> /// List nodes on endpoint /// </summary> private static async Task ListNodesAsync(IIoTHubConfig config, ILogger logger, string deviceId, string moduleId, string endpointUrl, CancellationToken ct) { if (string.IsNullOrEmpty(endpointUrl)) { throw new ArgumentNullException(nameof(endpointUrl)); } var client = new IoTHubTwinMethodClient(CreateClient(config, logger), logger); while (!ct.IsCancellationRequested) { await Task.Delay(TimeSpan.FromSeconds(5), ct); try { var content = new GetNodesRequestModel { EndpointUrl = endpointUrl }; var result = await client.CallMethodAsync(deviceId, moduleId, "GetConfiguredNodesOnEndpoint", JsonConvertEx.SerializeObject(content), null, ct); var response = JsonConvertEx.DeserializeObject <GetNodesResponseModel>(result); logger.Information("Published nodes: {@response}", response); } catch (Exception ex) { logger.Verbose(ex, "Failed to list published nodes."); } } }
/// <inheritdoc/> public void Apply(OpenApiParameter parameter, ParameterFilterContext context) { // // fix current bug where properties are not added correctly // Lookup property schema in schema repo // if (context.PropertyInfo != null) { // Query was passed a parameter with properties var propertySchema = context.SchemaRepository.Schemas .Where(p => p.Key.EqualsIgnoreCase(context.ParameterInfo.ParameterType.Name)) .SelectMany(p => p.Value.Properties) .Where(p => p.Key.EqualsIgnoreCase(context.PropertyInfo.Name)) .FirstOrDefault(); if (propertySchema.Value != null) { // Replace parameter definition with property schema parameter.Name = propertySchema.Key; // Quick and dirty clone of the schema for the parameter parameter.Schema = JsonConvertEx.DeserializeObject <OpenApiSchema>( JsonConvertEx.SerializeObject(propertySchema.Value)); } parameter.Required = context.PropertyInfo .GetCustomAttributes(typeof(RequiredAttribute), true) .Any(); AdjustSchema(context.PropertyInfo.PropertyType, parameter.Schema); } else if (context.ParameterInfo != null) { // Query was passed a parameter with properties AdjustSchema(context.ParameterInfo.ParameterType, parameter.Schema); } }
/// <inheritdoc/> public async Task <List <DiscoveredModuleModel> > GetModulesAsync( string deviceId) { if (!string.IsNullOrEmpty(_workloaduri)) { var request = _client.NewRequest(_workloaduri + "/modules?api-version=" + _apiVersion); var result = await Retry.WithExponentialBackoff(_logger, async() => { var response = await _client.GetAsync(request); response.Validate(); return(JsonConvertEx.DeserializeObject <EdgeletModules>( response.GetContentAsString())); }); return(result.Modules?.Select(m => new DiscoveredModuleModel { Id = m.Name, ImageName = m.Config?.Settings?.Image, ImageHash = m.Config?.Settings?.ImageHash, Version = GetVersionFromImageName(m.Config?.Settings?.Image), Status = m.Status?.RuntimeStatus?.Status }).ToList()); } _logger.Warn("Not running in iotedge context - no modules in scope."); return(new List <DiscoveredModuleModel>()); }
/// <inheritdoc/> public async Task <ValueWriteResponseApiModel> NodeValueWriteAsync(EndpointApiModel endpoint, ValueWriteRequestApiModel request, CancellationToken ct) { if (endpoint == null) { throw new ArgumentNullException(nameof(endpoint)); } if (string.IsNullOrEmpty(endpoint.Url)) { throw new ArgumentNullException(nameof(endpoint.Url)); } if (request == null) { throw new ArgumentNullException(nameof(request)); } if (request.Value == null) { throw new ArgumentNullException(nameof(request.Value)); } var response = await _methodClient.CallMethodAsync(_deviceId, _moduleId, "ValueWrite_V2", JsonConvertEx.SerializeObject(new { endpoint, request }), null, ct); return(JsonConvertEx.DeserializeObject <ValueWriteResponseApiModel>(response)); }
/// <inheritdoc/> public async Task <BrowsePathResponseApiModel> NodeBrowsePathAsync(EndpointApiModel endpoint, BrowsePathRequestApiModel request, CancellationToken ct) { if (endpoint == null) { throw new ArgumentNullException(nameof(endpoint)); } if (string.IsNullOrEmpty(endpoint.Url)) { throw new ArgumentNullException(nameof(endpoint.Url)); } if (request == null) { throw new ArgumentNullException(nameof(request)); } if (request.BrowsePaths == null || request.BrowsePaths.Count == 0 || request.BrowsePaths.Any(p => p == null || p.Length == 0)) { throw new ArgumentNullException(nameof(request.BrowsePaths)); } var response = await _methodClient.CallMethodAsync(_deviceId, _moduleId, "BrowsePath_V2", JsonConvertEx.SerializeObject(new { endpoint, request }), null, ct); return(JsonConvertEx.DeserializeObject <BrowsePathResponseApiModel>(response)); }
/// <summary> /// Get base edge configuration /// </summary> /// <returns></returns> private IDictionary <string, IDictionary <string, object> > CreateLayeredDeployment() { var registryCredentials = ""; if (!string.IsNullOrEmpty(_config.DockerServer) && _config.DockerServer != "mcr.microsoft.com") { var registryId = _config.DockerServer.Split('.')[0]; registryCredentials = @" ""properties.desired.runtime.settings.registryCredentials." + registryId + @""": { ""address"": """ + _config.DockerServer + @""", ""password"": """ + _config.DockerPassword + @""", ""username"": """ + _config.DockerUser + @""" }, "; } // Configure create options per os specified var createOptions = @" { ""Hostname"": ""opcpublisher"", ""Cmd"": [ ""--aa"" ] }"; createOptions = JObject.Parse(createOptions).ToString(Formatting.None).Replace("\"", "\\\""); var server = string.IsNullOrEmpty(_config.DockerServer) ? "mcr.microsoft.com" : _config.DockerServer; var ns = string.IsNullOrEmpty(_config.ImagesNamespace) ? "" : _config.ImagesNamespace.TrimEnd('/') + "/"; var version = _config.ImagesTag ?? "latest"; var image = $"{server}/{ns}iotedge/opc-publisher:{version}"; _logger.Information("Updating opc publisher module deployment with image {image}", image); // Return deployment modules object var content = @" { ""$edgeAgent"": { " + registryCredentials + @" ""properties.desired.modules.publisher"": { ""settings"": { ""image"": """ + image + @""", ""createOptions"": """ + createOptions + @""" }, ""type"": ""docker"", ""status"": ""running"", ""restartPolicy"": ""always"", ""version"": """ + (version == "latest" ? "1.0" : version) + @""" } }, ""$edgeHub"": { ""properties.desired.routes.upstream"": ""FROM /messages/* INTO $upstream"" } }"; return(JsonConvertEx.DeserializeObject <IDictionary <string, IDictionary <string, object> > >(content)); }
/// <inheritdoc/> public async Task <HistoryReadNextResponseApiModel <JToken> > HistoryReadRawNextAsync( EndpointApiModel endpoint, HistoryReadNextRequestApiModel request, CancellationToken ct) { if (endpoint == null) { throw new ArgumentNullException(nameof(endpoint)); } if (string.IsNullOrEmpty(endpoint.Url)) { throw new ArgumentNullException(nameof(endpoint.Url)); } if (request == null) { throw new ArgumentNullException(nameof(request)); } if (string.IsNullOrEmpty(request.ContinuationToken)) { throw new ArgumentNullException(nameof(request.ContinuationToken)); } var response = await _methodClient.CallMethodAsync(_deviceId, _moduleId, "HistoryReadNext_V2", JsonConvertEx.SerializeObject(new { endpoint, request }), null, ct); return(JsonConvertEx.DeserializeObject <HistoryReadNextResponseApiModel <JToken> >(response)); }
public async Task <string> CallMethodAsync(string deviceId, string moduleId, string method, string json, TimeSpan?timeout = null) { var processed = await _server.ProcessAsync( JsonConvertEx.DeserializeObject <MethodChunkModel>(json)); return(JsonConvertEx.SerializeObject(processed)); }
/// <inheritdoc/> public async Task <byte[]> InvokeAsync(byte[] payload, string contentType) { var data = JsonConvertEx.DeserializeObject <MethodChunkModel>( Encoding.UTF8.GetString(payload)); data = await _server.ProcessAsync(data); return(Encoding.UTF8.GetBytes(JsonConvertEx.SerializeObject(data))); }
/// <summary> /// Get base edge configuration /// </summary> /// <param name="version"></param> /// <returns></returns> private IDictionary <string, IDictionary <string, object> > GetEdgeBase(string version = "1.0") { return(JsonConvertEx.DeserializeObject <IDictionary <string, IDictionary <string, object> > >(@" { ""$edgeAgent"": { ""properties.desired"": { ""schemaVersion"": """ + kDefaultSchemaVersion + @""", ""runtime"": { ""type"": ""docker"", ""settings"": { ""minDockerVersion"": ""v1.25"", ""loggingOptions"": """", ""registryCredentials"": { } } }, ""systemModules"": { ""edgeAgent"": { ""type"": ""docker"", ""settings"": { ""image"": ""mcr.microsoft.com/azureiotedge-agent:" + version + @""", ""createOptions"": ""{}"" } }, ""edgeHub"": { ""type"": ""docker"", ""status"": ""running"", ""restartPolicy"": ""always"", ""settings"": { ""image"": ""mcr.microsoft.com/azureiotedge-hub:" + version + @""", ""createOptions"": ""{\""HostConfig\"":{\""PortBindings\"":{\""5671/tcp\"":[{\""HostPort\"":\""5671\""}],\""8883/tcp\"":[{\""HostPort\"":\""8883\""}],\""443/tcp\"":[{\""HostPort\"":\""443\""}]}}}"" } } }, ""modules"": { } } }, ""$edgeHub"": { ""properties.desired"": { ""schemaVersion"": """ + kDefaultSchemaVersion + @""", ""routes"": { ""upstream"": ""FROM /messages/* INTO $upstream"" }, ""storeAndForwardConfiguration"": { ""timeToLiveSecs"": 7200 } } } } ")); }
public async Task TestTestNoParametersInvocationNullParamUsingMethodClient() { var harness = new ModuleHostHarness(); await harness.RunTestAsync(GetControllers(), async (device, module, services) => { var hub = services.Resolve <IMethodClient>(); var response = await hub.CallMethodAsync(device, module, "TestNoParameters_V1", null); var returned = JsonConvertEx.DeserializeObject <string>(response); Assert.Equal(nameof(TestControllerV1.TestNoParametersAsync), returned); }); }
/// <summary> /// Get all jobs from file /// </summary> /// <returns></returns> private IEnumerable <JobInfoModel> ReadJobsFromFilesystem() { var files = Directory.GetFiles(_jobsDirectory, "*.json"); var jobs = new List <JobInfoModel>(); foreach (var file in files) { var json = File.ReadAllText(file); var job = JsonConvertEx.DeserializeObject <JobInfoModel>(json); jobs.Add(job); } return(jobs.ToArray()); }
public void TestTest2InvocationNonChunked(int size) { var router = GetRouter(); var expected = new byte[size]; r.NextBytes(expected); var response = router.InvokeMethodAsync(new MethodRequest( "Test2_V1", Encoding.UTF8.GetBytes( JsonConvertEx.SerializeObject(expected)))).Result; var returned = JsonConvertEx.DeserializeObject <byte[]>( response.ResultAsJson); Assert.Equal(expected, returned); }
/// <inheritdoc/> public async Task HandleAsync(string deviceId, string moduleId, byte[] payload, IDictionary <string, string> properties, Func <Task> checkpoint) { var json = Encoding.UTF8.GetString(payload); try { var message = JsonConvertEx.DeserializeObject <DataSetMessageModel>(json); await Task.WhenAll(_handlers.Select(h => h.HandleMessageAsync(message))); } catch (Exception ex) { _logger.Error(ex, "Exception handling sample from {deviceId}-{moduleId}", deviceId, moduleId); } }
/// <inheritdoc/> public async Task HandleAsync(string deviceId, string moduleId, byte[] payload, IDictionary <string, string> properties, Func <Task> checkpoint) { var json = Encoding.UTF8.GetString(payload); var message = JsonConvertEx.DeserializeObject <MonitoredItemSampleModel>(json); try { await Task.WhenAll(_handlers.Select(h => h.HandleSampleAsync(message))); } catch (Exception ex) { _logger.Error(ex, "Publishing message {message} failed with exception - skip", message); } }
/// <summary> /// helper to invoke service /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="R"></typeparam> /// <param name="service"></param> /// <param name="endpointId"></param> /// <param name="request"></param> /// <returns></returns> private async Task <R> CallServiceOnTwin <T, R>(string service, string endpointId, T request) { if (string.IsNullOrEmpty(endpointId)) { throw new ArgumentNullException(nameof(endpointId)); } var sw = Stopwatch.StartNew(); var result = await _client.CallMethodAsync(endpointId, null, service, JsonConvertEx.SerializeObject(request)); _logger.Debug("Twin call '{service}' took {elapsed} ms)!", service, sw.ElapsedMilliseconds); return(JsonConvertEx.DeserializeObject <R>(result)); }
/// <inheritdoc/> public Task <DeviceTwinModel> GetAsync(string deviceId, string moduleId) { if (string.IsNullOrEmpty(deviceId)) { throw new ArgumentNullException(nameof(deviceId)); } return(Retry.WithExponentialBackoff(_logger, async() => { var request = NewRequest( $"/twins/{ToResourceId(deviceId, moduleId)}"); var response = await _httpClient.GetAsync(request); response.Validate(); return JsonConvertEx.DeserializeObject <DeviceTwinModel>( response.GetContentAsString()); })); }
public async Task TestTest2InvocationWithLargeBufferUsingMethodClient() { var harness = new ModuleHostHarness(); await harness.RunTestAsync(GetControllers(), async (device, module, services) => { var hub = services.Resolve <IMethodClient>(); var buffer = new byte[300809]; r.NextBytes(buffer); var response = await hub.CallMethodAsync(device, module, "Test2_V1", JsonConvertEx.SerializeObject(buffer)); var returned = JsonConvertEx.DeserializeObject <byte[]>(response); Assert.True(buffer.SequenceEqual(returned)); }); }
public void TestTest2InvocationV2NonChunked() { var router = GetRouter(); var buffer = new byte[1049]; r.NextBytes(buffer); var response = router.InvokeMethodAsync(new MethodRequest( "Test2_v2", Encoding.UTF8.GetBytes( JsonConvertEx.SerializeObject(buffer)))).Result; Assert.Equal(400, response.Status); var ex = JsonConvertEx.DeserializeObject <ArgumentNullException>( response.ResultAsJson); Assert.Equal("request", ex.ParamName); }
public async Task TestTestNoParametersInvocationNoParam() { var harness = new ModuleHostHarness(); await harness.RunTestAsync(GetControllers(), async (device, module, services) => { var hub = services.Resolve <IIoTHubTwinServices>(); var response = await hub.CallMethodAsync(device, module, new MethodParameterModel { Name = "TestNoParameters_V1", JsonPayload = JsonConvertEx.SerializeObject(null) }); var returned = JsonConvertEx.DeserializeObject <string>(response.JsonPayload); Assert.Equal(nameof(TestControllerV1.TestNoParametersAsync), returned); Assert.Equal(200, response.Status); }); }
/// <inheritdoc/> public async Task <PublishedItemListResultModel> NodePublishListAsync( string endpointId, PublishedItemListRequestModel request) { if (string.IsNullOrEmpty(endpointId)) { throw new ArgumentNullException(nameof(endpointId)); } if (request == null) { throw new ArgumentNullException(nameof(request)); } var(publisherId, endpoint) = await _publishers.FindPublisherEndpoint(endpointId); var input = new GetNodesRequestModel { EndpointId = endpointId, EndpointUrl = endpoint.Url, ContinuationToken = request.ContinuationToken == null ? (ulong?)null : BitConverter.ToUInt64(request.ContinuationToken.DecodeAsBase64(), 0) }; var(errorInfo, result) = await CallMethodOnPublisherAsync(publisherId, "GetConfiguredNodesOnEndpoint", JsonConvertEx.SerializeObject(input)); if (result == null) { return(new PublishedItemListResultModel { ErrorInfo = errorInfo }); } var response = JsonConvertEx.DeserializeObject <GetNodesResponseModel>(result); return(new PublishedItemListResultModel { ContinuationToken = response.ContinuationToken == null ? null : BitConverter.GetBytes(response.ContinuationToken.Value) .ToBase64String(), Items = response.OpcNodes? .Select(s => new PublishedItemModel { NodeId = s.Id, DisplayName = s.DisplayName, PublishingInterval = s.OpcPublishingInterval == null ? (TimeSpan?)null : TimeSpan.FromMilliseconds(s.OpcPublishingInterval.Value), SamplingInterval = s.OpcSamplingInterval == null ? (TimeSpan?)null : TimeSpan.FromMilliseconds(s.OpcSamplingInterval.Value), }).ToList() }); }
protected void TestDeploymentManifestAndJson2() { var deployment1 = new EdgeDeploymentBase(Log.Logger) .WithModule("test1", "microsoft/test2:latest", new CreateContainerParameters { Env = new List <string> { "FOOBAR1=zzzzzzz", "FOOBAR2=zzzzzzz", "FOOBAR3=zzzzzzz", "FOOBAR4=zzzzzzz", }, NetworkingConfig = new NetworkingConfig { EndpointsConfig = new Dictionary <string, EndpointSettings> { ["test1"] = new EndpointSettings { IPAddress = "1.2.1.3", NetworkID = "ddid" }, ["test2"] = new EndpointSettings { IPAddress = "1.2.1.3", NetworkID = "ddid" } } }, }) .WithModule("test2", "microsoft/test1:latest", new Dictionary <string, dynamic> { ["On"] = new { Test = "test", Swa = "swa", b = new { x = 1, z = 1.0 } } }) .WithRoute("test12", "test1", "test2"); var deployment2 = new EdgeDeploymentBase( JsonConvertEx.DeserializeObject <ConfigurationContentModel>( deployment1.ToString()), Log.Logger); var config1 = JsonConvertEx.DeserializeObject <ConfigurationContentModel>( deployment1.ToString()); var config2 = JsonConvertEx.DeserializeObject <ConfigurationContentModel>( deployment2.ToString()); Assert.True(JToken.DeepEquals(JToken.FromObject(config1), JToken.FromObject(config2))); }
public void TestTest8InvocationV2Chunked(int size) { var router = GetRouter(); var client = new ChunkMethodClient(new TestMethodClient(router), Log.Logger); var expected = new byte[size]; kRand.NextBytes(expected); var response = client.CallMethodAsync("test", "test", "Test8_V2", Encoding.UTF8.GetBytes(JsonConvertEx.SerializeObject(expected)), null, null, CancellationToken.None).Result; var returned = JsonConvertEx.DeserializeObject <byte[]>( Encoding.UTF8.GetString(response)); Assert.Equal(expected, returned); }
public void TestTest2InvocationChunked(int size) { var router = GetRouter(); var client = new ChunkMethodClient(new TestMethodClient(router), new ConsoleLogger()); var expected = new byte[size]; r.NextBytes(expected); var response = client.CallMethodAsync("test", "test", "Test2_V1", Encoding.UTF8.GetBytes(JsonConvertEx.SerializeObject(expected)), null, null).Result; var returned = JsonConvertEx.DeserializeObject <byte[]>( Encoding.UTF8.GetString(response)); Assert.Equal(expected, returned); }
/// <summary> /// Read master from file /// </summary> private Dictionary <string, dynamic> Sync() { var path = Path.Combine(Path.GetTempPath(), _fileName); try { if (File.Exists(path)) { return(JsonConvertEx.DeserializeObject <Dictionary <string, dynamic> >( File.ReadAllText(path))); } } catch (Exception ex) { _logger.Error($"Failed to synchronize from {path}.", () => ex); } return(new Dictionary <string, dynamic>()); }
public async Task TestTest1InvocationWithLargeBufferUsingMethodClient() { var harness = new ModuleHostHarness(); await harness.RunTestAsync(GetControllers(), async (device, module, services) => { var hub = services.Resolve <IMethodClient>(); var buffer = new byte[300809]; r.NextBytes(buffer); var expected = new TestModel { Test = buffer }; var response = await hub.CallMethodAsync(device, module, "Test1_V1", JsonConvertEx.SerializeObject(expected)); var returned = JsonConvertEx.DeserializeObject <TestModel>(response); Assert.Equal(expected.Test, returned.Test); }); }