bp/intra-server-copy

Change-Id: I8302999b44b0027b37e040c5c8f807652a799279
This commit is contained in:
plemanach 2015-04-04 20:44:13 +01:00
parent 9a22fb78f8
commit cb625f9b01
8 changed files with 354 additions and 1 deletions

View File

@ -411,6 +411,55 @@ namespace OpenStack.Test.Storage
Assert.AreEqual(obj, resp);
}
[TestMethod]
public async Task CanCopyStorageObjects()
{
var containerName = "TestContainer";
var objectName = "TestObject";
var targetContainerName = "TargetTestContainer";
var obj = new StorageObject(objectName, targetContainerName, DateTime.UtcNow, "12345", 12345,
"application/octet-stream", new Dictionary<string, string>());
this.ServicePocoClient.CopyStorageObjectDelegate = async (s, container, destinationObjectName) =>
{
Assert.AreEqual(container, obj.ContainerName);
Assert.AreEqual(s.Name, obj.Name);
return await Task.Run(() => obj);
};
var client = new StorageServiceClient(GetValidCreds(), "Swift", CancellationToken.None, this.ServiceLocator);
var resp = await client.CopyStorageObject(containerName, objectName, targetContainerName);
Assert.AreEqual(obj, resp);
}
[TestMethod]
public async Task CanCopyStorageObjectsAndChangeName()
{
var containerName = "TestContainer";
var objectName = "TestObject";
var targetObjectName = "TargetTestObject";
var targetContainerName = "TargetTestContainer";
var obj = new StorageObject(targetObjectName, targetContainerName, DateTime.UtcNow, "12345", 12345,
"application/octet-stream", new Dictionary<string, string>());
this.ServicePocoClient.CopyStorageObjectDelegate = async (s, container, destinationObjectName) =>
{
Assert.AreEqual(container, obj.ContainerName);
Assert.AreEqual(destinationObjectName, obj.Name);
return await Task.Run(() => obj);
};
var client = new StorageServiceClient(GetValidCreds(), "Swift", CancellationToken.None, this.ServiceLocator);
var resp = await client.CopyStorageObject(containerName, objectName, targetContainerName, targetObjectName);
Assert.AreEqual(obj, resp);
}
[TestMethod]
public async Task CreatingAnObjectLargerThanTheThresholdCreatesObjectWithSegments()
{
@ -639,6 +688,77 @@ namespace OpenStack.Test.Storage
await client.CreateStorageObject(containerName, objectName, null, new MemoryStream());
}
#region Copy Storage Objects Tests
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public async Task CopyStorageObjectsWithNullContainerNameThrows()
{
var objectName = "TestObject";
var targetContainerName = "TargetTestContainer";
var client = new StorageServiceClient(GetValidCreds(), "Swift", CancellationToken.None, this.ServiceLocator);
await client.CopyStorageObject(null, objectName, targetContainerName);
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public async Task CopyStorageObjectsWithEmptyContainerNameThrows()
{
var objectName = "TestObject";
var targetContainerName = "TargetTestContainer";
var client = new StorageServiceClient(GetValidCreds(), "Swift", CancellationToken.None, this.ServiceLocator);
await client.CopyStorageObject(string.Empty, objectName, targetContainerName);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public async Task CopyStorageObjectsWithNullObjectNameThrows()
{
var containerName = "TestContainer";
var targetContainerName = "TargetTestContainer";
var client = new StorageServiceClient(GetValidCreds(), "Swift", CancellationToken.None, this.ServiceLocator);
await client.CopyStorageObject(containerName, null, targetContainerName);
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public async Task CopyStorageObjectsWithEmptyObjectNameThrows()
{
var containerName = "TestContainer";
var targetContainerName = "TargetTestContainer";
var client = new StorageServiceClient(GetValidCreds(), "Swift", CancellationToken.None, this.ServiceLocator);
await client.CopyStorageObject(containerName, string.Empty, targetContainerName);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public async Task CopyStorageObjectsWithNullTargetContainerThrows()
{
var containerName = "TestContainer";
var objectName = "TestObject";
var client = new StorageServiceClient(GetValidCreds(), "Swift", CancellationToken.None, this.ServiceLocator);
await client.CopyStorageObject(containerName, objectName, null);
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public async Task CopyStorageObjectsWithEmptyTargetContainerThrows()
{
var containerName = "TestContainer";
var objectName = "TestObject";
var client = new StorageServiceClient(GetValidCreds(), "Swift", CancellationToken.None, this.ServiceLocator);
await client.CopyStorageObject(containerName, objectName, string.Empty);
}
#endregion
[TestMethod]
public async Task CanCreateStaticStorageManifest()
{

View File

@ -1375,6 +1375,162 @@ namespace OpenStack.Test.Storage
#endregion
#region Copy Storage Object Tests
[TestMethod]
public async Task CanCopyStorageObjectWithCreatedResponse()
{
var containerName = "TestContainer";
var objectName = "TestObject";
var targetContainerName = "TargetTestContainer";
var headers = new HttpHeadersAbstraction()
{
{"Content-Length", "0"},
{"Content-Type", "application/octet-stream"},
{"X-Copied-From-Last-Modified","Wed, 12 Mar 2014 22:42:23 GMT"},
{"X-Copied-From" , "TestContainer/TestObject"},
{"Last-Modified", "Wed, 12 Mar 2014 23:42:23 GMT"},
{"ETag", "d41d8cd98f00b204e9800998ecf8427e"}
};
var objRequest = new StorageObject(objectName, containerName);
var restResp = new HttpResponseAbstraction(new MemoryStream(), headers, HttpStatusCode.Created);
this.StorageServiceRestClient.Responses.Enqueue(restResp);
var client = new StorageServicePocoClient(GetValidContext(), this.ServiceLocator);
var result = await client.CopyStorageObject(objRequest, targetContainerName);
Assert.IsNotNull(result);
Assert.AreEqual(objectName, result.Name);
Assert.AreEqual(containerName, result.ContainerName);
Assert.AreEqual(0, result.Length); //length of content stream
Assert.AreEqual("application/octet-stream", result.ContentType);
Assert.AreEqual("d41d8cd98f00b204e9800998ecf8427e", result.ETag);
Assert.AreEqual(DateTime.Parse("Wed, 12 Mar 2014 23:42:23 GMT"), result.LastModified);
}
[TestMethod]
public async Task CanCopyStorageObjectWithFoldersAndCreatedResponse()
{
var containerName = "TestContainer";
var objectName = "a/b/TestObject";
var targetContainerName = "TargetTestContainer";
var headers = new HttpHeadersAbstraction()
{
{"Content-Length", "0"},
{"Content-Type", "application/octet-stream"},
{"X-Copied-From-Last-Modified","Wed, 12 Mar 2014 22:42:23 GMT"},
{"X-Copied-From" , "TestContainer/a/b/TestObject"},
{"Last-Modified", "Wed, 12 Mar 2014 23:42:23 GMT"},
{"ETag", "d41d8cd98f00b204e9800998ecf8427e"}
};
var objRequest = new StorageObject(objectName, containerName);
var restResp = new HttpResponseAbstraction(new MemoryStream(), headers, HttpStatusCode.Created);
this.StorageServiceRestClient.Responses.Enqueue(restResp);
var client = new StorageServicePocoClient(GetValidContext(), this.ServiceLocator);
var result = await client.CopyStorageObject(objRequest, targetContainerName);
Assert.IsNotNull(result);
Assert.AreEqual(objectName, result.FullName);
Assert.AreEqual(containerName, result.ContainerName);
Assert.AreEqual(0, result.Length);
Assert.AreEqual("application/octet-stream", result.ContentType);
Assert.AreEqual("d41d8cd98f00b204e9800998ecf8427e", result.ETag);
Assert.AreEqual(DateTime.Parse("Wed, 12 Mar 2014 23:42:23 GMT"), result.LastModified);
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task ExceptionThrownWhenCopyingaStorageObjectWithMissingLength()
{
var containerName = "TestContainer";
var objectName = "TestObject";
var targetContainerName = "TargetTestContainer";
var objRequest = new StorageObject(objectName, containerName);
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.LengthRequired);
this.StorageServiceRestClient.Responses.Enqueue(restResp);
var client = new StorageServicePocoClient(GetValidContext(), this.ServiceLocator);
await client.CopyStorageObject(objRequest, targetContainerName);
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task ExceptionThrownWhenCopyingaStorageObjectWithBadETag()
{
var containerName = "TestContainer";
var objectName = "TestObject";
var targetContainerName = "TargetTestContainer";
var objRequest = new StorageObject(objectName, containerName);
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), (HttpStatusCode)422);
this.StorageServiceRestClient.Responses.Enqueue(restResp);
var client = new StorageServicePocoClient(GetValidContext(), this.ServiceLocator);
await client.CopyStorageObject(objRequest, targetContainerName);
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task ExceptionThrownWhenCopyingaStorageObjectWithBadAuth()
{
var containerName = "TestContainer";
var objectName = "TestObject";
var targetContainerName = "TargetTestContainer";
var objRequest = new StorageObject(objectName, containerName);
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.Unauthorized);
this.StorageServiceRestClient.Responses.Enqueue(restResp);
var client = new StorageServicePocoClient(GetValidContext(), this.ServiceLocator);
await client.CopyStorageObject(objRequest, targetContainerName);
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task ExceptionThrownWhenCopyingaStorageObjectHasInternalServerError()
{
var containerName = "TestContainer";
var objectName = "TestObject";
var targetContainerName = "TargetTestContainer";
var objRequest = new StorageObject(objectName, containerName);
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.InternalServerError);
this.StorageServiceRestClient.Responses.Enqueue(restResp);
var client = new StorageServicePocoClient(GetValidContext(), this.ServiceLocator);
await client.CopyStorageObject(objRequest, targetContainerName);
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task ExceptionThrownWhenCopyingaStorageObjectTimesOut()
{
var containerName = "TestContainer";
var objectName = "TestObject";
var targetContainerName = "TargetTestContainer";
var objRequest = new StorageObject(objectName, containerName);
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.RequestTimeout);
this.StorageServiceRestClient.Responses.Enqueue(restResp);
var client = new StorageServicePocoClient(GetValidContext(), this.ServiceLocator);
await client.CopyStorageObject(objRequest, targetContainerName);
}
#endregion
#region Create Storage Folder Tests
[TestMethod]

View File

@ -44,6 +44,8 @@ namespace OpenStack.Test.Storage
public Func<string, string, IDictionary<string, string>, Stream, Task<StorageObject>> CreateStorageObjectDelegate { get; set; }
public Func<string, string, string, string, Task<StorageObject>> CopyStorageObjectDelegate { get; set; }
public Func<string, string, IDictionary<string, string>, Stream, int, Task<StorageObject>> CreateLargeStorageObjectDelegate { get; set; }
public Func<string, string, Task<StorageObject>> GetStorageObjectDelegate { get; set; }
@ -64,7 +66,6 @@ namespace OpenStack.Test.Storage
public Func<string, string, Task> CreateStorageFolderDelegate { get; set; }
public Func<string, string, Task> DeleteStorageFolderDelegate { get; set; }
public Func<Uri> GetPublicEndpointDelegate { get; set; }
@ -114,6 +115,11 @@ namespace OpenStack.Test.Storage
return await CreateStorageObjectDelegate(containerName, objectName, metadata, content);
}
public async Task<StorageObject> CopyStorageObject(string containerName, string objectName, string destinationContainerName, string destinationObjectName = null)
{
return await CopyStorageObjectDelegate(containerName, objectName, destinationContainerName, destinationObjectName);
}
public async Task<StorageObject> CreateLargeStorageObject(string containerName, string objectName, IDictionary<string, string> metadata, Stream content,
int numberOfsegments)
{

View File

@ -26,6 +26,8 @@ namespace OpenStack.Test.Storage
{
public Func<StorageObject, Stream, Task<StorageObject>> CreateStorageObjectDelegate { get; set; }
public Func<StorageObject, string, string, Task<StorageObject>> CopyStorageObjectDelegate { get; set; }
public Func<StorageManifest,Task<StorageManifest>> CreateStorageManifestDelegate { get; set; }
public Func<StorageContainer, Task<StorageContainer>> CreateStorageContainerDelegate { get; set; }
@ -59,6 +61,11 @@ namespace OpenStack.Test.Storage
return await this.CreateStorageObjectDelegate(obj, content);
}
public async Task<StorageObject> CopyStorageObject(StorageObject obj, string destinationContainerName, string destinationObjectName = null)
{
return await this.CopyStorageObjectDelegate(obj, destinationContainerName, destinationObjectName);
}
public async Task<StorageManifest> CreateStorageManifest(StorageManifest manifest)
{
return await this.CreateStorageManifestDelegate(manifest);

View File

@ -100,6 +100,16 @@ namespace OpenStack.Storage
/// <returns>A storage object. </returns>
Task<StorageObject> CreateStorageObject(string containerName, string objectName, IDictionary<string, string> metadata, Stream content);
/// <summary>
/// Copy a storage object on the remote OpenStack instance.
/// </summary>
/// <param name="containerName">The name of the parent container.</param>
/// <param name="objectName">The name of the object.</param>
/// <param name="destinationContainerName">The container destination name.</param>
/// <param name="destinationObjectName">The object destination name.</param>
/// <returns>A storage object. </returns>
Task<StorageObject> CopyStorageObject(string containerName, string objectName, string destinationContainerName, string destinationObjectName = null);
/// <summary>
/// Creates a storage object on the remote OpenStack instance.
/// </summary>

View File

@ -32,6 +32,15 @@ namespace OpenStack.Storage
/// <returns>A storage object.</returns>
Task<StorageObject> CreateStorageObject(StorageObject obj, Stream content);
/// <summary>
/// Copy a storage object on the remote OpenStack instance.
/// </summary>
/// <param name="obj">The storage object to copy.</param>
/// <param name="destinationContainerName">The container destination name.</param>
/// <param name="destinationObjectName">The destination object name.</param>
/// <returns>A storage object.</returns>
Task<StorageObject> CopyStorageObject(StorageObject obj, string destinationContainerName, string destinationObjectName = null);
/// <summary>
/// Creates a storage manifest on the remote OpenStack instance.
/// </summary>

View File

@ -86,6 +86,18 @@ namespace OpenStack.Storage
return await client.CreateStorageObject(requestObject, content);
}
/// <inheritdoc/>
public async Task<StorageObject> CopyStorageObject(string containerName, string objectName, string destinationContainerName, string destinationObjectName = null)
{
containerName.AssertIsNotNullOrEmpty("containerName", "Cannot copy a storage object with a container name that is null or empty.");
objectName.AssertIsNotNullOrEmpty("objectName", "Cannot copy a storage object with a name that is null or empty.");
destinationContainerName.AssertIsNotNullOrEmpty("destinationContainerName", "Cannot copy a storage object with null or empty destination container.");
var requestObject = new StorageObject(objectName, containerName);
var client = this.GetPocoClient();
return await client.CopyStorageObject(requestObject, destinationContainerName, destinationObjectName);
}
/// <inheritdoc/>
public async Task CreateStorageContainer(string containerName, IDictionary<string, string> metadata)
{

View File

@ -66,6 +66,39 @@ namespace OpenStack.Storage
return respObj;
}
/// <inheritdoc/>
public async Task<StorageObject> CopyStorageObject(StorageObject obj, string destinationContainerName, string destinationObjectName = null)
{
obj.AssertIsNotNull("obj", "Cannot create a null storage object.");
obj.ContainerName.AssertIsNotNullOrEmpty("obj.ContainerName", "Cannot copy a storage object with a null or empty container name.");
obj.Name.AssertIsNotNullOrEmpty("obj.Name", "Cannot copy a storage object without a name.");
destinationContainerName.AssertIsNotNullOrEmpty("destinationContainerName", "Cannot copy a storage object to a null or empty destination container name.");
string localDestinationObjectName = null;
if(!string.IsNullOrEmpty(destinationObjectName))
{
localDestinationObjectName = destinationObjectName;
}
else
{
localDestinationObjectName = obj.FullName;
}
var client = this.GetRestClient();
var resp = await client.CopyObject(obj.ContainerName, obj.FullName, destinationContainerName, localDestinationObjectName);
if (resp.StatusCode != HttpStatusCode.Created)
{
throw new InvalidOperationException(string.Format("Failed to copy storage object '{0}'. The remote server returned the following status code: '{1}'.", obj.Name, resp.StatusCode));
}
var converter = this.ServiceLocator.Locate<IStorageObjectPayloadConverter>();
var respObj = converter.Convert(obj.ContainerName, obj.FullName, resp.Headers);
return respObj;
}
public async Task<StorageManifest> CreateStorageManifest(StorageManifest manifest)
{
manifest.AssertIsNotNull("manifest", "Cannot create a null storage manifest.");