Skip to content

Commit 9fc56b7

Browse files
authored
s3-zip file support (#687)
* s3-zip file support * Addresses build issue and implements review comment * Rebase * Rebase and resolve merge conflicts * Rebasing and fixing merge conflicts-3 * Rebase and fix merge conflicts * Comments out the test causing build failure on Windows * Rebase and fix merge conflicts - 4 * Removes the forgotten comment * Cosmetic cleanups * Rebase and fix merge conflicts-2 * Rebase and fix merge conflicts-3 * Rebase and fix merge conflicts-4
1 parent 7d5a239 commit 9fc56b7

File tree

5 files changed

+141
-11
lines changed

5 files changed

+141
-11
lines changed

Minio.Functional.Tests/FunctionalTest.cs

Lines changed: 134 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
using System.Threading.Tasks;
3434
using System.Web;
3535
using System.Xml;
36+
using ICSharpCode.SharpZipLib.Core;
37+
using ICSharpCode.SharpZipLib.Zip;
3638
using Microsoft.VisualStudio.TestTools.UnitTesting;
3739
using Minio.DataModel;
3840
using Minio.DataModel.ILM;
@@ -2393,6 +2395,129 @@ internal static async Task ObjectRetentionAsync_Test1(MinioClient minio)
23932395

23942396
#endregion
23952397

2398+
internal static MemoryStream CreateZipFile(string prefix, int nFiles)
2399+
{
2400+
var outputMemStream = new MemoryStream();
2401+
var zipStream = new ZipOutputStream(outputMemStream);
2402+
2403+
zipStream.SetLevel(3); //0-9, 9 being the highest level of compression
2404+
byte[] bytes = null;
2405+
2406+
for (var i = 0; i <= nFiles; i++)
2407+
{
2408+
// Make one large, compressible file.
2409+
if (i == nFiles) i = 1000000;
2410+
2411+
var fileName = prefix + "file-" + i + ".bin";
2412+
Directory.CreateDirectory(prefix);
2413+
var newEntry = new ZipEntry(fileName);
2414+
newEntry.DateTime = DateTime.Now;
2415+
zipStream.PutNextEntry(newEntry);
2416+
2417+
bytes = rsg.GenerateStreamFromSeed(i).ToArray();
2418+
var inStream = new MemoryStream(bytes);
2419+
if (i == 0) StreamUtils.Copy(inStream, zipStream, new byte[128]);
2420+
else StreamUtils.Copy(inStream, zipStream, new byte[i * 128]);
2421+
2422+
inStream.Close();
2423+
zipStream.CloseEntry();
2424+
}
2425+
2426+
zipStream.IsStreamOwner = false; // False stops the Close also Closing the underlying stream.
2427+
zipStream.Close(); // Must finish the ZipOutputStream before using outputMemStream.
2428+
2429+
outputMemStream.Position = 0;
2430+
outputMemStream.Seek(0, SeekOrigin.Begin);
2431+
2432+
return outputMemStream;
2433+
}
2434+
2435+
internal static async Task GetObjectS3Zip_Test1(MinioClient minio)
2436+
{
2437+
var path = "test/small/";
2438+
var startTime = DateTime.Now;
2439+
var bucketName = GetRandomName(15);
2440+
var randomFileName = GetRandomName(15) + ".zip";
2441+
var objectName = GetRandomObjectName(15) + ".zip";
2442+
2443+
var args = new Dictionary<string, string>
2444+
{
2445+
{ "bucketName", bucketName },
2446+
{ "objectName", objectName }
2447+
};
2448+
try
2449+
{
2450+
await Setup_Test(minio, bucketName);
2451+
const int nFiles = 500;
2452+
var memStream = CreateZipFile(path, nFiles);
2453+
2454+
var putObjectArgs = new PutObjectArgs()
2455+
.WithBucket(bucketName)
2456+
.WithObject(objectName)
2457+
.WithStreamData(memStream)
2458+
.WithObjectSize(memStream.Length);
2459+
await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
2460+
2461+
var getObjectArgs = new GetObjectArgs()
2462+
.WithBucket(bucketName)
2463+
.WithFile(randomFileName)
2464+
.WithObject(objectName);
2465+
2466+
var resp = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false);
2467+
2468+
var statArgs = new StatObjectArgs()
2469+
.WithBucket(bucketName)
2470+
.WithObject(objectName);
2471+
var stat = await minio.StatObjectAsync(statArgs).ConfigureAwait(false);
2472+
2473+
var lOpts = new Dictionary<string, string>();
2474+
lOpts.Add("x-minio-extract", "true");
2475+
2476+
// Test with different prefix values
2477+
// prefix value="", expected number of files listed=1
2478+
var prefix = "";
2479+
ListObjects_Test(minio, bucketName, prefix, 1, true, headers: lOpts);
2480+
2481+
// prefix value="/", expected number of files listed=nFiles+1
2482+
prefix = objectName + "/";
2483+
ListObjects_Test(minio, bucketName, prefix, nFiles + 1, true, headers: lOpts);
2484+
2485+
// prefix value="/test", expected number of files listed=nFiles + 1
2486+
prefix = objectName + "/test";
2487+
ListObjects_Test(minio, bucketName, prefix, nFiles + 1, true, headers: lOpts);
2488+
2489+
// prefix value="/test/", expected number of files listed=nFiles+1
2490+
prefix = objectName + "/test/";
2491+
ListObjects_Test(minio, bucketName, prefix, nFiles + 1, true, headers: lOpts);
2492+
2493+
// prefix value="/test", expected number of files listed=nFiles+1
2494+
prefix = objectName + "/test/small";
2495+
ListObjects_Test(minio, bucketName, prefix, nFiles + 1, true, headers: lOpts);
2496+
2497+
// prefix value="/test", expected number of files listed=nFiles+1
2498+
prefix = objectName + "/test/small/";
2499+
ListObjects_Test(minio, bucketName, prefix, nFiles + 1, true, headers: lOpts);
2500+
2501+
// prefix value="/test", expected number of files listed=1
2502+
prefix = objectName + "/test/small/" + "file-1.bin";
2503+
ListObjects_Test(minio, bucketName, prefix, 1, true, headers: lOpts);
2504+
2505+
new MintLogger("GetObjectS3Zip_Test1", getObjectSignature, "Tests s3Zip files", TestStatus.PASS,
2506+
DateTime.Now - startTime, args: args).Log();
2507+
}
2508+
catch (Exception ex)
2509+
{
2510+
new MintLogger("GetObjectS3Zip_Test1", getObjectSignature, "Tests s3Zip files", TestStatus.FAIL,
2511+
DateTime.Now - startTime, ex.Message, ex.ToString(), args: args).Log();
2512+
throw;
2513+
}
2514+
finally
2515+
{
2516+
File.Delete(randomFileName);
2517+
Directory.Delete(path.Split("/")[0], true);
2518+
await TearDown(minio, bucketName);
2519+
}
2520+
}
23962521

23972522
#region Bucket Notifications
23982523

@@ -4976,13 +5101,14 @@ internal static async Task ListObjectVersions_Test1(MinioClient minio)
49765101

49775102

49785103
internal static void ListObjects_Test(MinioClient minio, string bucketName, string prefix, int numObjects,
4979-
bool recursive = true, bool versions = false)
5104+
bool recursive = true, bool versions = false, Dictionary<string, string> headers = null)
49805105
{
49815106
var startTime = DateTime.Now;
49825107
var count = 0;
49835108
var args = new ListObjectsArgs()
49845109
.WithBucket(bucketName)
49855110
.WithPrefix(prefix)
5111+
.WithHeaders(headers)
49865112
.WithRecursive(recursive)
49875113
.WithVersions(versions);
49885114
if (!versions)
@@ -4991,11 +5117,11 @@ internal static void ListObjects_Test(MinioClient minio, string bucketName, stri
49915117
var subscription = observable.Subscribe(
49925118
item =>
49935119
{
4994-
Assert.IsTrue(item.Key.StartsWith(prefix));
4995-
count += 1;
5120+
if (!string.IsNullOrEmpty(prefix)) Assert.IsTrue(item.Key.StartsWith(prefix));
5121+
count++;
49965122
},
49975123
ex => throw ex,
4998-
() => { Assert.AreEqual(count, numObjects); });
5124+
() => { ; });
49995125
}
50005126
else
50015127
{
@@ -5007,8 +5133,11 @@ internal static void ListObjects_Test(MinioClient minio, string bucketName, stri
50075133
count += 1;
50085134
},
50095135
ex => throw ex,
5010-
() => { Assert.AreEqual(count, numObjects); });
5136+
() => { ; });
50115137
}
5138+
5139+
Thread.Sleep(1000);
5140+
Assert.AreEqual(numObjects, count);
50125141
}
50135142

50145143
#endregion

Minio.Functional.Tests/Minio.Functional.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
</PropertyGroup>
88
<ItemGroup>
99
<PackageReference Include="MSTest.TestFramework" Version="1.3.2" />
10+
<PackageReference Include="SharpZipLib" Version="1.3.3" />
1011
<PackageReference Include="System.Net.Http" Version="4.3.4" />
1112
<ProjectReference Include="..\Minio\Minio.csproj" />
1213
</ItemGroup>

Minio.Functional.Tests/Program.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ public static void Main(string[] args)
165165
// Test SetPolicyAsync function
166166
FunctionalTest.SetBucketPolicy_Test1(minioClient).Wait();
167167

168+
// Test S3Zip function
169+
FunctionalTest.GetObjectS3Zip_Test1(minioClient).Wait();
170+
168171
// Test Presigned Get/Put operations
169172
FunctionalTest.PresignedGetObject_Test1(minioClient).Wait();
170173
FunctionalTest.PresignedGetObject_Test2(minioClient).Wait();

Minio/ApiEndpoints/BucketOperations.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ public IObservable<Item> ListObjectsAsync(ListObjectsArgs args, CancellationToke
218218
.WithContinuationToken(nextContinuationToken)
219219
.WithMarker(marker)
220220
.WithListObjectsV1(!args.UseV2)
221+
.WithHeaders(args.Headers)
221222
.WithVersionIdMarker(versionIdMarker);
222223
if (args.Versions)
223224
{

Minio/DataModel/BucketOperationsArgs.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,8 @@ public GetObjectListArgs WithListObjectsV1(bool useV1)
187187

188188
internal override HttpRequestMessageBuilder BuildRequest(HttpRequestMessageBuilder requestMessageBuilder)
189189
{
190-
// using System.Web; Not sure if we need to add query parameters like this vs. requestMessageBuilder.AddQueryParameter()
191-
// var query = HttpUtility.ParseQueryString(string.Empty);
192-
// query["foo"] = "bar<>&-baz";
193-
// query["bar"] = "bazinga";
194-
// string queryString = query.ToString(); {
195-
190+
foreach (var h in Headers)
191+
requestMessageBuilder.AddOrUpdateHeaderParameter(h.Key, h.Value);
196192

197193
requestMessageBuilder.AddQueryParameter("delimiter", Delimiter);
198194
requestMessageBuilder.AddQueryParameter("max-keys", "1000");

0 commit comments

Comments
 (0)