From d1271df207e4811f26902820e0f2099185b4b18b Mon Sep 17 00:00:00 2001
From: Pavel Gross
Date: Mon, 23 Sep 2024 18:53:21 +0300
Subject: [PATCH] [#13] Client: Use code analyzers
Signed-off-by: Pavel Gross
---
.editorconfig | 901 ++++++++++++++++++
FrostFS.SDK.sln | 12 +-
.../Exceptions/FrostFsException.cs | 18 +
.../Exceptions/InvalidObjectException.cs | 13 +-
.../Exceptions/ResponseException.cs | 21 +-
.../FrostFS.SDK.ClientV2.csproj | 15 +-
.../{Client.cs => FrostFSClient.cs} | 129 ++-
.../Interceptors/MetricsInterceptor.cs | 26 +-
.../Interfaces/IFrostFSClient.cs | 6 +-
src/FrostFS.SDK.ClientV2/Mappers/Container.cs | 10 +-
.../Mappers/ContainerId.cs | 16 +-
.../Mappers/MetaHeader.cs | 9 +-
.../Mappers/Netmap/Netmap.cs | 6 +
.../Mappers/Netmap/NodeInfo.cs | 10 +
.../Mappers/Netmap/PlacementPolicy.cs | 24 +-
.../Mappers/Netmap/Replica.cs | 7 +
.../Mappers/Object/Object.cs | 2 +-
.../Mappers/Object/ObjectAttributeMapper.cs | 18 +-
.../Mappers/Object/ObjectFilterMapper.cs | 7 +-
.../Mappers/Object/ObjectHeaderMapper.cs | 26 +-
.../Mappers/Object/ObjectId.cs | 12 +
src/FrostFS.SDK.ClientV2/Mappers/OwnerId.cs | 12 +-
.../Mappers/Session/SessionMapper.cs | 9 +-
.../Mappers/SignatureMapper.cs | 8 +-
src/FrostFS.SDK.ClientV2/Mappers/Status.cs | 2 +-
src/FrostFS.SDK.ClientV2/Mappers/Version.cs | 12 +-
.../Models/Chain/ChainTarget.cs | 28 +-
.../Models/Chain/FrostFsChain.cs | 28 +-
.../Models/Chain/FrostFsTargetType.cs | 2 +-
.../Models/Client/ClientSettings.cs | 27 +-
.../Models/Containers/FrostFsContainerId.cs | 28 +-
.../Models/Containers/FrostFsContainerInfo.cs | 46 +-
.../Models/Enums/BasicAcl.cs | 21 -
.../Models/Misc/CheckSum.cs | 11 +-
.../Models/Misc/Constants.cs | 4 +-
.../Models/Netmap/FrostFsPlacementPolicy.cs | 79 +-
.../Models/Netmap/FrostFsReplica.cs | 34 +-
.../Models/Netmap/FrostFsVersion.cs | 7 +-
...FsAttribute.cs => FrostFsAttributePair.cs} | 2 +-
.../Models/Object/FrostFsLinkObject.cs | 20 +-
.../Models/Object/FrostFsObject.cs | 28 +-
.../Models/Object/FrostFsObjectFilter.cs | 2 +-
.../Models/Object/FrostFsObjectHeader.cs | 19 +-
.../Models/Object/FrostFsObjectId.cs | 5 +
.../Models/Object/FrostFsOwner.cs | 6 +-
.../Models/Object/FrostFsSplit.cs | 20 +-
.../Models/Object/SplitId.cs | 26 +-
.../Models/Response/FrostFsSignature.cs | 2 +-
.../Parameters/Context.cs | 24 +-
.../Parameters/PrmBase.cs | 4 +-
.../Parameters/PrmContainerCreate.cs | 2 +-
.../Parameters/PrmNetmapSnapshot.cs | 2 +-
.../Parameters/PrmNetworkSettings.cs | 2 +-
.../Parameters/PrmNodeInfo.cs | 2 +-
.../Parameters/PrmObjectHeadGet.cs | 2 +-
.../Parameters/PrmObjectPut.cs | 6 +-
.../Services/ContainerServiceProvider.cs | 77 +-
.../Services/NetmapServiceProvider.cs | 43 +-
.../Services/ObjectServiceProvider.cs | 183 ++--
.../Services/SessionServiceProvider.cs | 21 +-
.../Shared/ApeManagerServiceProvider.cs | 22 +-
.../Services/Shared/SessionProvider.cs | 9 +-
.../Tools/ClientEnvironment.cs | 8 +-
src/FrostFS.SDK.ClientV2/Tools/Object.cs | 57 --
.../Tools/ObjectReader.cs | 24 +-
.../Tools/ObjectStreamer.cs | 14 +-
src/FrostFS.SDK.ClientV2/Tools/ObjectTools.cs | 39 +-
src/FrostFS.SDK.ClientV2/Tools/Range.cs | 18 +-
.../Tools/RequestConstructor.cs | 28 +-
.../Tools/RequestSigner.cs | 42 +-
.../Tools/SearchReader.cs | 8 +-
src/FrostFS.SDK.ClientV2/Tools/Verifier.cs | 46 +-
src/FrostFS.SDK.ClientV2/Ростелеком.txt | 8 +
src/FrostFS.SDK.Cryptography/Base58.cs | 15 +-
src/FrostFS.SDK.Cryptography/Extentions.cs | 12 +-
.../FrostFS.SDK.Cryptography.csproj | 4 +
src/FrostFS.SDK.Cryptography/Key.cs | 28 +-
src/FrostFS.SDK.Cryptography/Murmur3_128.cs | 6 +-
src/FrostFS.SDK.Cryptography/Range.cs | 6 +-
src/FrostFS.SDK.Cryptography/UUID.cs | 12 +-
.../Interfaces/IVerificationHeader.cs | 1 +
.../apemanager/Extension.Message.cs | 6 +-
.../container/Extension.Message.cs | 6 +-
.../netmap/Extension.Message.cs | 1 +
.../object/Extension.Message.cs | 4 +-
.../session/Extension.Message.cs | 1 +
src/FrostFS.SDK.Tests/ContainerTest.cs | 27 +-
src/FrostFS.SDK.Tests/MetricsInterceptor.cs | 12 +-
.../Mocks/AsyncStreamReaderMock.cs | 2 +-
.../Mocks/ClientStreamWriter.cs | 7 +-
.../ContainerServiceBase.cs | 34 +-
.../ContainerServiceMocks/ContainerStub.cs | 1 +
.../ContainerServiceMocks/GetContainerMock.cs | 32 +-
.../ContainerServiceMocks/RequestData.cs | 1 -
src/FrostFS.SDK.Tests/Mocks/NetworkMocker.cs | 7 +-
src/FrostFS.SDK.Tests/Mocks/ObjectMock.cs | 20 +-
src/FrostFS.SDK.Tests/Mocks/SessionMock.cs | 3 +
src/FrostFS.SDK.Tests/NetworkTest.cs | 28 +-
src/FrostFS.SDK.Tests/ObjectTest.cs | 46 +-
src/FrostFS.SDK.Tests/SessionTests.cs | 12 +-
src/FrostFS.SDK.Tests/SmokeTests.cs | 99 +-
src/FrostFS.SDK.Tests/SmokeTestsBase.cs | 1 +
102 files changed, 2168 insertions(+), 733 deletions(-)
create mode 100644 .editorconfig
create mode 100644 src/FrostFS.SDK.ClientV2/Exceptions/FrostFsException.cs
rename src/FrostFS.SDK.ClientV2/{Client.cs => FrostFSClient.cs} (79%)
delete mode 100644 src/FrostFS.SDK.ClientV2/Models/Enums/BasicAcl.cs
rename src/FrostFS.SDK.ClientV2/Models/Object/{FrostFsAttribute.cs => FrostFsAttributePair.cs} (66%)
delete mode 100644 src/FrostFS.SDK.ClientV2/Tools/Object.cs
create mode 100644 src/FrostFS.SDK.ClientV2/Ростелеком.txt
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..7a29e50
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,901 @@
+[*.cs]
+
+# CA1001: Types that own disposable fields should be disposable
+dotnet_diagnostic.CA1001.severity = warning
+
+# CA1000: Do not declare static members on generic types
+dotnet_diagnostic.CA1000.severity = warning
+
+# CA1002: Do not expose generic lists
+dotnet_diagnostic.CA1002.severity = warning
+
+# CA1003: Use generic event handler instances
+dotnet_diagnostic.CA1003.severity = warning
+
+# CA1005: Avoid excessive parameters on generic types
+dotnet_diagnostic.CA1005.severity = warning
+
+# CA1008: Enums should have zero value
+dotnet_diagnostic.CA1008.severity = warning
+
+# CA1010: Generic interface should also be implemented
+dotnet_diagnostic.CA1010.severity = warning
+
+# CA1012: Abstract types should not have public constructors
+dotnet_diagnostic.CA1012.severity = warning
+
+# CA1014: Mark assemblies with CLSCompliant
+dotnet_diagnostic.CA1014.severity = warning
+
+# CA1016: Mark assemblies with assembly version
+dotnet_diagnostic.CA1016.severity = warning
+
+# CA1017: Mark assemblies with ComVisible
+dotnet_diagnostic.CA1017.severity = warning
+
+# CA1018: Mark attributes with AttributeUsageAttribute
+dotnet_diagnostic.CA1018.severity = warning
+
+# CA1019: Define accessors for attribute arguments
+dotnet_diagnostic.CA1019.severity = warning
+
+# CA1021: Avoid out parameters
+dotnet_diagnostic.CA1021.severity = warning
+
+# CA1024: Use properties where appropriate
+dotnet_diagnostic.CA1024.severity = warning
+
+# CA1027: Mark enums with FlagsAttribute
+dotnet_diagnostic.CA1027.severity = warning
+
+# CA1028: Enum Storage should be Int32
+dotnet_diagnostic.CA1028.severity = warning
+
+# CA1030: Use events where appropriate
+dotnet_diagnostic.CA1030.severity = warning
+
+# CA1031: Do not catch general exception types
+dotnet_diagnostic.CA1031.severity = warning
+
+# CA1033: Interface methods should be callable by child types
+dotnet_diagnostic.CA1033.severity = warning
+
+# CA1034: Nested types should not be visible
+dotnet_diagnostic.CA1034.severity = warning
+
+# CA1036: Override methods on comparable types
+dotnet_diagnostic.CA1036.severity = warning
+
+# CA1040: Avoid empty interfaces
+dotnet_diagnostic.CA1040.severity = warning
+
+# CA1041: Provide ObsoleteAttribute message
+dotnet_diagnostic.CA1041.severity = warning
+
+# CA1043: Use Integral Or String Argument For Indexers
+dotnet_diagnostic.CA1043.severity = warning
+
+# CA1044: Properties should not be write only
+dotnet_diagnostic.CA1044.severity = warning
+
+# CA1045: Do not pass types by reference
+dotnet_diagnostic.CA1045.severity = warning
+
+# CA1046: Do not overload equality operator on reference types
+dotnet_diagnostic.CA1046.severity = warning
+
+# CA1050: Declare types in namespaces
+dotnet_diagnostic.CA1050.severity = warning
+
+# CA1051: Do not declare visible instance fields
+dotnet_diagnostic.CA1051.severity = warning
+
+# CA1052: Static holder types should be Static or NotInheritable
+dotnet_diagnostic.CA1052.severity = warning
+
+# CA1054: URI-like parameters should not be strings
+dotnet_diagnostic.CA1054.severity = warning
+
+# CA1055: URI-like return values should not be strings
+dotnet_diagnostic.CA1055.severity = warning
+
+# CA1056: URI-like properties should not be strings
+dotnet_diagnostic.CA1056.severity = warning
+
+# CA1058: Types should not extend certain base types
+dotnet_diagnostic.CA1058.severity = warning
+
+# CA1060: Move pinvokes to native methods class
+dotnet_diagnostic.CA1060.severity = warning
+
+# CA1061: Do not hide base class methods
+dotnet_diagnostic.CA1061.severity = warning
+
+# CA1062: Validate arguments of public methods
+dotnet_diagnostic.CA1062.severity = warning
+
+# CA1063: Implement IDisposable Correctly
+dotnet_diagnostic.CA1063.severity = warning
+
+# CA1064: Exceptions should be public
+dotnet_diagnostic.CA1064.severity = warning
+
+# CA1065: Do not raise exceptions in unexpected locations
+dotnet_diagnostic.CA1065.severity = warning
+
+# CA1066: Implement IEquatable when overriding Object.Equals
+dotnet_diagnostic.CA1066.severity = warning
+
+# CA1067: Override Object.Equals(object) when implementing IEquatable
+dotnet_diagnostic.CA1067.severity = warning
+
+# CA1068: CancellationToken parameters must come last
+dotnet_diagnostic.CA1068.severity = warning
+
+# CA1069: Enums values should not be duplicated
+dotnet_diagnostic.CA1069.severity = warning
+
+# CA1070: Do not declare event fields as virtual
+dotnet_diagnostic.CA1070.severity = warning
+
+# CA1303: Do not pass literals as localized parameters
+dotnet_diagnostic.CA1303.severity = warning
+
+# CA1304: Specify CultureInfo
+dotnet_diagnostic.CA1304.severity = warning
+
+# CA1305: Specify IFormatProvider
+dotnet_diagnostic.CA1305.severity = warning
+
+# CA1307: Specify StringComparison for clarity
+dotnet_diagnostic.CA1307.severity = warning
+
+# CA1308: Normalize strings to uppercase
+dotnet_diagnostic.CA1308.severity = warning
+
+# CA1310: Specify StringComparison for correctness
+dotnet_diagnostic.CA1310.severity = warning
+
+# CA1401: P/Invokes should not be visible
+dotnet_diagnostic.CA1401.severity = warning
+
+# CA1416: Validate platform compatibility
+dotnet_diagnostic.CA1416.severity = warning
+
+# CA1417: Do not use 'OutAttribute' on string parameters for P/Invokes
+dotnet_diagnostic.CA1417.severity = warning
+
+# CA1418: Use valid platform string
+dotnet_diagnostic.CA1418.severity = warning
+
+# CA1419: Provide a parameterless constructor that is as visible as the containing type for concrete types derived from 'System.Runtime.InteropServices.SafeHandle'
+dotnet_diagnostic.CA1419.severity = warning
+
+# CA1420: Property, type, or attribute requires runtime marshalling
+dotnet_diagnostic.CA1420.severity = warning
+
+# CA1421: This method uses runtime marshalling even when the 'DisableRuntimeMarshallingAttribute' is applied
+dotnet_diagnostic.CA1421.severity = warning
+
+# CA1422: Validate platform compatibility
+dotnet_diagnostic.CA1422.severity = warning
+
+# CA1501: Avoid excessive inheritance
+dotnet_diagnostic.CA1501.severity = warning
+
+# CA1502: Avoid excessive complexity
+dotnet_diagnostic.CA1502.severity = warning
+
+# CA1505: Avoid unmaintainable code
+dotnet_diagnostic.CA1505.severity = warning
+
+# CA1506: Avoid excessive class coupling
+# dotnet_diagnostic.CA1506.severity = warning
+
+# CA1509: Invalid entry in code metrics rule specification file
+dotnet_diagnostic.CA1509.severity = warning
+
+# CA1510: Use ArgumentNullException throw helper
+dotnet_diagnostic.CA1510.severity = warning
+
+# CA1511: Use ArgumentException throw helper
+dotnet_diagnostic.CA1511.severity = warning
+
+# CA1512: Use ArgumentOutOfRangeException throw helper
+dotnet_diagnostic.CA1512.severity = warning
+
+# CA1513: Use ObjectDisposedException throw helper
+dotnet_diagnostic.CA1513.severity = warning
+
+# CA1700: Do not name enum values 'Reserved'
+dotnet_diagnostic.CA1700.severity = warning
+
+# CA1707: Identifiers should not contain underscores
+dotnet_diagnostic.CA1707.severity = warning
+
+# CA1708: Identifiers should differ by more than case
+dotnet_diagnostic.CA1708.severity = warning
+
+# CA1710: Identifiers should have correct suffix
+dotnet_diagnostic.CA1710.severity = warning
+
+# CA1711: Identifiers should not have incorrect suffix
+dotnet_diagnostic.CA1711.severity = warning
+
+# CA1712: Do not prefix enum values with type name
+dotnet_diagnostic.CA1712.severity = warning
+
+# CA1713: Events should not have 'Before' or 'After' prefix
+dotnet_diagnostic.CA1713.severity = warning
+
+# CA1715: Identifiers should have correct prefix
+dotnet_diagnostic.CA1715.severity = warning
+
+# CA1716: Identifiers should not match keywords
+dotnet_diagnostic.CA1716.severity = warning
+
+# CA1720: Identifier contains type name
+dotnet_diagnostic.CA1720.severity = warning
+
+# CA1721: Property names should not match get methods
+dotnet_diagnostic.CA1721.severity = warning
+
+# CA1724: Type names should not match namespaces
+dotnet_diagnostic.CA1724.severity = warning
+
+# CA1725: Parameter names should match base declaration
+dotnet_diagnostic.CA1725.severity = warning
+
+# CA1727: Use PascalCase for named placeholders
+dotnet_diagnostic.CA1727.severity = warning
+
+# CA1806: Do not ignore method results
+dotnet_diagnostic.CA1806.severity = warning
+
+# CA1810: Initialize reference type static fields inline
+dotnet_diagnostic.CA1810.severity = warning
+
+# CA1813: Avoid unsealed attributes
+dotnet_diagnostic.CA1813.severity = warning
+
+# CA1814: Prefer jagged arrays over multidimensional
+dotnet_diagnostic.CA1814.severity = warning
+
+# CA1815: Override equals and operator equals on value types
+dotnet_diagnostic.CA1815.severity = warning
+
+# CA1816: Dispose methods should call SuppressFinalize
+dotnet_diagnostic.CA1816.severity = warning
+
+# CA1819: Properties should not return arrays
+# dotnet_diagnostic.CA1819.severity = warning
+
+# CA1820: Test for empty strings using string length
+dotnet_diagnostic.CA1820.severity = warning
+
+# CA1821: Remove empty Finalizers
+dotnet_diagnostic.CA1821.severity = warning
+
+# CA1822: Mark members as static
+dotnet_diagnostic.CA1822.severity = warning
+
+# CA1823: Avoid unused private fields
+dotnet_diagnostic.CA1823.severity = warning
+
+# CA1826: Do not use Enumerable methods on indexable collections
+dotnet_diagnostic.CA1826.severity = warning
+
+# CA1827: Do not use Count() or LongCount() when Any() can be used
+dotnet_diagnostic.CA1827.severity = warning
+
+# CA1828: Do not use CountAsync() or LongCountAsync() when AnyAsync() can be used
+dotnet_diagnostic.CA1828.severity = warning
+
+# CA1829: Use Length/Count property instead of Count() when available
+dotnet_diagnostic.CA1829.severity = warning
+
+# CA1830: Prefer strongly-typed Append and Insert method overloads on StringBuilder
+dotnet_diagnostic.CA1830.severity = warning
+
+# CA1831: Use AsSpan or AsMemory instead of Range-based indexers when appropriate
+dotnet_diagnostic.CA1831.severity = warning
+
+# CA1832: Use AsSpan or AsMemory instead of Range-based indexers when appropriate
+dotnet_diagnostic.CA1832.severity = warning
+
+# CA1833: Use AsSpan or AsMemory instead of Range-based indexers when appropriate
+dotnet_diagnostic.CA1833.severity = warning
+
+# CA1834: Consider using 'StringBuilder.Append(char)' when applicable
+dotnet_diagnostic.CA1834.severity = warning
+
+# CA1835: Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'
+dotnet_diagnostic.CA1835.severity = warning
+
+# CA1836: Prefer IsEmpty over Count
+dotnet_diagnostic.CA1836.severity = warning
+
+# CA1837: Use 'Environment.ProcessId'
+dotnet_diagnostic.CA1837.severity = warning
+
+# CA1838: Avoid 'StringBuilder' parameters for P/Invokes
+dotnet_diagnostic.CA1838.severity = warning
+
+# CA1839: Use 'Environment.ProcessPath'
+dotnet_diagnostic.CA1839.severity = warning
+
+# CA1840: Use 'Environment.CurrentManagedThreadId'
+dotnet_diagnostic.CA1840.severity = warning
+
+# CA1842: Do not use 'WhenAll' with a single task
+dotnet_diagnostic.CA1842.severity = warning
+
+# CA1843: Do not use 'WaitAll' with a single task
+dotnet_diagnostic.CA1843.severity = warning
+
+# CA1844: Provide memory-based overrides of async methods when subclassing 'Stream'
+dotnet_diagnostic.CA1844.severity = warning
+
+# CA1846: Prefer 'AsSpan' over 'Substring'
+dotnet_diagnostic.CA1846.severity = warning
+
+# CA1847: Use char literal for a single character lookup
+dotnet_diagnostic.CA1847.severity = warning
+
+# CA1848: Use the LoggerMessage delegates
+dotnet_diagnostic.CA1848.severity = warning
+
+# CA1849: Call async methods when in an async method
+dotnet_diagnostic.CA1849.severity = warning
+
+# CA1850: Prefer static 'HashData' method over 'ComputeHash'
+dotnet_diagnostic.CA1850.severity = warning
+
+# CA1852: Seal internal types
+dotnet_diagnostic.CA1852.severity = warning
+
+# CA1853: Unnecessary call to 'Dictionary.ContainsKey(key)'
+dotnet_diagnostic.CA1853.severity = warning
+
+# CA1854: Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method
+dotnet_diagnostic.CA1854.severity = warning
+
+# CA1858: Use 'StartsWith' instead of 'IndexOf'
+dotnet_diagnostic.CA1858.severity = warning
+
+# CA1859: Use concrete types when possible for improved performance
+dotnet_diagnostic.CA1859.severity = warning
+
+# CA1860: Avoid using 'Enumerable.Any()' extension method
+dotnet_diagnostic.CA1860.severity = warning
+
+# CA1861: Avoid constant arrays as arguments
+dotnet_diagnostic.CA1861.severity = warning
+
+# CA1862: Use the 'StringComparison' method overloads to perform case-insensitive string comparisons
+dotnet_diagnostic.CA1862.severity = warning
+
+# CA1863: Use 'CompositeFormat'
+dotnet_diagnostic.CA1863.severity = warning
+
+# CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method
+dotnet_diagnostic.CA1864.severity = warning
+
+# CA1868: Unnecessary call to 'Contains(item)'
+dotnet_diagnostic.CA1868.severity = warning
+
+# CA1869: Cache and reuse 'JsonSerializerOptions' instances
+dotnet_diagnostic.CA1869.severity = warning
+
+# CA2000: Dispose objects before losing scope
+dotnet_diagnostic.CA2000.severity = warning
+
+# CA2002: Do not lock on objects with weak identity
+dotnet_diagnostic.CA2002.severity = warning
+
+# CA2007: Consider calling ConfigureAwait on the awaited task
+dotnet_diagnostic.CA2007.severity = warning
+
+# CA2008: Do not create tasks without passing a TaskScheduler
+dotnet_diagnostic.CA2008.severity = warning
+
+# CA2009: Do not call ToImmutableCollection on an ImmutableCollection value
+dotnet_diagnostic.CA2009.severity = warning
+
+# CA2011: Avoid infinite recursion
+dotnet_diagnostic.CA2011.severity = warning
+
+# CA2012: Use ValueTasks correctly
+dotnet_diagnostic.CA2012.severity = warning
+
+# CA2013: Do not use ReferenceEquals with value types
+dotnet_diagnostic.CA2013.severity = warning
+
+# CA2015: Do not define finalizers for types derived from MemoryManager
+dotnet_diagnostic.CA2015.severity = warning
+
+# CA2017: Parameter count mismatch
+dotnet_diagnostic.CA2017.severity = warning
+
+# CA2018: 'Buffer.BlockCopy' expects the number of bytes to be copied for the 'count' argument
+dotnet_diagnostic.CA2018.severity = warning
+
+# CA2019: Improper 'ThreadStatic' field initialization
+dotnet_diagnostic.CA2019.severity = warning
+
+# CA2021: Do not call Enumerable.Cast or Enumerable.OfType with incompatible types
+dotnet_diagnostic.CA2021.severity = warning
+
+# CA2100: Review SQL queries for security vulnerabilities
+dotnet_diagnostic.CA2100.severity = warning
+
+# CA2101: Specify marshaling for P/Invoke string arguments
+dotnet_diagnostic.CA2101.severity = warning
+
+# CA2119: Seal methods that satisfy private interfaces
+dotnet_diagnostic.CA2119.severity = warning
+
+# CA2153: Do Not Catch Corrupted State Exceptions
+dotnet_diagnostic.CA2153.severity = warning
+
+# CA2200: Rethrow to preserve stack details
+dotnet_diagnostic.CA2200.severity = warning
+
+# CA2201: Do not raise reserved exception types
+dotnet_diagnostic.CA2201.severity = warning
+
+# CA2207: Initialize value type static fields inline
+dotnet_diagnostic.CA2207.severity = warning
+
+# CA2208: Instantiate argument exceptions correctly
+dotnet_diagnostic.CA2208.severity = warning
+
+# CA2211: Non-constant fields should not be visible
+dotnet_diagnostic.CA2211.severity = warning
+
+# CA2213: Disposable fields should be disposed
+dotnet_diagnostic.CA2213.severity = warning
+
+# CA2214: Do not call overridable methods in constructors
+dotnet_diagnostic.CA2214.severity = warning
+
+# CA2215: Dispose methods should call base class dispose
+dotnet_diagnostic.CA2215.severity = warning
+
+# CA2216: Disposable types should declare finalizer
+dotnet_diagnostic.CA2216.severity = warning
+
+# CA2217: Do not mark enums with FlagsAttribute
+dotnet_diagnostic.CA2217.severity = warning
+
+# CA2219: Do not raise exceptions in finally clauses
+dotnet_diagnostic.CA2219.severity = warning
+
+# CA2225: Operator overloads have named alternates
+dotnet_diagnostic.CA2225.severity = warning
+
+# CA2226: Operators should have symmetrical overloads
+dotnet_diagnostic.CA2226.severity = warning
+
+# CA2227: Collection properties should be read only
+dotnet_diagnostic.CA2227.severity = warning
+
+# CA2231: Overload operator equals on overriding value type Equals
+dotnet_diagnostic.CA2231.severity = warning
+
+# CA2235: Mark all non-serializable fields
+dotnet_diagnostic.CA2235.severity = warning
+
+# CA2237: Mark ISerializable types with serializable
+dotnet_diagnostic.CA2237.severity = warning
+
+# CA2241: Provide correct arguments to formatting methods
+dotnet_diagnostic.CA2241.severity = warning
+
+# CA2242: Test for NaN correctly
+dotnet_diagnostic.CA2242.severity = warning
+
+# CA2243: Attribute string literals should parse correctly
+dotnet_diagnostic.CA2243.severity = warning
+
+# CA2244: Do not duplicate indexed element initializations
+dotnet_diagnostic.CA2244.severity = warning
+
+# CA2245: Do not assign a property to itself
+dotnet_diagnostic.CA2245.severity = warning
+
+# CA2246: Assigning symbol and its member in the same statement
+dotnet_diagnostic.CA2246.severity = warning
+
+# CA2247: Argument passed to TaskCompletionSource constructor should be TaskCreationOptions enum instead of TaskContinuationOptions enum
+dotnet_diagnostic.CA2247.severity = warning
+
+# CA2248: Provide correct 'enum' argument to 'Enum.HasFlag'
+dotnet_diagnostic.CA2248.severity = warning
+
+# CA2249: Consider using 'string.Contains' instead of 'string.IndexOf'
+dotnet_diagnostic.CA2249.severity = warning
+
+# CA2250: Use 'ThrowIfCancellationRequested'
+dotnet_diagnostic.CA2250.severity = warning
+
+# CA2251: Use 'string.Equals'
+dotnet_diagnostic.CA2251.severity = warning
+
+# CA2253: Named placeholders should not be numeric values
+dotnet_diagnostic.CA2253.severity = warning
+
+# CA2254: Template should be a static expression
+dotnet_diagnostic.CA2254.severity = warning
+
+# CA2255: The 'ModuleInitializer' attribute should not be used in libraries
+dotnet_diagnostic.CA2255.severity = warning
+
+# CA2256: All members declared in parent interfaces must have an implementation in a DynamicInterfaceCastableImplementation-attributed interface
+dotnet_diagnostic.CA2256.severity = warning
+
+# CA2257: Members defined on an interface with the 'DynamicInterfaceCastableImplementationAttribute' should be 'static'
+dotnet_diagnostic.CA2257.severity = warning
+
+# CA2258: Providing a 'DynamicInterfaceCastableImplementation' interface in Visual Basic is unsupported
+dotnet_diagnostic.CA2258.severity = warning
+
+# CA2259: 'ThreadStatic' only affects static fields
+dotnet_diagnostic.CA2259.severity = warning
+
+# CA2261: Do not use ConfigureAwaitOptions.SuppressThrowing with Task
+dotnet_diagnostic.CA2261.severity = warning
+
+# CA2300: Do not use insecure deserializer BinaryFormatter
+dotnet_diagnostic.CA2300.severity = warning
+
+# CA2301: Do not call BinaryFormatter.Deserialize without first setting BinaryFormatter.Binder
+dotnet_diagnostic.CA2301.severity = warning
+
+# CA2302: Ensure BinaryFormatter.Binder is set before calling BinaryFormatter.Deserialize
+dotnet_diagnostic.CA2302.severity = warning
+
+# CA2305: Do not use insecure deserializer LosFormatter
+dotnet_diagnostic.CA2305.severity = warning
+
+# CA2310: Do not use insecure deserializer NetDataContractSerializer
+dotnet_diagnostic.CA2310.severity = warning
+
+# CA2311: Do not deserialize without first setting NetDataContractSerializer.Binder
+dotnet_diagnostic.CA2311.severity = warning
+
+# CA2312: Ensure NetDataContractSerializer.Binder is set before deserializing
+dotnet_diagnostic.CA2312.severity = warning
+
+# CA2315: Do not use insecure deserializer ObjectStateFormatter
+dotnet_diagnostic.CA2315.severity = warning
+
+# CA2321: Do not deserialize with JavaScriptSerializer using a SimpleTypeResolver
+dotnet_diagnostic.CA2321.severity = warning
+
+# CA2322: Ensure JavaScriptSerializer is not initialized with SimpleTypeResolver before deserializing
+dotnet_diagnostic.CA2322.severity = warning
+
+# CA2326: Do not use TypeNameHandling values other than None
+dotnet_diagnostic.CA2326.severity = warning
+
+# CA2327: Do not use insecure JsonSerializerSettings
+dotnet_diagnostic.CA2327.severity = warning
+
+# CA2328: Ensure that JsonSerializerSettings are secure
+dotnet_diagnostic.CA2328.severity = warning
+
+# CA2329: Do not deserialize with JsonSerializer using an insecure configuration
+dotnet_diagnostic.CA2329.severity = warning
+
+# CA2330: Ensure that JsonSerializer has a secure configuration when deserializing
+dotnet_diagnostic.CA2330.severity = warning
+
+# CA2350: Do not use DataTable.ReadXml() with untrusted data
+dotnet_diagnostic.CA2350.severity = warning
+
+# CA2351: Do not use DataSet.ReadXml() with untrusted data
+dotnet_diagnostic.CA2351.severity = warning
+
+# CA2361: Ensure auto-generated class containing DataSet.ReadXml() is not used with untrusted data
+dotnet_diagnostic.CA2361.severity = warning
+
+# CA3001: Review code for SQL injection vulnerabilities
+dotnet_diagnostic.CA3001.severity = warning
+
+# CA3002: Review code for XSS vulnerabilities
+dotnet_diagnostic.CA3002.severity = warning
+
+# CA3003: Review code for file path injection vulnerabilities
+dotnet_diagnostic.CA3003.severity = warning
+
+# CA3004: Review code for information disclosure vulnerabilities
+dotnet_diagnostic.CA3004.severity = warning
+
+# CA3005: Review code for LDAP injection vulnerabilities
+dotnet_diagnostic.CA3005.severity = warning
+
+# CA3006: Review code for process command injection vulnerabilities
+dotnet_diagnostic.CA3006.severity = warning
+
+# CA3007: Review code for open redirect vulnerabilities
+dotnet_diagnostic.CA3007.severity = warning
+
+# CA3008: Review code for XPath injection vulnerabilities
+dotnet_diagnostic.CA3008.severity = warning
+
+# CA3009: Review code for XML injection vulnerabilities
+dotnet_diagnostic.CA3009.severity = warning
+
+# CA3010: Review code for XAML injection vulnerabilities
+dotnet_diagnostic.CA3010.severity = warning
+
+# CA3011: Review code for DLL injection vulnerabilities
+dotnet_diagnostic.CA3011.severity = warning
+
+# CA3012: Review code for regex injection vulnerabilities
+dotnet_diagnostic.CA3012.severity = warning
+
+# CA3061: Do Not Add Schema By URL
+dotnet_diagnostic.CA3061.severity = warning
+
+# CA3075: Insecure DTD processing in XML
+dotnet_diagnostic.CA3075.severity = warning
+
+# CA3076: Insecure XSLT script processing
+dotnet_diagnostic.CA3076.severity = warning
+
+# CA3077: Insecure Processing in API Design, XmlDocument and XmlTextReader
+dotnet_diagnostic.CA3077.severity = warning
+
+# CA3147: Mark Verb Handlers With Validate Antiforgery Token
+dotnet_diagnostic.CA3147.severity = warning
+
+# CA5350: Do Not Use Weak Cryptographic Algorithms
+dotnet_diagnostic.CA5350.severity = warning
+
+# CA5351: Do Not Use Broken Cryptographic Algorithms
+dotnet_diagnostic.CA5351.severity = warning
+
+# CA5358: Review cipher mode usage with cryptography experts
+dotnet_diagnostic.CA5358.severity = warning
+
+# CA5359: Do Not Disable Certificate Validation
+dotnet_diagnostic.CA5359.severity = warning
+
+# CA5360: Do Not Call Dangerous Methods In Deserialization
+dotnet_diagnostic.CA5360.severity = warning
+
+# CA5361: Do Not Disable SChannel Use of Strong Crypto
+dotnet_diagnostic.CA5361.severity = warning
+
+# CA5362: Potential reference cycle in deserialized object graph
+dotnet_diagnostic.CA5362.severity = warning
+
+# CA5363: Do Not Disable Request Validation
+dotnet_diagnostic.CA5363.severity = warning
+
+# CA5364: Do Not Use Deprecated Security Protocols
+dotnet_diagnostic.CA5364.severity = warning
+
+# CA5365: Do Not Disable HTTP Header Checking
+dotnet_diagnostic.CA5365.severity = warning
+
+# CA5366: Use XmlReader for 'DataSet.ReadXml()'
+dotnet_diagnostic.CA5366.severity = warning
+
+# CA5367: Do Not Serialize Types With Pointer Fields
+dotnet_diagnostic.CA5367.severity = warning
+
+# CA5368: Set ViewStateUserKey For Classes Derived From Page
+dotnet_diagnostic.CA5368.severity = warning
+
+# CA5369: Use XmlReader for 'XmlSerializer.Deserialize()'
+dotnet_diagnostic.CA5369.severity = warning
+
+# CA5370: Use XmlReader for XmlValidatingReader constructor
+dotnet_diagnostic.CA5370.severity = warning
+
+# CA5371: Use XmlReader for 'XmlSchema.Read()'
+dotnet_diagnostic.CA5371.severity = warning
+
+# CA5372: Use XmlReader for XPathDocument constructor
+dotnet_diagnostic.CA5372.severity = warning
+
+# CA5373: Do not use obsolete key derivation function
+dotnet_diagnostic.CA5373.severity = warning
+
+# CA5374: Do Not Use XslTransform
+dotnet_diagnostic.CA5374.severity = warning
+
+# CA5375: Do Not Use Account Shared Access Signature
+dotnet_diagnostic.CA5375.severity = warning
+
+# CA5376: Use SharedAccessProtocol HttpsOnly
+dotnet_diagnostic.CA5376.severity = warning
+
+# CA5377: Use Container Level Access Policy
+dotnet_diagnostic.CA5377.severity = warning
+
+# CA5378: Do not disable ServicePointManagerSecurityProtocols
+dotnet_diagnostic.CA5378.severity = warning
+
+# CA5379: Ensure Key Derivation Function algorithm is sufficiently strong
+dotnet_diagnostic.CA5379.severity = warning
+
+# CA5380: Do Not Add Certificates To Root Store
+dotnet_diagnostic.CA5380.severity = warning
+
+# CA5381: Ensure Certificates Are Not Added To Root Store
+dotnet_diagnostic.CA5381.severity = warning
+
+# CA5382: Use Secure Cookies In ASP.NET Core
+dotnet_diagnostic.CA5382.severity = warning
+
+# CA5383: Ensure Use Secure Cookies In ASP.NET Core
+dotnet_diagnostic.CA5383.severity = warning
+
+# CA5384: Do Not Use Digital Signature Algorithm (DSA)
+dotnet_diagnostic.CA5384.severity = warning
+
+# CA5385: Use Rivest-Shamir-Adleman (RSA) Algorithm With Sufficient Key Size
+dotnet_diagnostic.CA5385.severity = warning
+
+# CA5386: Avoid hardcoding SecurityProtocolType value
+dotnet_diagnostic.CA5386.severity = warning
+
+# CA5387: Do Not Use Weak Key Derivation Function With Insufficient Iteration Count
+dotnet_diagnostic.CA5387.severity = warning
+
+# CA5388: Ensure Sufficient Iteration Count When Using Weak Key Derivation Function
+dotnet_diagnostic.CA5388.severity = warning
+
+# CA5389: Do Not Add Archive Item's Path To The Target File System Path
+dotnet_diagnostic.CA5389.severity = warning
+
+# CA5390: Do not hard-code encryption key
+dotnet_diagnostic.CA5390.severity = warning
+
+# CA5391: Use antiforgery tokens in ASP.NET Core MVC controllers
+dotnet_diagnostic.CA5391.severity = warning
+
+# CA5392: Use DefaultDllImportSearchPaths attribute for P/Invokes
+dotnet_diagnostic.CA5392.severity = warning
+
+# CA5393: Do not use unsafe DllImportSearchPath value
+dotnet_diagnostic.CA5393.severity = warning
+
+# CA5394: Do not use insecure randomness
+dotnet_diagnostic.CA5394.severity = warning
+
+# CA5395: Miss HttpVerb attribute for action methods
+dotnet_diagnostic.CA5395.severity = warning
+
+# CA5396: Set HttpOnly to true for HttpCookie
+dotnet_diagnostic.CA5396.severity = warning
+
+# CA5397: Do not use deprecated SslProtocols values
+dotnet_diagnostic.CA5397.severity = warning
+
+# CA5398: Avoid hardcoded SslProtocols values
+dotnet_diagnostic.CA5398.severity = warning
+
+# CA5399: HttpClients should enable certificate revocation list checks
+dotnet_diagnostic.CA5399.severity = warning
+
+# CA5400: Ensure HttpClient certificate revocation list check is not disabled
+dotnet_diagnostic.CA5400.severity = warning
+
+# CA5401: Do not use CreateEncryptor with non-default IV
+dotnet_diagnostic.CA5401.severity = warning
+
+# CA5402: Use CreateEncryptor with the default IV
+dotnet_diagnostic.CA5402.severity = warning
+
+# CA5403: Do not hard-code certificate
+dotnet_diagnostic.CA5403.severity = warning
+
+# CA5404: Do not disable token validation checks
+dotnet_diagnostic.CA5404.severity = warning
+
+# CA5405: Do not always skip token validation in delegates
+dotnet_diagnostic.CA5405.severity = warning
+
+# CA1032: Implement standard exception constructors
+dotnet_diagnostic.CA1032.severity = warning
+
+# CA1200: Avoid using cref tags with a prefix
+dotnet_diagnostic.CA1200.severity = warning
+
+# CA1309: Use ordinal string comparison
+dotnet_diagnostic.CA1309.severity = warning
+
+# CA1311: Specify a culture or use an invariant version
+dotnet_diagnostic.CA1311.severity = warning
+
+# CA1507: Use nameof to express symbol names
+dotnet_diagnostic.CA1507.severity = warning
+
+# CA1508: Avoid dead conditional code
+dotnet_diagnostic.CA1508.severity = warning
+
+# CA1802: Use literals where appropriate
+dotnet_diagnostic.CA1802.severity = warning
+
+# CA1805: Do not initialize unnecessarily
+dotnet_diagnostic.CA1805.severity = warning
+
+# CA1812: Avoid uninstantiated internal classes
+dotnet_diagnostic.CA1812.severity = warning
+
+# CA1824: Mark assemblies with NeutralResourcesLanguageAttribute
+dotnet_diagnostic.CA1824.severity = warning
+
+# CA1825: Avoid zero-length array allocations
+dotnet_diagnostic.CA1825.severity = warning
+
+# CA1841: Prefer Dictionary.Contains methods
+dotnet_diagnostic.CA1841.severity = warning
+
+# CA1845: Use span-based 'string.Concat'
+dotnet_diagnostic.CA1845.severity = warning
+
+# CA1851: Possible multiple enumerations of 'IEnumerable' collection
+dotnet_diagnostic.CA1851.severity = warning
+
+# CA1855: Prefer 'Clear' over 'Fill'
+dotnet_diagnostic.CA1855.severity = warning
+
+# CA1856: Incorrect usage of ConstantExpected attribute
+dotnet_diagnostic.CA1856.severity = warning
+
+# CA1857: A constant is expected for the parameter
+dotnet_diagnostic.CA1857.severity = warning
+
+# CA1865: Use char overload
+dotnet_diagnostic.CA1865.severity = warning
+
+# CA1866: Use char overload
+dotnet_diagnostic.CA1866.severity = warning
+
+# CA1867: Use char overload
+dotnet_diagnostic.CA1867.severity = warning
+
+# CA1870: Use a cached 'SearchValues' instance
+dotnet_diagnostic.CA1870.severity = warning
+
+# CA2014: Do not use stackalloc in loops
+dotnet_diagnostic.CA2014.severity = warning
+
+# CA2016: Forward the 'CancellationToken' parameter to methods
+dotnet_diagnostic.CA2016.severity = warning
+
+# CA2020: Prevent behavioral change
+dotnet_diagnostic.CA2020.severity = warning
+
+# CA2234: Pass system uri objects instead of strings
+dotnet_diagnostic.CA2234.severity = warning
+
+# CA2252: This API requires opting into preview features
+dotnet_diagnostic.CA2252.severity = warning
+
+# CA2260: Use correct type parameter
+dotnet_diagnostic.CA2260.severity = warning
+
+# CA2352: Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks
+dotnet_diagnostic.CA2352.severity = warning
+
+# CA2353: Unsafe DataSet or DataTable in serializable type
+dotnet_diagnostic.CA2353.severity = warning
+
+# CA2354: Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks
+dotnet_diagnostic.CA2354.severity = warning
+
+# CA2355: Unsafe DataSet or DataTable type found in deserializable object graph
+dotnet_diagnostic.CA2355.severity = warning
+
+# CA2356: Unsafe DataSet or DataTable type in web deserializable object graph
+dotnet_diagnostic.CA2356.severity = warning
+
+# CA2362: Unsafe DataSet or DataTable in auto-generated serializable type can be vulnerable to remote code execution attacks
+dotnet_diagnostic.CA2362.severity = warning
diff --git a/FrostFS.SDK.sln b/FrostFS.SDK.sln
index f0c0d87..9d9fbbe 100644
--- a/FrostFS.SDK.sln
+++ b/FrostFS.SDK.sln
@@ -1,6 +1,8 @@
-Microsoft Visual Studio Solution File, Format Version 12.00
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
VisualStudioVersion = 17.5.002.0
+MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrostFS.SDK.ClientV2", "src\FrostFS.SDK.ClientV2\FrostFS.SDK.ClientV2.csproj", "{50D8F61F-C302-4AC9-8D8A-AB0B8C0988C3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrostFS.SDK.Cryptography", "src\FrostFS.SDK.Cryptography\FrostFS.SDK.Cryptography.csproj", "{3D804F4A-B0B2-47A5-B006-BE447BE64B50}"
@@ -9,6 +11,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrostFS.SDK.ProtosV2", "src
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrostFS.SDK.Tests", "src\FrostFS.SDK.Tests\FrostFS.SDK.Tests.csproj", "{8FDA7E0D-9C75-4874-988E-6592CD28F76C}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2F030ACD-F87C-4E83-9A68-4CC5DF03AD90}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -32,4 +39,7 @@ Global
{8FDA7E0D-9C75-4874-988E-6592CD28F76C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8FDA7E0D-9C75-4874-988E-6592CD28F76C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
EndGlobal
diff --git a/src/FrostFS.SDK.ClientV2/Exceptions/FrostFsException.cs b/src/FrostFS.SDK.ClientV2/Exceptions/FrostFsException.cs
new file mode 100644
index 0000000..ba31b9d
--- /dev/null
+++ b/src/FrostFS.SDK.ClientV2/Exceptions/FrostFsException.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace FrostFS.SDK.ClientV2;
+
+public class FrostFsException : Exception
+{
+ public FrostFsException()
+ {
+ }
+
+ public FrostFsException(string message) : base(message)
+ {
+ }
+
+ public FrostFsException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/FrostFS.SDK.ClientV2/Exceptions/InvalidObjectException.cs b/src/FrostFS.SDK.ClientV2/Exceptions/InvalidObjectException.cs
index f2a8ea7..c15e591 100644
--- a/src/FrostFS.SDK.ClientV2/Exceptions/InvalidObjectException.cs
+++ b/src/FrostFS.SDK.ClientV2/Exceptions/InvalidObjectException.cs
@@ -2,6 +2,17 @@ using System;
namespace FrostFS.SDK.ClientV2;
-public class InvalidObjectException() : Exception()
+public class InvalidObjectException : Exception
{
+ public InvalidObjectException()
+ {
+ }
+
+ public InvalidObjectException(string message) : base(message)
+ {
+ }
+
+ public InvalidObjectException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
}
\ No newline at end of file
diff --git a/src/FrostFS.SDK.ClientV2/Exceptions/ResponseException.cs b/src/FrostFS.SDK.ClientV2/Exceptions/ResponseException.cs
index ad3c63e..ce7f19a 100644
--- a/src/FrostFS.SDK.ClientV2/Exceptions/ResponseException.cs
+++ b/src/FrostFS.SDK.ClientV2/Exceptions/ResponseException.cs
@@ -2,7 +2,24 @@ using System;
namespace FrostFS.SDK.ClientV2;
-public class ResponseException(FrostFsResponseStatus status) : Exception()
+public class ResponseException : Exception
{
- public FrostFsResponseStatus Status { get; set; } = status;
+ public FrostFsResponseStatus? Status { get; private set; }
+
+ public ResponseException()
+ {
+ }
+
+ public ResponseException(FrostFsResponseStatus status)
+ {
+ Status = status;
+ }
+
+ public ResponseException(string message) : base(message)
+ {
+ }
+
+ public ResponseException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
}
\ No newline at end of file
diff --git a/src/FrostFS.SDK.ClientV2/FrostFS.SDK.ClientV2.csproj b/src/FrostFS.SDK.ClientV2/FrostFS.SDK.ClientV2.csproj
index 5f423dd..b16e7e7 100644
--- a/src/FrostFS.SDK.ClientV2/FrostFS.SDK.ClientV2.csproj
+++ b/src/FrostFS.SDK.ClientV2/FrostFS.SDK.ClientV2.csproj
@@ -4,14 +4,23 @@
netstandard2.0
12.0
enable
+ AllEnabledByDefault
-
- true
-
+
+ true
+
+
+
+ true
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/src/FrostFS.SDK.ClientV2/Client.cs b/src/FrostFS.SDK.ClientV2/FrostFSClient.cs
similarity index 79%
rename from src/FrostFS.SDK.ClientV2/Client.cs
rename to src/FrostFS.SDK.ClientV2/FrostFSClient.cs
index 8209571..4a680de 100644
--- a/src/FrostFS.SDK.ClientV2/Client.cs
+++ b/src/FrostFS.SDK.ClientV2/FrostFSClient.cs
@@ -3,6 +3,9 @@ using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
+using Frostfs.V2.Ape;
+using Frostfs.V2.Apemanager;
+
using FrostFS.Container;
using FrostFS.Netmap;
using FrostFS.Object;
@@ -15,35 +18,33 @@ using Grpc.Core.Interceptors;
using Grpc.Net.Client;
using Microsoft.Extensions.Options;
-using Frostfs.V2.Apemanager;
-using Frostfs.V2.Ape;
namespace FrostFS.SDK.ClientV2;
-public class Client : IFrostFSClient
+public class FrostFSClient : IFrostFSClient
{
private bool isDisposed;
-
+
internal ContainerService.ContainerServiceClient? ContainerServiceClient { get; set; }
-
+
internal NetmapService.NetmapServiceClient? NetmapServiceClient { get; set; }
internal APEManagerService.APEManagerServiceClient? ApeManagerServiceClient { get; set; }
internal SessionService.SessionServiceClient? SessionServiceClient { get; set; }
-
+
internal ObjectService.ObjectServiceClient? ObjectServiceClient { get; set; }
internal ClientEnvironment ClientCtx { get; set; }
public static IFrostFSClient GetInstance(IOptions clientOptions, GrpcChannelOptions? channelOptions = null)
{
- return new Client(clientOptions, channelOptions);
+ return new FrostFSClient(clientOptions, channelOptions);
}
public static IFrostFSClient GetSingleOwnerInstance(IOptions clientOptions, GrpcChannelOptions? channelOptions = null)
{
- return new Client(clientOptions, channelOptions);
+ return new FrostFSClient(clientOptions, channelOptions);
}
///
@@ -64,10 +65,15 @@ public class Client : IFrostFSClient
ContainerService.ContainerServiceClient containerService,
ObjectService.ObjectServiceClient objectService)
{
- return new Client(clientOptions, channelOptions, containerService, netmapService, sessionService, objectService);
+ if (clientOptions is null)
+ {
+ throw new ArgumentNullException(nameof(clientOptions));
+ }
+
+ return new FrostFSClient(clientOptions, channelOptions, containerService, netmapService, sessionService, objectService);
}
- private Client(
+ private FrostFSClient(
IOptions settings,
GrpcChannelOptions? channelOptions,
ContainerService.ContainerServiceClient containerService,
@@ -75,6 +81,11 @@ public class Client : IFrostFSClient
SessionService.SessionServiceClient sessionService,
ObjectService.ObjectServiceClient objectService)
{
+ if (settings is null)
+ {
+ throw new ArgumentNullException(nameof(settings));
+ }
+
var ecdsaKey = settings.Value.Key.LoadWif();
FrostFsOwner.FromKey(ecdsaKey);
@@ -85,13 +96,13 @@ public class Client : IFrostFSClient
channel: InitGrpcChannel(settings.Value.Host, channelOptions),
version: new FrostFsVersion(2, 13));
- ContainerServiceClient = containerService;
- NetmapServiceClient = netmapService;
- SessionServiceClient = sessionService;
- ObjectServiceClient = objectService;
+ ContainerServiceClient = containerService ?? throw new ArgumentNullException(nameof(containerService));
+ NetmapServiceClient = netmapService ?? throw new ArgumentNullException(nameof(netmapService));
+ SessionServiceClient = sessionService ?? throw new ArgumentNullException(nameof(sessionService));
+ ObjectServiceClient = objectService ?? throw new ArgumentNullException(nameof(objectService));
}
- private Client(IOptions options, GrpcChannelOptions? channelOptions)
+ private FrostFSClient(IOptions options, GrpcChannelOptions? channelOptions)
{
var clientSettings = (options?.Value) ?? throw new ArgumentException("Options must be initialized");
@@ -110,14 +121,14 @@ public class Client : IFrostFSClient
// CheckFrostFsVersionSupport(new Context { Timeout = TimeSpan.FromSeconds(20) });
}
- private Client(IOptions options, GrpcChannelOptions? channelOptions)
+ private FrostFSClient(IOptions options, GrpcChannelOptions? channelOptions)
{
var clientSettings = (options?.Value) ?? throw new ArgumentException("Options must be initialized");
clientSettings.Validate();
var ecdsaKey = clientSettings.Key.LoadWif();
-
+
var channel = InitGrpcChannel(clientSettings.Host, channelOptions);
ClientCtx = new ClientEnvironment(
@@ -128,7 +139,7 @@ public class Client : IFrostFSClient
version: new FrostFsVersion(2, 13));
// TODO: define timeout logic
- CheckFrostFsVersionSupport(new Context { Timeout = TimeSpan.FromSeconds(20)});
+ // CheckFrostFsVersionSupport(new Context { Timeout = TimeSpan.FromSeconds(20) });
}
public void Dispose()
@@ -149,18 +160,31 @@ public class Client : IFrostFSClient
#region ApeManagerImplementation
public Task AddChainAsync(PrmApeChainAdd args)
{
+ if (args is null)
+ {
+ throw new ArgumentNullException(nameof(args));
+ }
+
var service = GetApeManagerService(args);
return service.AddChainAsync(args);
}
public Task RemoveChainAsync(PrmApeChainRemove args)
{
+ if (args is null)
+ {
+ throw new ArgumentNullException(nameof(args));
+ }
+
var service = GetApeManagerService(args);
return service.RemoveChainAsync(args);
}
public Task ListChainAsync(PrmApeChainList args)
{
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
var service = GetApeManagerService(args);
return service.ListChainAsync(args);
}
@@ -169,6 +193,9 @@ public class Client : IFrostFSClient
#region ContainerImplementation
public Task GetContainerAsync(PrmContainerGet args)
{
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
var service = GetContainerService(args);
return service.GetContainerAsync(args);
}
@@ -176,18 +203,24 @@ public class Client : IFrostFSClient
public IAsyncEnumerable ListContainersAsync(PrmContainerGetAll? args = null)
{
args ??= new PrmContainerGetAll();
- var service = GetContainerService(args);
+ var service = GetContainerService(args);
return service.ListContainersAsync(args);
}
public Task CreateContainerAsync(PrmContainerCreate args)
{
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
var service = GetContainerService(args);
return service.CreateContainerAsync(args);
}
public Task DeleteContainerAsync(PrmContainerDelete args)
{
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
var service = GetContainerService(args);
return service.DeleteContainerAsync(args);
}
@@ -219,36 +252,54 @@ public class Client : IFrostFSClient
#region ObjectImplementation
public Task GetObjectHeadAsync(PrmObjectHeadGet args)
{
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
var service = GetObjectService(args);
return service.GetObjectHeadAsync(args);
}
public Task GetObjectAsync(PrmObjectGet args)
{
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
var service = GetObjectService(args);
return service.GetObjectAsync(args);
}
public Task PutObjectAsync(PrmObjectPut args)
{
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
var service = GetObjectService(args);
return service.PutObjectAsync(args);
}
public Task PutSingleObjectAsync(PrmSingleObjectPut args)
{
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
var service = GetObjectService(args);
return service.PutSingleObjectAsync(args);
}
public Task DeleteObjectAsync(PrmObjectDelete args)
{
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
var service = GetObjectService(args);
return service.DeleteObjectAsync(args);
}
public IAsyncEnumerable SearchObjectsAsync(PrmObjectSearch args)
{
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
var service = GetObjectService(args);
return service.SearchObjectsAsync(args);
}
@@ -257,17 +308,23 @@ public class Client : IFrostFSClient
#region SessionImplementation
public async Task CreateSessionAsync(PrmSessionCreate args)
{
- var session = await CreateSessionInternalAsync(args);
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
+ var session = await CreateSessionInternalAsync(args).ConfigureAwait(false);
var token = session.Serialize();
-
+
return new FrostFsSessionToken(token);
}
- internal Task CreateSessionInternalAsync(PrmSessionCreate args)
+ internal Task CreateSessionInternalAsync(PrmSessionCreate args)
{
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
var service = GetSessionService(args);
return service.CreateSessionAsync(args);
- }
+ }
#endregion
#region ToolsImplementation
@@ -283,20 +340,24 @@ public class Client : IFrostFSClient
private async void CheckFrostFsVersionSupport(Context? ctx = default)
{
var args = new PrmNodeInfo { Context = ctx };
+
+ if (ctx?.Version == null)
+ throw new InvalidObjectException(nameof(ctx.Version));
+
var service = GetNetmapService(args);
- var localNodeInfo = await service.GetLocalNodeInfoAsync(args);
-
- if (!localNodeInfo.Version.IsSupported(args.Context!.Version))
+ var localNodeInfo = await service.GetLocalNodeInfoAsync(args).ConfigureAwait(false);
+
+ if (!localNodeInfo.Version.IsSupported(ctx.Version))
{
var msg = $"FrostFS {localNodeInfo.Version} is not supported.";
- throw new ApplicationException(msg);
+ throw new FrostFsException(msg);
}
}
private CallInvoker? SetupEnvironment(IContext ctx)
{
if (isDisposed)
- throw new Exception("Client is disposed.");
+ throw new InvalidObjectException("Client is disposed.");
ctx.Context ??= new Context();
@@ -304,14 +365,14 @@ public class Client : IFrostFSClient
{
if (ClientCtx.Key == null)
{
- throw new Exception("Key is not initialized.");
+ throw new InvalidObjectException("Key is not initialized.");
}
ctx.Context.Key = ClientCtx.Key.ECDsaKey;
}
if (ctx.Context.OwnerId == null)
- {
+ {
ctx.Context.OwnerId = ClientCtx.Owner ?? FrostFsOwner.FromKey(ctx.Context.Key);
}
@@ -319,7 +380,7 @@ public class Client : IFrostFSClient
{
if (ClientCtx.Version == null)
{
- throw new Exception("Version is not initialized.");
+ throw new InvalidObjectException("Version is not initialized.");
}
ctx.Context.Version = ClientCtx.Version;
@@ -336,7 +397,7 @@ public class Client : IFrostFSClient
if (ctx.Context.Callback != null)
callInvoker = AddInvoker(callInvoker, new MetricsInterceptor(ctx.Context.Callback));
-
+
return callInvoker;
CallInvoker AddInvoker(CallInvoker? callInvoker, Interceptor interceptor)
@@ -382,7 +443,7 @@ public class Client : IFrostFSClient
private ContainerServiceProvider GetContainerService(IContext ctx)
{
- var callInvoker = SetupEnvironment(ctx);
+ var callInvoker = SetupEnvironment(ctx);
var client = ContainerServiceClient ?? (callInvoker != null
? new ContainerService.ContainerServiceClient(callInvoker)
: new ContainerService.ContainerServiceClient(ClientCtx.Channel));
@@ -408,7 +469,7 @@ public class Client : IFrostFSClient
if (channelOptions != null)
return GrpcChannel.ForAddress(uri, channelOptions);
-
+
return GrpcChannel.ForAddress(uri, new GrpcChannelOptions
{
HttpHandler = new HttpClientHandler()
diff --git a/src/FrostFS.SDK.ClientV2/Interceptors/MetricsInterceptor.cs b/src/FrostFS.SDK.ClientV2/Interceptors/MetricsInterceptor.cs
index dc439f9..9b3199c 100644
--- a/src/FrostFS.SDK.ClientV2/Interceptors/MetricsInterceptor.cs
+++ b/src/FrostFS.SDK.ClientV2/Interceptors/MetricsInterceptor.cs
@@ -14,6 +14,11 @@ public class MetricsInterceptor(Action callback) : Interceptor
ClientInterceptorContext context,
AsyncUnaryCallContinuation continuation)
{
+ if (continuation is null)
+ {
+ throw new ArgumentNullException(nameof(continuation));
+ }
+
var call = continuation(request, context);
return new AsyncUnaryCall(
@@ -28,7 +33,10 @@ public class MetricsInterceptor(Action callback) : Interceptor
ClientInterceptorContext context,
AsyncClientStreamingCallContinuation continuation)
{
- var call = continuation(context);
+ if (continuation is null)
+ throw new ArgumentNullException(nameof(continuation));
+
+ var call = continuation(context);
return new AsyncClientStreamingCall(
call.RequestStream,
@@ -43,31 +51,31 @@ public class MetricsInterceptor(Action callback) : Interceptor
{
var watch = new Stopwatch();
watch.Start();
-
- var response = await call.ResponseAsync;
+
+ var response = await call.ResponseAsync.ConfigureAwait(false);
watch.Stop();
- var elapsed = watch.ElapsedTicks * 1_000_000/Stopwatch.Frequency;
+ var elapsed = watch.ElapsedTicks * 1_000_000 / Stopwatch.Frequency;
callback(new CallStatistics { MethodName = call.ToString(), ElapsedMicroSeconds = elapsed });
- return response;
+ return response;
}
private async Task HandleStreamResponse(AsyncClientStreamingCall call)
{
var watch = new Stopwatch();
watch.Start();
-
- var response = await call.ResponseAsync;
+
+ var response = await call.ResponseAsync.ConfigureAwait(false);
watch.Stop();
- var elapsed = watch.ElapsedTicks * 1_000_000/Stopwatch.Frequency;
+ var elapsed = watch.ElapsedTicks * 1_000_000 / Stopwatch.Frequency;
callback(new CallStatistics { MethodName = call.ToString(), ElapsedMicroSeconds = elapsed });
- return response;
+ return response;
}
}
diff --git a/src/FrostFS.SDK.ClientV2/Interfaces/IFrostFSClient.cs b/src/FrostFS.SDK.ClientV2/Interfaces/IFrostFSClient.cs
index a580149..3af0c0b 100644
--- a/src/FrostFS.SDK.ClientV2/Interfaces/IFrostFSClient.cs
+++ b/src/FrostFS.SDK.ClientV2/Interfaces/IFrostFSClient.cs
@@ -36,21 +36,21 @@ public interface IFrostFSClient : IDisposable
Task DeleteContainerAsync(PrmContainerDelete args);
#endregion
-
+
#region Object
Task GetObjectHeadAsync(PrmObjectHeadGet args);
Task GetObjectAsync(PrmObjectGet args);
Task PutObjectAsync(PrmObjectPut args);
-
+
Task PutSingleObjectAsync(PrmSingleObjectPut args);
Task DeleteObjectAsync(PrmObjectDelete args);
IAsyncEnumerable SearchObjectsAsync(PrmObjectSearch args);
#endregion
-
+
#region Tools
FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header, Context ctx);
#endregion
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/Container.cs b/src/FrostFS.SDK.ClientV2/Mappers/Container.cs
index 181de40..e631472 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/Container.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/Container.cs
@@ -9,14 +9,12 @@ public static class ContainerMapper
{
public static FrostFsContainerInfo ToModel(this Container.Container container)
{
- if (!Enum.IsDefined(typeof(BasicAcl),(int)container.BasicAcl))
- throw new ArgumentException($"Unknown BasicACL rule. Value: '{container.BasicAcl}'.");
-
- BasicAcl acl = (BasicAcl)container.BasicAcl;
+ if (container == null)
+ throw new ArgumentNullException(nameof(container));
- return new FrostFsContainerInfo(acl,
+ return new FrostFsContainerInfo(
container.PlacementPolicy.ToModel(),
- container.Attributes?.Select(a => new FrostFsAttribute(a.Key, a.Value)).ToList(),
+ container.Attributes?.Select(a => new FrostFsAttributePair(a.Key, a.Value)).ToArray(),
container.Version?.ToModel(),
container.OwnerId?.ToModel(),
container.Nonce?.ToUuid());
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/ContainerId.cs b/src/FrostFS.SDK.ClientV2/Mappers/ContainerId.cs
index f5feccc..86449e2 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/ContainerId.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/ContainerId.cs
@@ -17,19 +17,23 @@ public static class ContainerIdMapper
public static ContainerID ToMessage(this FrostFsContainerId model)
{
- if (model.Value == null)
+ if (model is null)
+ {
throw new ArgumentNullException(nameof(model));
-
- if (!Cache.Containers.TryGetValue(model.Value, out ContainerID? message))
+ }
+
+ var containerId = model.GetValue() ?? throw new ArgumentNullException(nameof(model));
+
+ if (!Cache.Containers.TryGetValue(containerId, out ContainerID? message))
{
message = new ContainerID
{
- Value = ByteString.CopyFrom(Base58.Decode(model.Value))
+ Value = ByteString.CopyFrom(Base58.Decode(containerId))
};
- Cache.Containers.Set(model.Value, message, _oneHourExpiration);
+ Cache.Containers.Set(containerId, message, _oneHourExpiration);
}
- return message!;
+ return message!;
}
}
\ No newline at end of file
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/MetaHeader.cs b/src/FrostFS.SDK.ClientV2/Mappers/MetaHeader.cs
index 6b4901c..5bf994e 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/MetaHeader.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/MetaHeader.cs
@@ -1,3 +1,5 @@
+using System;
+
using FrostFS.Session;
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
@@ -6,11 +8,16 @@ public static class MetaHeaderMapper
{
public static RequestMetaHeader ToMessage(this MetaHeader metaHeader)
{
+ if (metaHeader is null)
+ {
+ throw new ArgumentNullException(nameof(metaHeader));
+ }
+
return new RequestMetaHeader
{
Version = metaHeader.Version.ToMessage(),
Epoch = (uint)metaHeader.Epoch,
Ttl = (uint)metaHeader.Ttl
};
- }
+ }
}
\ No newline at end of file
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/Netmap/Netmap.cs b/src/FrostFS.SDK.ClientV2/Mappers/Netmap/Netmap.cs
index 31a8a0f..6729501 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/Netmap/Netmap.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/Netmap/Netmap.cs
@@ -1,3 +1,4 @@
+using System;
using System.Linq;
using FrostFS.Netmap;
@@ -8,6 +9,11 @@ public static class NetmapMapper
{
public static FrostFsNetmapSnapshot ToModel(this NetmapSnapshotResponse netmap)
{
+ if (netmap is null)
+ {
+ throw new ArgumentNullException(nameof(netmap));
+ }
+
return new FrostFsNetmapSnapshot(
netmap.Body.Netmap.Epoch,
netmap.Body.Netmap.Nodes
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/Netmap/NodeInfo.cs b/src/FrostFS.SDK.ClientV2/Mappers/Netmap/NodeInfo.cs
index 86e5ff0..d882127 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/Netmap/NodeInfo.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/Netmap/NodeInfo.cs
@@ -10,11 +10,21 @@ public static class NodeInfoMapper
{
public static FrostFsNodeInfo ToModel(this LocalNodeInfoResponse.Types.Body node)
{
+ if (node is null)
+ {
+ throw new ArgumentNullException(nameof(node));
+ }
+
return node.NodeInfo.ToModel(node.Version);
}
public static FrostFsNodeInfo ToModel(this NodeInfo nodeInfo, Refs.Version version)
{
+ if (nodeInfo is null)
+ {
+ throw new ArgumentNullException(nameof(nodeInfo));
+ }
+
NodeState state = nodeInfo.State switch
{
NodeInfo.Types.State.Unspecified => NodeState.Unspecified,
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/Netmap/PlacementPolicy.cs b/src/FrostFS.SDK.ClientV2/Mappers/Netmap/PlacementPolicy.cs
index 2f66ed8..c44a397 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/Netmap/PlacementPolicy.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/Netmap/PlacementPolicy.cs
@@ -1,3 +1,4 @@
+using System;
using System.Linq;
using FrostFS.Netmap;
@@ -6,26 +7,13 @@ namespace FrostFS.SDK.ClientV2;
public static class PlacementPolicyMapper
{
- public static PlacementPolicy ToMessage(this FrostFsPlacementPolicy placementPolicy)
- {
- var pp = new PlacementPolicy
- {
- Filters = { },
- Selectors = { },
- Replicas = { },
- Unique = placementPolicy.Unique
- };
-
- foreach (var replica in placementPolicy.Replicas)
- {
- pp.Replicas.Add(replica.ToMessage());
- }
-
- return pp;
- }
-
public static FrostFsPlacementPolicy ToModel(this PlacementPolicy placementPolicy)
{
+ if (placementPolicy is null)
+ {
+ throw new ArgumentNullException(nameof(placementPolicy));
+ }
+
return new FrostFsPlacementPolicy(
placementPolicy.Unique,
placementPolicy.Replicas.Select(replica => replica.ToModel()).ToArray()
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/Netmap/Replica.cs b/src/FrostFS.SDK.ClientV2/Mappers/Netmap/Replica.cs
index 422891d..d9ea0cd 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/Netmap/Replica.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/Netmap/Replica.cs
@@ -1,3 +1,5 @@
+using System;
+
using FrostFS.Netmap;
namespace FrostFS.SDK.ClientV2;
@@ -15,6 +17,11 @@ public static class ReplicaMapper
public static FrostFsReplica ToModel(this Replica replica)
{
+ if (replica is null)
+ {
+ throw new ArgumentNullException(nameof(replica));
+ }
+
return new FrostFsReplica((int)replica.Count, replica.Selector);
}
}
\ No newline at end of file
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/Object/Object.cs b/src/FrostFS.SDK.ClientV2/Mappers/Object/Object.cs
index 0e10ffe..d9f5d13 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/Object/Object.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/Object/Object.cs
@@ -8,5 +8,5 @@ internal static class ObjectMapper
{
ObjectId = FrostFsObjectId.FromHash(obj.ObjectId.Value.ToByteArray())
};
- }
+ }
}
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectAttributeMapper.cs b/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectAttributeMapper.cs
index de596ad..85c7c5a 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectAttributeMapper.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectAttributeMapper.cs
@@ -1,11 +1,18 @@
+using System;
+
using FrostFS.Object;
namespace FrostFS.SDK.ClientV2.Mappers.GRPC;
public static class ObjectAttributeMapper
{
- public static Header.Types.Attribute ToMessage(this FrostFsAttribute attribute)
+ public static Header.Types.Attribute ToMessage(this FrostFsAttributePair attribute)
{
+ if (attribute is null)
+ {
+ throw new ArgumentNullException(nameof(attribute));
+ }
+
return new Header.Types.Attribute
{
Key = attribute.Key,
@@ -13,8 +20,13 @@ public static class ObjectAttributeMapper
};
}
- public static FrostFsAttribute ToModel(this Header.Types.Attribute attribute)
+ public static FrostFsAttributePair ToModel(this Header.Types.Attribute attribute)
{
- return new FrostFsAttribute(attribute.Key, attribute.Value);
+ if (attribute is null)
+ {
+ throw new ArgumentNullException(nameof(attribute));
+ }
+
+ return new FrostFsAttributePair(attribute.Key, attribute.Value);
}
}
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectFilterMapper.cs b/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectFilterMapper.cs
index 0303213..76d1c92 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectFilterMapper.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectFilterMapper.cs
@@ -8,6 +8,11 @@ public static class ObjectFilterMapper
{
public static SearchRequest.Types.Body.Types.Filter ToMessage(this IObjectFilter filter)
{
+ if (filter is null)
+ {
+ throw new ArgumentNullException(nameof(filter));
+ }
+
var objMatchTypeName = filter.MatchType switch
{
FrostFsMatchType.Unspecified => MatchType.Unspecified,
@@ -25,5 +30,5 @@ public static class ObjectFilterMapper
Key = filter.Key,
Value = filter.GetSerializedValue()
};
- }
+ }
}
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectHeaderMapper.cs b/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectHeaderMapper.cs
index fb4c77d..bdeb862 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectHeaderMapper.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectHeaderMapper.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.ObjectModel;
using System.Linq;
using FrostFS.Object;
@@ -10,6 +11,11 @@ public static class ObjectHeaderMapper
{
public static FrostFsObjectHeader ToModel(this Header header)
{
+ if (header is null)
+ {
+ throw new ArgumentNullException(nameof(header));
+ }
+
var objTypeName = header.ObjectType switch
{
ObjectType.Regular => FrostFsObjectType.Regular,
@@ -22,15 +28,15 @@ public static class ObjectHeaderMapper
if (header.Split != null)
{
- split = new FrostFsSplit(new SplitId(header.Split.SplitId.ToUuid()))
- {
- Parent = header.Split.Parent?.ToModel(),
- ParentHeader = header.Split.ParentHeader?.ToModel(),
- Previous = header.Split.Previous?.ToModel()
- };
+ var children = header.Split.Children.Count != 0 ? new ReadOnlyCollection(
+ header.Split.Children.Select(x => x.ToModel()).ToList()) : null;
- if (header.Split.Children.Count != 0)
- split.Children.AddRange(header.Split.Children.Select(x => x.ToModel()));
+ split = new FrostFsSplit(new SplitId(header.Split.SplitId.ToUuid()),
+ header.Split.Previous?.ToModel(),
+ header.Split.Parent?.ToModel(),
+ header.Split.ParentHeader?.ToModel(),
+ null,
+ children);
}
var model = new FrostFsObjectHeader(
@@ -40,10 +46,10 @@ public static class ObjectHeaderMapper
split,
header.OwnerId.ToModel(),
header.Version.ToModel())
- {
+ {
PayloadLength = header.PayloadLength,
};
return model;
- }
+ }
}
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectId.cs b/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectId.cs
index d20a915..10f8409 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectId.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/Object/ObjectId.cs
@@ -1,3 +1,5 @@
+using System;
+
using FrostFS.Refs;
using Google.Protobuf;
@@ -8,6 +10,11 @@ public static class ObjectIdMapper
{
public static ObjectID ToMessage(this FrostFsObjectId objectId)
{
+ if (objectId is null)
+ {
+ throw new ArgumentNullException(nameof(objectId));
+ }
+
return new ObjectID
{
Value = ByteString.CopyFrom(objectId.ToHash())
@@ -16,6 +23,11 @@ public static class ObjectIdMapper
public static FrostFsObjectId ToModel(this ObjectID objectId)
{
+ if (objectId is null)
+ {
+ throw new ArgumentNullException(nameof(objectId));
+ }
+
return FrostFsObjectId.FromHash(objectId.Value.ToByteArray());
}
}
\ No newline at end of file
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/OwnerId.cs b/src/FrostFS.SDK.ClientV2/Mappers/OwnerId.cs
index ff81321..6f3276d 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/OwnerId.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/OwnerId.cs
@@ -17,6 +17,11 @@ public static class OwnerIdMapper
public static OwnerID ToMessage(this FrostFsOwner model)
{
+ if (model is null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+
if (!Cache.Owners.TryGetValue(model, out OwnerID? message))
{
message = new OwnerID
@@ -32,10 +37,15 @@ public static class OwnerIdMapper
public static FrostFsOwner ToModel(this OwnerID message)
{
+ if (message is null)
+ {
+ throw new ArgumentNullException(nameof(message));
+ }
+
if (!Cache.Owners.TryGetValue(message, out FrostFsOwner? model))
{
model = new FrostFsOwner(Base58.Encode(message.Value.ToByteArray()));
-
+
Cache.Owners.Set(message, model, _oneHourExpiration);
}
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/Session/SessionMapper.cs b/src/FrostFS.SDK.ClientV2/Mappers/Session/SessionMapper.cs
index 97b1c69..9f4a36f 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/Session/SessionMapper.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/Session/SessionMapper.cs
@@ -1,3 +1,5 @@
+using System;
+
using Google.Protobuf;
namespace FrostFS.SDK.ClientV2;
@@ -6,8 +8,13 @@ public static class SessionMapper
{
public static byte[] Serialize(this Session.SessionToken token)
{
+ if (token is null)
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
byte[] bytes = new byte[token.CalculateSize()];
- CodedOutputStream stream = new(bytes);
+ using CodedOutputStream stream = new(bytes);
token.WriteTo(stream);
return bytes;
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/SignatureMapper.cs b/src/FrostFS.SDK.ClientV2/Mappers/SignatureMapper.cs
index 0b280cf..d3bf988 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/SignatureMapper.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/SignatureMapper.cs
@@ -8,13 +8,17 @@ public static class SignatureMapper
{
public static Refs.Signature ToMessage(this FrostFsSignature signature)
{
+ if (signature is null)
+ {
+ throw new ArgumentNullException(nameof(signature));
+ }
+
var scheme = signature.Scheme switch
{
SignatureScheme.EcdsaRfc6979Sha256 => Refs.SignatureScheme.EcdsaRfc6979Sha256,
SignatureScheme.EcdsaRfc6979Sha256WalletConnect => Refs.SignatureScheme.EcdsaRfc6979Sha256WalletConnect,
SignatureScheme.EcdsaSha512 => Refs.SignatureScheme.EcdsaSha512,
- _ => throw new ArgumentException(message: $"Unexpected enum value: {signature.Scheme}",
- paramName: nameof(signature.Scheme))
+ _ => throw new ArgumentException(nameof(signature.Scheme), $"Unexpected enum value: {signature.Scheme}")
};
return new Refs.Signature
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/Status.cs b/src/FrostFS.SDK.ClientV2/Mappers/Status.cs
index d3555ac..ad9ea7d 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/Status.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/Status.cs
@@ -6,7 +6,7 @@ public static class StatusMapper
{
public static FrostFsResponseStatus ToModel(this Status.Status status)
{
- if (status is null)
+ if (status is null)
return new FrostFsResponseStatus(FrostFsStatusCode.Success);
var codeName = Enum.GetName(typeof(FrostFsStatusCode), status.Code);
diff --git a/src/FrostFS.SDK.ClientV2/Mappers/Version.cs b/src/FrostFS.SDK.ClientV2/Mappers/Version.cs
index f17509a..d4cc254 100644
--- a/src/FrostFS.SDK.ClientV2/Mappers/Version.cs
+++ b/src/FrostFS.SDK.ClientV2/Mappers/Version.cs
@@ -9,10 +9,15 @@ public static class VersionMapper
{
private static readonly Hashtable _cacheMessages = [];
private static readonly Hashtable _cacheModels = [];
- private static SpinLock _spinlock = new();
+ private static SpinLock _spinlock;
public static Version ToMessage(this FrostFsVersion model)
{
+ if (model is null)
+ {
+ throw new System.ArgumentNullException(nameof(model));
+ }
+
var key = model.Major << 16 + model.Minor;
if (!_cacheMessages.ContainsKey(key))
@@ -46,6 +51,11 @@ public static class VersionMapper
public static FrostFsVersion ToModel(this Version message)
{
+ if (message is null)
+ {
+ throw new System.ArgumentNullException(nameof(message));
+ }
+
var key = (int)message.Major << 16 + (int)message.Minor;
if (!_cacheModels.ContainsKey(key))
diff --git a/src/FrostFS.SDK.ClientV2/Models/Chain/ChainTarget.cs b/src/FrostFS.SDK.ClientV2/Models/Chain/ChainTarget.cs
index 0d47993..e9ce527 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Chain/ChainTarget.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Chain/ChainTarget.cs
@@ -4,7 +4,7 @@ using Frostfs.V2.Ape;
namespace FrostFS.SDK.ClientV2
{
- public struct FrostFsChainTarget(FrostFsTargetType type, string name)
+ public struct FrostFsChainTarget(FrostFsTargetType type, string name) : IEquatable
{
private ChainTarget? chainTarget;
@@ -33,5 +33,31 @@ namespace FrostFS.SDK.ClientV2
_ => throw new ArgumentException("Unexpected value for TargetType", nameof(type)),
};
}
+
+ public override readonly bool Equals(object obj)
+ {
+ var target = (FrostFsChainTarget)obj;
+ return Equals(target);
+ }
+
+ public override readonly int GetHashCode()
+ {
+ return $"{Name}{Type}".GetHashCode();
+ }
+
+ public static bool operator ==(FrostFsChainTarget left, FrostFsChainTarget right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(FrostFsChainTarget left, FrostFsChainTarget right)
+ {
+ return !(left == right);
+ }
+
+ public readonly bool Equals(FrostFsChainTarget other)
+ {
+ return Type == other.Type && Name.Equals(other.Name, StringComparison.Ordinal);
+ }
}
}
diff --git a/src/FrostFS.SDK.ClientV2/Models/Chain/FrostFsChain.cs b/src/FrostFS.SDK.ClientV2/Models/Chain/FrostFsChain.cs
index 0c21521..d6b4b1d 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Chain/FrostFsChain.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Chain/FrostFsChain.cs
@@ -2,7 +2,7 @@
namespace FrostFS.SDK.ClientV2
{
- public struct FrostFsChain (byte[] raw)
+ public struct FrostFsChain(byte[] raw) : System.IEquatable
{
private ByteString? grpcRaw;
@@ -12,5 +12,31 @@ namespace FrostFS.SDK.ClientV2
{
return grpcRaw ??= ByteString.CopyFrom(Raw);
}
+
+ public override readonly bool Equals(object obj)
+ {
+ var chain = (FrostFsChain)obj;
+ return Equals(chain);
+ }
+
+ public override readonly int GetHashCode()
+ {
+ return Raw.GetHashCode();
+ }
+
+ public static bool operator ==(FrostFsChain left, FrostFsChain right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(FrostFsChain left, FrostFsChain right)
+ {
+ return !(left == right);
+ }
+
+ public readonly bool Equals(FrostFsChain other)
+ {
+ return Raw == other.Raw;
+ }
}
}
diff --git a/src/FrostFS.SDK.ClientV2/Models/Chain/FrostFsTargetType.cs b/src/FrostFS.SDK.ClientV2/Models/Chain/FrostFsTargetType.cs
index 56617d3..03b1521 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Chain/FrostFsTargetType.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Chain/FrostFsTargetType.cs
@@ -1,6 +1,6 @@
namespace FrostFS.SDK.ClientV2
{
- public enum FrostFsTargetType
+ public enum FrostFsTargetType
{
Undefined = 0,
Namespace,
diff --git a/src/FrostFS.SDK.ClientV2/Models/Client/ClientSettings.cs b/src/FrostFS.SDK.ClientV2/Models/Client/ClientSettings.cs
index 650c7d6..b1faf79 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Client/ClientSettings.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Client/ClientSettings.cs
@@ -1,5 +1,6 @@
using System;
-using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Globalization;
using System.Text;
namespace FrostFS.SDK;
@@ -17,18 +18,24 @@ public class ClientSettings
ThrowException(errors);
}
- protected List? CheckFields()
+ protected Collection? CheckFields()
{
- List? errors = null;
-
if (string.IsNullOrWhiteSpace(Host))
- (errors ??= []).Add(string.Format(errorTemplate, nameof(Host)));
+ {
+ var error = string.Format(CultureInfo.InvariantCulture, errorTemplate, nameof(Host));
+ return new Collection([error]);
+ }
- return errors;
+ return null;
}
- protected static void ThrowException(List errors)
+ protected static void ThrowException(Collection errors)
{
+ if (errors is null)
+ {
+ throw new ArgumentNullException(nameof(errors));
+ }
+
StringBuilder messages = new();
foreach (var error in errors)
@@ -51,12 +58,12 @@ public class SingleOwnerClientSettings : ClientSettings
ThrowException(errors);
}
- protected new List? CheckFields()
+ protected new Collection? CheckFields()
{
- List? errors = base.CheckFields();
+ Collection? errors = base.CheckFields();
if (string.IsNullOrWhiteSpace(Key))
- (errors ??= []).Add(string.Format(errorTemplate, nameof(Key)));
+ (errors ??= []).Add(string.Format(CultureInfo.InvariantCulture, errorTemplate, nameof(Key)));
return errors;
}
diff --git a/src/FrostFS.SDK.ClientV2/Models/Containers/FrostFsContainerId.cs b/src/FrostFS.SDK.ClientV2/Models/Containers/FrostFsContainerId.cs
index 895f25a..1ebbe04 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Containers/FrostFsContainerId.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Containers/FrostFsContainerId.cs
@@ -1,8 +1,7 @@
using FrostFS.Refs;
-using FrostFS.SDK.Cryptography;
-
-using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.SDK.ClientV2;
+using FrostFS.SDK.ClientV2.Mappers.GRPC;
+using FrostFS.SDK.Cryptography;
namespace FrostFS.SDK;
@@ -21,21 +20,18 @@ public class FrostFsContainerId
this.containerID = id;
}
- public string Value
+ public string GetValue()
{
- get
+ if (this.modelId != null)
+ return this.modelId;
+
+ if (containerID != null)
{
- if (this.modelId != null)
- return this.modelId;
-
- if (containerID != null)
- {
- this.modelId = Base58.Encode(containerID.Value.ToByteArray());
- return this.modelId;
- }
-
- throw new InvalidObjectException();
+ this.modelId = Base58.Encode(containerID.Value.ToByteArray());
+ return this.modelId;
}
+
+ throw new InvalidObjectException();
}
internal ContainerID ContainerID
@@ -57,6 +53,6 @@ public class FrostFsContainerId
public override string ToString()
{
- return Value;
+ return GetValue();
}
}
\ No newline at end of file
diff --git a/src/FrostFS.SDK.ClientV2/Models/Containers/FrostFsContainerInfo.cs b/src/FrostFS.SDK.ClientV2/Models/Containers/FrostFsContainerInfo.cs
index 74d0e41..e7336b2 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Containers/FrostFsContainerInfo.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Containers/FrostFsContainerInfo.cs
@@ -1,10 +1,10 @@
using System;
-using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Linq;
using FrostFS.SDK.ClientV2;
-using FrostFS.SDK.Cryptography;
using FrostFS.SDK.ClientV2.Mappers.GRPC;
+using FrostFS.SDK.Cryptography;
using Google.Protobuf;
@@ -12,61 +12,59 @@ namespace FrostFS.SDK;
public class FrostFsContainerInfo
{
- private FrostFS.Container.Container.Types.Attribute[]? grpsAttributes;
- private List? attributes;
+ private Container.Container.Types.Attribute[]? grpsAttributes;
+ private ReadOnlyCollection? attributes;
private FrostFsPlacementPolicy? placementPolicy;
private Guid? nonce;
- private Container.Container container;
+ private Container.Container? container;
public FrostFsContainerInfo(
- BasicAcl basicAcl,
FrostFsPlacementPolicy placementPolicy,
- List? attributes = null,
+ FrostFsAttributePair[]? attributes = null,
FrostFsVersion? version = null,
FrostFsOwner? owner = null,
Guid? nonce = null)
{
- BasicAcl = basicAcl;
this.placementPolicy = placementPolicy;
- this.attributes = attributes;
Version = version;
Owner = owner;
this.nonce = nonce;
+
+ if (attributes != null)
+ this.attributes = new ReadOnlyCollection(attributes);
}
internal FrostFsContainerInfo(Container.Container container)
{
this.container = container;
}
-
- public Guid Nonce
+
+ public Guid Nonce
{
get
{
nonce ??= container?.Nonce != null ? container.Nonce.ToUuid() : Guid.NewGuid();
return nonce.Value;
}
- }
-
- public BasicAcl BasicAcl { get; private set; }
+ }
public FrostFsPlacementPolicy? PlacementPolicy
{
get
{
- placementPolicy ??= container.PlacementPolicy?.ToModel();
+ placementPolicy ??= container?.PlacementPolicy?.ToModel();
return placementPolicy;
}
}
- public List? Attributes
+ public ReadOnlyCollection? Attributes
{
get
{
if (attributes == null && grpsAttributes != null)
- attributes = grpsAttributes.Select(a => new FrostFsAttribute(a.Key, a.Value)).ToList();
-
+ attributes = new ReadOnlyCollection(grpsAttributes.Select(a => new FrostFsAttributePair(a.Key, a.Value)).ToList());
+
return attributes;
}
}
@@ -74,8 +72,8 @@ public class FrostFsContainerInfo
public FrostFsVersion? Version { get; private set; }
public FrostFsOwner? Owner { get; private set; }
-
- internal Container.Container.Types.Attribute[]? GetGrpsAttributes()
+
+ internal Container.Container.Types.Attribute[]? GetGrpsAttributes()
{
grpsAttributes ??= Attributes?
.Select(a => new Container.Container.Types.Attribute { Key = a.Key, Value = a.Value })
@@ -88,10 +86,14 @@ public class FrostFsContainerInfo
{
if (this.container == null)
{
+ if (PlacementPolicy == null)
+ {
+ throw new InvalidObjectException("PlacementPolicy is null");
+ }
+
this.container = new Container.Container()
{
- BasicAcl = (uint)BasicAcl,
- PlacementPolicy = PlacementPolicy.ToMessage(),
+ PlacementPolicy = PlacementPolicy.Value.GetPolicy(),
Nonce = ByteString.CopyFrom(Nonce.ToBytes()),
OwnerId = Owner?.OwnerID,
Version = Version?.Version
diff --git a/src/FrostFS.SDK.ClientV2/Models/Enums/BasicAcl.cs b/src/FrostFS.SDK.ClientV2/Models/Enums/BasicAcl.cs
deleted file mode 100644
index dd3252b..0000000
--- a/src/FrostFS.SDK.ClientV2/Models/Enums/BasicAcl.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.ComponentModel;
-
-namespace FrostFS.SDK;
-
-public enum BasicAcl
-{
- [Description("Not defined ACL")]
- NotDefined = 0x00000000,
-
- [Description("Basic ACL for private container")]
- Private = 0x1C8C8CCC,
-
- [Description("Basic ACL for public RO container")]
- PublicRO = 0x1FBF8CFF,
-
- [Description("Basic ACL for public RW container")]
- PublicRW = 0x1FBFBFFF,
-
- [Description("Basic ACL for public append container")]
- PublicAppend = 0x1FBF9FFF,
-}
\ No newline at end of file
diff --git a/src/FrostFS.SDK.ClientV2/Models/Misc/CheckSum.cs b/src/FrostFS.SDK.ClientV2/Models/Misc/CheckSum.cs
index 82017f9..fdeac99 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Misc/CheckSum.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Misc/CheckSum.cs
@@ -1,20 +1,21 @@
-using FrostFS.SDK.Cryptography;
using System;
+using FrostFS.SDK.Cryptography;
+
namespace FrostFS.SDK;
public class CheckSum
{
- // type is always Sha256
- public byte[]? Hash { get; set; }
+ private byte[]? hash;
+ private string? text;
public static CheckSum CreateCheckSum(byte[] content)
{
- return new CheckSum { Hash = content.Sha256() };
+ return new CheckSum { hash = content.Sha256() };
}
public override string ToString()
{
- return BitConverter.ToString(Hash).Replace("-", "");
+ return text ??= BitConverter.ToString(hash).Replace("-", "");
}
}
\ No newline at end of file
diff --git a/src/FrostFS.SDK.ClientV2/Models/Misc/Constants.cs b/src/FrostFS.SDK.ClientV2/Models/Misc/Constants.cs
index 332a3e3..28c8cf0 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Misc/Constants.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Misc/Constants.cs
@@ -1,8 +1,8 @@
namespace FrostFS.SDK;
-public class Constants
+public static class Constants
{
- public const int ObjectChunkSize = 3 * (1 << 20);
+ public const int ObjectChunkSize = 3 * (1 << 20);
public const int Sha256HashLength = 32;
// HeaderPrefix is a prefix of key to object header value or property.
diff --git a/src/FrostFS.SDK.ClientV2/Models/Netmap/FrostFsPlacementPolicy.cs b/src/FrostFS.SDK.ClientV2/Models/Netmap/FrostFsPlacementPolicy.cs
index 410598c..62f7fb2 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Netmap/FrostFsPlacementPolicy.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Netmap/FrostFsPlacementPolicy.cs
@@ -1,28 +1,89 @@
+
using System;
using System.Linq;
+using FrostFS.Netmap;
+using FrostFS.SDK.ClientV2;
+
namespace FrostFS.SDK;
-public class FrostFsPlacementPolicy(bool unique, params FrostFsReplica[] replicas) : IComparable
+public struct FrostFsPlacementPolicy(bool unique, params FrostFsReplica[] replicas)
+ : IEquatable
{
+ private PlacementPolicy policy;
+
public FrostFsReplica[] Replicas { get; private set; } = replicas;
public bool Unique { get; private set; } = unique;
- public int CompareTo(FrostFsPlacementPolicy other)
+ public override readonly bool Equals(object obj)
{
- var notEqual = other == null
- || Unique != other.Unique
- || Replicas.Length != other.Replicas.Length;
+ if (obj is null)
+ return false;
+
+ var other = (FrostFsPlacementPolicy)obj;
+
+ return Equals(other);
+ }
+
+ public PlacementPolicy GetPolicy()
+ {
+ if (policy == null)
+ {
+ policy = new PlacementPolicy
+ {
+ Filters = { },
+ Selectors = { },
+ Replicas = { },
+ Unique = Unique
+ };
+
+ foreach (var replica in Replicas)
+ {
+ policy.Replicas.Add(replica.ToMessage());
+ }
+ }
+
+ return policy;
+ }
+
+ //public static FrostFsPlacementPolicy ToModel(placementPolicy)
+ //{
+ // return new FrostFsPlacementPolicy(
+ // placementPolicy.Unique,
+ // placementPolicy.Replicas.Select(replica => replica.ToModel()).ToArray()
+ // );
+ //}
+
+
+ public override readonly int GetHashCode()
+ {
+ return Unique ? 17 : 0 + Replicas.GetHashCode();
+ }
+
+ public static bool operator ==(FrostFsPlacementPolicy left, FrostFsPlacementPolicy right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(FrostFsPlacementPolicy left, FrostFsPlacementPolicy right)
+ {
+ return !(left == right);
+ }
+
+ public readonly bool Equals(FrostFsPlacementPolicy other)
+ {
+ var notEqual = Unique != other.Unique
+ || Replicas.Length != other.Replicas.Length;
if (notEqual)
- return 1;
+ return false;
foreach (var replica in Replicas)
{
- if (!other!.Replicas.Any(r => r.Count == replica.Count && r.Selector == replica.Selector))
- return 1;
+ if (!other.Replicas.Any(r => r.Equals(replica)))
+ return false;
}
- return 0;
+ return true;
}
}
\ No newline at end of file
diff --git a/src/FrostFS.SDK.ClientV2/Models/Netmap/FrostFsReplica.cs b/src/FrostFS.SDK.ClientV2/Models/Netmap/FrostFsReplica.cs
index 8fd1bd9..fa2f8db 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Netmap/FrostFsReplica.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Netmap/FrostFsReplica.cs
@@ -1,6 +1,8 @@
+using System;
+
namespace FrostFS.SDK;
-public class FrostFsReplica
+public struct FrostFsReplica : IEquatable
{
public int Count { get; set; }
public string Selector { get; set; }
@@ -12,4 +14,34 @@ public class FrostFsReplica
Count = count;
Selector = selector;
}
+
+ public override readonly bool Equals(object obj)
+ {
+ if (obj is null)
+ return false;
+
+ var other = (FrostFsReplica)obj;
+
+ return Count == other.Count && Selector == other.Selector;
+ }
+
+ public override readonly int GetHashCode()
+ {
+ return Count + Selector.GetHashCode();
+ }
+
+ public static bool operator ==(FrostFsReplica left, FrostFsReplica right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(FrostFsReplica left, FrostFsReplica right)
+ {
+ return !(left == right);
+ }
+
+ public readonly bool Equals(FrostFsReplica other)
+ {
+ return Count == other.Count && Selector == other.Selector;
+ }
}
\ No newline at end of file
diff --git a/src/FrostFS.SDK.ClientV2/Models/Netmap/FrostFsVersion.cs b/src/FrostFS.SDK.ClientV2/Models/Netmap/FrostFsVersion.cs
index da66403..e63d9ac 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Netmap/FrostFsVersion.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Netmap/FrostFsVersion.cs
@@ -5,7 +5,7 @@ namespace FrostFS.SDK;
public class FrostFsVersion(int major, int minor)
{
- public Version version;
+ private Version? version;
public int Major { get; set; } = major;
public int Minor { get; set; } = minor;
@@ -21,6 +21,11 @@ public class FrostFsVersion(int major, int minor)
public bool IsSupported(FrostFsVersion version)
{
+ if (version is null)
+ {
+ throw new System.ArgumentNullException(nameof(version));
+ }
+
return Major == version.Major;
}
diff --git a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsAttribute.cs b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsAttributePair.cs
similarity index 66%
rename from src/FrostFS.SDK.ClientV2/Models/Object/FrostFsAttribute.cs
rename to src/FrostFS.SDK.ClientV2/Models/Object/FrostFsAttributePair.cs
index 8a69fd4..64d865f 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsAttribute.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsAttributePair.cs
@@ -1,6 +1,6 @@
namespace FrostFS.SDK;
-public class FrostFsAttribute(string key, string value)
+public class FrostFsAttributePair(string key, string value)
{
public string Key { get; set; } = key;
diff --git a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsLinkObject.cs b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsLinkObject.cs
index 5b9e349..f43c6d0 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsLinkObject.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsLinkObject.cs
@@ -1,13 +1,21 @@
-namespace FrostFS.SDK;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace FrostFS.SDK;
public class FrostFsLinkObject : FrostFsObject
{
- public FrostFsLinkObject(FrostFsContainerId containerId, SplitId splitId, FrostFsObjectHeader largeObjectHeader)
+ public FrostFsLinkObject(FrostFsContainerId containerId,
+ SplitId splitId,
+ FrostFsObjectHeader largeObjectHeader,
+ IList children)
: base(containerId)
{
- Header!.Split = new FrostFsSplit(splitId)
- {
- ParentHeader = largeObjectHeader
- };
+ Header!.Split = new FrostFsSplit(splitId,
+ null,
+ null,
+ largeObjectHeader,
+ null,
+ new ReadOnlyCollection(children));
}
}
\ No newline at end of file
diff --git a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObject.cs b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObject.cs
index 5ee8b8e..a6c82db 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObject.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObject.cs
@@ -1,9 +1,11 @@
-using System;
+using FrostFS.SDK.ClientV2;
namespace FrostFS.SDK;
public class FrostFsObject
{
+ private byte[]? bytes;
+
///
/// Creates new instance from ObjectHeader
///
@@ -37,19 +39,27 @@ public class FrostFsObject
get; set;
}
- ///
- /// The size of payload cannot exceed MaxObjectSize value from NetworkSettings
- /// Used only for PutSingleObject method
- ///
- /// Buffer for output data
- public byte[] Payload { get; set; } = [];
-
///
/// A payload is obtained via stream reader
///
/// Reader for received data
public IObjectReader? ObjectReader { get; set; }
+ internal byte[] SingleObjectPayload
+ {
+ get { return bytes ?? []; }
+ }
+
+ ///
+ /// The size of payload cannot exceed MaxObjectSize value from NetworkSettings
+ /// Used only for PutSingleObject method
+ ///
+ /// Buffer for output data
+ public void SetSingleObjectPayload(byte[] bytes)
+ {
+ this.bytes = bytes;
+ }
+
///
/// Applied only for the last Object in chain in case of manual multipart uploading
///
@@ -57,7 +67,7 @@ public class FrostFsObject
public void SetParent(FrostFsObjectHeader largeObjectHeader)
{
if (Header?.Split == null)
- throw new Exception("The object is not initialized properly");
+ throw new InvalidObjectException("The object is not initialized properly");
Header.Split.ParentHeader = largeObjectHeader;
}
diff --git a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectFilter.cs b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectFilter.cs
index feae9bd..f2f21d7 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectFilter.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectFilter.cs
@@ -27,7 +27,7 @@ public abstract class FrostFsObjectFilter(FrostFsMatchType matchType, string
/// Match type
/// Attribute key
/// Attribute value
-public class FilterByAttribute(FrostFsMatchType matchType, string key, string value) : FrostFsObjectFilter(matchType, key, value) { }
+public class FilterByAttributePair(FrostFsMatchType matchType, string key, string value) : FrostFsObjectFilter(matchType, key, value) { }
///
/// Creates filter to search by ObjectId
diff --git a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectHeader.cs b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectHeader.cs
index e384ece..ad8887f 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectHeader.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectHeader.cs
@@ -1,5 +1,5 @@
using System;
-using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Linq;
using FrostFS.Object;
@@ -11,15 +11,17 @@ namespace FrostFS.SDK;
public class FrostFsObjectHeader(
FrostFsContainerId containerId,
FrostFsObjectType type = FrostFsObjectType.Regular,
- FrostFsAttribute[]? attributes = null,
+ FrostFsAttributePair[]? attributes = null,
FrostFsSplit? split = null,
FrostFsOwner? owner = null,
FrostFsVersion? version = null)
{
- private Header header;
+ private Header? header;
private Container.Container.Types.Attribute[]? grpsAttributes;
-
- public List Attributes { get; internal set; } = attributes != null ? [.. attributes] : [];
+
+ public ReadOnlyCollection? Attributes { get; internal set; } =
+ attributes == null ? null :
+ new ReadOnlyCollection(attributes);
public FrostFsContainerId ContainerId { get; } = containerId;
@@ -65,9 +67,12 @@ public class FrostFsObjectHeader(
PayloadLength = PayloadLength
};
- foreach (var attribute in Attributes)
+ if (Attributes != null)
{
- this.header.Attributes.Add(attribute.ToMessage());
+ foreach (var attribute in Attributes)
+ {
+ this.header.Attributes.Add(attribute.ToMessage());
+ }
}
var split = Split;
diff --git a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectId.cs b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectId.cs
index 4e4dbf0..49fde5a 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectId.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsObjectId.cs
@@ -10,6 +10,11 @@ public class FrostFsObjectId(string id)
public static FrostFsObjectId FromHash(byte[] hash)
{
+ if (hash is null)
+ {
+ throw new ArgumentNullException(nameof(hash));
+ }
+
if (hash.Length != Constants.Sha256HashLength)
throw new FormatException("ObjectID must be a sha256 hash.");
diff --git a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsOwner.cs b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsOwner.cs
index d249d80..0a24164 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsOwner.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsOwner.cs
@@ -8,7 +8,7 @@ namespace FrostFS.SDK;
public class FrostFsOwner(string id)
{
- private OwnerID ownerID;
+ private OwnerID? ownerID;
public string Value { get; } = id;
@@ -17,9 +17,9 @@ public class FrostFsOwner(string id)
return new FrostFsOwner(key.PublicKey().PublicKeyToAddress());
}
- internal OwnerID OwnerID
+ internal OwnerID OwnerID
{
- get
+ get
{
ownerID ??= this.ToMessage();
return ownerID;
diff --git a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsSplit.cs b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsSplit.cs
index 947662f..64e68e2 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsSplit.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Object/FrostFsSplit.cs
@@ -1,8 +1,13 @@
-using System.Collections.Generic;
+using System.Collections.ObjectModel;
namespace FrostFS.SDK;
-public class FrostFsSplit(SplitId splitId)
+public class FrostFsSplit(SplitId splitId,
+ FrostFsObjectId? previous = null,
+ FrostFsObjectId? parent = null,
+ FrostFsObjectHeader? parentHeader = null,
+ FrostFsSignature? parentSignature = null,
+ ReadOnlyCollection? children = null)
{
public FrostFsSplit() : this(new SplitId())
{
@@ -10,15 +15,14 @@ public class FrostFsSplit(SplitId splitId)
public SplitId SplitId { get; private set; } = splitId;
- public FrostFsObjectId? Parent { get; set; }
+ public FrostFsObjectId? Previous { get; } = previous;
- public FrostFsObjectId? Previous { get; set; }
+ public FrostFsObjectId? Parent { get; } = parent;
- public FrostFsSignature? ParentSignature { get; set; }
+ public FrostFsSignature? ParentSignature { get; } = parentSignature;
- public FrostFsObjectHeader? ParentHeader { get; set; }
+ public FrostFsObjectHeader? ParentHeader { get; set; } = parentHeader;
- public List Children { get; } = [];
+ public ReadOnlyCollection? Children { get; } = children;
- public Refs.Signature ParentSignatureGrpc { get; set; }
}
diff --git a/src/FrostFS.SDK.ClientV2/Models/Object/SplitId.cs b/src/FrostFS.SDK.ClientV2/Models/Object/SplitId.cs
index bb8e617..177817e 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Object/SplitId.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Object/SplitId.cs
@@ -1,35 +1,35 @@
-using FrostFS.SDK.Cryptography;
+using System;
+
+using FrostFS.SDK.Cryptography;
using Google.Protobuf;
-using System;
-
namespace FrostFS.SDK;
public class SplitId
{
private readonly Guid id;
- private ByteString? _message;
+ private ByteString? message;
public SplitId()
{
- id = Guid.NewGuid();
+ this.id = Guid.NewGuid();
}
- public SplitId(Guid guid)
+ public SplitId(Guid id)
{
- id = guid;
+ this.id = id;
}
private SplitId(byte[] binary)
{
- id = new Guid(binary);
+ this.id = new Guid(binary);
}
private SplitId(string str)
{
- id = new Guid(str);
+ this.id = new Guid(str);
}
public static SplitId CreateFromBinary(byte[] binaryData)
@@ -44,19 +44,19 @@ public class SplitId
public override string ToString()
{
- return id.ToString();
+ return this.id.ToString();
}
public byte[]? ToBinary()
{
- if (id == Guid.Empty)
+ if (this.id == Guid.Empty)
return null;
- return id.ToBytes();
+ return this.id.ToBytes();
}
public ByteString? GetSplitId()
{
- return _message ??= ByteString.CopyFrom(ToBinary());
+ return this.message ??= ByteString.CopyFrom(ToBinary());
}
}
diff --git a/src/FrostFS.SDK.ClientV2/Models/Response/FrostFsSignature.cs b/src/FrostFS.SDK.ClientV2/Models/Response/FrostFsSignature.cs
index d7ca6b6..995b161 100644
--- a/src/FrostFS.SDK.ClientV2/Models/Response/FrostFsSignature.cs
+++ b/src/FrostFS.SDK.ClientV2/Models/Response/FrostFsSignature.cs
@@ -1,6 +1,6 @@
namespace FrostFS.SDK;
-public class FrostFsSignature
+public class FrostFsSignature()
{
public byte[]? Key { get; set; }
diff --git a/src/FrostFS.SDK.ClientV2/Parameters/Context.cs b/src/FrostFS.SDK.ClientV2/Parameters/Context.cs
index f1704a9..0e96929 100644
--- a/src/FrostFS.SDK.ClientV2/Parameters/Context.cs
+++ b/src/FrostFS.SDK.ClientV2/Parameters/Context.cs
@@ -1,5 +1,5 @@
using System;
-using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Security.Cryptography;
using System.Threading;
@@ -13,32 +13,32 @@ namespace FrostFS.SDK.ClientV2;
public class Context()
{
- private List? interceptors;
+ private ReadOnlyCollection? interceptors;
private ByteString? publicKeyCache;
- public ECDsa Key { get; set; }
+ public ECDsa? Key { get; set; }
- public FrostFsOwner OwnerId { get; set; }
+ public FrostFsOwner? OwnerId { get; set; }
- public FrostFsVersion Version { get; set; }
+ public FrostFsVersion? Version { get; set; }
+
+ public CancellationToken CancellationToken { get; set; }
+
+ public TimeSpan Timeout { get; set; }
- public CancellationToken CancellationToken { get; set; } = default;
-
- public TimeSpan Timeout { get; set; } = default;
-
public DateTime? Deadline => Timeout.Ticks > 0 ? DateTime.UtcNow.Add(Timeout) : null;
public Action? Callback { get; set; }
- public List Interceptors
+ public ReadOnlyCollection? Interceptors
{
- get { return this.interceptors ??= []; }
+ get { return this.interceptors; }
set { this.interceptors = value; }
}
public ByteString? GetPublicKeyCache()
- {
+ {
if (publicKeyCache == null && Key != null)
{
publicKeyCache = ByteString.CopyFrom(Key.PublicKey());
diff --git a/src/FrostFS.SDK.ClientV2/Parameters/PrmBase.cs b/src/FrostFS.SDK.ClientV2/Parameters/PrmBase.cs
index 1aedefe..2a6e542 100644
--- a/src/FrostFS.SDK.ClientV2/Parameters/PrmBase.cs
+++ b/src/FrostFS.SDK.ClientV2/Parameters/PrmBase.cs
@@ -2,12 +2,12 @@
namespace FrostFS.SDK.ClientV2;
-public class PrmBase() : IContext
+public class PrmBase(NameValueCollection? xheaders = null) : IContext
{
///
/// FrostFS request X-Headers
///
- public NameValueCollection XHeaders { get; set; } = [];
+ public NameValueCollection XHeaders { get; } = xheaders ?? [];
///
public Context? Context { get; set; }
diff --git a/src/FrostFS.SDK.ClientV2/Parameters/PrmContainerCreate.cs b/src/FrostFS.SDK.ClientV2/Parameters/PrmContainerCreate.cs
index 01f87a8..da4c50b 100644
--- a/src/FrostFS.SDK.ClientV2/Parameters/PrmContainerCreate.cs
+++ b/src/FrostFS.SDK.ClientV2/Parameters/PrmContainerCreate.cs
@@ -9,7 +9,7 @@ public sealed class PrmContainerCreate(FrostFsContainerInfo container) : PrmBase
///
/// Rules for polling the result
public PrmWait? WaitParams { get; set; }
-
+
///
/// Blank session token
///
diff --git a/src/FrostFS.SDK.ClientV2/Parameters/PrmNetmapSnapshot.cs b/src/FrostFS.SDK.ClientV2/Parameters/PrmNetmapSnapshot.cs
index f129109..6031ca6 100644
--- a/src/FrostFS.SDK.ClientV2/Parameters/PrmNetmapSnapshot.cs
+++ b/src/FrostFS.SDK.ClientV2/Parameters/PrmNetmapSnapshot.cs
@@ -1,5 +1,5 @@
namespace FrostFS.SDK.ClientV2;
public sealed class PrmNetmapSnapshot() : PrmBase
-{
+{
}
diff --git a/src/FrostFS.SDK.ClientV2/Parameters/PrmNetworkSettings.cs b/src/FrostFS.SDK.ClientV2/Parameters/PrmNetworkSettings.cs
index 3e82ff5..f014f14 100644
--- a/src/FrostFS.SDK.ClientV2/Parameters/PrmNetworkSettings.cs
+++ b/src/FrostFS.SDK.ClientV2/Parameters/PrmNetworkSettings.cs
@@ -1,5 +1,5 @@
namespace FrostFS.SDK.ClientV2;
public sealed class PrmNetworkSettings() : PrmBase
-{
+{
}
diff --git a/src/FrostFS.SDK.ClientV2/Parameters/PrmNodeInfo.cs b/src/FrostFS.SDK.ClientV2/Parameters/PrmNodeInfo.cs
index 7a3d1dc..05b541d 100644
--- a/src/FrostFS.SDK.ClientV2/Parameters/PrmNodeInfo.cs
+++ b/src/FrostFS.SDK.ClientV2/Parameters/PrmNodeInfo.cs
@@ -1,5 +1,5 @@
namespace FrostFS.SDK.ClientV2;
public sealed class PrmNodeInfo() : PrmBase
-{
+{
}
diff --git a/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectHeadGet.cs b/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectHeadGet.cs
index 67919aa..40410f3 100644
--- a/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectHeadGet.cs
+++ b/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectHeadGet.cs
@@ -3,7 +3,7 @@
public sealed class PrmObjectHeadGet(FrostFsContainerId containerId, FrostFsObjectId objectId) : PrmBase, ISessionToken
{
public FrostFsContainerId ContainerId { get; set; } = containerId;
-
+
public FrostFsObjectId ObjectId { get; set; } = objectId;
///
diff --git a/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectPut.cs b/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectPut.cs
index 0be09e8..3d216d5 100644
--- a/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectPut.cs
+++ b/src/FrostFS.SDK.ClientV2/Parameters/PrmObjectPut.cs
@@ -28,7 +28,7 @@ public sealed class PrmObjectPut : PrmBase, ISessionToken
/// Overrides default size of the buffer for stream transferring.
///
/// Size of the buffer
- public int BufferMaxSize { get; set; }
+ public int BufferMaxSize { get; set; }
///
/// Allows to define a buffer for chunks to manage by the memory allocation and releasing.
@@ -40,7 +40,7 @@ public sealed class PrmObjectPut : PrmBase, ISessionToken
internal int MaxObjectSizeCache { get; set; }
- internal ulong CurrentStreamPosition { get; set; } = 0;
+ internal ulong CurrentStreamPosition { get; set; }
- internal ulong FullLength { get; set; } = 0;
+ internal ulong FullLength { get; set; }
}
diff --git a/src/FrostFS.SDK.ClientV2/Services/ContainerServiceProvider.cs b/src/FrostFS.SDK.ClientV2/Services/ContainerServiceProvider.cs
index 1e0ef9b..c42b2ba 100644
--- a/src/FrostFS.SDK.ClientV2/Services/ContainerServiceProvider.cs
+++ b/src/FrostFS.SDK.ClientV2/Services/ContainerServiceProvider.cs
@@ -3,22 +3,22 @@ using System.Collections.Generic;
using System.Collections.Specialized;
using System.Threading.Tasks;
-using FrostFS.SDK.ClientV2;
using FrostFS.Container;
+using FrostFS.Refs;
+using FrostFS.SDK.ClientV2;
using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.SDK.Cryptography;
-using FrostFS.Refs;
using FrostFS.Session;
namespace FrostFS.SDK.ClientV2;
-internal class ContainerServiceProvider(ContainerService.ContainerServiceClient service, ClientEnvironment context) : ContextAccessor(context), ISessionProvider
+internal sealed class ContainerServiceProvider(ContainerService.ContainerServiceClient service, ClientEnvironment context) : ContextAccessor(context), ISessionProvider
{
readonly SessionProvider sessions = new(context);
public async ValueTask GetOrCreateSession(ISessionToken args, Context ctx)
{
- return await sessions.GetOrCreateSession(args, ctx);
+ return await sessions.GetOrCreateSession(args, ctx).ConfigureAwait(false);
}
internal async Task GetContainerAsync(PrmContainerGet args)
@@ -35,22 +35,29 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
internal async IAsyncEnumerable ListContainersAsync(PrmContainerGetAll args)
{
var ctx = args.Context!;
+ ctx.OwnerId ??= Context.Owner;
+ ctx.Key ??= Context.Key?.ECDsaKey;
+
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+ if (ctx.OwnerId == null)
+ throw new InvalidObjectException(nameof(ctx.OwnerId));
var request = new ListRequest
{
- Body = new ()
+ Body = new()
{
- OwnerId = ctx.OwnerId.ToMessage()
+ OwnerId = ctx.OwnerId.ToMessage()
}
};
-
+
request.AddMetaHeader(args.XHeaders);
request.Sign(ctx.Key);
var response = await service.ListAsync(request, null, ctx.Deadline, ctx.CancellationToken);
-
+
Verifier.CheckResponse(response);
-
+
foreach (var cid in response.Body.ContainerIds)
{
yield return new FrostFsContainerId(Base58.Encode(cid.Value.ToByteArray()));
@@ -63,42 +70,52 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
var grpcContainer = args.Container.GetContainer();
- grpcContainer.OwnerId ??= ctx.OwnerId.ToMessage();
- grpcContainer.Version ??= ctx.Version.ToMessage();
+ grpcContainer.OwnerId ??= ctx.OwnerId?.ToMessage();
+ grpcContainer.Version ??= ctx.Version?.ToMessage();
+
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+ if (grpcContainer.OwnerId == null)
+ throw new InvalidObjectException(nameof(grpcContainer.OwnerId));
+ if (grpcContainer.Version == null)
+ throw new InvalidObjectException(nameof(grpcContainer.Version));
var request = new PutRequest
{
Body = new PutRequest.Types.Body
{
Container = grpcContainer,
- Signature = ctx.Key.SignRFC6979(grpcContainer)
+ Signature = ctx.Key.SignRFC6979(grpcContainer)
}
};
- var sessionToken = await GetOrCreateSession(args, ctx);
+ var sessionToken = await GetOrCreateSession(args, ctx).ConfigureAwait(false);
sessionToken.CreateContainerTokenContext(
null,
ContainerSessionContext.Types.Verb.Put,
ctx.Key,
- ctx.GetPublicKeyCache());
+ ctx.GetPublicKeyCache()!);
request.AddMetaHeader(args.XHeaders, sessionToken);
request.Sign(ctx.Key);
var response = await service.PutAsync(request, null, ctx.Deadline, ctx.CancellationToken);
-
+
Verifier.CheckResponse(response);
- await WaitForContainer(WaitExpects.Exists, response.Body.ContainerId, args.WaitParams, ctx);
-
- return new FrostFsContainerId(response.Body.ContainerId);
+ await WaitForContainer(WaitExpects.Exists, response.Body.ContainerId, args.WaitParams, ctx).ConfigureAwait(false);
+
+ return new FrostFsContainerId(response.Body.ContainerId);
}
internal async Task DeleteContainerAsync(PrmContainerDelete args)
{
var ctx = args.Context!;
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+
var request = new DeleteRequest
{
Body = new DeleteRequest.Types.Body
@@ -108,13 +125,13 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
}
};
- var sessionToken = await GetOrCreateSession(args, ctx);
+ var sessionToken = await GetOrCreateSession(args, ctx).ConfigureAwait(false);
sessionToken.CreateContainerTokenContext(
request.Body.ContainerId,
ContainerSessionContext.Types.Verb.Delete,
ctx.Key,
- ctx.GetPublicKeyCache());
+ ctx.GetPublicKeyCache()!);
request.AddMetaHeader(args.XHeaders, sessionToken);
@@ -124,13 +141,17 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
Verifier.CheckResponse(response);
- await WaitForContainer(WaitExpects.Removed, request.Body.ContainerId, args.WaitParams, ctx);
-
+ await WaitForContainer(WaitExpects.Removed, request.Body.ContainerId, args.WaitParams, ctx)
+ .ConfigureAwait(false);
+
Verifier.CheckResponse(response);
}
private static GetRequest GetContainerRequest(ContainerID id, NameValueCollection? xHeaders, Context ctx)
{
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+
var request = new GetRequest
{
Body = new GetRequest.Types.Body
@@ -146,7 +167,7 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
}
private enum WaitExpects
- {
+ {
Exists,
Removed
}
@@ -161,7 +182,7 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
Verifier.CheckResponse(response);
}
- await WaitFor(action, expect, waitParams);
+ await WaitFor(action, expect, waitParams).ConfigureAwait(false);
}
private static async Task WaitFor(
@@ -176,7 +197,7 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
{
try
{
- await action();
+ await action().ConfigureAwait(false);
if (expect == WaitExpects.Exists)
return;
@@ -184,20 +205,20 @@ internal class ContainerServiceProvider(ContainerService.ContainerServiceClient
if (DateTime.UtcNow >= deadLine)
throw new TimeoutException();
- await Task.Delay(waitParams.PollInterval);
+ await Task.Delay(waitParams.PollInterval).ConfigureAwait(false);
}
catch (ResponseException ex)
{
if (DateTime.UtcNow >= deadLine)
throw new TimeoutException();
- if (ex.Status.Code != FrostFsStatusCode.ContainerNotFound)
+ if (ex.Status?.Code != FrostFsStatusCode.ContainerNotFound)
throw;
if (expect == WaitExpects.Removed)
return;
- await Task.Delay(waitParams.PollInterval);
+ await Task.Delay(waitParams.PollInterval).ConfigureAwait(false);
}
}
}
diff --git a/src/FrostFS.SDK.ClientV2/Services/NetmapServiceProvider.cs b/src/FrostFS.SDK.ClientV2/Services/NetmapServiceProvider.cs
index d932dfb..91cca73 100644
--- a/src/FrostFS.SDK.ClientV2/Services/NetmapServiceProvider.cs
+++ b/src/FrostFS.SDK.ClientV2/Services/NetmapServiceProvider.cs
@@ -8,12 +8,12 @@ using static FrostFS.Netmap.NetworkConfig.Types;
namespace FrostFS.SDK.ClientV2;
-internal class NetmapServiceProvider : ContextAccessor
-{
+internal sealed class NetmapServiceProvider : ContextAccessor
+{
private readonly NetmapService.NetmapServiceClient netmapServiceClient;
-
- internal NetmapServiceProvider(NetmapService.NetmapServiceClient netmapServiceClient, ClientEnvironment context)
- : base(context)
+
+ internal NetmapServiceProvider(NetmapService.NetmapServiceClient netmapServiceClient, ClientEnvironment context)
+ : base(context)
{
this.netmapServiceClient = netmapServiceClient;
}
@@ -23,7 +23,7 @@ internal class NetmapServiceProvider : ContextAccessor
if (Context.NetworkSettings != null)
return Context.NetworkSettings;
- var info = await GetNetworkInfoAsync(ctx);
+ var info = await GetNetworkInfoAsync(ctx).ConfigureAwait(false);
var settings = new NetworkSettings();
@@ -33,13 +33,18 @@ internal class NetmapServiceProvider : ContextAccessor
}
Context.NetworkSettings = settings;
-
+
return settings;
}
internal async Task GetLocalNodeInfoAsync(PrmNodeInfo args)
{
var ctx = args.Context!;
+ ctx.Key ??= Context.Key?.ECDsaKey;
+
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+
var request = new LocalNodeInfoRequest
{
Body = new LocalNodeInfoRequest.Types.Body { }
@@ -47,7 +52,7 @@ internal class NetmapServiceProvider : ContextAccessor
request.AddMetaHeader(args.XHeaders);
request.Sign(ctx.Key);
-
+
var response = await netmapServiceClient.LocalNodeInfoAsync(request, null, ctx.Deadline, ctx.CancellationToken);
Verifier.CheckResponse(response);
@@ -57,12 +62,18 @@ internal class NetmapServiceProvider : ContextAccessor
internal async Task GetNetworkInfoAsync(Context ctx)
{
- var request = new NetworkInfoRequest();
+ ctx.Key ??= Context.Key?.ECDsaKey;
+
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+
+ var request = new NetworkInfoRequest();
request.AddMetaHeader(null);
request.Sign(ctx.Key);
-
- var response = await netmapServiceClient.NetworkInfoAsync(request, null, ctx.Deadline, ctx.CancellationToken);
+
+ var response = await netmapServiceClient.NetworkInfoAsync(request, null, ctx.Deadline, ctx.CancellationToken)
+ .ConfigureAwait(false);
Verifier.CheckResponse(response);
@@ -72,12 +83,16 @@ internal class NetmapServiceProvider : ContextAccessor
internal async Task GetNetmapSnapshotAsync(PrmNetmapSnapshot args)
{
var ctx = args.Context!;
+ ctx.Key ??= Context.Key?.ECDsaKey;
+
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
var request = new NetmapSnapshotRequest();
request.AddMetaHeader(args.XHeaders);
request.Sign(ctx.Key);
-
+
var response = await netmapServiceClient.NetmapSnapshotAsync(request, null, ctx.Deadline, ctx.CancellationToken);
Verifier.CheckResponse(response);
@@ -95,12 +110,12 @@ internal class NetmapServiceProvider : ContextAccessor
ulong val = 0;
for (var i = bytes.Length - 1; i >= 0; i--)
val = (val << 8) + bytes[i];
-
+
return val;
}
private static void SetNetworksParam(Parameter param, NetworkSettings settings)
- {
+ {
var key = Encoding.UTF8.GetString(param.Key.ToByteArray());
var valueBytes = param.Value.ToByteArray();
diff --git a/src/FrostFS.SDK.ClientV2/Services/ObjectServiceProvider.cs b/src/FrostFS.SDK.ClientV2/Services/ObjectServiceProvider.cs
index bf8acf2..dce9787 100644
--- a/src/FrostFS.SDK.ClientV2/Services/ObjectServiceProvider.cs
+++ b/src/FrostFS.SDK.ClientV2/Services/ObjectServiceProvider.cs
@@ -6,9 +6,8 @@ using System.Threading.Tasks;
using FrostFS.Object;
using FrostFS.Refs;
-using FrostFS.SDK.ClientV2.Extensions;
-using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.SDK.ClientV2;
+using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.SDK.Cryptography;
using FrostFS.Session;
@@ -16,19 +15,30 @@ using Google.Protobuf;
namespace FrostFS.SDK.ClientV2;
-internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, ClientEnvironment env)
- : ContextAccessor(env), ISessionProvider
+internal sealed class ObjectServiceProvider : ContextAccessor, ISessionProvider
{
- readonly SessionProvider sessions = new (env);
+ private readonly SessionProvider sessions;
+ private ObjectService.ObjectServiceClient client;
- public async ValueTask GetOrCreateSession(ISessionToken args, Context ctx)
+ internal ObjectServiceProvider(ObjectService.ObjectServiceClient client, ClientEnvironment env)
+ : base(env)
{
- return await sessions.GetOrCreateSession(args, ctx);
+ this.sessions = new(Context);
+ this.client = client;
+ }
+
+ public async ValueTask GetOrCreateSession(ISessionToken args, Context ctx)
+ {
+ return await sessions.GetOrCreateSession(args, ctx).ConfigureAwait(false);
}
internal async Task GetObjectHeadAsync(PrmObjectHeadGet args)
{
var ctx = args.Context!;
+ ctx.Key ??= Context.Key?.ECDsaKey;
+
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
var request = new HeadRequest
{
@@ -42,7 +52,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
}
};
- var sessionToken = await GetOrCreateSession(args, ctx);
+ var sessionToken = await GetOrCreateSession(args, ctx).ConfigureAwait(false);
sessionToken.CreateObjectTokenContext(
request.Body.Address,
@@ -53,8 +63,8 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
request.Sign(ctx.Key);
- var response = await client!.HeadAsync(request, null, ctx.Deadline, ctx.CancellationToken);
-
+ var response = await client!.HeadAsync(request, null, ctx.Deadline, ctx.CancellationToken).ConfigureAwait(false);
+
Verifier.CheckResponse(response);
return response.Body.Header.Header.ToModel();
@@ -63,7 +73,12 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
internal async Task GetObjectAsync(PrmObjectGet args)
{
var ctx = args.Context!;
-
+
+ ctx.Key ??= Context.Key?.ECDsaKey;
+
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+
var request = new GetRequest
{
Body = new GetRequest.Types.Body
@@ -76,7 +91,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
}
};
- var sessionToken = await GetOrCreateSession(args, ctx);
+ var sessionToken = await GetOrCreateSession(args, ctx).ConfigureAwait(false);
sessionToken.CreateObjectTokenContext(
request.Body.Address,
@@ -87,12 +102,17 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
request.Sign(ctx.Key);
- return await GetObject(request, ctx);
+ return await GetObject(request, ctx).ConfigureAwait(false);
}
internal async Task DeleteObjectAsync(PrmObjectDelete args)
{
var ctx = args.Context!;
+ ctx.Key ??= Context.Key?.ECDsaKey;
+
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+
var request = new DeleteRequest
{
Body = new DeleteRequest.Types.Body
@@ -105,7 +125,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
}
};
- var sessionToken = await GetOrCreateSession(args, ctx);
+ var sessionToken = await GetOrCreateSession(args, ctx).ConfigureAwait(false);
sessionToken.CreateObjectTokenContext(
request.Body.Address,
@@ -116,26 +136,29 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
request.Sign(ctx.Key);
var response = await client.DeleteAsync(request, null, ctx.Deadline, ctx.CancellationToken);
-
+
Verifier.CheckResponse(response);
}
internal async IAsyncEnumerable SearchObjectsAsync(PrmObjectSearch args)
{
var ctx = args.Context!;
+
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+
var request = new SearchRequest
{
Body = new SearchRequest.Types.Body
{
ContainerId = args.ContainerId.ToMessage(),
- Filters = { },
Version = 1 // TODO: clarify this param
}
};
request.Body.Filters.AddRange(args.Filters.Select(f => f.ToMessage()));
-
- var sessionToken = await GetOrCreateSession(args, ctx);
+
+ var sessionToken = await GetOrCreateSession(args, ctx).ConfigureAwait(false);
sessionToken.CreateObjectTokenContext(
new Address { ContainerId = request.Body.ContainerId },
@@ -143,7 +166,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
ctx.Key);
request.AddMetaHeader(args.XHeaders, sessionToken);
-
+
request.Sign(ctx.Key);
var objectsIds = SearchObjects(request, ctx);
@@ -156,14 +179,17 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
internal async Task PutObjectAsync(PrmObjectPut args)
{
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
if (args.Header == null)
- throw new ArgumentException("Value cannot be null", nameof(args.Header));
-
+ throw new ArgumentException(nameof(args.Header));
+
if (args.Payload == null)
- throw new ArgumentException("Value cannot be null", nameof(args.Payload));
+ throw new ArgumentException(nameof(args.Payload));
if (args.ClientCut)
- return await PutClientCutObject(args);
+ return await PutClientCutObject(args).ConfigureAwait(false);
else
{
if (args.Header.PayloadLength > 0)
@@ -171,24 +197,28 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
else if (args.Payload.CanSeek)
args.FullLength = (ulong)args.Payload.Length;
- return (await PutStreamObject(args)).ObjectId;
+ return (await PutStreamObject(args).ConfigureAwait(false)).ObjectId;
}
}
-
+
internal async Task PutSingleObjectAsync(PrmSingleObjectPut args)
{
var ctx = args.Context!;
+
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+
var grpcObject = ObjectTools.CreateObject(args.FrostFsObject, ctx);
var request = new PutSingleRequest
{
- Body = new () { Object = grpcObject }
+ Body = new() { Object = grpcObject }
};
- var sessionToken = await GetOrCreateSession(args, ctx);
+ var sessionToken = await GetOrCreateSession(args, ctx).ConfigureAwait(false);
sessionToken.CreateObjectTokenContext(
- new Address { ContainerId = grpcObject.Header.ContainerId, ObjectId = grpcObject.ObjectId},
+ new Address { ContainerId = grpcObject.Header.ContainerId, ObjectId = grpcObject.ObjectId },
ObjectSessionContext.Types.Verb.Put,
ctx.Key);
@@ -196,18 +226,18 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
request.Sign(ctx.Key);
- var response = await client.PutSingleAsync(request, null, ctx.Deadline, ctx.CancellationToken);
+ var response = await client.PutSingleAsync(request, null, ctx.Deadline, ctx.CancellationToken).ConfigureAwait(false);
Verifier.CheckResponse(response);
-
+
return FrostFsObjectId.FromHash(grpcObject.ObjectId.Value.ToByteArray());
}
-
+
private async Task PutClientCutObject(PrmObjectPut args)
{
var ctx = args.Context!;
-
- var tokenRaw = await GetOrCreateSession(args, ctx);
+
+ var tokenRaw = await GetOrCreateSession(args, ctx).ConfigureAwait(false);
var token = new FrostFsSessionToken(tokenRaw.Serialize());
args.SessionToken = token;
@@ -216,7 +246,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
var header = args.Header!;
var fullLength = header.PayloadLength;
-
+
if (payloadStream.CanSeek && fullLength == 0)
fullLength = (ulong)payloadStream.Length;
@@ -224,12 +254,14 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
if (args.MaxObjectSizeCache == 0)
{
- var networkSettings = await Context.Client.GetNetworkSettingsAsync(new PrmNetworkSettings() { Context = ctx });
+ var networkSettings = await Context.Client.GetNetworkSettingsAsync(new PrmNetworkSettings() { Context = ctx })
+ .ConfigureAwait(false);
+
args.MaxObjectSizeCache = (int)networkSettings.MaxObjectSize;
}
var restBytes = fullLength - args.CurrentStreamPosition;
- var objectSize = restBytes > 0 ? (int)Math.Min((ulong)args.MaxObjectSizeCache, restBytes) : args.MaxObjectSizeCache;
+ var objectSize = restBytes > 0 ? (int)Math.Min((ulong)args.MaxObjectSizeCache, restBytes) : args.MaxObjectSizeCache;
//define collection capacity
var restPart = (restBytes % (ulong)objectSize) > 0 ? 1 : 0;
@@ -238,23 +270,20 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
List sentObjectIds = new(objectsCount);
FrostFsSplit? split = null;
+ SplitId splitId = new();
// keep attributes for the large object
var attributes = args.Header!.Attributes;
+ args.Header!.Attributes = null;
// send all parts except the last one as separate Objects
- while (restBytes > (ulong)args.MaxObjectSizeCache)
+ while (restBytes > (ulong)args.MaxObjectSizeCache)
{
- if (split == null)
- {
- split = new FrostFsSplit();
- args.Header!.Attributes = [];
- }
+ split = new FrostFsSplit(splitId, sentObjectIds.LastOrDefault());
- split!.Previous = sentObjectIds.LastOrDefault();
args.Header!.Split = split;
- var result = await PutStreamObject(args);
+ var result = await PutStreamObject(args).ConfigureAwait(false);
sentObjectIds.Add(result.ObjectId);
@@ -264,26 +293,30 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
// send the last part and create linkObject
if (sentObjectIds.Count > 0)
{
- var largeObjectHeader = new FrostFsObjectHeader(header.ContainerId) { PayloadLength = fullLength };
-
- largeObjectHeader.Attributes.AddRange(attributes);
+ var largeObjectHeader = new FrostFsObjectHeader(header.ContainerId, FrostFsObjectType.Regular, [.. attributes])
+ {
+ PayloadLength = fullLength,
+ };
args.Header.Split!.ParentHeader = largeObjectHeader;
- var result = await PutStreamObject(args);
+ var result = await PutStreamObject(args).ConfigureAwait(false);
sentObjectIds.Add(result.ObjectId);
- var linkObject = new FrostFsLinkObject(header.ContainerId, split!.SplitId, largeObjectHeader)
- .AddChildren(sentObjectIds);
+ var linkObject = new FrostFsLinkObject(header.ContainerId, split!.SplitId, largeObjectHeader, sentObjectIds);
- _ = await PutSingleObjectAsync(new PrmSingleObjectPut(linkObject) { Context = args.Context});
+ _ = await PutSingleObjectAsync(new PrmSingleObjectPut(linkObject) { Context = args.Context }).ConfigureAwait(false);
- return split.Parent!;
+ var parentHeader = args.Header.GetHeader();
+
+ return parentHeader.Split!.Parent.ToModel();
}
// We are here if the payload is placed to one Object. It means no cut action, just simple PUT.
- var singlePartResult = await PutStreamObject(args);
+ args.Header!.Attributes = attributes;
+
+ var singlePartResult = await PutStreamObject(args).ConfigureAwait(false);
return singlePartResult.ObjectId;
}
@@ -297,6 +330,9 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
private async Task PutStreamObject(PrmObjectPut args)
{
var ctx = args.Context!;
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+
var payload = args.Payload!;
var chunkSize = args.BufferMaxSize > 0 ? args.BufferMaxSize : Constants.ObjectChunkSize;
@@ -307,7 +343,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
bool isRentBuffer = false;
byte[]? chunkBuffer = null;
-
+
try
{
if (args.CustomBuffer != null)
@@ -316,7 +352,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
}
else
{
- chunkBuffer = env.GetArrayPool(Constants.ObjectChunkSize).Rent(chunkSize);
+ chunkBuffer = Context.GetArrayPool(Constants.ObjectChunkSize).Rent(chunkSize);
isRentBuffer = true;
}
@@ -325,7 +361,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
// 0 means no limit from client, so server side cut is performed
var objectLimitSize = args.ClientCut ? args.MaxObjectSizeCache : 0;
- var stream = await GetUploadStream(args, ctx);
+ using var stream = await GetUploadStream(args, ctx).ConfigureAwait(false);
while (objectLimitSize == 0 || sentBytes < objectLimitSize)
{
@@ -334,7 +370,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
(int)Math.Min(objectLimitSize - sentBytes, chunkSize)
: chunkSize;
- var bytesCount = await payload.ReadAsync(chunkBuffer, 0, bufferSize, ctx.CancellationToken);
+ var bytesCount = await payload.ReadAsync(chunkBuffer, 0, bufferSize, ctx.CancellationToken).ConfigureAwait(false);
if (bytesCount == 0)
break;
@@ -351,10 +387,10 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
chunkRequest.Sign(ctx.Key);
- await stream.Write(chunkRequest);
+ await stream.Write(chunkRequest).ConfigureAwait(false);
}
- var response = await stream.Close();
+ var response = await stream.Close().ConfigureAwait(false);
Verifier.CheckResponse(response);
return new PutObjectResult(FrostFsObjectId.FromHash(response.Body.ObjectId.Value.ToByteArray()), sentBytes);
@@ -372,6 +408,9 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
{
var header = args.Header!;
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+
header.OwnerId ??= ctx.OwnerId;
header.Version ??= ctx.Version;
@@ -395,7 +434,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
}
};
- var sessionToken = await GetOrCreateSession(args, ctx);
+ var sessionToken = await GetOrCreateSession(args, ctx).ConfigureAwait(false);
sessionToken.CreateObjectTokenContext(
new Address { ContainerId = grpcHeader.ContainerId, ObjectId = oid },
@@ -407,19 +446,19 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
initRequest.Sign(ctx.Key);
- return await PutObjectInit(initRequest, ctx);
+ return await PutObjectInit(initRequest, ctx).ConfigureAwait(false);
}
private async Task GetObject(GetRequest request, Context ctx)
{
var reader = GetObjectInit(request, ctx);
-
- var grpcObject = await reader.ReadHeader();
+
+ var grpcObject = await reader.ReadHeader().ConfigureAwait(false);
var modelObject = grpcObject.ToModel();
-
+
modelObject.ObjectReader = reader;
- return modelObject;
+ return modelObject;
}
private ObjectReader GetObjectInit(GetRequest initRequest, Context ctx)
@@ -428,7 +467,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
throw new ArgumentNullException(nameof(initRequest));
var call = client.Get(initRequest, null, ctx.Deadline, ctx.CancellationToken);
-
+
return new ObjectReader(call);
}
@@ -441,7 +480,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
var call = client.Put(null, ctx.Deadline, ctx.CancellationToken);
- await call.RequestStream.WriteAsync(initRequest);
+ await call.RequestStream.WriteAsync(initRequest).ConfigureAwait(false);
return new ObjectStreamer(call);
}
@@ -449,14 +488,14 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
private async IAsyncEnumerable SearchObjects(SearchRequest request, Context ctx)
{
using var stream = GetSearchReader(request, ctx);
-
+
while (true)
{
- var ids = await stream.Read(ctx.CancellationToken);
+ var ids = await stream.Read(ctx.CancellationToken).ConfigureAwait(false);
if (ids == null)
break;
-
+
foreach (var oid in ids)
{
yield return oid;
@@ -472,7 +511,7 @@ internal class ObjectServiceProvider(ObjectService.ObjectServiceClient client, C
}
var call = client.Search(initRequest, null, ctx.Deadline, ctx.CancellationToken);
-
+
return new SearchReader(call);
- }
+ }
}
diff --git a/src/FrostFS.SDK.ClientV2/Services/SessionServiceProvider.cs b/src/FrostFS.SDK.ClientV2/Services/SessionServiceProvider.cs
index 4498b3c..de22165 100644
--- a/src/FrostFS.SDK.ClientV2/Services/SessionServiceProvider.cs
+++ b/src/FrostFS.SDK.ClientV2/Services/SessionServiceProvider.cs
@@ -1,17 +1,17 @@
using System.Threading.Tasks;
-using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.SDK.ClientV2;
+using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.Session;
namespace FrostFS.SDK.ClientV2;
-internal class SessionServiceProvider : ContextAccessor
-{
+internal sealed class SessionServiceProvider : ContextAccessor
+{
private readonly SessionService.SessionServiceClient? _sessionServiceClient;
internal SessionServiceProvider(SessionService.SessionServiceClient? sessionServiceClient, ClientEnvironment context)
- : base (context)
+ : base(context)
{
_sessionServiceClient = sessionServiceClient;
}
@@ -19,27 +19,30 @@ internal class SessionServiceProvider : ContextAccessor
internal async Task CreateSessionAsync(PrmSessionCreate args)
{
var ctx = args.Context!;
+
+ ctx.OwnerId ??= Context.Owner;
+
var request = new CreateRequest
{
Body = new CreateRequest.Types.Body
{
- OwnerId = ctx.OwnerId.ToMessage(),
+ OwnerId = ctx.OwnerId!.ToMessage(),
Expiration = args.Expiration
}
};
request.AddMetaHeader(args.XHeaders);
- request.Sign(ctx.Key);
+ request.Sign(ctx.Key!);
- return await CreateSession(request, args.Context!);
+ return await CreateSession(request, args.Context!).ConfigureAwait(false);
}
internal async Task CreateSession(CreateRequest request, Context ctx)
{
var response = await _sessionServiceClient!.CreateAsync(request, null, ctx.Deadline, ctx.CancellationToken);
-
+
Verifier.CheckResponse(response);
-
+
return new SessionToken
{
Body = new SessionToken.Types.Body
diff --git a/src/FrostFS.SDK.ClientV2/Services/Shared/ApeManagerServiceProvider.cs b/src/FrostFS.SDK.ClientV2/Services/Shared/ApeManagerServiceProvider.cs
index 596d79e..ea92329 100644
--- a/src/FrostFS.SDK.ClientV2/Services/Shared/ApeManagerServiceProvider.cs
+++ b/src/FrostFS.SDK.ClientV2/Services/Shared/ApeManagerServiceProvider.cs
@@ -5,12 +5,12 @@ using Frostfs.V2.Apemanager;
namespace FrostFS.SDK.ClientV2;
-internal class ApeManagerServiceProvider : ContextAccessor
-{
+internal sealed class ApeManagerServiceProvider : ContextAccessor
+{
private readonly APEManagerService.APEManagerServiceClient? _apeManagerServiceClient;
internal ApeManagerServiceProvider(APEManagerService.APEManagerServiceClient? apeManagerServiceClient, ClientEnvironment context)
- : base (context)
+ : base(context)
{
_apeManagerServiceClient = apeManagerServiceClient;
}
@@ -18,12 +18,16 @@ internal class ApeManagerServiceProvider : ContextAccessor
internal async Task AddChainAsync(PrmApeChainAdd args)
{
var ctx = args.Context!;
+ ctx.Key ??= Context.Key?.ECDsaKey;
+
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
AddChainRequest request = new()
{
Body = new()
{
- Chain = new () { Raw = args.Chain.GetRaw() },
+ Chain = new() { Raw = args.Chain.GetRaw() },
Target = args.Target.GetChainTarget()
}
};
@@ -41,6 +45,11 @@ internal class ApeManagerServiceProvider : ContextAccessor
internal async Task RemoveChainAsync(PrmApeChainRemove args)
{
var ctx = args.Context!;
+ ctx.Key ??= Context.Key?.ECDsaKey;
+
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+
RemoveChainRequest request = new()
{
Body = new()
@@ -61,6 +70,11 @@ internal class ApeManagerServiceProvider : ContextAccessor
internal async Task ListChainAsync(PrmApeChainList args)
{
var ctx = args.Context!;
+ ctx.Key ??= Context.Key?.ECDsaKey;
+
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+
ListChainsRequest request = new()
{
Body = new()
diff --git a/src/FrostFS.SDK.ClientV2/Services/Shared/SessionProvider.cs b/src/FrostFS.SDK.ClientV2/Services/Shared/SessionProvider.cs
index 9e5b142..8d0d1f5 100644
--- a/src/FrostFS.SDK.ClientV2/Services/Shared/SessionProvider.cs
+++ b/src/FrostFS.SDK.ClientV2/Services/Shared/SessionProvider.cs
@@ -7,13 +7,14 @@ internal interface ISessionProvider
ValueTask GetOrCreateSession(ISessionToken args, Context ctx);
}
-internal class SessionProvider(ClientEnvironment env)
-{
+internal sealed class SessionProvider(ClientEnvironment env)
+{
public async ValueTask GetOrCreateSession(ISessionToken args, Context ctx)
{
if (args.SessionToken is null)
- {
- return await env.Client.CreateSessionInternalAsync(new PrmSessionCreate(uint.MaxValue) { Context = ctx });
+ {
+ return await env.Client.CreateSessionInternalAsync(new PrmSessionCreate(uint.MaxValue) { Context = ctx })
+ .ConfigureAwait(false);
}
return new Session.SessionToken().Deserialize(args.SessionToken.Token);
diff --git a/src/FrostFS.SDK.ClientV2/Tools/ClientEnvironment.cs b/src/FrostFS.SDK.ClientV2/Tools/ClientEnvironment.cs
index 1ac5183..11023e7 100644
--- a/src/FrostFS.SDK.ClientV2/Tools/ClientEnvironment.cs
+++ b/src/FrostFS.SDK.ClientV2/Tools/ClientEnvironment.cs
@@ -6,9 +6,9 @@ using Grpc.Net.Client;
namespace FrostFS.SDK.ClientV2;
-public class ClientEnvironment(Client client, ECDsa? key, FrostFsOwner? owner, GrpcChannel channel, FrostFsVersion version) : IDisposable
+public class ClientEnvironment(FrostFSClient client, ECDsa? key, FrostFsOwner? owner, GrpcChannel channel, FrostFsVersion version) : IDisposable
{
- private ArrayPool _arrayPool;
+ private ArrayPool? _arrayPool;
internal FrostFsOwner? Owner { get; } = owner;
@@ -18,7 +18,7 @@ public class ClientEnvironment(Client client, ECDsa? key, FrostFsOwner? owner, G
internal NetworkSettings? NetworkSettings { get; set; }
- internal Client Client { get; } = client;
+ internal FrostFSClient Client { get; } = client;
internal ClientKey? Key { get; } = key != null ? new ClientKey(key) : null;
@@ -28,7 +28,7 @@ public class ClientEnvironment(Client client, ECDsa? key, FrostFsOwner? owner, G
internal ArrayPool GetArrayPool(int size)
{
_arrayPool ??= ArrayPool.Create(size, 256);
-
+
return _arrayPool;
}
diff --git a/src/FrostFS.SDK.ClientV2/Tools/Object.cs b/src/FrostFS.SDK.ClientV2/Tools/Object.cs
deleted file mode 100644
index 05d957c..0000000
--- a/src/FrostFS.SDK.ClientV2/Tools/Object.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace FrostFS.SDK.ClientV2.Extensions;
-
-public static class ObjectExtensions
-{
- public static FrostFsObject SetPayloadLength(this FrostFsObject obj, ulong length)
- {
- obj.Header.PayloadLength = length;
- return obj;
- }
-
- public static FrostFsObject SetPayload(this FrostFsObject obj, byte[] bytes)
- {
- obj.Payload = bytes;
- return obj;
- }
-
- public static FrostFsObject AddAttribute(this FrostFsObject obj, string key, string value)
- {
- obj.AddAttribute(new FrostFsAttribute(key, value));
- return obj;
- }
-
- public static FrostFsObject AddAttribute(this FrostFsObject obj, FrostFsAttribute attribute)
- {
- obj.Header.Attributes.Add(attribute);
- return obj;
- }
-
- public static FrostFsObject AddAttributes(this FrostFsObject obj, IEnumerable attributes)
- {
- obj.Header.Attributes.AddRange(attributes);
- return obj;
- }
-
- public static FrostFsObject SetSplit(this FrostFsObject obj, FrostFsSplit? split)
- {
- obj.Header.Split = split;
- return obj;
- }
-
- public static FrostFsLinkObject AddChildren(this FrostFsLinkObject linkObject, IEnumerable objectIds)
- {
- linkObject.Header.Split!.Children.AddRange(objectIds);
- return linkObject;
- }
-
- public static FrostFsObject CalculateObjectId(this FrostFsObject obj)
- {
- if (obj.Header == null)
- throw new MissingFieldException("Header cannot be null");
-
- return obj;
- }
-}
\ No newline at end of file
diff --git a/src/FrostFS.SDK.ClientV2/Tools/ObjectReader.cs b/src/FrostFS.SDK.ClientV2/Tools/ObjectReader.cs
index 07c4793..b1ad4f7 100644
--- a/src/FrostFS.SDK.ClientV2/Tools/ObjectReader.cs
+++ b/src/FrostFS.SDK.ClientV2/Tools/ObjectReader.cs
@@ -1,30 +1,30 @@
using System;
+using System.Threading;
using System.Threading.Tasks;
+using FrostFS.Object;
+
using Grpc.Core;
-using FrostFS.Object;
-using System.Threading;
-
namespace FrostFS.SDK.ClientV2;
-public class ObjectReader(AsyncServerStreamingCall call) : IObjectReader
+public sealed class ObjectReader(AsyncServerStreamingCall call) : IObjectReader
{
- private bool disposed = false;
+ private bool disposed;
public AsyncServerStreamingCall Call { get; private set; } = call;
internal async Task ReadHeader()
{
- if (!await Call.ResponseStream.MoveNext())
+ if (!await Call.ResponseStream.MoveNext().ConfigureAwait(false))
throw new InvalidOperationException("unexpected end of stream");
-
+
var response = Call.ResponseStream.Current;
Verifier.CheckResponse(response);
-
+
if (response.Body.ObjectPartCase != GetResponse.Types.Body.ObjectPartOneofCase.Init)
throw new InvalidOperationException("unexpected message type");
-
+
return new Object.Object
{
ObjectId = response.Body.Init.ObjectId,
@@ -34,12 +34,12 @@ public class ObjectReader(AsyncServerStreamingCall call) : IObjectR
public async Task?> ReadChunk(CancellationToken cancellationToken = default)
{
- if (!await Call.ResponseStream.MoveNext(cancellationToken))
+ if (!await Call.ResponseStream.MoveNext(cancellationToken).ConfigureAwait(false))
return null;
-
+
var response = Call.ResponseStream.Current;
Verifier.CheckResponse(response);
-
+
if (response.Body.ObjectPartCase != GetResponse.Types.Body.ObjectPartOneofCase.Chunk)
throw new InvalidOperationException("unexpected message type");
diff --git a/src/FrostFS.SDK.ClientV2/Tools/ObjectStreamer.cs b/src/FrostFS.SDK.ClientV2/Tools/ObjectStreamer.cs
index 9350282..acd0d28 100644
--- a/src/FrostFS.SDK.ClientV2/Tools/ObjectStreamer.cs
+++ b/src/FrostFS.SDK.ClientV2/Tools/ObjectStreamer.cs
@@ -1,13 +1,13 @@
using System;
using System.Threading.Tasks;
-using Grpc.Core;
-
using FrostFS.Object;
+using Grpc.Core;
+
namespace FrostFS.SDK.ClientV2;
-internal class ObjectStreamer(AsyncClientStreamingCall call) : IDisposable
+internal sealed class ObjectStreamer(AsyncClientStreamingCall call) : IDisposable
{
public AsyncClientStreamingCall Call { get; private set; } = call;
@@ -18,14 +18,14 @@ internal class ObjectStreamer(AsyncClientStreamingCall
throw new ArgumentNullException(nameof(request));
}
- await Call.RequestStream.WriteAsync(request);
+ await Call.RequestStream.WriteAsync(request).ConfigureAwait(false);
}
public async Task Close()
{
- await Call.RequestStream.CompleteAsync();
-
- return await Call.ResponseAsync;
+ await Call.RequestStream.CompleteAsync().ConfigureAwait(false);
+
+ return await Call.ResponseAsync.ConfigureAwait(false);
}
public void Dispose()
diff --git a/src/FrostFS.SDK.ClientV2/Tools/ObjectTools.cs b/src/FrostFS.SDK.ClientV2/Tools/ObjectTools.cs
index 64c09cd..0303626 100644
--- a/src/FrostFS.SDK.ClientV2/Tools/ObjectTools.cs
+++ b/src/FrostFS.SDK.ClientV2/Tools/ObjectTools.cs
@@ -1,35 +1,35 @@
using System.Linq;
-using Google.Protobuf;
-
using FrostFS.Object;
using FrostFS.Refs;
using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.SDK.Cryptography;
+using Google.Protobuf;
+
namespace FrostFS.SDK.ClientV2;
-internal class ObjectTools
+internal static class ObjectTools
{
internal static FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header, Context ctx)
- {
+ {
var grpcHeader = CreateHeader(header, [], ctx);
if (header.Split != null)
SetSplitValues(grpcHeader, header.Split, ctx);
- return new ObjectID { Value = grpcHeader.Sha256() }.ToModel();
+ return new ObjectID { Value = grpcHeader.Sha256() }.ToModel();
}
- internal static Object.Object CreateObject(FrostFsObject @object, Context ctx)
+ internal static Object.Object CreateObject(FrostFsObject @object, Context ctx)
{
@object.Header.OwnerId ??= ctx.OwnerId;
@object.Header.Version ??= ctx.Version;
var grpcHeader = @object.Header.GetHeader();
-
- grpcHeader.PayloadLength = (ulong)@object.Payload.Length;
- grpcHeader.PayloadHash = Sha256Checksum(@object.Payload);
+
+ grpcHeader.PayloadLength = (ulong)@object.SingleObjectPayload.Length;
+ grpcHeader.PayloadHash = Sha256Checksum(@object.SingleObjectPayload);
var split = @object.Header.Split;
if (split != null)
@@ -41,15 +41,15 @@ internal class ObjectTools
{
Header = grpcHeader,
ObjectId = new ObjectID { Value = grpcHeader.Sha256() },
- Payload = ByteString.CopyFrom(@object.Payload)
+ Payload = ByteString.CopyFrom(@object.SingleObjectPayload)
};
- obj.Signature = new Refs.Signature
+ obj.Signature = new Signature
{
Key = ctx.GetPublicKeyCache(),
- Sign = ByteString.CopyFrom(ctx.Key.SignData(obj.ObjectId.ToByteArray())),
- };
-
+ Sign = ByteString.CopyFrom(ctx.Key!.SignData(obj.ObjectId.ToByteArray())),
+ };
+
return obj;
}
@@ -58,6 +58,9 @@ internal class ObjectTools
if (split == null)
return;
+ if (ctx.Key == null)
+ throw new InvalidObjectException(nameof(ctx.Key));
+
grpcHeader.Split = new Header.Types.Split
{
SplitId = split.SplitId?.GetSplitId()
@@ -72,13 +75,11 @@ internal class ObjectTools
grpcHeader.Split.Parent = new ObjectID { Value = grpcParentHeader.Sha256() };
grpcHeader.Split.ParentHeader = grpcParentHeader;
- grpcHeader.Split.ParentSignature = new Refs.Signature
+ grpcHeader.Split.ParentSignature = new Signature
{
Key = ctx.GetPublicKeyCache(),
Sign = ByteString.CopyFrom(ctx.Key.SignData(grpcHeader.Split.Parent.ToByteArray())),
};
-
- split.Parent = grpcHeader.Split.Parent.ToModel();
}
grpcHeader.Split.Previous = split.Previous?.ToMessage();
@@ -90,10 +91,10 @@ internal class ObjectTools
header.Version ??= ctx.Version;
var grpcHeader = header.GetHeader();
-
+
if (payload != null) // && payload.Length > 0
grpcHeader.PayloadHash = Sha256Checksum(payload);
-
+
return grpcHeader;
}
diff --git a/src/FrostFS.SDK.ClientV2/Tools/Range.cs b/src/FrostFS.SDK.ClientV2/Tools/Range.cs
index eae7b50..8add54e 100644
--- a/src/FrostFS.SDK.ClientV2/Tools/Range.cs
+++ b/src/FrostFS.SDK.ClientV2/Tools/Range.cs
@@ -25,7 +25,7 @@ namespace System
{
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
-
+
if (fromEnd)
_value = ~value;
else
@@ -51,7 +51,7 @@ namespace System
{
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
-
+
return new Index(value);
}
@@ -62,7 +62,7 @@ namespace System
{
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
-
+
return new Index(~value);
}
@@ -119,9 +119,9 @@ namespace System
public override string ToString()
{
if (IsFromEnd)
- return "^" + ((uint)Value).ToString();
+ return $"^{(uint)Value}";
- return ((uint)Value).ToString();
+ return $"{(uint)Value}";
}
}
@@ -189,7 +189,7 @@ namespace System
{
int start;
var startIndex = Start;
-
+
if (startIndex.IsFromEnd)
start = length - startIndex.Value;
else
@@ -205,7 +205,7 @@ namespace System
if ((uint)end > (uint)length || (uint)start > (uint)end)
throw new ArgumentOutOfRangeException(nameof(length));
-
+
return (start, end - start);
}
}
@@ -222,7 +222,7 @@ namespace System.Runtime.CompilerServices
{
if (array == null)
throw new ArgumentNullException(nameof(array));
-
+
(int offset, int length) = range.GetOffsetAndLength(array.Length);
if (default(T) != null || typeof(T[]) == array.GetType())
@@ -231,7 +231,7 @@ namespace System.Runtime.CompilerServices
if (length == 0)
return [];
-
+
var dest = new T[length];
Array.Copy(array, offset, dest, 0, length);
return dest;
diff --git a/src/FrostFS.SDK.ClientV2/Tools/RequestConstructor.cs b/src/FrostFS.SDK.ClientV2/Tools/RequestConstructor.cs
index c12d280..6f19ad0 100644
--- a/src/FrostFS.SDK.ClientV2/Tools/RequestConstructor.cs
+++ b/src/FrostFS.SDK.ClientV2/Tools/RequestConstructor.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Specialized;
using System.Linq;
using System.Security.Cryptography;
@@ -12,9 +13,14 @@ namespace FrostFS.SDK.ClientV2;
public static class RequestConstructor
{
- public static void AddMetaHeader(this IRequest request, NameValueCollection? xHeaders, Session.SessionToken? sessionToken = null)
+ public static void AddMetaHeader(this IRequest request,
+ NameValueCollection? xHeaders,
+ SessionToken? sessionToken = null)
{
- if (request.MetaHeader is not null)
+ if (request is null)
+ throw new ArgumentNullException(nameof(request));
+
+ if (request.MetaHeader is not null)
return;
request.MetaHeader = MetaHeader.Default().ToMessage();
@@ -28,11 +34,21 @@ public static class RequestConstructor
(k, v) => new XHeader { Key = k, Value = v }));
}
- public static void CreateObjectTokenContext(this Session.SessionToken sessionToken,
+ public static void CreateObjectTokenContext(this SessionToken sessionToken,
Address address,
ObjectSessionContext.Types.Verb verb,
ECDsa key)
{
+ if (sessionToken is null)
+ {
+ throw new ArgumentNullException(nameof(sessionToken));
+ }
+
+ if (address is null)
+ {
+ throw new ArgumentNullException(nameof(address));
+ }
+
if (sessionToken.Body.Object?.Target != null)
return;
@@ -52,7 +68,7 @@ public static class RequestConstructor
sessionToken.Signature = key.SignMessagePart(sessionToken.Body);
}
- public static void CreateContainerTokenContext(this Session.SessionToken sessionToken,
+ internal static void CreateContainerTokenContext(this SessionToken sessionToken,
ContainerID? containerId,
ContainerSessionContext.Types.Verb verb,
ECDsa key,
@@ -61,7 +77,7 @@ public static class RequestConstructor
if (sessionToken.Body.Container?.ContainerId != null)
return;
- sessionToken.Body.Container = new (){ Verb = verb };
+ sessionToken.Body.Container = new() { Verb = verb };
if (containerId != null)
sessionToken.Body.Container.ContainerId = containerId;
@@ -69,7 +85,7 @@ public static class RequestConstructor
sessionToken.Body.Container.Wildcard = true;
sessionToken.Body.SessionKey = publicKey;
-
+
sessionToken.Signature = key.SignMessagePart(sessionToken.Body);
}
}
diff --git a/src/FrostFS.SDK.ClientV2/Tools/RequestSigner.cs b/src/FrostFS.SDK.ClientV2/Tools/RequestSigner.cs
index c2d80f7..13d87b0 100644
--- a/src/FrostFS.SDK.ClientV2/Tools/RequestSigner.cs
+++ b/src/FrostFS.SDK.ClientV2/Tools/RequestSigner.cs
@@ -18,35 +18,45 @@ namespace FrostFS.SDK.ClientV2;
public static class RequestSigner
{
- public const int RFC6979SignatureSize = 64;
+ internal const int RFC6979SignatureSize = 64;
- public static byte[] SignRFC6979(this ECDsa key, byte[] data)
+ internal static byte[] SignRFC6979(this ECDsa key, byte[] data)
{
+ if (key is null)
+ {
+ throw new ArgumentNullException(nameof(key));
+ }
+
+ if (data is null)
+ {
+ throw new ArgumentNullException(nameof(data));
+ }
+
var digest = new Sha256Digest();
var secp256R1 = SecNamedCurves.GetByName("secp256r1");
var ecParameters = new ECDomainParameters(secp256R1.Curve, secp256R1.G, secp256R1.N);
var privateKey = new ECPrivateKeyParameters(new BigInteger(1, key.PrivateKey()), ecParameters);
var signer = new ECDsaSigner(new HMacDsaKCalculator(digest));
var hash = new byte[digest.GetDigestSize()];
-
+
digest.BlockUpdate(data, 0, data.Length);
digest.DoFinal(hash, 0);
signer.Init(true, privateKey);
-
+
var rs = signer.GenerateSignature(hash);
var signature = new byte[RFC6979SignatureSize];
var rbytes = rs[0].ToByteArrayUnsigned();
var sbytes = rs[1].ToByteArrayUnsigned();
var index = RFC6979SignatureSize / 2 - rbytes.Length;
-
+
rbytes.CopyTo(signature, index);
index = RFC6979SignatureSize - sbytes.Length;
sbytes.CopyTo(signature, index);
-
+
return signature;
}
- public static SignatureRFC6979 SignRFC6979(this ECDsa key, IMessage message)
+ internal static SignatureRFC6979 SignRFC6979(this ECDsa key, IMessage message)
{
return new SignatureRFC6979
{
@@ -54,8 +64,8 @@ public static class RequestSigner
Sign = ByteString.CopyFrom(key.SignRFC6979(message.ToByteArray())),
};
}
-
- public static SignatureRFC6979 SignRFC6979(this ECDsa key, ByteString data)
+
+ internal static SignatureRFC6979 SignRFC6979(this ECDsa key, ByteString data)
{
return new SignatureRFC6979
{
@@ -74,7 +84,7 @@ public static class RequestSigner
return hash;
}
- public static Signature SignMessagePart(this ECDsa key, IMessage? data)
+ internal static Signature SignMessagePart(this ECDsa key, IMessage? data)
{
var data2Sign = data is null ? [] : data.ToByteArray();
var sig = new Signature
@@ -86,7 +96,7 @@ public static class RequestSigner
return sig;
}
- public static void Sign(this IVerifiableMessage message, ECDsa key)
+ internal static void Sign(this IVerifiableMessage message, ECDsa key)
{
var meta = message.GetMetaHeader();
IVerificationHeader verify = message switch
@@ -95,17 +105,17 @@ public static class RequestSigner
IResponse => new ResponseVerificationHeader(),
_ => throw new InvalidOperationException("Unsupported message type")
};
-
+
var verifyOrigin = message.GetVerificationHeader();
-
+
if (verifyOrigin is null)
verify.BodySignature = key.SignMessagePart(message.GetBody());
- else
+ else
verify.SetOrigin(verifyOrigin);
-
+
verify.MetaSignature = key.SignMessagePart(meta);
verify.OriginSignature = key.SignMessagePart(verifyOrigin);
-
+
message.SetVerificationHeader(verify);
}
}
diff --git a/src/FrostFS.SDK.ClientV2/Tools/SearchReader.cs b/src/FrostFS.SDK.ClientV2/Tools/SearchReader.cs
index 1bcf398..ceed0da 100644
--- a/src/FrostFS.SDK.ClientV2/Tools/SearchReader.cs
+++ b/src/FrostFS.SDK.ClientV2/Tools/SearchReader.cs
@@ -11,17 +11,17 @@ using Grpc.Core;
namespace FrostFS.SDK.ClientV2;
-internal class SearchReader(AsyncServerStreamingCall call) : IDisposable
+internal sealed class SearchReader(AsyncServerStreamingCall call) : IDisposable
{
public AsyncServerStreamingCall Call { get; private set; } = call;
public async Task?> Read(CancellationToken cancellationToken)
{
- if (!await Call.ResponseStream.MoveNext(cancellationToken))
+ if (!await Call.ResponseStream.MoveNext(cancellationToken).ConfigureAwait(false))
return null;
-
+
var response = Call.ResponseStream.Current;
-
+
Verifier.CheckResponse(response);
return response.Body?.IdList.ToList();
diff --git a/src/FrostFS.SDK.ClientV2/Tools/Verifier.cs b/src/FrostFS.SDK.ClientV2/Tools/Verifier.cs
index 2640e45..2896209 100644
--- a/src/FrostFS.SDK.ClientV2/Tools/Verifier.cs
+++ b/src/FrostFS.SDK.ClientV2/Tools/Verifier.cs
@@ -45,7 +45,7 @@ public static class Verifier
var ecParameters = new ECDomainParameters(secp256R1.Curve, secp256R1.G, secp256R1.N);
var bcPublicKey = new ECPublicKeyParameters(secp256R1.Curve.DecodePoint(publicKey), ecParameters);
var hash = new byte[digest.GetDigestSize()];
-
+
digest.BlockUpdate(data, 0, data.Length);
digest.DoFinal(hash, 0);
signer.Init(false, bcPublicKey);
@@ -55,11 +55,25 @@ public static class Verifier
public static bool VerifyRFC6979(this SignatureRFC6979 signature, IMessage message)
{
+ if (signature is null)
+ {
+ throw new ArgumentNullException(nameof(signature));
+ }
+
return signature.Key.ToByteArray().VerifyRFC6979(message.ToByteArray(), signature.Sign.ToByteArray());
}
public static bool VerifyData(this ECDsa key, byte[] data, byte[] sig)
{
+ if (key is null)
+ throw new ArgumentNullException(nameof(key));
+
+ if (data is null)
+ throw new ArgumentNullException(nameof(data));
+
+ if (sig is null)
+ throw new ArgumentNullException(nameof(sig));
+
return key.VerifyHash(data.Sha512(), sig[1..]);
}
@@ -70,36 +84,41 @@ public static class Verifier
using var key = sig.Key.ToByteArray().LoadPublicKey();
var data2Verify = data is null ? [] : data.ToByteArray();
-
+
return key.VerifyData(data2Verify, sig.Sign.ToByteArray());
}
- public static bool VerifyMatryoskaLevel(IMessage body, IMetaHeader meta, IVerificationHeader verification)
+ internal static bool VerifyMatryoskaLevel(IMessage body, IMetaHeader meta, IVerificationHeader verification)
{
- if (!verification.MetaSignature.VerifyMessagePart(meta))
+ if (!verification.MetaSignature.VerifyMessagePart(meta))
return false;
-
+
var origin = verification.GetOrigin();
-
- if (!verification.OriginSignature.VerifyMessagePart(origin))
+
+ if (!verification.OriginSignature.VerifyMessagePart(origin))
return false;
-
+
if (origin is null)
return verification.BodySignature.VerifyMessagePart(body);
-
+
return verification.BodySignature is null && VerifyMatryoskaLevel(body, meta.GetOrigin(), origin);
}
public static bool Verify(this IVerifiableMessage message)
{
+ if (message is null)
+ {
+ throw new ArgumentNullException(nameof(message));
+ }
+
return VerifyMatryoskaLevel(message.GetBody(), message.GetMetaHeader(), message.GetVerificationHeader());
}
- public static void CheckResponse(IResponse resp)
+ internal static void CheckResponse(IResponse resp)
{
if (!resp.Verify())
throw new FormatException($"invalid response, type={resp.GetType()}");
-
+
var status = resp.MetaHeader.Status.ToModel();
if (status != null && !status.IsSuccess)
@@ -112,6 +131,11 @@ public static class Verifier
/// Created by SDK request to gRpc proxy
public static void CheckRequest(IRequest request)
{
+ if (request is null)
+ {
+ throw new ArgumentNullException(nameof(request));
+ }
+
if (!request.Verify())
throw new FormatException($"invalid response, type={request.GetType()}");
}
diff --git a/src/FrostFS.SDK.ClientV2/Ростелеком.txt b/src/FrostFS.SDK.ClientV2/Ростелеком.txt
new file mode 100644
index 0000000..d3687ed
--- /dev/null
+++ b/src/FrostFS.SDK.ClientV2/Ростелеком.txt
@@ -0,0 +1,8 @@
+Для возврата денег потребуются документы:
+1. Заполненное заявление
+Форму заявления можно скачать с сайта
+Шаблон заявления скачайте на сайте rt.ru. Внизу страницы перейдите в Договоры и соглашения -> «Бланки и заявления»
+2. Скан-фото паспорта владельца договора (2, 3, 5 страница: кем и когда выдан, адрес регистрации)
+3. Реквизиты счета владельца, выданные банком, на которые будет выполнен возврат
+4. Чек об оплате
+Сканы документов должны быть хорошо читаемые
diff --git a/src/FrostFS.SDK.Cryptography/Base58.cs b/src/FrostFS.SDK.Cryptography/Base58.cs
index 95b07f0..1b8f084 100644
--- a/src/FrostFS.SDK.Cryptography/Base58.cs
+++ b/src/FrostFS.SDK.Cryptography/Base58.cs
@@ -13,17 +13,17 @@ public static class Base58
{
if (input is null)
throw new ArgumentNullException(nameof(input));
-
+
byte[] buffer = Decode(input);
- if (buffer.Length < 4)
+ if (buffer.Length < 4)
throw new FormatException();
-
+
byte[] checksum = buffer[0..(buffer.Length - 4)].Sha256().Sha256();
if (!buffer.AsSpan(buffer.Length - 4).SequenceEqual(checksum[..4].AsSpan()))
throw new FormatException();
-
+
var ret = buffer[..^4];
Array.Clear(buffer, 0, buffer.Length);
return ret;
@@ -34,7 +34,7 @@ public static class Base58
byte[] checksum = data.ToArray().Sha256().Sha256();
Span buffer = stackalloc byte[data.Length + 4];
data.CopyTo(buffer);
-
+
checksum[..4].AsSpan().CopyTo(buffer[data.Length..]);
var ret = Encode(buffer);
buffer.Clear();
@@ -44,6 +44,9 @@ public static class Base58
public static byte[] Decode(string input)
{
+ if (input == null)
+ throw new ArgumentNullException(nameof(input));
+
// Decode Base58 string to BigInteger
var bi = BigInteger.Zero;
for (int i = 0; i < input.Length; i++)
@@ -61,7 +64,7 @@ public static class Base58
if (bi.IsZero)
return leadingZeros;
- var bytesBigEndian = bi.ToByteArray().Reverse();
+ var bytesBigEndian = bi.ToByteArray().Reverse().ToArray();
var firstNonZeroIndex = 0;
diff --git a/src/FrostFS.SDK.Cryptography/Extentions.cs b/src/FrostFS.SDK.Cryptography/Extentions.cs
index 32c8259..9d61972 100644
--- a/src/FrostFS.SDK.Cryptography/Extentions.cs
+++ b/src/FrostFS.SDK.Cryptography/Extentions.cs
@@ -1,17 +1,19 @@
-using Google.Protobuf;
-using Org.BouncyCastle.Crypto.Digests;
using System.Security.Cryptography;
using System.Threading;
+using Google.Protobuf;
+
+using Org.BouncyCastle.Crypto.Digests;
+
namespace FrostFS.SDK.Cryptography;
public static class Extentions
{
private static readonly SHA256 _sha256 = SHA256.Create();
- private static SpinLock _spinlockSha256 = new();
+ private static SpinLock _spinlockSha256;
private static readonly SHA512 _sha512 = SHA512.Create();
- private static SpinLock _spinlockSha512 = new();
+ private static SpinLock _spinlockSha512;
internal static byte[] RIPEMD160(this byte[] value)
{
@@ -22,7 +24,7 @@ public static class Extentions
digest.DoFinal(hash, 0);
return hash;
}
-
+
public static ByteString Sha256(this IMessage data)
{
return ByteString.CopyFrom(data.ToByteArray().Sha256());
diff --git a/src/FrostFS.SDK.Cryptography/FrostFS.SDK.Cryptography.csproj b/src/FrostFS.SDK.Cryptography/FrostFS.SDK.Cryptography.csproj
index e276848..59bde16 100644
--- a/src/FrostFS.SDK.Cryptography/FrostFS.SDK.Cryptography.csproj
+++ b/src/FrostFS.SDK.Cryptography/FrostFS.SDK.Cryptography.csproj
@@ -13,6 +13,10 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/src/FrostFS.SDK.Cryptography/Key.cs b/src/FrostFS.SDK.Cryptography/Key.cs
index bbffab8..0c9fd3b 100644
--- a/src/FrostFS.SDK.Cryptography/Key.cs
+++ b/src/FrostFS.SDK.Cryptography/Key.cs
@@ -20,6 +20,9 @@ public static class KeyExtension
public static byte[] Compress(this byte[] publicKey)
{
+ if (publicKey == null)
+ throw new ArgumentNullException(nameof(publicKey));
+
if (publicKey.Length != UncompressedPublicKeyLength)
throw new FormatException(
$"{nameof(Compress)} argument isn't uncompressed public key. " +
@@ -34,6 +37,9 @@ public static class KeyExtension
public static byte[] Decompress(this byte[] publicKey)
{
+ if (publicKey == null)
+ throw new ArgumentNullException(nameof(publicKey));
+
if (publicKey.Length != CompressedPublicKeyLength)
throw new FormatException(
$"{nameof(Decompress)} argument isn't compressed public key. " +
@@ -64,6 +70,9 @@ public static class KeyExtension
public static byte[] GetScriptHash(this byte[] publicKey)
{
+ if (publicKey == null)
+ throw new ArgumentNullException(nameof(publicKey));
+
var script = publicKey.CreateSignatureRedeemScript();
return script.Sha256().RIPEMD160();
}
@@ -79,14 +88,14 @@ public static class KeyExtension
private static byte[] GetPrivateKeyFromWIF(string wif)
{
- if (wif == null)
+ if (wif == null)
throw new ArgumentNullException(nameof(wif));
-
+
var data = wif.Base58CheckDecode();
-
+
if (data.Length != 34 || data[0] != 0x80 || data[33] != 0x01)
throw new FormatException();
-
+
var privateKey = new byte[32];
Buffer.BlockCopy(data, 1, privateKey, 0, privateKey.Length);
Array.Clear(data, 0, data.Length);
@@ -100,6 +109,9 @@ public static class KeyExtension
public static string PublicKeyToAddress(this byte[] publicKey)
{
+ if (publicKey == null)
+ throw new ArgumentNullException(nameof(publicKey));
+
if (publicKey.Length != CompressedPublicKeyLength)
throw new FormatException(
nameof(publicKey) +
@@ -112,6 +124,9 @@ public static class KeyExtension
public static byte[] PublicKey(this ECDsa key)
{
+ if (key == null)
+ throw new ArgumentNullException(nameof(key));
+
var param = key.ExportParameters(false);
var pubkey = new byte[33];
var pos = 33 - param.Q.X.Length;
@@ -127,6 +142,9 @@ public static class KeyExtension
public static byte[] PrivateKey(this ECDsa key)
{
+ if (key == null)
+ throw new ArgumentNullException(nameof(key));
+
return key.ExportParameters(true).D;
}
@@ -153,7 +171,7 @@ public static class KeyExtension
public static ECDsa LoadWif(this string wif)
{
var privateKey = GetPrivateKeyFromWIF(wif);
-
+
return LoadPrivateKey(privateKey);
}
diff --git a/src/FrostFS.SDK.Cryptography/Murmur3_128.cs b/src/FrostFS.SDK.Cryptography/Murmur3_128.cs
index 5cb35a1..e8f52fc 100644
--- a/src/FrostFS.SDK.Cryptography/Murmur3_128.cs
+++ b/src/FrostFS.SDK.Cryptography/Murmur3_128.cs
@@ -28,7 +28,7 @@ internal class Murmur3_128 : HashAlgorithm
length += cbSize;
int remainder = cbSize & 15;
int alignedLength = ibStart + (cbSize - remainder);
-
+
for (int i = ibStart; i < alignedLength; i += 16)
{
ulong k1 = BinaryPrimitives.ReadUInt64LittleEndian(array.AsSpan(i));
@@ -50,7 +50,7 @@ internal class Murmur3_128 : HashAlgorithm
h2 += h1;
h2 = h2 * m + n2;
}
-
+
if (remainder > 0)
{
ulong k1 = 0, k2 = 0;
@@ -101,7 +101,7 @@ internal class Murmur3_128 : HashAlgorithm
h2 = Fimix64(h2);
h1 += h2;
h2 += h1;
-
+
return BitConverter.GetBytes(h1);
}
diff --git a/src/FrostFS.SDK.Cryptography/Range.cs b/src/FrostFS.SDK.Cryptography/Range.cs
index 92aa82f..495479d 100644
--- a/src/FrostFS.SDK.Cryptography/Range.cs
+++ b/src/FrostFS.SDK.Cryptography/Range.cs
@@ -122,9 +122,9 @@ namespace System
public override string ToString()
{
if (IsFromEnd)
- return "^" + ((uint)Value).ToString();
+ return $"^{(uint)Value}";
- return ((uint)Value).ToString();
+ return $"{(uint)Value}";
}
}
@@ -140,7 +140,7 @@ namespace System
/// Construct a Range object using the start and end indexes.
/// Represent the inclusive start index of the range.
/// Represent the exclusive end index of the range.
- internal readonly struct Range (Index start, Index end) : IEquatable
+ internal readonly struct Range(Index start, Index end) : IEquatable
{
/// Represent the inclusive start index of the Range.
public Index Start { get; } = start;
diff --git a/src/FrostFS.SDK.Cryptography/UUID.cs b/src/FrostFS.SDK.Cryptography/UUID.cs
index fee2df9..c92a874 100644
--- a/src/FrostFS.SDK.Cryptography/UUID.cs
+++ b/src/FrostFS.SDK.Cryptography/UUID.cs
@@ -1,5 +1,6 @@
-using Google.Protobuf;
-using System;
+using System;
+
+using Google.Protobuf;
namespace FrostFS.SDK.Cryptography;
@@ -7,13 +8,16 @@ public static class UUIDExtension
{
public static Guid ToUuid(this ByteString id)
{
+ if (id == null)
+ throw new ArgumentNullException(nameof(id));
+
var bytes = id.ToByteArray();
-
+
var orderedBytes = GetGuidBytesDirectOrder(bytes);
return new Guid(orderedBytes);
}
-
+
///
/// Serializes Guid to binary representation in direct order bytes format
///
diff --git a/src/FrostFS.SDK.ProtosV2/Interfaces/IVerificationHeader.cs b/src/FrostFS.SDK.ProtosV2/Interfaces/IVerificationHeader.cs
index 6a637c3..32ba5d4 100644
--- a/src/FrostFS.SDK.ProtosV2/Interfaces/IVerificationHeader.cs
+++ b/src/FrostFS.SDK.ProtosV2/Interfaces/IVerificationHeader.cs
@@ -1,4 +1,5 @@
using FrostFS.Refs;
+
using Google.Protobuf;
namespace FrostFS.Session;
diff --git a/src/FrostFS.SDK.ProtosV2/apemanager/Extension.Message.cs b/src/FrostFS.SDK.ProtosV2/apemanager/Extension.Message.cs
index 1f02ea5..408622d 100644
--- a/src/FrostFS.SDK.ProtosV2/apemanager/Extension.Message.cs
+++ b/src/FrostFS.SDK.ProtosV2/apemanager/Extension.Message.cs
@@ -1,7 +1,7 @@
-using Google.Protobuf;
-
-using FrostFS.Session;
using FrostFS.SDK.ProtosV2.Interfaces;
+using FrostFS.Session;
+
+using Google.Protobuf;
namespace Frostfs.V2.Apemanager;
diff --git a/src/FrostFS.SDK.ProtosV2/container/Extension.Message.cs b/src/FrostFS.SDK.ProtosV2/container/Extension.Message.cs
index 0b876f0..010072e 100644
--- a/src/FrostFS.SDK.ProtosV2/container/Extension.Message.cs
+++ b/src/FrostFS.SDK.ProtosV2/container/Extension.Message.cs
@@ -1,7 +1,7 @@
-using Google.Protobuf;
-
-using FrostFS.Session;
using FrostFS.SDK.ProtosV2.Interfaces;
+using FrostFS.Session;
+
+using Google.Protobuf;
namespace FrostFS.Container;
diff --git a/src/FrostFS.SDK.ProtosV2/netmap/Extension.Message.cs b/src/FrostFS.SDK.ProtosV2/netmap/Extension.Message.cs
index 2c1c8b6..1001bce 100644
--- a/src/FrostFS.SDK.ProtosV2/netmap/Extension.Message.cs
+++ b/src/FrostFS.SDK.ProtosV2/netmap/Extension.Message.cs
@@ -1,5 +1,6 @@
using FrostFS.SDK.ProtosV2.Interfaces;
using FrostFS.Session;
+
using Google.Protobuf;
namespace FrostFS.Netmap;
diff --git a/src/FrostFS.SDK.ProtosV2/object/Extension.Message.cs b/src/FrostFS.SDK.ProtosV2/object/Extension.Message.cs
index dbfdd79..7c0c87d 100644
--- a/src/FrostFS.SDK.ProtosV2/object/Extension.Message.cs
+++ b/src/FrostFS.SDK.ProtosV2/object/Extension.Message.cs
@@ -1,6 +1,8 @@
using System.Diagnostics;
+
using FrostFS.SDK.ProtosV2.Interfaces;
using FrostFS.Session;
+
using Google.Protobuf;
namespace FrostFS.Object
@@ -117,7 +119,7 @@ namespace FrostFS.Object
}
}
- public partial class PutSingleRequest : IRequest
+ public partial class PutSingleRequest : IRequest
{
IMetaHeader IVerifiableMessage.GetMetaHeader()
{
diff --git a/src/FrostFS.SDK.ProtosV2/session/Extension.Message.cs b/src/FrostFS.SDK.ProtosV2/session/Extension.Message.cs
index decf002..4f0850b 100644
--- a/src/FrostFS.SDK.ProtosV2/session/Extension.Message.cs
+++ b/src/FrostFS.SDK.ProtosV2/session/Extension.Message.cs
@@ -1,4 +1,5 @@
using FrostFS.SDK.ProtosV2.Interfaces;
+
using Google.Protobuf;
namespace FrostFS.Session;
diff --git a/src/FrostFS.SDK.Tests/ContainerTest.cs b/src/FrostFS.SDK.Tests/ContainerTest.cs
index fcfcb39..e58e18c 100644
--- a/src/FrostFS.SDK.Tests/ContainerTest.cs
+++ b/src/FrostFS.SDK.Tests/ContainerTest.cs
@@ -1,12 +1,12 @@
using FrostFS.SDK.ClientV2;
-using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.SDK.ClientV2.Interfaces;
-using FrostFS.SDK.ClientV2;
+using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.SDK.Cryptography;
-using Microsoft.Extensions.Options;
using Google.Protobuf;
+using Microsoft.Extensions.Options;
+
namespace FrostFS.SDK.Tests;
public abstract class ContainerTestsBase
@@ -34,7 +34,7 @@ public abstract class ContainerTestsBase
protected IFrostFSClient GetClient()
{
- return ClientV2.Client.GetTestInstance(
+ return ClientV2.FrostFSClient.GetTestInstance(
Settings,
null,
new NetworkMocker(this.key).GetMock().Object,
@@ -45,17 +45,17 @@ public abstract class ContainerTestsBase
}
public class ContainerTest : ContainerTestsBase
-{
+{
[Fact]
public async void CreateContainerTest()
{
- var param = new PrmContainerCreate(new FrostFsContainerInfo(BasicAcl.PublicRW, Mocker.PlacementPolicy));
+ var param = new PrmContainerCreate(new FrostFsContainerInfo(Mocker.PlacementPolicy));
var result = await GetClient().CreateContainerAsync(param);
Assert.NotNull(result);
- Assert.NotNull(result.Value);
- Assert.True(Base58.Encode(Mocker.ContainerGuid.ToBytes()) == result.Value);
+ Assert.NotNull(result.GetValue());
+ Assert.True(Base58.Encode(Mocker.ContainerGuid.ToBytes()) == result.GetValue());
}
[Fact]
@@ -63,14 +63,11 @@ public class ContainerTest : ContainerTestsBase
{
var cid = new FrostFsContainerId(Base58.Encode(Mocker.ContainerGuid.ToBytes()));
- Mocker.Acl = BasicAcl.PublicRO;
-
var result = await GetClient().GetContainerAsync(new PrmContainerGet(cid));
Assert.NotNull(result);
- Assert.Equal(Mocker.Acl, result.BasicAcl);
Assert.Equal(Mocker.ContainerGuid, result.Nonce);
- Assert.Equal(0, Mocker.PlacementPolicy.CompareTo(result.PlacementPolicy));
+ Assert.Equal(Mocker.PlacementPolicy, result.PlacementPolicy);
Assert.Equal(Mocker.Version.ToString(), result.Version!.ToString());
}
@@ -89,7 +86,7 @@ public class ContainerTest : ContainerTestsBase
await foreach (var cid in result)
{
var val = Base58.Encode(ByteString.CopyFrom(Mocker.ContainerIds[i++]).ToByteArray());
- Assert.Equal(val, cid.Value);
+ Assert.Equal(val, cid.GetValue());
}
Assert.Equal(3, i);
@@ -106,7 +103,7 @@ public class ContainerTest : ContainerTestsBase
Assert.Single(Mocker.Requests);
var request = Mocker.Requests.First();
-
- Assert.Equal(cid.ToMessage(), request.Request.Body.ContainerId);
+
+ Assert.Equal(cid.ToMessage(), request.Request.Body.ContainerId);
}
}
diff --git a/src/FrostFS.SDK.Tests/MetricsInterceptor.cs b/src/FrostFS.SDK.Tests/MetricsInterceptor.cs
index cc6b438..958a73e 100644
--- a/src/FrostFS.SDK.Tests/MetricsInterceptor.cs
+++ b/src/FrostFS.SDK.Tests/MetricsInterceptor.cs
@@ -1,7 +1,7 @@
-using Grpc.Core;
-using Grpc.Core.Interceptors;
+using System.Diagnostics;
-using System.Diagnostics;
+using Grpc.Core;
+using Grpc.Core.Interceptors;
namespace FrostFS.SDK.SmokeTests;
@@ -21,12 +21,12 @@ public class MetricsInterceptor() : Interceptor
call.GetTrailers,
call.Dispose);
}
-
+
private static async Task HandleUnaryResponse(AsyncUnaryCall call)
{
var watch = new Stopwatch();
watch.Start();
-
+
var response = await call.ResponseAsync;
watch.Stop();
@@ -34,6 +34,6 @@ public class MetricsInterceptor() : Interceptor
// Do something with call info
// var elapsed = watch.ElapsedTicks * 1_000_000/Stopwatch.Frequency;
- return response;
+ return response;
}
}
diff --git a/src/FrostFS.SDK.Tests/Mocks/AsyncStreamReaderMock.cs b/src/FrostFS.SDK.Tests/Mocks/AsyncStreamReaderMock.cs
index a8ddbbd..22172f2 100644
--- a/src/FrostFS.SDK.Tests/Mocks/AsyncStreamReaderMock.cs
+++ b/src/FrostFS.SDK.Tests/Mocks/AsyncStreamReaderMock.cs
@@ -20,7 +20,7 @@ public class AsyncStreamReaderMock(string key, FrostFsObjectHeader objectHeader)
{
var header = new Header
{
- ContainerId = objectHeader.ContainerId.ToMessage(),
+ ContainerId = objectHeader.ContainerId.ToMessage(),
PayloadLength = objectHeader.PayloadLength,
Version = objectHeader.Version!.ToMessage(),
OwnerId = objectHeader.OwnerId!.ToMessage()
diff --git a/src/FrostFS.SDK.Tests/Mocks/ClientStreamWriter.cs b/src/FrostFS.SDK.Tests/Mocks/ClientStreamWriter.cs
index 56746e4..9836d37 100644
--- a/src/FrostFS.SDK.Tests/Mocks/ClientStreamWriter.cs
+++ b/src/FrostFS.SDK.Tests/Mocks/ClientStreamWriter.cs
@@ -1,6 +1,7 @@
-using Grpc.Core;
using FrostFS.SDK.ProtosV2.Interfaces;
+using Grpc.Core;
+
namespace FrostFS.SDK.Tests;
public class ClientStreamWriter : IClientStreamWriter
@@ -17,13 +18,13 @@ public class ClientStreamWriter : IClientStreamWriter
public Task CompleteAsync()
{
CompletedTask = true;
- return Task.CompletedTask;
+ return Task.CompletedTask;
}
public Task WriteAsync(IRequest message)
{
Object.PutRequest pr = new((Object.PutRequest)message);
- Messages.Add(pr);
+ Messages.Add(pr);
return Task.CompletedTask;
}
}
diff --git a/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/ContainerServiceBase.cs b/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/ContainerServiceBase.cs
index 4235f71..ba34cde 100644
--- a/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/ContainerServiceBase.cs
+++ b/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/ContainerServiceBase.cs
@@ -1,15 +1,17 @@
using System.Security.Cryptography;
-using FrostFS.Container;
-using Moq;
+using FrostFS.Container;
+using FrostFS.Object;
+using FrostFS.SDK.ClientV2;
+using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.SDK.Cryptography;
using FrostFS.Session;
+
using Google.Protobuf;
-using FrostFS.SDK.ClientV2;
-using FrostFS.Object;
using Grpc.Core;
-using FrostFS.SDK.ClientV2.Mappers.GRPC;
+
+using Moq;
namespace FrostFS.SDK.Tests;
@@ -18,11 +20,9 @@ public abstract class ServiceBase(string key)
public string StringKey { get; private set; } = key;
public ECDsa Key { get; private set; } = key.LoadWif();
public FrostFsVersion Version { get; set; } = DefaultVersion;
- public BasicAcl Acl { get; set; } = DefaultAcl;
public FrostFsPlacementPolicy PlacementPolicy { get; set; } = DefaultPlacementPolicy;
public static FrostFsVersion DefaultVersion { get; } = new(2, 13);
- public static BasicAcl DefaultAcl { get; } = BasicAcl.PublicRW;
public static FrostFsPlacementPolicy DefaultPlacementPolicy { get; } = new FrostFsPlacementPolicy(true, new FrostFsReplica(1));
public Metadata Metadata { get; protected set; }
@@ -61,23 +61,23 @@ public abstract class ServiceBase(string key)
}
public ResponseMetaHeader ResponseMetaHeader => new()
- {
- Version = Version.ToMessage(),
- Epoch = 100,
- Ttl = 1
- };
+ {
+ Version = Version.ToMessage(),
+ Epoch = 100,
+ Ttl = 1
+ };
}
-public abstract class ContainerServiceBase(string key) : ServiceBase (key)
+public abstract class ContainerServiceBase(string key) : ServiceBase(key)
{
public Guid ContainerGuid { get; set; } = Guid.NewGuid();
-
+
public abstract Mock GetMock();
}
-public abstract class ObjectServiceBase(string key) : ServiceBase (key)
+public abstract class ObjectServiceBase(string key) : ServiceBase(key)
{
- public abstract Mock GetMock();
-
+ public abstract Mock GetMock();
+
public Guid ContainerGuid { get; set; } = Guid.NewGuid();
}
diff --git a/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/ContainerStub.cs b/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/ContainerStub.cs
index c0b69a3..2734a26 100644
--- a/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/ContainerStub.cs
+++ b/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/ContainerStub.cs
@@ -1,4 +1,5 @@
using FrostFS.Container;
+
using Moq;
namespace FrostFS.SDK.Tests;
diff --git a/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/GetContainerMock.cs b/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/GetContainerMock.cs
index c76cc9f..d77322a 100644
--- a/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/GetContainerMock.cs
+++ b/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/GetContainerMock.cs
@@ -1,14 +1,15 @@
using FrostFS.Container;
-using Google.Protobuf;
-using Grpc.Core;
-using Moq;
-
-using FrostFS.SDK.Cryptography;
-using FrostFS.SDK.ClientV2;
-
-using FrostFS.SDK.ClientV2.Mappers.GRPC;
-using FrostFS.Session;
using FrostFS.Refs;
+using FrostFS.SDK.ClientV2;
+using FrostFS.SDK.ClientV2.Mappers.GRPC;
+using FrostFS.SDK.Cryptography;
+using FrostFS.Session;
+
+using Google.Protobuf;
+
+using Grpc.Core;
+
+using Moq;
namespace FrostFS.SDK.Tests;
@@ -67,8 +68,7 @@ public class ContainerMocker(string key) : ContainerServiceBase(key)
{
Version = grpcVersion,
Nonce = ByteString.CopyFrom(ContainerGuid.ToBytes()),
- BasicAcl = (uint)Acl,
- PlacementPolicy = PlacementPolicy.ToMessage()
+ PlacementPolicy = PlacementPolicy.GetPolicy()
}
},
MetaHeader = ResponseMetaHeader
@@ -78,10 +78,10 @@ public class ContainerMocker(string key) : ContainerServiceBase(key)
var getNoContainerResponse = new GetResponse
{
- Body = new (),
+ Body = new(),
MetaHeader = new ResponseMetaHeader
- {
- Status = new Status.Status
+ {
+ Status = new Status.Status
{
Code = 3072,
Message = "container not found"
@@ -107,7 +107,7 @@ public class ContainerMocker(string key) : ContainerServiceBase(key)
Task.FromResult(ResponseMetaData),
() => new Grpc.Core.Status(StatusCode.NotFound, string.Empty),
() => ResponseMetaData,
- () => { });
+ () => { });
}
return new AsyncUnaryCall(
@@ -115,7 +115,7 @@ public class ContainerMocker(string key) : ContainerServiceBase(key)
Task.FromResult(ResponseMetaData),
() => new Grpc.Core.Status(StatusCode.OK, string.Empty),
() => ResponseMetaData,
- () => { });
+ () => { });
});
var listResponse = new ListResponse
diff --git a/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/RequestData.cs b/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/RequestData.cs
index 8af698b..f60a2c8 100644
--- a/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/RequestData.cs
+++ b/src/FrostFS.SDK.Tests/Mocks/ContainerServiceMocks/RequestData.cs
@@ -9,4 +9,3 @@ public class RequestData(T request, Metadata m, DateTime? dt, CancellationTok
public DateTime? Deadline => dt;
public CancellationToken CancellationToken => ct;
}
-
\ No newline at end of file
diff --git a/src/FrostFS.SDK.Tests/Mocks/NetworkMocker.cs b/src/FrostFS.SDK.Tests/Mocks/NetworkMocker.cs
index 8a63410..72b3aab 100644
--- a/src/FrostFS.SDK.Tests/Mocks/NetworkMocker.cs
+++ b/src/FrostFS.SDK.Tests/Mocks/NetworkMocker.cs
@@ -1,8 +1,11 @@
-using Moq;
using FrostFS.Netmap;
-using Grpc.Core;
+
using Google.Protobuf;
+using Grpc.Core;
+
+using Moq;
+
namespace FrostFS.SDK.Tests;
public class NetworkMocker(string key) : ServiceBase(key)
diff --git a/src/FrostFS.SDK.Tests/Mocks/ObjectMock.cs b/src/FrostFS.SDK.Tests/Mocks/ObjectMock.cs
index 7e26a3e..1dc9152 100644
--- a/src/FrostFS.SDK.Tests/Mocks/ObjectMock.cs
+++ b/src/FrostFS.SDK.Tests/Mocks/ObjectMock.cs
@@ -1,12 +1,16 @@
-using Google.Protobuf;
-using Grpc.Core;
-using Moq;
-using FrostFS.SDK.ClientV2;
-using FrostFS.Object;
-using FrostFS.SDK.ClientV2.Mappers.GRPC;
using System.Security.Cryptography;
+
+using FrostFS.Object;
+using FrostFS.SDK.ClientV2;
+using FrostFS.SDK.ClientV2.Mappers.GRPC;
using FrostFS.SDK.Cryptography;
+using Google.Protobuf;
+
+using Grpc.Core;
+
+using Moq;
+
namespace FrostFS.SDK.Tests;
public class ObjectMocker(string key) : ObjectServiceBase(key)
@@ -183,7 +187,7 @@ public class ObjectMocker(string key) : ObjectServiceBase(key)
() => { });
});
}
-
+
return mock;
}
@@ -195,7 +199,7 @@ public class ObjectMocker(string key) : ObjectServiceBase(key)
public List? ResultObjectIds { get; set; }
- public ClientStreamWriter? ClientStreamWriter { get; private set; } = new ();
+ public ClientStreamWriter? ClientStreamWriter { get; private set; } = new();
public List PutSingleRequests { get; private set; } = [];
diff --git a/src/FrostFS.SDK.Tests/Mocks/SessionMock.cs b/src/FrostFS.SDK.Tests/Mocks/SessionMock.cs
index e1800b6..359f10b 100644
--- a/src/FrostFS.SDK.Tests/Mocks/SessionMock.cs
+++ b/src/FrostFS.SDK.Tests/Mocks/SessionMock.cs
@@ -1,6 +1,9 @@
using FrostFS.Session;
+
using Google.Protobuf;
+
using Grpc.Core;
+
using Moq;
namespace FrostFS.SDK.Tests;
diff --git a/src/FrostFS.SDK.Tests/NetworkTest.cs b/src/FrostFS.SDK.Tests/NetworkTest.cs
index 11a7ff0..0079d82 100644
--- a/src/FrostFS.SDK.Tests/NetworkTest.cs
+++ b/src/FrostFS.SDK.Tests/NetworkTest.cs
@@ -1,3 +1,5 @@
+using System.Security.Cryptography;
+
using FrostFS.Netmap;
using FrostFS.SDK.ClientV2;
using FrostFS.SDK.ClientV2.Interfaces;
@@ -8,8 +10,6 @@ using Google.Protobuf;
using Microsoft.Extensions.Options;
-using System.Security.Cryptography;
-
namespace FrostFS.SDK.Tests;
public abstract class NetworkTestsBase
@@ -40,7 +40,7 @@ public abstract class NetworkTestsBase
protected IFrostFSClient GetClient()
{
- return ClientV2.Client.GetTestInstance(
+ return ClientV2.FrostFSClient.GetTestInstance(
Settings,
null,
Mocker.GetMock().Object,
@@ -88,9 +88,9 @@ public class NetworkTest : NetworkTestsBase
}
var validTimeoutFrom = DateTime.UtcNow.AddSeconds(20);
-
+
var result = await GetClient().GetNetworkSettingsAsync(param);
-
+
var validTimeoutTo = DateTime.UtcNow.AddSeconds(20);
Assert.NotNull(result);
@@ -105,7 +105,7 @@ public class NetworkTest : NetworkTestsBase
Assert.Equal(Mocker.Parameters["MaxECParityCount"], [(byte)result.MaxECParityCount]);
Assert.Equal(Mocker.Parameters["MaxObjectSize"], [(byte)result.MaxObjectSize]);
Assert.Equal(Mocker.Parameters["WithdrawFee"], [(byte)result.WithdrawFee]);
-
+
Assert.True(result.HomomorphicHashingDisabled);
Assert.True(result.MaintenanceModeAllowed);
@@ -142,13 +142,13 @@ public class NetworkTest : NetworkTestsBase
nodeInfo1.Addresses.Add("address1");
nodeInfo1.Addresses.Add("address2");
- nodeInfo1.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key1", Value = "value1"});
+ nodeInfo1.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key1", Value = "value1" });
nodeInfo1.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key2", Value = "value2" });
var nodeInfo2 = new NodeInfo
{
State = NodeInfo.Types.State.Offline,
- PublicKey = ByteString.CopyFrom([3,4,5])
+ PublicKey = ByteString.CopyFrom([3, 4, 5])
};
nodeInfo2.Addresses.Add("address3");
@@ -190,7 +190,7 @@ public class NetworkTest : NetworkTestsBase
Assert.Equal(2, node1.Addresses.Count);
Assert.Equal("address1", node1.Addresses.ElementAt(0));
Assert.Equal("address2", node1.Addresses.ElementAt(1));
-
+
Assert.Equal(2, node1.Attributes.Count);
Assert.Equal("key1", node1.Attributes.ElementAt(0).Key);
@@ -202,7 +202,7 @@ public class NetworkTest : NetworkTestsBase
Assert.Equal(NodeState.Offline, node2.State);
Assert.Single(node2.Addresses);
Assert.Equal("address3", node2.Addresses.ElementAt(0));
-
+
Assert.Single(node2.Attributes);
Assert.Equal("key3", node2.Attributes.ElementAt(0).Key);
@@ -241,10 +241,10 @@ public class NetworkTest : NetworkTestsBase
},
Version = new Refs.Version { Major = 2, Minor = 12 }
};
-
+
body.NodeInfo.Addresses.Add("address1");
body.NodeInfo.Addresses.Add("address2");
- body.NodeInfo.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key1", Value = "value1"});
+ body.NodeInfo.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key1", Value = "value1" });
body.NodeInfo.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key2", Value = "value2" });
Mocker.NodeInfoResponse = new LocalNodeInfoResponse { Body = body };
@@ -273,11 +273,11 @@ public class NetworkTest : NetworkTestsBase
Assert.NotNull(result);
Assert.Equal(NodeState.Online, result.State);
-
+
Assert.Equal(2, result.Addresses.Count);
Assert.Equal("address1", result.Addresses.ElementAt(0));
Assert.Equal("address2", result.Addresses.ElementAt(1));
-
+
Assert.Equal(2, result.Attributes.Count);
Assert.Equal("value1", result.Attributes["key1"]);
Assert.Equal("value2", result.Attributes["key2"]);
diff --git a/src/FrostFS.SDK.Tests/ObjectTest.cs b/src/FrostFS.SDK.Tests/ObjectTest.cs
index 37fe81a..af58346 100644
--- a/src/FrostFS.SDK.Tests/ObjectTest.cs
+++ b/src/FrostFS.SDK.Tests/ObjectTest.cs
@@ -1,3 +1,6 @@
+using System.Security.Cryptography;
+using System.Text;
+
using FrostFS.Refs;
using FrostFS.SDK.ClientV2;
using FrostFS.SDK.ClientV2.Interfaces;
@@ -9,9 +12,6 @@ using Google.Protobuf;
using Microsoft.Extensions.Options;
-using System.Security.Cryptography;
-using System.Text;
-
namespace FrostFS.SDK.Tests;
public abstract class ObjectTestsBase
@@ -29,7 +29,7 @@ public abstract class ObjectTestsBase
protected ObjectTestsBase()
{
var ecdsaKey = key.LoadWif();
-
+
Settings = Options.Create(new SingleOwnerClientSettings
{
Key = key,
@@ -46,17 +46,17 @@ public abstract class ObjectTestsBase
ContainerId = new FrostFsContainerId(Base58.Encode(Mocker.ContainerGuid.ToBytes()));
Mocker.ObjectHeader = new(
- ContainerId,
- FrostFsObjectType.Regular,
- [new FrostFsAttribute("k", "v")],
+ ContainerId,
+ FrostFsObjectType.Regular,
+ [new FrostFsAttributePair("k", "v")],
null,
FrostFsOwner.FromKey(ecdsaKey),
new FrostFsVersion(2, 13));
}
protected IFrostFSClient GetClient()
- {
- return Client.GetTestInstance(
+ {
+ return FrostFSClient.GetTestInstance(
Settings,
null,
NetworkMocker.GetMock().Object,
@@ -75,30 +75,32 @@ public class ObjectTest : ObjectTestsBase
var ecdsaKey = key.LoadWif();
- var ctx = new Context {
- Key = ecdsaKey,
- OwnerId = FrostFsOwner.FromKey(ecdsaKey),
- Version = new FrostFsVersion(2, 13) };
+ var ctx = new Context
+ {
+ Key = ecdsaKey,
+ OwnerId = FrostFsOwner.FromKey(ecdsaKey),
+ Version = new FrostFsVersion(2, 13)
+ };
var objectId = client.CalculateObjectId(Mocker.ObjectHeader!, ctx);
-
+
var result = await client.GetObjectAsync(new PrmObjectGet(ContainerId, objectId) { Context = ctx });
Assert.NotNull(result);
- Assert.Equal(Mocker.ObjectHeader!.ContainerId.Value, result.Header.ContainerId.Value);
+ Assert.Equal(Mocker.ObjectHeader!.ContainerId.GetValue(), result.Header.ContainerId.GetValue());
Assert.Equal(Mocker.ObjectHeader!.OwnerId!.Value, result.Header.OwnerId!.Value);
Assert.Equal(Mocker.ObjectHeader.PayloadLength, result.Header.PayloadLength);
Assert.Single(result.Header.Attributes);
Assert.Equal(Mocker.ObjectHeader.Attributes[0].Key, result.Header.Attributes[0].Key);
- Assert.Equal(Mocker.ObjectHeader.Attributes[0].Value,result.Header.Attributes[0].Value);
+ Assert.Equal(Mocker.ObjectHeader.Attributes[0].Value, result.Header.Attributes[0].Value);
}
[Fact]
public async void PutObjectTest()
{
Mocker.ResultObjectIds = new([SHA256.HashData([])]);
-
+
Random rnd = new();
var bytes = new byte[1024];
rnd.NextBytes(bytes);
@@ -119,20 +121,20 @@ public class ObjectTest : ObjectTestsBase
Assert.NotNull(result);
Assert.Equal(Mocker.ResultObjectIds.First(), result.ToHash());
-
+
Assert.True(Mocker.ClientStreamWriter.CompletedTask);
Assert.Equal(0, body1!.Chunk.Length);
Assert.Equal(Object.PutRequest.Types.Body.ObjectPartOneofCase.Init, body1!.ObjectPartCase);
Assert.Equal(1024, body2!.Chunk.Length);
- Assert.Equal(Object.PutRequest.Types.Body.ObjectPartOneofCase.Chunk, body2!.ObjectPartCase);
+ Assert.Equal(Object.PutRequest.Types.Body.ObjectPartOneofCase.Chunk, body2!.ObjectPartCase);
}
[Fact]
public async void ClientCutTest()
{
- NetworkMocker.Parameters = new Dictionary() { { "MaxObjectSize", [0x0, 0xa] } };
+ NetworkMocker.Parameters = new Dictionary() { { "MaxObjectSize", [0x0, 0xa] } };
var blockSize = 2560;
byte[] bytes = File.ReadAllBytes(@".\..\..\..\TestData\cat.jpg");
@@ -251,11 +253,11 @@ public class ObjectTest : ObjectTestsBase
Assert.Equal(Mocker.ObjectId.ToMessage(), request.Body.Address.ObjectId);
Assert.NotNull(response);
- Assert.Equal(ContainerId.Value, response.ContainerId.Value);
+ Assert.Equal(ContainerId.GetValue(), response.ContainerId.GetValue());
Assert.Equal(Mocker.ObjectHeader!.OwnerId!.Value, response.OwnerId!.Value);
Assert.Equal(Mocker.ObjectHeader!.Version!.ToString(), response.Version!.ToString());
-
+
Assert.Equal(Mocker.HeadResponse!.PayloadLength, response.PayloadLength);
Assert.Equal(FrostFsObjectType.Regular, response.ObjectType);
diff --git a/src/FrostFS.SDK.Tests/SessionTests.cs b/src/FrostFS.SDK.Tests/SessionTests.cs
index 7eda05e..2e17816 100644
--- a/src/FrostFS.SDK.Tests/SessionTests.cs
+++ b/src/FrostFS.SDK.Tests/SessionTests.cs
@@ -1,3 +1,5 @@
+using System.Security.Cryptography;
+
using FrostFS.SDK.ClientV2;
using FrostFS.SDK.ClientV2.Interfaces;
using FrostFS.SDK.ClientV2.Mappers.GRPC;
@@ -6,8 +8,6 @@ using FrostFS.SDK.Cryptography;
using Microsoft.Extensions.Options;
-using System.Security.Cryptography;
-
namespace FrostFS.SDK.Tests;
public abstract class SessionTestsBase
@@ -16,7 +16,7 @@ public abstract class SessionTestsBase
protected IOptions Settings { get; set; }
-
+
protected ECDsa ECDsaKey { get; set; }
protected FrostFsOwner OwnerId { get; set; }
protected SessionMocker Mocker { get; set; }
@@ -41,7 +41,7 @@ public abstract class SessionTestsBase
protected IFrostFSClient GetClient()
{
- return ClientV2.Client.GetTestInstance(
+ return ClientV2.FrostFSClient.GetTestInstance(
Settings,
null,
new NetworkMocker(this.key).GetMock().Object,
@@ -100,8 +100,8 @@ public class SessionTest : SessionTestsBase
Assert.Equal(exp, Mocker.CreateSessionRequest.Body.Expiration);
Assert.NotNull(Mocker.CreateSessionRequest.MetaHeader);
Assert.Equal(Mocker.Version.ToMessage(), Mocker.CreateSessionRequest.MetaHeader.Version);
-
-
+
+
Assert.Null(Mocker.Metadata);
if (useContext)
diff --git a/src/FrostFS.SDK.Tests/SmokeTests.cs b/src/FrostFS.SDK.Tests/SmokeTests.cs
index 548d757..9c86ff9 100644
--- a/src/FrostFS.SDK.Tests/SmokeTests.cs
+++ b/src/FrostFS.SDK.Tests/SmokeTests.cs
@@ -11,16 +11,16 @@ namespace FrostFS.SDK.SmokeTests;
public class SmokeTests : SmokeTestsBase
{
- private static readonly PrmWait lightWait = new (100, 1);
+ private static readonly PrmWait lightWait = new(100, 1);
[Theory]
[InlineData(false)]
[InlineData(true)]
public async void NetworkMapTest(bool isSingleOnwerClient)
{
- using var client = isSingleOnwerClient ? Client.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url)) : Client.GetInstance(GetOptions(this.url));
-
- PrmNetmapSnapshot? prm = isSingleOnwerClient ? default : new () { Context = Ctx };
+ using var client = isSingleOnwerClient ? FrostFSClient.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url)) : FrostFSClient.GetInstance(GetOptions(this.url));
+
+ PrmNetmapSnapshot? prm = isSingleOnwerClient ? default : new() { Context = Ctx };
var result = await client.GetNetmapSnapshotAsync(prm);
Assert.True(result.Epoch > 0);
@@ -41,7 +41,7 @@ public class SmokeTests : SmokeTestsBase
[InlineData(true)]
public async void NodeInfoTest(bool isSingleOnwerClient)
{
- using var client = isSingleOnwerClient ? Client.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url)) : Client.GetInstance(GetOptions(this.url));
+ using var client = isSingleOnwerClient ? FrostFSClient.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url)) : FrostFSClient.GetInstance(GetOptions(this.url));
PrmNodeInfo? prm = isSingleOnwerClient ? default : new() { Context = Ctx };
@@ -63,9 +63,9 @@ public class SmokeTests : SmokeTestsBase
Callback = (cs) => Console.WriteLine($"{cs.MethodName} took {cs.ElapsedMicroSeconds} microseconds")
};
- using var client = Client.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url));
+ using var client = FrostFSClient.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url));
- var result = await client.GetNodeInfoAsync();
+ var result = await client.GetNodeInfoAsync();
}
[Theory]
@@ -73,7 +73,7 @@ public class SmokeTests : SmokeTestsBase
[InlineData(true)]
public async void GetSessionTest(bool isSingleOnwerClient)
{
- using var client = isSingleOnwerClient ? Client.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url)) : Client.GetInstance(GetOptions(this.url));
+ using var client = isSingleOnwerClient ? FrostFSClient.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url)) : FrostFSClient.GetInstance(GetOptions(this.url));
PrmSessionCreate? prm = isSingleOnwerClient ? new PrmSessionCreate(100) : new PrmSessionCreate(100) { Context = Ctx };
@@ -82,7 +82,7 @@ public class SmokeTests : SmokeTestsBase
var session = new Session.SessionToken().Deserialize(token.Token);
var ownerHash = Base58.Decode(OwnerId.Value);
-
+
Assert.NotNull(session);
Assert.Null(session.Body.Container);
Assert.Null(session.Body.Object);
@@ -96,14 +96,14 @@ public class SmokeTests : SmokeTestsBase
[Fact]
public async void CreateObjectWithSessionToken()
{
- using var client = Client.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url));
-
+ using var client = FrostFSClient.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url));
+
await Cleanup(client);
var token = await client.CreateSessionAsync(new PrmSessionCreate(int.MaxValue));
var createContainerParam = new PrmContainerCreate(
- new FrostFsContainerInfo(BasicAcl.PublicRW, new FrostFsPlacementPolicy(true, new FrostFsReplica(1))));
+ new FrostFsContainerInfo(new FrostFsPlacementPolicy(true, new FrostFsReplica(1))));
createContainerParam.XHeaders.Add("key1", "value1");
@@ -116,39 +116,44 @@ public class SmokeTests : SmokeTestsBase
Header = new FrostFsObjectHeader(
containerId: containerId,
type: FrostFsObjectType.Regular,
- [new FrostFsAttribute("fileName", "test")]),
+ [new FrostFsAttributePair("fileName", "test")]),
Payload = new MemoryStream(bytes),
ClientCut = false,
- SessionToken = token
+ SessionToken = token
};
-
- var objectId = await client.PutObjectAsync(param);
- var @object = await client.GetObjectAsync(new PrmObjectGet(containerId, objectId));
+ var objectId = await client.PutObjectAsync(param).ConfigureAwait(true);
+
+ var @object = await client.GetObjectAsync(new PrmObjectGet(containerId, objectId))
+ .ConfigureAwait(true);
var downloadedBytes = new byte[@object.Header.PayloadLength];
MemoryStream ms = new(downloadedBytes);
ReadOnlyMemory? chunk = null;
- while ((chunk = await @object.ObjectReader!.ReadChunk()) != null)
+ while ((chunk = await @object.ObjectReader!.ReadChunk().ConfigureAwait(true)) != null)
{
ms.Write(chunk.Value.Span);
}
- Assert.Equal(MD5.HashData(bytes), MD5.HashData(downloadedBytes));
+ Assert.Equal(SHA256.HashData(bytes), SHA256.HashData(downloadedBytes));
- await Cleanup(client);
+ await Cleanup(client).ConfigureAwait(true);
}
[Fact]
public async void FilterTest()
{
- using var client = Client.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url));
+ using var client = FrostFSClient.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url));
+
+ //var prm = new PrmApeChainList(new FrostFsChainTarget(FrostFsTargetType.Namespace, "root"));
+
+ //var chains = await client.ListChainAsync(prm);
await Cleanup(client);
var createContainerParam = new PrmContainerCreate(
- new FrostFsContainerInfo(BasicAcl.PublicRW, new FrostFsPlacementPolicy(true, new FrostFsReplica(1))))
+ new FrostFsContainerInfo(new FrostFsPlacementPolicy(true, new FrostFsReplica(1))))
{
WaitParams = lightWait
};
@@ -169,7 +174,7 @@ public class SmokeTests : SmokeTestsBase
Header = new FrostFsObjectHeader(
containerId: containerId,
type: FrostFsObjectType.Regular,
- [new FrostFsAttribute("fileName", "test")],
+ [new FrostFsAttributePair("fileName", "test")],
new FrostFsSplit()),
Payload = new MemoryStream(bytes),
ClientCut = false
@@ -189,7 +194,7 @@ public class SmokeTests : SmokeTestsBase
await CheckFilter(client, containerId, new FilterBySplitId(FrostFsMatchType.Equals, param.Header.Split.SplitId));
- await CheckFilter(client, containerId, new FilterByAttribute(FrostFsMatchType.Equals, "fileName", "test"));
+ await CheckFilter(client, containerId, new FilterByAttributePair(FrostFsMatchType.Equals, "fileName", "test"));
await CheckFilter(client, containerId, new FilterByObjectId(FrostFsMatchType.Equals, objectId));
@@ -227,14 +232,14 @@ public class SmokeTests : SmokeTestsBase
[InlineData(6 * 1024 * 1024 + 100)]
public async void SimpleScenarioTest(int objectSize)
{
- using var client = Client.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url));
-
+ using var client = FrostFSClient.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url));
+
await Cleanup(client);
bool callbackInvoked = false;
var ctx = new Context
{
- // Timeout = TimeSpan.FromSeconds(20),
+ // Timeout = TimeSpan.FromSeconds(20),
Callback = new((CallStatistics cs) =>
{
callbackInvoked = true;
@@ -243,7 +248,7 @@ public class SmokeTests : SmokeTestsBase
};
var createContainerParam = new PrmContainerCreate(
- new FrostFsContainerInfo(BasicAcl.PublicRW, new FrostFsPlacementPolicy(true, new FrostFsReplica(1)),[new ("testKey", "testValue")]))
+ new FrostFsContainerInfo(new FrostFsPlacementPolicy(true, new FrostFsReplica(1)), [new("testKey", "testValue")]))
{
Context = ctx
};
@@ -261,7 +266,7 @@ public class SmokeTests : SmokeTestsBase
Header = new FrostFsObjectHeader(
containerId: createdContainer,
type: FrostFsObjectType.Regular,
- [new FrostFsAttribute("fileName", "test")]),
+ [new FrostFsAttributePair("fileName", "test")]),
Payload = new MemoryStream(bytes),
ClientCut = false,
Context = new Context
@@ -272,7 +277,7 @@ public class SmokeTests : SmokeTestsBase
var objectId = await client.PutObjectAsync(param);
- var filter = new FilterByAttribute(FrostFsMatchType.Equals, "fileName", "test");
+ var filter = new FilterByAttributePair(FrostFsMatchType.Equals, "fileName", "test");
bool hasObject = false;
await foreach (var objId in client.SearchObjectsAsync(new PrmObjectSearch(createdContainer) { Filters = [filter] }))
@@ -315,7 +320,7 @@ public class SmokeTests : SmokeTestsBase
[InlineData(6 * 1024 * 1024 + 100)]
public async void SimpleScenarioWithSessionTest(int objectSize)
{
- using var client = Client.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url));
+ using var client = FrostFSClient.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url));
var token = await client.CreateSessionAsync(new PrmSessionCreate(int.MaxValue));
@@ -328,7 +333,7 @@ public class SmokeTests : SmokeTestsBase
};
var createContainerParam = new PrmContainerCreate(
- new FrostFsContainerInfo(BasicAcl.PublicRW, new FrostFsPlacementPolicy(true, new FrostFsReplica(1))))
+ new FrostFsContainerInfo(new FrostFsPlacementPolicy(true, new FrostFsReplica(1))))
{
Context = ctx
};
@@ -345,7 +350,7 @@ public class SmokeTests : SmokeTestsBase
Header = new FrostFsObjectHeader(
containerId: container,
type: FrostFsObjectType.Regular,
- [new FrostFsAttribute("fileName", "test")]),
+ [new FrostFsAttributePair("fileName", "test")]),
Payload = new MemoryStream(bytes),
ClientCut = false,
Context = new Context
@@ -357,7 +362,7 @@ public class SmokeTests : SmokeTestsBase
var objectId = await client.PutObjectAsync(param);
- var filter = new FilterByAttribute(FrostFsMatchType.Equals, "fileName", "test");
+ var filter = new FilterByAttributePair(FrostFsMatchType.Equals, "fileName", "test");
bool hasObject = false;
await foreach (var objId in client.SearchObjectsAsync(new PrmObjectSearch(container) { Filters = [filter], SessionToken = token }))
@@ -402,12 +407,12 @@ public class SmokeTests : SmokeTestsBase
[InlineData(2 * 64 * 1024 * 1024 + 256)]
[InlineData(200)]
public async void ClientCutScenarioTest(int objectSize)
- {
- using var client = Client.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url));
+ {
+ using var client = FrostFSClient.GetSingleOwnerInstance(GetSingleOwnerOptions(this.key, this.url));
await Cleanup(client);
- var createContainerParam = new PrmContainerCreate(new FrostFsContainerInfo(BasicAcl.PublicRW, new FrostFsPlacementPolicy(true, new FrostFsReplica(1))))
+ var createContainerParam = new PrmContainerCreate(new FrostFsContainerInfo(new FrostFsPlacementPolicy(true, new FrostFsReplica(1))))
{
WaitParams = lightWait
};
@@ -431,14 +436,14 @@ public class SmokeTests : SmokeTestsBase
Header = new FrostFsObjectHeader(
containerId: containerId,
type: FrostFsObjectType.Regular,
- [new FrostFsAttribute("fileName", "test")]),
+ [new FrostFsAttributePair("fileName", "test")]),
Payload = new MemoryStream(bytes),
ClientCut = true
};
var objectId = await client.PutObjectAsync(param);
- var filter = new FilterByAttribute(FrostFsMatchType.Equals, "fileName", "test");
+ var filter = new FilterByAttributePair(FrostFsMatchType.Equals, "fileName", "test");
bool hasObject = false;
await foreach (var objId in client.SearchObjectsAsync(new PrmObjectSearch(containerId, filter)))
@@ -476,16 +481,16 @@ public class SmokeTests : SmokeTestsBase
IAsyncEnumerator? enumerator = null;
do
{
- if (deadline <= DateTime.UtcNow)
- {
- Assert.Fail("Containers exist");
- break;
- }
+ if (deadline <= DateTime.UtcNow)
+ {
+ Assert.Fail("Containers exist");
+ break;
+ }
- enumerator = client.ListContainersAsync().GetAsyncEnumerator();
- await Task.Delay(500);
+ enumerator = client.ListContainersAsync().GetAsyncEnumerator();
+ await Task.Delay(500);
}
- while (await enumerator!.MoveNextAsync());
+ while (await enumerator!.MoveNextAsync());
}
private static byte[] GetRandomBytes(int size)
diff --git a/src/FrostFS.SDK.Tests/SmokeTestsBase.cs b/src/FrostFS.SDK.Tests/SmokeTestsBase.cs
index 45f3460..5bf7733 100644
--- a/src/FrostFS.SDK.Tests/SmokeTestsBase.cs
+++ b/src/FrostFS.SDK.Tests/SmokeTestsBase.cs
@@ -8,6 +8,7 @@ namespace FrostFS.SDK.SmokeTests;
public abstract class SmokeTestsBase
{
protected readonly string key = "KzPXA6669m2pf18XmUdoR8MnP1pi1PMmefiFujStVFnv7WR5SRmK";
+
protected readonly string url = "http://172.23.32.4:8080";
protected ECDsa Key { get; }