Skip to content
Open
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
91 changes: 91 additions & 0 deletions src/DataStax.AstraDB.DataApi/Admin/AstraDatabasesAdmin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Core.Commands;
using DataStax.AstraDB.DataApi.Utils;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -37,6 +38,7 @@ public class AstraDatabasesAdmin
{
private readonly CommandOptions _adminOptions;
private readonly DataAPIClient _client;
private readonly ILogger _logger;

private CommandOptions[] OptionsTree => new CommandOptions[] { _client.ClientOptions, _adminOptions };

Expand All @@ -57,6 +59,7 @@ internal AstraDatabasesAdmin(DataAPIClient client, CommandOptions adminOptions)
Guard.NotNull(client, nameof(client));
_client = client;
_adminOptions = adminOptions;
_logger = client.Logger;
}

internal string DevOpsAPISuffix(DBEnvironment? environment) => environment switch
Expand Down Expand Up @@ -166,6 +169,51 @@ internal async Task<DatabaseAdminAstra> CreateDatabaseAsync(CreateDatabaseOption
Guard.NotNullOrEmpty(options.Name, nameof(options.Name));
Guard.NotNull(options.CloudProvider, nameof(options.CloudProvider));
Guard.NotNullOrEmpty(options.Region, nameof(options.Region));

if (options.PCUGroupId != null)
{
_logger.LogInformation("PCUGroupId specified ({PCUGroupId}): validating against available PCU groups.", options.PCUGroupId);
var listPCUOptions = ListPCUGroupsOptions.FromCommandOptions(options);
List<PCUGroup> pcuGroups = null;
try
{
pcuGroups = await ListPCUGroupsAsync(listPCUOptions, runSynchronously).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to retrieve PCU groups; skipping PCU group validation.");
}

if (pcuGroups != null)
{
_logger.LogInformation("Retrieved {Count} PCU group(s); searching for id={PCUGroupId}.", pcuGroups.Count, options.PCUGroupId);
var matchedGroup = pcuGroups.FirstOrDefault(g =>
string.Equals(g.Id, options.PCUGroupId, StringComparison.OrdinalIgnoreCase));

if (matchedGroup == null)
{
_logger.LogInformation("PCU group '{PCUGroupId}' was not found: aborting database creation.", options.PCUGroupId);
throw new InvalidOperationException(
$"No PCU group with id '{options.PCUGroupId}' was found.");
}

_logger.LogInformation("Found PCU group '{PCUGroupId}': cloudProvider={CloudProvider}, region={Region}.", matchedGroup.Id, matchedGroup.CloudProvider, matchedGroup.Region);

bool cloudProviderMatches = matchedGroup.CloudProvider == options.CloudProvider;
bool regionMatches = string.Equals(matchedGroup.Region, options.Region, StringComparison.OrdinalIgnoreCase);

if (!cloudProviderMatches || !regionMatches)
{
_logger.LogInformation("PCU group '{PCUGroupId}' was found in a different region: aborting database creation.", matchedGroup.Id);
throw new InvalidOperationException(
$"PCU group '{options.PCUGroupId}' is in cloudProvider={matchedGroup.CloudProvider}, region={matchedGroup.Region}, " +
$"which does not match the requested cloudProvider={options.CloudProvider}, region={options.Region}.");
}

_logger.LogInformation("PCU group '{PCUGroupId}' validated successfully; proceeding with database creation.", options.PCUGroupId);
}
}

Command command = CreateCommand()
.AddUrlPath("databases")
.WithPayload(options.ToPayload())
Expand Down Expand Up @@ -407,6 +455,49 @@ internal async Task<List<RegionInfo>> FindAvailableRegionsAsync(FindAvailableReg
return response;
}

/// <summary>
/// Synchronous version of <see cref="ListPCUGroupsAsync(ListPCUGroupsOptions)"/>
/// </summary>
/// <inheritdoc cref="ListPCUGroupsAsync(ListPCUGroupsOptions)"/>
public List<PCUGroup> ListPCUGroups(ListPCUGroupsOptions options = null)
{
return ListPCUGroupsAsync(options, true).ResultSync();
}

/// <summary>
/// List the PCU (Provisioned Capacity Units) Groups pertaining to the current org.
/// </summary>
/// <param name="options">Additional options to the DevOps API query, such as cloud provider/region filters and general request execution parameters.</param>
/// <returns>A list of the PCU Groups according to the requested filtering.</returns>
public Task<List<PCUGroup>> ListPCUGroupsAsync(ListPCUGroupsOptions options = null)
{
return ListPCUGroupsAsync(options, false);
}

internal async Task<List<PCUGroup>> ListPCUGroupsAsync(ListPCUGroupsOptions options, bool runSynchronously)
{
if (options != null && (options.CloudProvider == null) != (options.Region == null))
throw new ArgumentException(
"Either both or none of CloudProvider and Region must be set for filtering PCU Groups.",
nameof(options));

var command = CreateCommand()
.AddUrlPath("pcus/actions/get")
.WithPayload(new Dictionary<string, string>())
.WithTimeoutManager(new DatabaseAdminTimeoutManager())
.AddCommandOptions(options);

var response = await command.RunAsyncRaw<List<PCUGroup>>(HttpMethod.Post, runSynchronously);
// apply cloud/region filter if required:
if (options?.CloudProvider == null)
{
return response;
}
return response
.Where(group => group.CloudProvider == options.CloudProvider && group.Region == options.Region)
.ToList();
}

private DatabaseAdminAstra GetDatabaseAdmin(DatabaseInfo dbInfo, GetDatabaseAdminOptions options = null)
{
var commandOptions = CommandOptions.Merge(new CommandOptions[] {_adminOptions, options});
Expand Down
5 changes: 2 additions & 3 deletions src/DataStax.AstraDB.DataApi/Admin/CloudProviderType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ namespace DataStax.AstraDB.DataApi.Admin;
/// <summary>
/// Specifies the cloud provider on which an Astra DB database is deployed.
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter<CloudProviderType>))]
public enum CloudProviderType
{
/// <summary>Amazon Web Services.</summary>
Expand All @@ -32,5 +31,5 @@ public enum CloudProviderType
GCP,
/// <summary>Microsoft Azure.</summary>
[JsonStringEnumMemberName("azure")]
Azure
}
AZURE
}
36 changes: 31 additions & 5 deletions src/DataStax.AstraDB.DataApi/Admin/CreateDatabaseOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ namespace DataStax.AstraDB.DataApi.Admin;
/// </summary>
public class CreateDatabaseOptions : BlockingCommandOptions
{
private const string DefaultTier = "serverless";
private const int DefaultCapacityUnits = 1;
private const string DefaultDbType = "vector";

/// <summary>
/// Name of the database to be created.
/// </summary>
Expand All @@ -49,15 +53,33 @@ public class CreateDatabaseOptions : BlockingCommandOptions
set => base.Keyspace = value;
}

/// <summary>
/// Database tier (defaults to "serverless").
/// </summary>
public string Tier { get; set; } = DefaultTier;

/// <summary>
/// Capacity units for the database (defaults to 1).
/// </summary>
public int CapacityUnits { get; set; } = DefaultCapacityUnits;

/// <summary>
/// Database type (defaults to "vector").
/// </summary>
public string DBType { get; set; } = DefaultDbType;

/// <summary>
/// PCU group ID to use for provisioning the database. Optional.
/// </summary>
public string PCUGroupId { get; set; } = null;

internal object ToPayload()
{
var payload = new Dictionary<string, object>();

// hardcoded properties
payload["tier"] = "serverless";
payload["capacityUnits"] = 1;
payload["dbType"] = "vector";
// specified properties
payload["tier"] = Tier;
payload["capacityUnits"] = CapacityUnits;
payload["dbType"] = DBType;
if ( Name != null )
{
payload["name"] = Name;
Expand All @@ -74,6 +96,10 @@ internal object ToPayload()
{
payload["keyspace"] = Keyspace;
}
if ( PCUGroupId != null )
{
payload["pcuGroupUUID"] = PCUGroupId;
}

return payload;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
* limitations under the License.
*/

namespace DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Core;

namespace DataStax.AstraDB.DataApi.Admin;

/// <summary>
/// Options specific to the database admin command to create a keyspace.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
* limitations under the License.
*/

namespace DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Core;

namespace DataStax.AstraDB.DataApi.Admin;

/// <summary>
/// Command options specific to the database admin's DoesKeyspaceExist methods.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
* limitations under the License.
*/

namespace DataStax.AstraDB.DataApi.Core;
using DataStax.AstraDB.DataApi.Core;

namespace DataStax.AstraDB.DataApi.Admin;

/// <summary>
/// Options specific to the database admin command to drop a keyspace.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
* limitations under the License.
*/

using DataStax.AstraDB.DataApi.Admin;
using DataStax.AstraDB.DataApi.Core;

namespace DataStax.AstraDB.DataApi.Core;
namespace DataStax.AstraDB.DataApi.Admin;

/// <summary>
/// Command options specific to the database admin's ListKeyspaces methods.
Expand Down
60 changes: 60 additions & 0 deletions src/DataStax.AstraDB.DataApi/Admin/ListPCUGroupsOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright DataStax, Inc.
*
* 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 DataStax.AstraDB.DataApi.Core;

namespace DataStax.AstraDB.DataApi.Admin;

/// <summary>
/// Options for AstraDatabasesAdmin's ListPCUGroups command.
/// </summary>
public class ListPCUGroupsOptions : CommandOptions
{

/// <summary>
/// If set, filters results to this cloud provider only.
/// Either both or none of CloudProvider and Region must be set
/// </summary>
public CloudProviderType? CloudProvider { get; set; }

/// <summary>
/// If set, filters results to this region only.
/// Either both or none of CloudProvider and Region must be set
/// </summary>
public string Region { get; set; }

internal ListPCUGroupsOptions(CommandOptions source) : base(source)
{
}

/// <summary>
/// Creates a new instance of <see cref="ListPCUGroupsOptions"/> with default values.
/// </summary>
public ListPCUGroupsOptions() : base()
{
}

static internal ListPCUGroupsOptions FromCommandOptions(
CommandOptions options, CloudProviderType? cloudProvider = null, string region = null
)
{
if (options == null) return null;
return new ListPCUGroupsOptions(options) {
CloudProvider = cloudProvider, Region = region
};
}

}
Loading
Loading