private async Task <string> ResolvePath(string path) { using (CommandConnection connection = await BuildConnection()) { return(await connection.ResolvePath(path)); } }
/// <summary> /// Handler for property changes of the Directories namespace in the machine model /// </summary> /// <param name="sender">Sender object</param> /// <param name="e">Information about the changed property</param> private async void Directories_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == nameof(Directories.WWW)) { Directories directories = (Directories)sender; string path = await _commandConnection.ResolvePath(directories.WWW); OnWebDirectoryChanged?.Invoke(path); } }
private async Task ValidateProvider() { using (CommandConnection connection = new CommandConnection()) { await connection.Connect(_configuration.GetValue("SocketPath", DuetAPI.Connection.Defaults.SocketPath)); string wwwRoot = await connection.ResolvePath("0:/www"); if (wwwRoot != _wwwRoot) { _provider = new PhysicalFileProvider(wwwRoot); _wwwRoot = wwwRoot; } } }
/// <summary> /// Synchronize all registered endpoints and user sessions /// </summary> public async Task Execute() { string unixSocket = _configuration.GetValue("SocketPath", DuetAPI.Connection.Defaults.FullSocketPath); int retryDelay = _configuration.GetValue("ModelRetryDelay", 5000); MachineModel model; try { do { try { // Establish connections to DCS using SubscribeConnection subscribeConnection = new SubscribeConnection(); using CommandConnection commandConnection = new CommandConnection(); await subscribeConnection.Connect(DuetAPI.Connection.SubscriptionMode.Patch, "directories/www|httpEndpoints/**|userSessions/**", unixSocket); await commandConnection.Connect(unixSocket); _logger.LogInformation("Connections to DuetControlServer established"); // Get the machine model and keep it up-to-date model = await subscribeConnection.GetMachineModel(_stopRequest.Token); lock (Endpoints) { foreach (HttpEndpoint ep in model.HttpEndpoints) { string fullPath = $"{ep.EndpointType}/machine/{ep.Namespace}/{ep.Path}"; Endpoints[fullPath] = ep; _logger.LogInformation("Registered HTTP {0} endpoint via /machine/{1}/{2}", ep.EndpointType, ep.Namespace, ep.Path); } } // Keep track of the web directory _commandConnection = commandConnection; model.Directories.PropertyChanged += Directories_PropertyChanged; string wwwDirectory = await commandConnection.ResolvePath(model.Directories.WWW); OnWebDirectoryChanged?.Invoke(wwwDirectory); do { // Wait for more updates using JsonDocument jsonPatch = await subscribeConnection.GetMachineModelPatch(_stopRequest.Token); DuetAPI.Utility.JsonPatch.Patch(model, jsonPatch); // Check if the HTTP sessions have changed and rebuild them on demand if (jsonPatch.RootElement.TryGetProperty("httpEndpoints", out _)) { _logger.LogInformation("New number of custom HTTP endpoints: {0}", model.HttpEndpoints.Count); lock (Endpoints) { Endpoints.Clear(); foreach (HttpEndpoint ep in model.HttpEndpoints) { string fullPath = $"{ep.EndpointType}/machine/{ep.Namespace}/{ep.Path}"; Endpoints[fullPath] = ep; _logger.LogInformation("Registered HTTP {0} endpoint via /machine/{1}/{2}", ep.EndpointType, ep.Namespace, ep.Path); } } } // Rebuild the list of user sessions on demand if (jsonPatch.RootElement.TryGetProperty("userSessions", out _)) { lock (UserSessions) { UserSessions.Clear(); foreach (UserSession session in model.UserSessions) { UserSessions[session.Origin] = session.Id; } } } }while (!!_stopRequest.IsCancellationRequested); } catch (Exception e) when(!(e is OperationCanceledException)) { _logger.LogWarning(e, "Failed to synchronize machine model"); await Task.Delay(retryDelay, _stopRequest.Token); } }while (!_stopRequest.IsCancellationRequested); } catch (Exception e) { if (!(e is OperationCanceledException)) { _logger.LogError(e, "Failed to synchronize object model"); } } }
/// <summary> /// Synchronize all registered endpoints and user sessions /// </summary> public async Task Execute() { string unixSocket = _configuration.GetValue("SocketPath", DuetAPI.Connection.Defaults.FullSocketPath); int retryDelay = _configuration.GetValue("ModelRetryDelay", 5000); ObjectModel model; try { do { try { // Establish connections to DCS using SubscribeConnection subscribeConnection = new SubscribeConnection(); using CommandConnection commandConnection = new CommandConnection(); await subscribeConnection.Connect(DuetAPI.Connection.SubscriptionMode.Patch, new string[] { "directories/www", "httpEndpoints/**", "network/corsSite", "userSessions/**" }, unixSocket); await commandConnection.Connect(unixSocket); _logger.LogInformation("Connections to DuetControlServer established"); // Get the machine model and keep it up-to-date model = await subscribeConnection.GetObjectModel(_stopRequest.Token); if (!string.IsNullOrEmpty(model.Network.CorsSite)) { _logger.LogInformation("Changing CORS policy to accept site '{0}'", model.Network.CorsSite); CorsPolicy.Origins.Add(model.Network.CorsSite); } lock (Endpoints) { Endpoints.Clear(); foreach (HttpEndpoint ep in model.HttpEndpoints) { string fullPath = (ep.Namespace == HttpEndpoint.RepRapFirmwareNamespace) ? $"{ep.EndpointType}/rr_{ep.Path}" : $"{ep.EndpointType}/machine/{ep.Namespace}/{ep.Path}"; Endpoints[fullPath] = ep; _logger.LogInformation("Registered HTTP endpoint {0}", fullPath); } } // Keep track of the web directory _commandConnection = commandConnection; model.Directories.PropertyChanged += Directories_PropertyChanged; string wwwDirectory = await commandConnection.ResolvePath(model.Directories.Web); OnWebDirectoryChanged?.Invoke(wwwDirectory); do { // Wait for more updates using JsonDocument jsonPatch = await subscribeConnection.GetObjectModelPatch(_stopRequest.Token); model.UpdateFromJson(jsonPatch.RootElement); // Check for updated CORS site if (jsonPatch.RootElement.TryGetProperty("network", out _)) { CorsPolicy.Origins.Clear(); if (!string.IsNullOrEmpty(model.Network.CorsSite)) { _logger.LogInformation("Changing CORS policy to accept site '{0}'", model.Network.CorsSite); CorsPolicy.Origins.Add(model.Network.CorsSite); } else { _logger.LogInformation("Reset CORS policy"); } } // Check if the HTTP sessions have changed and rebuild them on demand if (jsonPatch.RootElement.TryGetProperty("httpEndpoints", out _)) { _logger.LogInformation("New number of custom HTTP endpoints: {0}", model.HttpEndpoints.Count); lock (Endpoints) { Endpoints.Clear(); foreach (HttpEndpoint ep in model.HttpEndpoints) { string fullPath = $"{ep.EndpointType}/machine/{ep.Namespace}/{ep.Path}"; Endpoints[fullPath] = ep; _logger.LogInformation("Registered HTTP {0} endpoint via /machine/{1}/{2}", ep.EndpointType, ep.Namespace, ep.Path); } } } // Rebuild the list of user sessions on demand if (jsonPatch.RootElement.TryGetProperty("userSessions", out _)) { lock (UserSessions) { UserSessions.Clear(); foreach (UserSession session in model.UserSessions) { UserSessions[session.Origin] = session.Id; } } } }while (!_stopRequest.IsCancellationRequested); } catch (Exception e) when(!(e is OperationCanceledException)) { _logger.LogWarning(e, "Failed to synchronize machine model"); await Task.Delay(retryDelay, _stopRequest.Token); } }while (!_stopRequest.IsCancellationRequested); } catch (OperationCanceledException) { // unhandled } }