Skip to content

Commit

Permalink
Add WithHeaders and WithMetadata extension methods for StorageMetadata
Browse files Browse the repository at this point in the history
  • Loading branch information
sharwell committed Jan 28, 2015
1 parent bb95456 commit a09fc52
Show file tree
Hide file tree
Showing 13 changed files with 185 additions and 36 deletions.
1 change: 1 addition & 0 deletions src/OpenStack.Net/OpenStack.Net.net35.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@
<Compile Include="OpenStack\Services\ObjectStorage\V1\SetObjectMetadataApiCall.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\SetVersionsLocationApiCall.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\StorageMetadata.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\StorageMetadataExtensions.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriExtension.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriExtensions.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriSupportedApiCall.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/OpenStack.Net/OpenStack.Net.net40.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@
<Compile Include="OpenStack\Services\ObjectStorage\V1\SetObjectMetadataApiCall.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\SetVersionsLocationApiCall.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\StorageMetadata.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\StorageMetadataExtensions.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriExtension.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriExtensions.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriSupportedApiCall.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/OpenStack.Net/OpenStack.Net.net45.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
<Compile Include="OpenStack\Services\ObjectStorage\V1\SetObjectMetadataApiCall.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\SetVersionsLocationApiCall.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\StorageMetadata.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\StorageMetadataExtensions.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriExtension.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriExtensions.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriSupportedApiCall.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/OpenStack.Net/OpenStack.Net.netcore45.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@
<Compile Include="OpenStack\Services\ObjectStorage\V1\SetObjectMetadataApiCall.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\SetVersionsLocationApiCall.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\StorageMetadata.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\StorageMetadataExtensions.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriExtension.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriExtensions.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriSupportedApiCall.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/OpenStack.Net/OpenStack.Net.portable-net40.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@
<Compile Include="OpenStack\Services\ObjectStorage\V1\SetObjectMetadataApiCall.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\SetVersionsLocationApiCall.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\StorageMetadata.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\StorageMetadataExtensions.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriExtension.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriExtensions.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriSupportedApiCall.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/OpenStack.Net/OpenStack.Net.portable-net45.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@
<Compile Include="OpenStack\Services\ObjectStorage\V1\SetObjectMetadataApiCall.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\SetVersionsLocationApiCall.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\StorageMetadata.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\StorageMetadataExtensions.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriExtension.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriExtensions.cs" />
<Compile Include="OpenStack\Services\ObjectStorage\V1\TemporaryUriSupportedApiCall.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ public static string GetSecretKey2(this AccountMetadata metadata)
public static AccountMetadata WithSecretKey(this AccountMetadata metadata, string key)
{
ImmutableDictionary<string, string> updatedMetadata = metadata.Metadata.SetItem(AccountSecretKey, key ?? string.Empty);
return new AccountMetadata(metadata.Headers, updatedMetadata);
return metadata.WithMetadata(updatedMetadata);
}

/// <summary>
Expand All @@ -285,7 +285,7 @@ public static AccountMetadata WithSecretKey(this AccountMetadata metadata, strin
public static AccountMetadata WithSecretKey2(this AccountMetadata metadata, string key)
{
ImmutableDictionary<string, string> updatedMetadata = metadata.Metadata.SetItem(AccountSecretKey2, key ?? string.Empty);
return new AccountMetadata(metadata.Headers, updatedMetadata);
return metadata.WithMetadata(updatedMetadata);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public virtual Task<UpdateAccountMetadataApiCall> PrepareRemoveAccountMetadataAs
metadata.Add(key, string.Empty);
}

return PrepareUpdateAccountMetadataAsync(new AccountMetadata(ImmutableDictionary<string, string>.Empty, metadata.ToImmutable()), cancellationToken);
return PrepareUpdateAccountMetadataAsync(AccountMetadata.Empty.WithMetadata(metadata.ToImmutable()), cancellationToken);
}

/// <inheritdoc/>
Expand Down Expand Up @@ -316,7 +316,7 @@ public virtual Task<UpdateContainerMetadataApiCall> PrepareRemoveContainerMetada
metadata.Add(key, string.Empty);
}

return PrepareUpdateContainerMetadataAsync(container, new ContainerMetadata(ImmutableDictionary<string, string>.Empty, metadata.ToImmutable()), cancellationToken);
return PrepareUpdateContainerMetadataAsync(container, ContainerMetadata.Empty.WithMetadata(metadata.ToImmutable()), cancellationToken);
}

/// <inheritdoc/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ public static Task UpdateObjectMetadataAsync(this IObjectStorageService service,
/// <seealso href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/POST_updateObjectMeta__v1__account___container___object__storage_object_services.html">Create or update object metadata (OpenStack Object Storage API V1 Reference)</seealso>
public static Task RemoveObjectMetadataAsync(this IObjectStorageService service, ContainerName container, ObjectName @object, IEnumerable<string> keys, CancellationToken cancellationToken)
{
ObjectMetadata updatedMetadata = new ObjectMetadata(ImmutableDictionary<string, string>.Empty, keys.ToImmutableDictionary(i => i, i => string.Empty, StringComparer.OrdinalIgnoreCase));
ObjectMetadata updatedMetadata = ObjectMetadata.Empty.WithMetadata(keys.ToImmutableDictionary(i => i, i => string.Empty, StringComparer.OrdinalIgnoreCase));
return UpdateObjectMetadataAsync(service, container, @object, updatedMetadata, cancellationToken);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ public abstract class StorageMetadata
/// <summary>
/// This is the backing field for the <see cref="Headers"/> property.
/// </summary>
private readonly ImmutableDictionary<string, string> _headers;
private ImmutableDictionary<string, string> _headers;

/// <summary>
/// This is the backing field for the <see cref="Metadata"/> property.
/// </summary>
private readonly ImmutableDictionary<string, string> _metadata;
private ImmutableDictionary<string, string> _metadata;

/// <summary>
/// Initializes a new instance of the <see cref="StorageMetadata"/> class using the metadata present in the
Expand Down Expand Up @@ -183,5 +183,73 @@ public static string DecodeHeaderValue(string value)
byte[] encodedBytes = value.ToCharArray().ConvertAll(i => (byte)i);
return Encoding.UTF8.GetString(encodedBytes, 0, encodedBytes.Length);
}

/// <summary>
/// Gets a <see cref="StorageMetadata"/> with the same type and metadata from the current object and the
/// specified headers.
/// </summary>
/// <remarks>
/// <para>This method provides the implementation for
/// <see cref="StorageMetadataExtensions.WithHeaders{TMetadata}"/>.</para>
/// </remarks>
/// <param name="headers">The new headers for the object.</param>
/// <returns>
/// A <see cref="StorageMetadata"/> which represents the current object with the specified headers. If
/// <paramref name="headers"/> is the same as the existing <see cref="Headers"/> for the current object, the
/// method may return the same instance.
/// </returns>
/// <exception cref="ArgumentException">
/// If <paramref name="headers"/> contains two keys which are equivalent using the
/// <see cref="StringComparer.OrdinalIgnoreCase"/> comparer, but the associated values are different.
/// </exception>
/// <exception cref="ArgumentNullException">
/// If <paramref name="headers"/> is <see langword="null"/>.
/// </exception>
protected internal StorageMetadata WithHeadersImpl(ImmutableDictionary<string, string> headers)
{
if (headers == null)
throw new ArgumentNullException("headers");

if (_headers == headers)
return this;

StorageMetadata updated = (StorageMetadata)MemberwiseClone();
updated._headers = headers.WithComparers(StringComparer.OrdinalIgnoreCase);
return updated;
}

/// <summary>
/// Gets a <see cref="StorageMetadata"/> with the same type and headers from the current object and the
/// specified metadata.
/// </summary>
/// <remarks>
/// <para>This method provides the implementation for
/// <see cref="StorageMetadataExtensions.WithMetadata{TMetadata}"/>.</para>
/// </remarks>
/// <param name="metadata">The new metadata for the object.</param>
/// <returns>
/// A <see cref="StorageMetadata"/> which represents the current object with the specified metadata. If
/// <paramref name="metadata"/> is the same as the existing <see cref="Metadata"/> for the current object, the
/// method may return the same instance.
/// </returns>
/// <exception cref="ArgumentException">
/// If <paramref name="metadata"/> contains two keys which are equivalent using the
/// <see cref="StringComparer.OrdinalIgnoreCase"/> comparer, but the associated values are different.
/// </exception>
/// <exception cref="ArgumentNullException">
/// If <paramref name="metadata"/> is <see langword="null"/>.
/// </exception>
protected internal StorageMetadata WithMetadataImpl(ImmutableDictionary<string, string> metadata)
{
if (metadata == null)
throw new ArgumentNullException("metadata");

if (_metadata == metadata)
return this;

StorageMetadata updated = (StorageMetadata)MemberwiseClone();
updated._metadata = metadata.WithComparers(StringComparer.OrdinalIgnoreCase);
return updated;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
namespace OpenStack.Services.ObjectStorage.V1
{
using System;
using System.Collections.Immutable;

/// <summary>
/// This class provides extension methods for the <see cref="StorageMetadata"/> class.
/// </summary>
/// <threadsafety static="true" instance="false"/>
/// <preliminary/>
public static class StorageMetadataExtensions
{
/// <summary>
/// Gets a <see cref="StorageMetadata"/> instance with the same type and metadata from the input object and the
/// specified header values.
/// </summary>
/// <remarks>
/// <para>This method exposes <see cref="StorageMetadata.WithHeadersImpl"/> in a manner that preserves the
/// static type of the input <paramref name="storageMetadata"/>.</para>
/// </remarks>
/// <typeparam name="TMetadata">The static type of the input storage metadata.</typeparam>
/// <param name="storageMetadata">The storage metadata object.</param>
/// <param name="headers">The new headers for the object.</param>
/// <returns>
/// A <see cref="StorageMetadata"/> which represents the input <paramref name="storageMetadata"/> with the
/// specified headers. If <paramref name="headers"/> is the same as the existing
/// <see cref="StorageMetadata.Headers"/> for the input object, the method may return the
/// <paramref name="storageMetadata"/> instance itself.
/// </returns>
/// <exception cref="ArgumentException">
/// If <paramref name="headers"/> contains two keys which are equivalent using the
/// <see cref="StringComparer.OrdinalIgnoreCase"/> comparer, but the associated values are different.
/// </exception>
/// <exception cref="ArgumentNullException">
/// <para>If <paramref name="storageMetadata"/> is <see langword="null"/>.</para>
/// <para>-or-</para>
/// <para>If <paramref name="headers"/> is <see langword="null"/>.</para>
/// </exception>
public static TMetadata WithHeaders<TMetadata>(this TMetadata storageMetadata, ImmutableDictionary<string, string> headers)
where TMetadata : StorageMetadata
{
if (storageMetadata == null)
throw new ArgumentNullException("storageMetadata");

return (TMetadata)storageMetadata.WithHeadersImpl(headers);
}

/// <summary>
/// Gets a <see cref="StorageMetadata"/> instance with the same type and headers from the input object and the
/// specified metadata values.
/// </summary>
/// <remarks>
/// <para>This method exposes <see cref="StorageMetadata.WithMetadataImpl"/> in a manner that preserves the
/// static type of the input <paramref name="storageMetadata"/>.</para>
/// </remarks>
/// <typeparam name="TMetadata">The static type of the input storage metadata.</typeparam>
/// <param name="storageMetadata">The storage metadata object.</param>
/// <param name="metadata">The new metadata for the object.</param>
/// <returns>
/// A <see cref="StorageMetadata"/> which represents the input <paramref name="storageMetadata"/> with the
/// specified metadata. If <paramref name="metadata"/> is the same as the existing
/// <see cref="StorageMetadata.Metadata"/> for the input object, the method may return the
/// <paramref name="storageMetadata"/> instance itself.
/// </returns>
/// <exception cref="ArgumentException">
/// If <paramref name="metadata"/> contains two keys which are equivalent using the
/// <see cref="StringComparer.OrdinalIgnoreCase"/> comparer, but the associated values are different.
/// </exception>
/// <exception cref="ArgumentNullException">
/// <para>If <paramref name="storageMetadata"/> is <see langword="null"/>.</para>
/// <para>-or-</para>
/// <para>If <paramref name="metadata"/> is <see langword="null"/>.</para>
/// </exception>
public static TMetadata WithMetadata<TMetadata>(this TMetadata storageMetadata, ImmutableDictionary<string, string> metadata)
where TMetadata : StorageMetadata
{
if (storageMetadata == null)
throw new ArgumentNullException("storageMetadata");

return (TMetadata)storageMetadata.WithMetadataImpl(metadata);
}
}
}
Loading

0 comments on commit a09fc52

Please sign in to comment.