Browse Source

OLD code removed.

pull/596/head
Sebastian 5 years ago
parent
commit
38b78526b4
  1. 278
      backend/src/Squidex.Infrastructure.Amazon/Assets/AmazonS3AssetStore.cs
  2. 26
      backend/src/Squidex.Infrastructure.Amazon/Assets/AmazonS3Options.cs
  3. 85
      backend/src/Squidex.Infrastructure.Amazon/Assets/SeekFakerStream.cs
  4. 22
      backend/src/Squidex.Infrastructure.Amazon/Squidex.Infrastructure.Amazon.csproj
  5. 141
      backend/src/Squidex.Infrastructure.GoogleCloud/Assets/GoogleCloudAssetStore.cs
  6. 27
      backend/src/Squidex.Infrastructure.GoogleCloud/Squidex.Infrastructure.GoogleCloud.csproj

278
backend/src/Squidex.Infrastructure.Amazon/Assets/AmazonS3AssetStore.cs

@ -1,278 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Transfer;
namespace Squidex.Assets
{
public sealed class AmazonS3AssetStore : DisposableObjectBase, IAssetStore, IInitializable
{
private const int BufferSize = 81920;
private readonly AmazonS3Options options;
private TransferUtility transferUtility;
private IAmazonS3 s3Client;
public AmazonS3AssetStore(AmazonS3Options options)
{
Guard.NotNullOrEmpty(options.Bucket, nameof(options.Bucket));
Guard.NotNullOrEmpty(options.AccessKey, nameof(options.AccessKey));
Guard.NotNullOrEmpty(options.SecretKey, nameof(options.SecretKey));
this.options = options;
}
protected override void DisposeObject(bool disposing)
{
if (disposing)
{
s3Client?.Dispose();
transferUtility?.Dispose();
}
}
public async Task InitializeAsync(CancellationToken ct = default)
{
try
{
var amazonS3Config = new AmazonS3Config { ForcePathStyle = options.ForcePathStyle };
if (!string.IsNullOrWhiteSpace(options.ServiceUrl))
{
amazonS3Config.ServiceURL = options.ServiceUrl;
}
else
{
amazonS3Config.RegionEndpoint = RegionEndpoint.GetBySystemName(options.RegionName);
}
s3Client = new AmazonS3Client(options.AccessKey, options.SecretKey, amazonS3Config);
transferUtility = new TransferUtility(s3Client);
var exists = await s3Client.DoesS3BucketExistAsync(options.Bucket);
if (!exists)
{
throw new ConfigurationException($"Cannot connect to Amazon S3 bucket '{options.Bucket}'.");
}
}
catch (AmazonS3Exception ex)
{
throw new ConfigurationException($"Cannot connect to Amazon S3 bucket '{options.Bucket}'.", ex);
}
}
public string? GeneratePublicUrl(string fileName)
{
return null;
}
public async Task<long> GetSizeAsync(string fileName, CancellationToken ct = default)
{
var key = GetKey(fileName, nameof(fileName));
try
{
var request = new GetObjectMetadataRequest
{
BucketName = options.Bucket,
Key = key
};
var metadata = await s3Client.GetObjectMetadataAsync(request, ct);
return metadata.ContentLength;
}
catch (AmazonS3Exception ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
throw new AssetNotFoundException(fileName, ex);
}
}
public async Task CopyAsync(string sourceFileName, string targetFileName, CancellationToken ct = default)
{
var sourceKey = GetKey(sourceFileName, nameof(sourceFileName));
var targetKey = GetKey(targetFileName, nameof(targetFileName));
try
{
await EnsureNotExistsAsync(targetKey, targetFileName, ct);
var request = new CopyObjectRequest
{
SourceBucket = options.Bucket,
SourceKey = sourceKey,
DestinationBucket = options.Bucket,
DestinationKey = targetKey
};
await s3Client.CopyObjectAsync(request, ct);
}
catch (AmazonS3Exception ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
throw new AssetNotFoundException(sourceFileName, ex);
}
catch (AmazonS3Exception ex) when (ex.StatusCode == HttpStatusCode.PreconditionFailed)
{
throw new AssetAlreadyExistsException(targetFileName);
}
}
public async Task DownloadAsync(string fileName, Stream stream, BytesRange range = default, CancellationToken ct = default)
{
Guard.NotNull(stream, nameof(stream));
var key = GetKey(fileName, nameof(fileName));
try
{
var request = new GetObjectRequest
{
BucketName = options.Bucket,
Key = key
};
if (range.IsDefined)
{
request.ByteRange = new ByteRange(range.ToString());
}
using (var response = await s3Client.GetObjectAsync(request, ct))
{
await response.ResponseStream.CopyToAsync(stream, BufferSize, ct);
}
}
catch (AmazonS3Exception ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
throw new AssetNotFoundException(fileName, ex);
}
}
public async Task UploadAsync(string fileName, Stream stream, bool overwrite = false, CancellationToken ct = default)
{
Guard.NotNull(stream, nameof(stream));
var key = GetKey(fileName, nameof(fileName));
try
{
if (!overwrite)
{
await EnsureNotExistsAsync(key, fileName, ct);
}
var request = new TransferUtilityUploadRequest
{
BucketName = options.Bucket,
Key = key
};
if (!HasContentLength(stream))
{
var tempFileName = Path.GetTempFileName();
var tempStream = new FileStream(tempFileName,
FileMode.Create,
FileAccess.ReadWrite,
FileShare.Delete, 1024 * 16,
FileOptions.Asynchronous |
FileOptions.DeleteOnClose |
FileOptions.SequentialScan);
using (tempStream)
{
await stream.CopyToAsync(tempStream, ct);
request.InputStream = tempStream;
await transferUtility.UploadAsync(request, ct);
}
}
else
{
request.InputStream = new SeekFakerStream(stream);
request.AutoCloseStream = false;
await transferUtility.UploadAsync(request, ct);
}
}
catch (AmazonS3Exception ex) when (ex.StatusCode == HttpStatusCode.PreconditionFailed)
{
throw new AssetAlreadyExistsException(fileName);
}
}
public async Task DeleteAsync(string fileName)
{
var key = GetKey(fileName, nameof(fileName));
try
{
var request = new DeleteObjectRequest
{
BucketName = options.Bucket,
Key = key
};
await s3Client.DeleteObjectAsync(request);
}
catch (AmazonS3Exception ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
return;
}
}
private string GetKey(string fileName, string parameterName)
{
Guard.NotNullOrEmpty(fileName, parameterName);
if (!string.IsNullOrWhiteSpace(options.BucketFolder))
{
return $"{options.BucketFolder}/{fileName}";
}
else
{
return fileName;
}
}
private async Task EnsureNotExistsAsync(string key, string fileName, CancellationToken ct)
{
try
{
await s3Client.GetObjectAsync(options.Bucket, key, ct);
}
catch
{
return;
}
throw new AssetAlreadyExistsException(fileName);
}
private static bool HasContentLength(Stream stream)
{
try
{
return stream.Length > 0;
}
catch
{
return false;
}
}
}
}

26
backend/src/Squidex.Infrastructure.Amazon/Assets/AmazonS3Options.cs

@ -1,26 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
namespace Squidex.Assets
{
public sealed class AmazonS3Options
{
public string? ServiceUrl { get; set; }
public string? RegionName { get; set; }
public string Bucket { get; set; }
public string? BucketFolder { get; set; }
public string AccessKey { get; set; }
public string SecretKey { get; set; }
public bool ForcePathStyle { get; set; }
}
}

85
backend/src/Squidex.Infrastructure.Amazon/Assets/SeekFakerStream.cs

@ -1,85 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.IO;
namespace Squidex.Assets
{
public sealed class SeekFakerStream : Stream
{
private readonly Stream inner;
public override bool CanRead
{
get { return inner.CanRead; }
}
public override bool CanSeek
{
get { return true; }
}
public override bool CanWrite
{
get { return false; }
}
public override long Length
{
get { return inner.Length; }
}
public override long Position
{
get { return inner.Position; }
set { throw new NotSupportedException(); }
}
public SeekFakerStream(Stream inner)
{
Guard.NotNull(inner, nameof(inner));
if (!inner.CanRead)
{
throw new ArgumentException("Inner stream must be readable.");
}
this.inner = inner;
}
public override int Read(byte[] buffer, int offset, int count)
{
return inner.Read(buffer, offset, count);
}
public override void Flush()
{
throw new NotSupportedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
if (offset != 0 || origin != SeekOrigin.Begin)
{
throw new NotSupportedException();
}
return 0;
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
}
}

22
backend/src/Squidex.Infrastructure.Amazon/Squidex.Infrastructure.Amazon.csproj

@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>Squidex.Infrastructure</RootNamespace>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AWSSDK.S3" Version="3.5.3.2" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
</ItemGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>..\..\Squidex.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\stylecop.json" Link="stylecop.json" />
</ItemGroup>
</Project>

141
backend/src/Squidex.Infrastructure.GoogleCloud/Assets/GoogleCloudAssetStore.cs

@ -1,141 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.IO;
using System.Net;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using Google;
using Google.Cloud.Storage.V1;
namespace Squidex.Assets
{
public sealed class GoogleCloudAssetStore : IAssetStore, IInitializable
{
private static readonly UploadObjectOptions IfNotExists = new UploadObjectOptions { IfGenerationMatch = 0 };
private static readonly CopyObjectOptions IfNotExistsCopy = new CopyObjectOptions { IfGenerationMatch = 0 };
private readonly string bucketName;
private StorageClient storageClient;
public GoogleCloudAssetStore(string bucketName)
{
Guard.NotNullOrEmpty(bucketName, nameof(bucketName));
this.bucketName = bucketName;
}
public async Task InitializeAsync(CancellationToken ct = default)
{
try
{
storageClient = await StorageClient.CreateAsync();
await storageClient.GetBucketAsync(bucketName, cancellationToken: ct);
}
catch (Exception ex)
{
throw new ConfigurationException($"Cannot connect to google cloud bucket '{bucketName}'.", ex);
}
}
public string? GeneratePublicUrl(string fileName)
{
return null;
}
public async Task<long> GetSizeAsync(string fileName, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
try
{
var obj = await storageClient.GetObjectAsync(bucketName, fileName, null, ct);
if (!obj.Size.HasValue)
{
throw new AssetNotFoundException(fileName);
}
return (long)obj.Size.Value;
}
catch (GoogleApiException ex) when (ex.HttpStatusCode == HttpStatusCode.NotFound)
{
throw new AssetNotFoundException(fileName, ex);
}
}
public async Task CopyAsync(string sourceFileName, string targetFileName, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(sourceFileName, nameof(sourceFileName));
Guard.NotNullOrEmpty(targetFileName, nameof(targetFileName));
try
{
await storageClient.CopyObjectAsync(bucketName, sourceFileName, bucketName, targetFileName, IfNotExistsCopy, ct);
}
catch (GoogleApiException ex) when (ex.HttpStatusCode == HttpStatusCode.NotFound)
{
throw new AssetNotFoundException(sourceFileName, ex);
}
catch (GoogleApiException ex) when (ex.HttpStatusCode == HttpStatusCode.PreconditionFailed)
{
throw new AssetAlreadyExistsException(targetFileName);
}
}
public async Task DownloadAsync(string fileName, Stream stream, BytesRange range = default, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
try
{
var downloadOptions = new DownloadObjectOptions();
if (range.IsDefined)
{
downloadOptions.Range = new RangeHeaderValue(range.From, range.To);
}
await storageClient.DownloadObjectAsync(bucketName, fileName, stream, downloadOptions, ct);
}
catch (GoogleApiException ex) when (ex.HttpStatusCode == HttpStatusCode.NotFound)
{
throw new AssetNotFoundException(fileName, ex);
}
}
public async Task UploadAsync(string fileName, Stream stream, bool overwrite = false, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
try
{
await storageClient.UploadObjectAsync(bucketName, fileName, "application/octet-stream", stream, overwrite ? null : IfNotExists, ct);
}
catch (GoogleApiException ex) when (ex.HttpStatusCode == HttpStatusCode.PreconditionFailed)
{
throw new AssetAlreadyExistsException(fileName);
}
}
public async Task DeleteAsync(string fileName)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
try
{
await storageClient.DeleteObjectAsync(bucketName, fileName);
}
catch (GoogleApiException ex) when (ex.HttpStatusCode == HttpStatusCode.NotFound)
{
return;
}
}
}
}

27
backend/src/Squidex.Infrastructure.GoogleCloud/Squidex.Infrastructure.GoogleCloud.csproj

@ -1,27 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>Squidex.Infrastructure</RootNamespace>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType>
<DebugSymbols>True</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Cloud.Storage.V1" Version="3.3.0" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
</ItemGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>..\..\Squidex.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\stylecop.json" Link="stylecop.json" />
</ItemGroup>
</Project>
Loading…
Cancel
Save