Skip to content

Added support for the <delimiter> query parameter in CloudFilesProvi… #642

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/corelib/Core/Providers/IObjectStorageProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,7 @@ public interface IObjectStorageProvider
/// <param name="marker">When specified, only objects with names greater than <paramref name="marker"/> are returned. If the value is <see langword="null"/>, the list starts at the beginning.</param>
/// <param name="markerEnd">When specified, only objects with names less than <paramref name="markerEnd"/> are returned. If the value is <see langword="null"/>, the list proceeds to the end, or until the <paramref name="limit"/> is reached.</param>
/// <param name="prefix">Prefix of object names to include</param>
/// <param name="delimiter">A character that define the end of a file name. If the value is '\0', no delimiter are specified.</param>
/// <param name="region">The region in which to execute this action. If not specified, the user's default region will be used.</param>
/// <param name="useInternalUrl"><see langword="true"/> to use the endpoint's <see cref="Endpoint.InternalURL"/>; otherwise <see langword="false"/> to use the endpoint's <see cref="Endpoint.PublicURL"/>.</param>
/// <param name="identity">The cloud identity to use for this request. If not specified, the default identity for the current provider instance will be used.</param>
Expand Down Expand Up @@ -1062,7 +1063,7 @@ public interface IObjectStorageProvider
/// <code source="..\Samples\FSharpCodeSamples\ObjectStorageProviderExamples.fs" region="ListObjectsInContainer" language="fs"/>
/// </example>
/// <seealso href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/GET_showContainerDetails_v1__account___container__storage_container_services.html">Show container details and list objects (OpenStack Object Storage API v1 Reference)</seealso>
IEnumerable<ContainerObject> ListObjects(string container, int? limit = null, string marker = null, string markerEnd = null, string prefix = null, string region = null, bool useInternalUrl = false, CloudIdentity identity = null);
IEnumerable<ContainerObject> ListObjects(string container, int? limit = null, string marker = null, string markerEnd = null, string prefix = null, char delimiter = '\0', string region = null, bool useInternalUrl = false, CloudIdentity identity = null);

/// <summary>
/// Creates an object using data from a file. If the destination file already exists, the contents are overwritten.
Expand Down
56 changes: 34 additions & 22 deletions src/corelib/Providers/Rackspace/CloudFilesProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ public class CloudFilesProvider : ProviderBase<IObjectStorageProvider>, IObjectS
/// implementation.
/// </summary>
public CloudFilesProvider()
: this(null, null, null, null) { }
: this(null, null, null, null)
{ }

/// <summary>
/// Initializes a new instance of the <see cref="CloudFilesProvider"/> class with
Expand All @@ -83,7 +84,8 @@ public CloudFilesProvider()
/// </summary>
/// <param name="defaultIdentity">The default identity to use for calls that do not explicitly specify an identity. If this value is <see langword="null"/>, no default identity is available so all calls must specify an explicit identity.</param>
public CloudFilesProvider(CloudIdentity defaultIdentity)
: this(defaultIdentity, null, null, null) { }
: this(defaultIdentity, null, null, null)
{ }

/// <summary>
/// Initializes a new instance of the <see cref="CloudFilesProvider"/> class with
Expand All @@ -92,7 +94,8 @@ public CloudFilesProvider(CloudIdentity defaultIdentity)
/// </summary>
/// <param name="restService">The implementation of <see cref="IRestService"/> to use for executing REST requests. If this value is <see langword="null"/>, the provider will use a new instance of <see cref="JsonRestServices"/>.</param>
public CloudFilesProvider(IRestService restService)
: this(null, null, null, restService) { }
: this(null, null, null, restService)
{ }

/// <summary>
/// Initializes a new instance of the <see cref="CloudFilesProvider"/> class with
Expand All @@ -101,7 +104,8 @@ public CloudFilesProvider(IRestService restService)
/// </summary>
/// <param name="identityProvider">The identity provider to use for authenticating requests to this provider. If this value is <see langword="null"/>, a new instance of <see cref="CloudIdentityProvider"/> is created with no default identity.</param>
public CloudFilesProvider(IIdentityProvider identityProvider)
: this(null, null, identityProvider, null) { }
: this(null, null, identityProvider, null)
{ }

/// <summary>
/// Initializes a new instance of the <see cref="CloudFilesProvider"/> class with
Expand All @@ -111,7 +115,8 @@ public CloudFilesProvider(IIdentityProvider identityProvider)
/// <param name="defaultIdentity">The default identity to use for calls that do not explicitly specify an identity. If this value is <see langword="null"/>, no default identity is available so all calls must specify an explicit identity.</param>
/// <param name="identityProvider">The identity provider to use for authenticating requests to this provider. If this value is <see langword="null"/>, a new instance of <see cref="CloudIdentityProvider"/> is created using <paramref name="defaultIdentity"/> as the default identity.</param>
public CloudFilesProvider(CloudIdentity defaultIdentity, IIdentityProvider identityProvider)
: this(defaultIdentity, null, identityProvider, null) { }
: this(defaultIdentity, null, identityProvider, null)
{ }

/// <summary>
/// Initializes a new instance of the <see cref="CloudFilesProvider"/> class with
Expand All @@ -121,7 +126,8 @@ public CloudFilesProvider(CloudIdentity defaultIdentity, IIdentityProvider ident
/// <param name="defaultIdentity">The default identity to use for calls that do not explicitly specify an identity. If this value is <see langword="null"/>, no default identity is available so all calls must specify an explicit identity.</param>
/// <param name="restService">The implementation of <see cref="IRestService"/> to use for executing REST requests. If this value is <see langword="null"/>, the provider will use a new instance of <see cref="JsonRestServices"/>.</param>
public CloudFilesProvider(CloudIdentity defaultIdentity, IRestService restService)
: this(defaultIdentity, null, null, restService) { }
: this(defaultIdentity, null, null, restService)
{ }

/// <summary>
/// Initializes a new instance of the <see cref="CloudFilesProvider"/> class with
Expand All @@ -134,7 +140,8 @@ public CloudFilesProvider(CloudIdentity defaultIdentity, IRestService restServic
/// <param name="identityProvider">The identity provider to use for authenticating requests to this provider. If this value is <see langword="null"/>, a new instance of <see cref="CloudIdentityProvider"/> is created using <paramref name="defaultIdentity"/> as the default identity.</param>
/// <param name="restService">The implementation of <see cref="IRestService"/> to use for executing REST requests. If this value is <see langword="null"/>, the provider will use a new instance of <see cref="JsonRestServices"/>.</param>
public CloudFilesProvider(CloudIdentity defaultIdentity, IIdentityProvider identityProvider, IRestService restService)
: this(defaultIdentity, null, identityProvider, restService) { }
: this(defaultIdentity, null, identityProvider, restService)
{ }

/// <summary>
/// Initializes a new instance of the <see cref="CloudFilesProvider"/> class with
Expand All @@ -148,7 +155,8 @@ public CloudFilesProvider(CloudIdentity defaultIdentity, IIdentityProvider ident
/// <param name="identityProvider">The identity provider to use for authenticating requests to this provider. If this value is <see langword="null"/>, a new instance of <see cref="CloudIdentityProvider"/> is created using <paramref name="defaultIdentity"/> as the default identity.</param>
/// <param name="restService">The implementation of <see cref="IRestService"/> to use for executing REST requests. If this value is <see langword="null"/>, the provider will use a new instance of <see cref="JsonRestServices"/>.</param>
public CloudFilesProvider(CloudIdentity defaultIdentity, string defaultRegion, IIdentityProvider identityProvider, IRestService restService)
: this(defaultIdentity, defaultRegion, identityProvider, restService, CloudFilesValidator.Default, CloudFilesMetadataProcessor.Default, EncodeDecodeProvider.Default, HttpStatusCodeParser.Default, new BulkDeletionResultMapper(HttpStatusCodeParser.Default)) { }
: this(defaultIdentity, defaultRegion, identityProvider, restService, CloudFilesValidator.Default, CloudFilesMetadataProcessor.Default, EncodeDecodeProvider.Default, HttpStatusCodeParser.Default, new BulkDeletionResultMapper(HttpStatusCodeParser.Default))
{ }

/// <summary>
/// Initializes a new instance of the <see cref="CloudFilesProvider"/> class with
Expand Down Expand Up @@ -176,7 +184,8 @@ public CloudFilesProvider(CloudIdentity defaultIdentity, string defaultRegion, I
/// <para>If <paramref name="mapper"/> is <see langword="null"/>.</para>
/// </exception>
internal CloudFilesProvider(string defaultRegion, IIdentityProvider identityProvider, IRestService restService, IObjectStorageValidator cloudFilesValidator, IObjectStorageMetadataProcessor cloudFilesMetadataProcessor, IEncodeDecodeProvider encodeDecodeProvider, IStatusParser statusParser, IObjectMapper<BulkDeleteResponse, BulkDeletionResults> mapper)
: this(null, defaultRegion, identityProvider, restService, cloudFilesValidator, cloudFilesMetadataProcessor, encodeDecodeProvider, statusParser, mapper) { }
: this(null, defaultRegion, identityProvider, restService, cloudFilesValidator, cloudFilesMetadataProcessor, encodeDecodeProvider, statusParser, mapper)
{ }

/// <summary>
/// Initializes a new instance of the <see cref="CloudFilesProvider"/> class with
Expand Down Expand Up @@ -274,14 +283,14 @@ public ObjectStore CreateContainer(string container, Dictionary<string, string>

switch (response.StatusCode)
{
case HttpStatusCode.Created:
return ObjectStore.ContainerCreated;
case HttpStatusCode.Created:
return ObjectStore.ContainerCreated;

case HttpStatusCode.Accepted:
return ObjectStore.ContainerExists;
case HttpStatusCode.Accepted:
return ObjectStore.ContainerExists;

default:
throw new ResponseException(string.Format("Unexpected status {0} returned by Create Container.", response.StatusCode), response);
default:
throw new ResponseException(string.Format("Unexpected status {0} returned by Create Container.", response.StatusCode), response);
}
}

Expand Down Expand Up @@ -310,12 +319,12 @@ public void DeleteContainer(string container, bool deleteObjects = false, string
{
var objects = ListObjects(container, count, region: region, useInternalUrl: useInternalUrl, identity: identity);

if(objects.Any())
if (objects.Any())
DeleteObjects(container, objects.Select(o => o.Name), region: region, useInternalUrl: useInternalUrl, identity: identity);
}
}
}

var urlPath = new Uri(string.Format("{0}/{1}", GetServiceEndpointCloudFiles(identity, region, useInternalUrl), _encodeDecodeProvider.UrlEncode(container)));

try
Expand Down Expand Up @@ -801,7 +810,7 @@ public Dictionary<string, string> GetObjectMetaData(string container, string obj
}

/// <inheritdoc />
public void UpdateObjectHeaders(string container, string objectName, Dictionary<string,string> headers, string region = null, bool useInternalUrl = false, CloudIdentity identity = null)
public void UpdateObjectHeaders(string container, string objectName, Dictionary<string, string> headers, string region = null, bool useInternalUrl = false, CloudIdentity identity = null)
{
if (container == null)
throw new ArgumentNullException("container");
Expand Down Expand Up @@ -834,7 +843,7 @@ public void UpdateObjectHeaders(string container, string objectName, Dictionary<
settings.ContentType = null;

ExecuteRESTRequest(identity, urlPath, HttpMethod.POST, headers: hdrs, settings: settings);

}

/// <inheritdoc />
Expand Down Expand Up @@ -942,7 +951,7 @@ public void DeleteObjectMetadata(string container, string objectName, string key
}

/// <inheritdoc />
public IEnumerable<ContainerObject> ListObjects(string container, int? limit = null, string marker = null, string markerEnd = null, string prefix = null, string region = null, bool useInternalUrl = false, CloudIdentity identity = null)
public IEnumerable<ContainerObject> ListObjects(string container, int? limit = null, string marker = null, string markerEnd = null, string prefix = null, char delimiter = '\0', string region = null, bool useInternalUrl = false, CloudIdentity identity = null)
{
if (container == null)
throw new ArgumentNullException("container");
Expand All @@ -960,6 +969,9 @@ public IEnumerable<ContainerObject> ListObjects(string container, int? limit = n
if (limit != null)
queryStringParameter.Add("limit", limit.ToString());

if (delimiter != '\0')
queryStringParameter.Add("delimiter", delimiter.ToString());

if (!string.IsNullOrEmpty(marker))
queryStringParameter.Add("marker", marker);

Expand Down Expand Up @@ -1258,7 +1270,7 @@ public void DeleteObject(string container, string objectName, Dictionary<string,
_cloudFilesValidator.ValidateObjectName(objectName);

Dictionary<string, string> objectHeader = null;
if(deleteSegments)
if (deleteSegments)
objectHeader = GetObjectHeaders(container, objectName, region, useInternalUrl, identity);

if (deleteSegments && objectHeader != null && objectHeader.Any(h => h.Key.Equals(ObjectManifest, StringComparison.OrdinalIgnoreCase)))
Expand Down Expand Up @@ -2592,6 +2604,6 @@ public long LargeFileBatchThreshold
public const string ProcessedHeadersHeaderKey = "headers";

#endregion

}
}