/* ======================================================================== * Copyright (c) 2005-2025 The OPC Foundation, Inc. All rights reserved. * * OPC Foundation MIT License 1.00 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * The complete license agreement can be found here: * http://opcfoundation.org/License/MIT/1.00/ * ======================================================================*/ using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; namespace Opc.Ua.Server.FileSystem { /// /// Async storage abstraction used by /// to expose the OPC UA /// Part 5 §C / Part 20 §4 FileType / /// FileDirectoryType companion model over an arbitrary /// backing store. /// /// /// /// All paths are forward-slash separated, provider-relative /// strings, with the empty string and "/" both denoting the /// root. Implementations are responsible for translating these /// portable paths to whatever the backing store understands /// (native filesystem paths, blob keys, in-memory tree keys …) /// and for rejecting path-traversal attempts (e.g. ".." /// segments that escape the mount root). /// /// /// Implementations should be safe for concurrent calls; the node /// manager does not serialise access on its side. Streams returned /// from and /// are owned by the caller (the node manager closes them /// when the corresponding OPC UA file handle is closed or the /// server shuts down). /// /// public interface IFileSystemProvider { /// /// Display name surfaced as the BrowseName of the root /// mount node in the server's address space. Must be a valid /// OPC UA name (non-null, non-empty, unique among providers /// mounted in the same server). /// string MountName { get; } /// /// true if the provider permits create / write / delete /// operations. Read-only providers report false here so /// the node manager can decline write requests with /// without /// round-tripping to the backend. /// bool IsWritable { get; } /// /// Returns metadata about the file or directory at /// , or null when the path /// resolves to nothing. /// ValueTask GetEntryAsync(string path, CancellationToken ct); /// /// Enumerates the immediate children (files + directories) of /// the directory at . Throws /// when /// refers to a missing or non-directory /// node. /// IAsyncEnumerable EnumerateAsync(string path, CancellationToken ct); /// /// Opens the file at for reading. /// /// If the file does not exist. ValueTask OpenReadAsync(string path, CancellationToken ct); /// /// Opens the file at for writing. /// /// Provider-relative file path. /// How the file should be opened / created. /// Cancellation token. ValueTask OpenWriteAsync(string path, FileWriteMode mode, CancellationToken ct); /// /// Creates a directory (and any missing parents) at /// . No-op when the directory already /// exists. Throws when a file /// already occupies the slot. /// ValueTask CreateDirectoryAsync(string path, CancellationToken ct); /// /// Creates an empty file at . Throws /// when the path already exists /// (either as a file or a directory). /// ValueTask CreateFileAsync(string path, CancellationToken ct); /// /// Deletes the file or directory at . /// Directories are deleted recursively. Throws /// / /// when the path /// does not exist. /// ValueTask DeleteAsync(string path, CancellationToken ct); /// /// Moves (renames) to /// . Both arguments are /// provider-relative paths. Throws /// on collision. /// ValueTask MoveAsync(string source, string target, CancellationToken ct); /// /// Recursively copies to /// . Both arguments are /// provider-relative paths. Throws /// on collision. /// ValueTask CopyAsync(string source, string target, CancellationToken ct); } }