Skip to content
Merged
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
7 changes: 4 additions & 3 deletions src/console/console.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="SimpleRESTServices, Version=1.0.6.3, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="SimpleRESTServices, Version=1.0.6.6, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SimpleRESTServices.1.0.6.3\lib\net40\SimpleRESTServices.dll</HintPath>
<HintPath>..\packages\SimpleRESTServices.1.0.6.6\lib\net40\SimpleRESTServices.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
Expand Down
2 changes: 1 addition & 1 deletion src/console/packages.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net40" />
<package id="SimpleRESTServices" version="1.0.6.3" targetFramework="net40" />
<package id="SimpleRESTServices" version="1.0.6.6" targetFramework="net40" />
</packages>
3 changes: 2 additions & 1 deletion src/corelib/Core/Domain/Volume.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace net.openstack.Core.Domain
Expand All @@ -25,7 +26,7 @@ public class Volume
public string SnapshotId { get; set; }

[DataMember]
public string[] Attachments { get; set; }
public Dictionary<string, string>[] Attachments { get; set; }

[DataMember]
public string Status { get; set; }
Expand Down
21 changes: 18 additions & 3 deletions src/corelib/Core/Providers/IObjectStorageProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -331,24 +331,39 @@ public interface IObjectStorageProvider
/// <param name="sourceObjectName">Name of the source object.<remarks>Example image_name.jpeg</remarks></param>
/// <param name="destinationContainer">The destination container name.</param>
/// <param name="destinationObjectName">Name of the destination object.<remarks>Example image_name.jpeg</remarks></param>
/// <param name="headers">The headers. </param>
/// <param name="headers">A list of HTTP headers to send to the service. </param>
/// <param name="region">The region in which to execute this action.<remarks>If not specified, the user’s default region will be used.</remarks></param>
///<param name="useInternalUrl">If set to <c>true</c> uses ServiceNet URL.</param>
/// <param name="identity">The users Cloud Identity. <see cref="CloudIdentity"/> <remarks>If not specified, the default identity given in the constructor will be used.</remarks> </param>
/// <returns><see cref="ObjectStore"/></returns>
ObjectStore CopyObject(string sourceContainer, string sourceObjectName, string destinationContainer, string destinationObjectName, Dictionary<string, string> headers = null, string region = null, bool useInternalUrl = false, CloudIdentity identity = null);

/// <summary>
/// Moves an object. <remarks>The original source object will be deleted only if the move is successful.</remarks>
/// </summary>
/// <param name="sourceContainer">The source container name.</param>
/// <param name="sourceObjectName">Name of the source object.<remarks>Example image_name.jpeg</remarks></param>
/// <param name="destinationContainer">The destination container name.</param>
/// <param name="destinationObjectName">Name of the destination object.<remarks>Example image_name.jpeg</remarks></param>
/// <param name="headers">A list of HTTP headers to send to the service. </param>
/// <param name="region">The region in which to execute this action.<remarks>If not specified, the user’s default region will be used.</remarks></param>
///<param name="useInternalUrl">If set to <c>true</c> uses ServiceNet URL.</param>
/// <param name="identity">The users Cloud Identity. <see cref="CloudIdentity"/> <remarks>If not specified, the default identity given in the constructor will be used.</remarks> </param>
/// <returns><see cref="ObjectStore"/></returns>
ObjectStore MoveObject(string sourceContainer, string sourceObjectName, string destinationContainer, string destinationObjectName, Dictionary<string, string> headers = null, string region = null, bool useInternalUrl = false, CloudIdentity identity = null);

/// <summary>
/// Deletes the object.
/// </summary>
/// <param name="container">The container name.</param>
/// <param name="objectName">Name of the object.<remarks>Example image_name.jpeg</remarks></param>
/// <param name="headers">The headers. </param>
/// <param name="headers">A list of HTTP headers to send to the service. </param>
/// <param name="deleteSegments">Indicates whether the file's segments should be deleted if any exist.</param>
/// <param name="region">The region in which to execute this action.<remarks>If not specified, the user’s default region will be used.</remarks></param>
/// <param name="useInternalUrl">If set to <c>true</c> uses ServiceNet URL.</param>
/// <param name="identity">The users Cloud Identity. <see cref="CloudIdentity"/> <remarks>If not specified, the default identity given in the constructor will be used.</remarks> </param>
/// <returns><see cref="ObjectStore"/></returns>
ObjectStore DeleteObject(string container, string objectName, Dictionary<string, string> headers = null, string region = null, bool useInternalUrl = false, CloudIdentity identity = null);
ObjectStore DeleteObject(string container, string objectName, Dictionary<string, string> headers = null, bool deleteSegments = true, string region = null, bool useInternalUrl = false, CloudIdentity identity = null);

/// <summary>
/// Purges the object from CDN.
Expand Down
88 changes: 42 additions & 46 deletions src/corelib/Providers/Rackspace/CloudFilesProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ public void CreateObject(string container, Stream stream, string objectName, int
}
var urlPath = new Uri(string.Format("{0}/{1}/{2}", GetServiceEndpointCloudFiles(identity, region, useInternalUrl), _encodeDecodeProvider.UrlEncode(container), _encodeDecodeProvider.UrlEncode(objectName)));

StreamRESTRequest(identity, urlPath, HttpMethod.PUT, stream, chunkSize, headers: headers, isRetry: true, progressUpdated: progressUpdated, requestSettings: new RequestSettings {ChunkRequest = true});
StreamRESTRequest(identity, urlPath, HttpMethod.PUT, stream, chunkSize, headers: headers, progressUpdated: progressUpdated, requestSettings: new RequestSettings {ChunkRequest = true});
}

/// <inheritdoc />
Expand Down Expand Up @@ -659,53 +659,57 @@ public ObjectStore CopyObject(string sourceContainer, string sourceObjectName, s
_cloudFilesValidator.ValidateContainerName(destinationContainer);
_cloudFilesValidator.ValidateObjectName(destinationObjectName);

if (headers != null)
{
if (string.IsNullOrWhiteSpace(headers.FirstOrDefault(x => x.Key.Equals(ContentLength, StringComparison.OrdinalIgnoreCase)).Value))
{
var contentLength = GetObjectContentLength(identity, sourceContainer, sourceObjectName, region, useInternalUrl);
headers.Add(ContentLength, contentLength);
}
}
else
{
var urlPath = new Uri(string.Format("{0}/{1}/{2}", GetServiceEndpointCloudFiles(identity, region, useInternalUrl), _encodeDecodeProvider.UrlEncode(sourceContainer), _encodeDecodeProvider.UrlEncode(sourceObjectName)));

if(headers == null)
headers = new Dictionary<string, string>();
var contentLength = GetObjectContentLength(identity, sourceContainer, sourceObjectName, region, useInternalUrl);
headers.Add(ContentLength, contentLength);

}

headers.Add(CopyFrom, string.Format("{0}/{1}", sourceContainer, sourceObjectName));

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

var response = ExecuteRESTRequest(identity, urlPath, HttpMethod.PUT, headers);
headers.Add(DestinationMetadataKey, string.Format("{0}/{1}", destinationContainer, destinationObjectName));
ExecuteRESTRequest(identity, urlPath, HttpMethod.COPY, headers: headers);

if (response.StatusCode == 201)
return ObjectStore.ObjectCreated;
if (response.StatusCode == 404)
return ObjectStore.ContainerNotFound;

return ObjectStore.Unknown;
return ObjectStore.ObjectCreated;
}

/// <inheritdoc />
public ObjectStore DeleteObject(string container, string objectName, Dictionary<string, string> headers = null, string region = null, bool useInternalUrl = false, CloudIdentity identity = null)
public ObjectStore DeleteObject(string container, string objectName, Dictionary<string, string> headers = null, bool deleteSegments = true, string region = null, bool useInternalUrl = false, CloudIdentity identity = null)
{
_cloudFilesValidator.ValidateContainerName(container);
_cloudFilesValidator.ValidateObjectName(objectName);

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

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

var response = ExecuteRESTRequest(identity, urlPath, HttpMethod.DELETE, headers);
ExecuteRESTRequest(identity, urlPath, HttpMethod.DELETE, headers: headers);

if (response.StatusCode == 204)
return ObjectStore.ObjectDeleted;
if (response.StatusCode == 404)
return ObjectStore.ContainerNotFound;
if (deleteSegments && objectHeader != null && objectHeader.Any(h => h.Key.Equals(ObjectManifestMetadataKey, StringComparison.OrdinalIgnoreCase)))
{
var objects = this.ListObjects(container, region: region, useInternalUrl: useInternalUrl, identity: identity);

return ObjectStore.Unknown;
if (objects != null && objects.Any())
{
var segments = objects.Where(f => f.Name.StartsWith(string.Format("{0}.seg", objectName)));
foreach (var segment in segments)
{
DeleteObject(container, segment.Name, headers, false, region, useInternalUrl, identity);
}
}
}

return ObjectStore.ObjectDeleted;
}

/// <inheritdoc />
public ObjectStore MoveObject(string sourceContainer, string sourceObjectName, string destinationContainer, string destinationObjectName, Dictionary<string, string> headers = null, string region = null, bool useInternalUrl = false, CloudIdentity identity = null)
{
var result = CopyObject(sourceContainer, sourceObjectName, destinationContainer, destinationObjectName, headers, region, useInternalUrl, identity);

if (result != ObjectStore.ObjectCreated)
return result;

return DeleteObject(sourceContainer, sourceObjectName, headers, true, region, useInternalUrl, identity);
}

/// <inheritdoc />
Expand Down Expand Up @@ -828,13 +832,6 @@ public void UpdateAccountHeaders(Dictionary<string, string> headers, string regi

#region Private methods

private string GetObjectContentLength(CloudIdentity identity, string sourceContainer, string sourceObjectName, string region, bool useInternalUrl)
{
var sourceHeaders = GetObjectHeaders(sourceContainer, sourceObjectName, region,useInternalUrl, identity);
var contentLength = sourceHeaders.FirstOrDefault(x => x.Key.Equals(ContentLength, StringComparison.OrdinalIgnoreCase)).Value;
return contentLength;
}

protected string GetServiceEndpointCloudFiles(CloudIdentity identity, string region = null, bool useInternalUrl = false)
{
return useInternalUrl ? base.GetInternalServiceEndpoint(identity, "cloudFiles", region) : base.GetPublicServiceEndpoint(identity, "cloudFiles", region);
Expand Down Expand Up @@ -886,7 +883,7 @@ private void CreateObjectInSegments(string container, Stream stream, string obje

var urlPath = new Uri(string.Format("{0}/{1}/{2}.seg{3}", GetServiceEndpointCloudFiles(identity, region, useInternalUrl), container, objectName, i));
long segmentBytesWritten = 0;
StreamRESTRequest(identity, urlPath, HttpMethod.PUT, stream, chunkSize, length, headers: headers, isRetry: true, requestSettings: new RequestSettings {ChunkRequest = true}, progressUpdated:
StreamRESTRequest(identity, urlPath, HttpMethod.PUT, stream, chunkSize, length, headers: headers, requestSettings: new RequestSettings {ChunkRequest = true}, progressUpdated:
bytesWritten =>
{
if (progressUpdated != null)
Expand All @@ -906,7 +903,7 @@ private void CreateObjectInSegments(string container, Stream stream, string obje
headers = new Dictionary<string, string>();

headers.Add(ObjectManifestMetadataKey, string.Format("{0}/{1}", container, objectName));
StreamRESTRequest(identity, segmentUrlPath, HttpMethod.PUT, new MemoryStream(new Byte[0]), chunkSize, headers: headers, isRetry: true, requestSettings: new RequestSettings {ChunkRequest = true}, progressUpdated:
StreamRESTRequest(identity, segmentUrlPath, HttpMethod.PUT, new MemoryStream(new Byte[0]), chunkSize, headers: headers, requestSettings: new RequestSettings {ChunkRequest = true}, progressUpdated:
(bytesWritten) =>
{
if (progressUpdated != null)
Expand Down Expand Up @@ -957,10 +954,9 @@ protected override IObjectStorageProvider BuildProvider(CloudIdentity identity)
public const string ObjectDeleteAfter = "x-delete-after";
public const string ObjectDeleteAt = "x-delete-at";
public const string Etag = "etag";
public const string ContentType = "content-type";
public const string ContentLength = "content-length";
public const string CopyFrom = "x-copy-from";
public const string ObjectManifestMetadataKey = "X-Object-Manifest";
public const string DestinationMetadataKey = "destination";
public const string ObjectManifestMetadataKey = "x-object-manifest";

//Cdn Object Constants
public const string CdnPurgeEmail = "x-purge-email";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using net.openstack.Core.Caching;
using net.openstack.Core.Domain;
using net.openstack.Providers.Rackspace.Exceptions;
using net.openstack.Providers.Rackspace.Objects;
using net.openstack.Providers.Rackspace.Validators;

namespace net.openstack.Providers.Rackspace
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using net.openstack.Core.Caching;
using net.openstack.Core.Domain;
using net.openstack.Core.Validators;
using net.openstack.Providers.Rackspace.Objects;
using net.openstack.Providers.Rackspace.Objects.Request;
using net.openstack.Providers.Rackspace.Objects.Response;

Expand Down
3 changes: 3 additions & 0 deletions src/corelib/Providers/Rackspace/Objects/AuthDetails.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ internal class AuthDetails

[DataMember(Name = "RAX-KSKEY:apiKeyCredentials", EmitDefaultValue = true)]
public Credentials APIKeyCredentials { get; set; }

[DataMember(Name = "RAX-AUTH:domain", EmitDefaultValue = true)]
public Domain Domain { get; set; }
}
}
11 changes: 11 additions & 0 deletions src/corelib/Providers/Rackspace/Objects/Domain.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Runtime.Serialization;

namespace net.openstack.Providers.Rackspace.Objects
{
[DataContract]
public class Domain
{
[DataMember(Name = "name")]
public string Name { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using net.openstack.Core.Domain;

namespace net.openstack.Providers.Rackspace
namespace net.openstack.Providers.Rackspace.Objects
{
public class RackspaceCloudIdentity : CloudIdentity
{
Expand All @@ -17,6 +17,8 @@ public RackspaceCloudIdentity(CloudIdentity cloudIdentity) : this()
}

public CloudInstance CloudInstance { get; set; }

public Domain Domain { get; set; }
}

public enum CloudInstance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ public static AuthRequest FromCloudIdentity(CloudIdentity identity)
creds.APIKeyCredentials = new Credentials() { Username = identity.Username, APIKey = identity.APIKey};
else
creds.PasswordCredentials = new Credentials(){Username = identity.Username, Password = identity.Password};

var raxIdentity = identity as RackspaceCloudIdentity;
if (raxIdentity != null)
{
creds.Domain = raxIdentity.Domain;
}

return new AuthRequest { Credencials = creds };
}
}
Expand Down
1 change: 1 addition & 0 deletions src/corelib/Providers/Rackspace/ProviderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using net.openstack.Core.Exceptions;
using net.openstack.Core.Providers;
using net.openstack.Core.Validators;
using net.openstack.Providers.Rackspace.Objects;
using net.openstack.Providers.Rackspace.Validators;

namespace net.openstack.Providers.Rackspace
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace net.openstack.Providers.Rackspace
using net.openstack.Providers.Rackspace.Objects;

namespace net.openstack.Providers.Rackspace
{
public class RackspaceImpersonationIdentity : RackspaceCloudIdentity
{
Expand Down
Loading