Skip to content
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License"):
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Threading.Tasks;
using Xunit;

namespace Google.Cloud.Storage.V1.IntegrationTests;
[Collection(nameof(StorageFixture))]
public class GetBucketTest
{
private readonly StorageFixture _fixture;

public GetBucketTest(StorageFixture fixture)
{
_fixture = fixture;
}

[Fact]
public async Task SoftDeleted()
{
var bucketName = _fixture.GenerateBucketName();
var softDeleteBucket = _fixture.CreateBucket(bucketName, false, true);
await _fixture.Client.DeleteBucketAsync(softDeleteBucket.Name, new DeleteBucketOptions { DeleteObjects = true });

var softDeleted = await _fixture.Client.GetBucketAsync(softDeleteBucket.Name, new GetBucketOptions { SoftDeleted = true, Generation = softDeleteBucket.Generation });
Assert.Equal(softDeleteBucket.Name, softDeleted.Name);
Assert.Equal(softDeleteBucket.Generation, softDeleted.Generation);
Assert.NotNull(softDeleted.SoftDeleteTimeDateTimeOffset);
Assert.NotNull(softDeleted.HardDeleteTimeDateTimeOffset);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,27 @@ public void PartialResponses()
}
}

[Fact]
public async Task SoftDeletedOnly()
{
var bucketName = _fixture.GenerateBucketName();
var softDeleteBucket = _fixture.CreateBucket(bucketName, false, true);
await _fixture.Client.DeleteBucketAsync(softDeleteBucket.Name, new DeleteBucketOptions { DeleteObjects = true });
var actualBuckets = await _fixture.Client.ListBucketsAsync(_fixture.ProjectId, new ListBucketsOptions { SoftDeletedOnly = true }).ToListAsync();

foreach (var bucket in actualBuckets)
{ // Verify if the bucket is soft-deleted only
Assert.NotNull(bucket.Generation);
Assert.NotNull(bucket.SoftDeleteTimeDateTimeOffset);
Assert.NotNull(bucket.HardDeleteTimeDateTimeOffset);

if (bucket.Name == softDeleteBucket.Name)
{ // Compare the generation number
Assert.Equal(bucket.Generation, softDeleteBucket.Generation);
}
}
}

// Fetches buckets using the given options in each possible way, validating that the expected bucket names are returned.
private async Task AssertBuckets(ListBucketsOptions options, params string[] expectedBucketNames)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2024 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Threading.Tasks;
using Xunit;

namespace Google.Cloud.Storage.V1.IntegrationTests;

[Collection(nameof(StorageFixture))]
public class RestoreBucketTest
{
private readonly StorageFixture _fixture;

public RestoreBucketTest(StorageFixture fixture)
{
_fixture = fixture;
}

[Fact]
public async Task RestoreSoftDeletedBucket()
{
var bucketName = _fixture.GenerateBucketName();
var softDeleteBucket = _fixture.CreateBucket(bucketName, false, true);
await _fixture.Client.DeleteBucketAsync(softDeleteBucket.Name, new DeleteBucketOptions { DeleteObjects = true });

var restoredBucket = await _fixture.Client.RestoreBucketAsync(softDeleteBucket.Name, softDeleteBucket.Generation.Value);
Assert.Equal(softDeleteBucket.Name, restoredBucket.Name);
Assert.Equal(softDeleteBucket.Generation, restoredBucket.Generation);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public void ModifyRequest_DefaultOptions()
Assert.Null(request.IfMetagenerationNotMatch);
Assert.Null(request.Projection);
Assert.Null(request.UserProject);
Assert.Null(request.SoftDeleted);
Assert.Null(request.Generation);
}

[Fact]
Expand All @@ -41,13 +43,17 @@ public void ModifyRequest_PositiveMatchOptions()
{
IfMetagenerationMatch = 1L,
Projection = Projection.Full,
UserProject = "proj"
UserProject = "proj",
SoftDeleted = true,
Generation = long.MaxValue
};
options.ModifyRequest(request);
Assert.Equal(1L, request.IfMetagenerationMatch);
Assert.Null(request.IfMetagenerationNotMatch);
Assert.Equal(ProjectionEnum.Full, request.Projection);
Assert.Equal("proj", request.UserProject);
Assert.Equal(true, request.SoftDeleted);
Assert.Equal(long.MaxValue,request.Generation);
}

[Fact]
Expand All @@ -61,6 +67,8 @@ public void ModifyRequest_NegativeMatchOptions()
};
options.ModifyRequest(request);
Assert.Null(request.IfMetagenerationMatch);
Assert.Null(request.SoftDeleted);
Assert.Null(request.Generation);
Assert.Equal(1L, request.IfMetagenerationNotMatch);
Assert.Equal(ProjectionEnum.Full, request.Projection);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public void ModifyRequest_DefaultOptions()
Assert.Null(request.Prefix);
Assert.Null(request.MaxResults);
Assert.Null(request.PageToken);
Assert.Null(request.SoftDeleted);
}

[Fact]
Expand All @@ -42,14 +43,16 @@ public void ModifyRequest_AllOptions()
Prefix = "prefix",
Projection = Projection.Full,
PageToken = "nextpage",
Fields = "items(name),nextPageToken"
Fields = "items(name),nextPageToken",
SoftDeletedOnly = true,
};
options.ModifyRequest(request);
Assert.Equal(10, request.MaxResults);
Assert.Equal("prefix", request.Prefix);
Assert.Equal(ProjectionEnum.Full, request.Projection);
Assert.Equal("nextpage", request.PageToken);
Assert.Equal("items(name),nextPageToken", request.Fields);
Assert.Equal(true, request.SoftDeleted);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License"):
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Xunit;
using static Google.Apis.Storage.v1.BucketsResource;
using static Google.Apis.Storage.v1.BucketsResource.RestoreRequest;

namespace Google.Cloud.Storage.V1.Tests;
public class RestoreBucketOptionsTest
{
[Fact]
public void ModifyRequest_DefaultOptions()
{
var request = new RestoreRequest(null, "bucket", 2L);
var options = new RestoreBucketOptions();
options.ModifyRequest(request);
Assert.Null(request.Projection);
Assert.Null(request.UserProject);
}

[Fact]
public void ModifyRequest_AllOptions()
{
var request = new RestoreRequest(null, "bucket", 2L);
var options = new RestoreBucketOptions
{
Projection = Projection.Full,
UserProject = "proj"
};
options.ModifyRequest(request);
Assert.Equal(ProjectionEnum.Full, request.Projection);
Assert.Equal("proj", request.UserProject);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ public sealed class GetBucketOptions
/// </summary>
public RetryOptions RetryOptions { get; set; }

/// <summary>
/// The bucket generation to be retrieved. It must be set if <see ref="SoftDelete" /> is true.
/// </summary>
public long? Generation { get; set; }

/// <summary>
/// If true, the soft-deleted version of the bucket will be retrieved.
/// If true, <see ref="Generation" /> must be set.
/// </summary>
public bool? SoftDeleted { get; set; }

internal void ModifyRequest(GetRequest request)
{
if (IfMetagenerationMatch != null && IfMetagenerationNotMatch != null)
Expand All @@ -75,6 +86,15 @@ internal void ModifyRequest(GetRequest request)
{
request.UserProject = UserProject;
}
if (Generation != null)
{
request.Generation = Generation;
}
if (SoftDeleted != null)
{
request.SoftDeleted = SoftDeleted;
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ConfigureAwaitChecker.Analyzer" PrivateAssets="All" />
<PackageReference Include="Google.Api.Gax.Rest" />
<PackageReference Include="Google.Apis.Storage.v1" VersionOverride="[1.68.0.3431, 2.0.0.0)" />
<PackageReference Include="Google.Api.Gax.Rest"/>
<PackageReference Include="Google.Apis.Storage.v1" VersionOverride="[1.68.0.3604, 2.0.0.0)" />
</ItemGroup>
<ItemGroup>
<Compile Update="StorageClient.*.cs">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ public sealed class ListBucketsOptions
/// </summary>
public RetryOptions RetryOptions { get; set; }

/// <summary>
/// If true, only soft-deleted buckets will be listed. The default is false.
/// </summary>
public bool? SoftDeletedOnly { get; set; }

/// <summary>
/// Modifies the specified request for all non-null properties of this options object.
/// </summary>
Expand All @@ -88,6 +93,10 @@ internal void ModifyRequest(ListRequest request)
{
request.Fields = Fields;
}
if (SoftDeletedOnly != null)
{
request.SoftDeleted = SoftDeletedOnly;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License"):
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Google.Api.Gax;
using static Google.Apis.Storage.v1.BucketsResource;
using static Google.Apis.Storage.v1.BucketsResource.RestoreRequest;

namespace Google.Cloud.Storage.V1;

/// <summary>
/// Options for RestoreBucket operations.
/// </summary>
public sealed class RestoreBucketOptions
{
/// <summary>
/// The projection of the restored bucket to return. Note the whole bucket will be restored,
/// except for the bucket's access controls. This only affects
/// what information is returned when restoration is successful.
/// </summary>
public Projection? Projection { get; set; }

/// <summary>
/// The encryption key to use for this operation. If this property is null, the <see cref="StorageClient.EncryptionKey"/>
/// will be used instead. Use <see cref="EncryptionKey.None"/> to remove encryption headers from this request.
/// </summary>
public EncryptionKey EncryptionKey { get; set; }

/// <summary>
/// If set, this is the ID of the project which will be billed for the request.
/// The caller must have suitable permissions for the project being billed.
/// </summary>
public string UserProject { get; set; }

/// <summary>
/// Options to pass custom retry configuration for each API request.
/// </summary>
public RetryOptions RetryOptions { get; set; }

internal void ModifyRequest(RestoreRequest request)
{
if (Projection != null)
{
request.Projection = GaxPreconditions.CheckEnumValue((ProjectionEnum) Projection, nameof(Projection));
}
if (UserProject != null)
{
request.UserProject = UserProject;
}
}
}
Loading