in src/Cli/ConfigGenerator.cs [84:275]
public static bool TryCreateRuntimeConfig(InitOptions options, FileSystemRuntimeConfigLoader loader, IFileSystem fileSystem, [NotNullWhen(true)] out RuntimeConfig? runtimeConfig)
{
runtimeConfig = null;
DatabaseType dbType = options.DatabaseType;
string? restPath = options.RestPath;
string graphQLPath = options.GraphQLPath;
string? runtimeBaseRoute = options.RuntimeBaseRoute;
Dictionary<string, object?> dbOptions = new();
HyphenatedNamingPolicy namingPolicy = new();
// If --rest.disabled flag is included in the init command, we log a warning to not use this flag as it will be deprecated in future versions of DAB.
if (options.RestDisabled is true)
{
_logger.LogWarning("The option --rest.disabled will be deprecated and support for the option will be removed in future versions of Data API builder." +
" We recommend that you use the --rest.enabled option instead.");
}
// If --graphql.disabled flag is included in the init command, we log a warning to not use this flag as it will be deprecated in future versions of DAB.
if (options.GraphQLDisabled is true)
{
_logger.LogWarning("The option --graphql.disabled will be deprecated and support for the option will be removed in future versions of Data API builder." +
" We recommend that you use the --graphql.enabled option instead.");
}
bool restEnabled, graphQLEnabled;
if (!TryDetermineIfApiIsEnabled(options.RestDisabled, options.RestEnabled, ApiType.REST, out restEnabled) ||
!TryDetermineIfApiIsEnabled(options.GraphQLDisabled, options.GraphQLEnabled, ApiType.GraphQL, out graphQLEnabled))
{
return false;
}
bool isMultipleCreateEnabledForGraphQL;
// Multiple mutation operations are applicable only for MSSQL database. When the option --graphql.multiple-create.enabled is specified for other database types,
// a warning is logged.
// When multiple mutation operations are extended for other database types, this option should be honored.
// Tracked by issue #2001: https://github.com/Azure/data-api-builder/issues/2001.
if (dbType is not DatabaseType.MSSQL && options.MultipleCreateOperationEnabled is not CliBool.None)
{
_logger.LogWarning($"The option --graphql.multiple-create.enabled is not supported for the {dbType.ToString()} database type and will not be honored.");
}
MultipleMutationOptions? multipleMutationOptions = null;
// Multiple mutation operations are applicable only for MSSQL database. When the option --graphql.multiple-create.enabled is specified for other database types,
// it is not honored.
if (dbType is DatabaseType.MSSQL && options.MultipleCreateOperationEnabled is not CliBool.None)
{
isMultipleCreateEnabledForGraphQL = IsMultipleCreateOperationEnabled(options.MultipleCreateOperationEnabled);
multipleMutationOptions = new(multipleCreateOptions: new MultipleCreateOptions(enabled: isMultipleCreateEnabledForGraphQL));
}
switch (dbType)
{
case DatabaseType.CosmosDB_NoSQL:
// If cosmosdb_nosql is specified, rest is disabled.
restEnabled = false;
string? cosmosDatabase = options.CosmosNoSqlDatabase;
string? cosmosContainer = options.CosmosNoSqlContainer;
string? graphQLSchemaPath = options.GraphQLSchemaPath;
if (string.IsNullOrEmpty(cosmosDatabase))
{
_logger.LogError("Missing mandatory configuration options for CosmosDB_NoSql: --cosmosdb_nosql-database, and --graphql-schema");
return false;
}
if (string.IsNullOrEmpty(graphQLSchemaPath))
{
graphQLSchemaPath = "schema.gql"; // Default to schema.gql
_logger.LogWarning("The GraphQL schema path, i.e. --graphql-schema, is not specified. Please either provide your schema or generate the schema using the `export` command before running `dab start`. For more detail, run 'dab export --help` ");
}
else if (!fileSystem.File.Exists(graphQLSchemaPath))
{
_logger.LogError("GraphQL Schema File: {graphQLSchemaPath} not found.", graphQLSchemaPath);
return false;
}
// If the option --rest.path is specified for cosmosdb_nosql, log a warning because
// rest is not supported for cosmosdb_nosql yet.
if (!RestRuntimeOptions.DEFAULT_PATH.Equals(restPath))
{
_logger.LogWarning("Configuration option --rest.path is not honored for cosmosdb_nosql since CosmosDB does not support REST.");
}
if (options.RestRequestBodyStrict is not CliBool.None)
{
_logger.LogWarning("Configuration option --rest.request-body-strict is not honored for cosmosdb_nosql since CosmosDB does not support REST.");
}
restPath = null;
dbOptions.Add(namingPolicy.ConvertName(nameof(CosmosDbNoSQLDataSourceOptions.Database)), cosmosDatabase);
dbOptions.Add(namingPolicy.ConvertName(nameof(CosmosDbNoSQLDataSourceOptions.Container)), cosmosContainer);
dbOptions.Add(namingPolicy.ConvertName(nameof(CosmosDbNoSQLDataSourceOptions.Schema)), graphQLSchemaPath);
break;
case DatabaseType.DWSQL:
case DatabaseType.MSSQL:
dbOptions.Add(namingPolicy.ConvertName(nameof(MsSqlOptions.SetSessionContext)), options.SetSessionContext);
break;
case DatabaseType.MySQL:
case DatabaseType.PostgreSQL:
case DatabaseType.CosmosDB_PostgreSQL:
break;
default:
throw new Exception($"DatabaseType: ${dbType} not supported.Please provide a valid database-type.");
}
// default value of connection-string should be used, i.e Empty-string
// if not explicitly provided by the user
DataSource dataSource = new(dbType, options.ConnectionString ?? string.Empty, dbOptions);
if (!ValidateAudienceAndIssuerForJwtProvider(options.AuthenticationProvider, options.Audience, options.Issuer))
{
return false;
}
if (!IsURIComponentValid(restPath))
{
_logger.LogError("{apiType} path {message}", ApiType.REST, RuntimeConfigValidatorUtil.URI_COMPONENT_WITH_RESERVED_CHARS_ERR_MSG);
return false;
}
if (!IsURIComponentValid(options.GraphQLPath))
{
_logger.LogError("{apiType} path {message}", ApiType.GraphQL, RuntimeConfigValidatorUtil.URI_COMPONENT_WITH_RESERVED_CHARS_ERR_MSG);
return false;
}
if (!IsURIComponentValid(runtimeBaseRoute))
{
_logger.LogError("Runtime base-route {message}", RuntimeConfigValidatorUtil.URI_COMPONENT_WITH_RESERVED_CHARS_ERR_MSG);
return false;
}
if (runtimeBaseRoute is not null)
{
if (!Enum.TryParse(options.AuthenticationProvider, ignoreCase: true, out EasyAuthType authMode) || authMode is not EasyAuthType.StaticWebApps)
{
_logger.LogError("Runtime base-route can only be specified when the authentication provider is Static Web Apps.");
return false;
}
}
if (options.RestDisabled && options.GraphQLDisabled)
{
_logger.LogError("Both Rest and GraphQL cannot be disabled together.");
return false;
}
string dabSchemaLink = loader.GetPublishedDraftSchemaLink();
// Prefix REST path with '/', if not already present.
if (restPath is not null && !restPath.StartsWith('/'))
{
restPath = "/" + restPath;
}
// Prefix base-route with '/', if not already present.
if (runtimeBaseRoute is not null && !runtimeBaseRoute.StartsWith('/'))
{
runtimeBaseRoute = "/" + runtimeBaseRoute;
}
// Prefix GraphQL path with '/', if not already present.
if (!graphQLPath.StartsWith('/'))
{
graphQLPath = "/" + graphQLPath;
}
runtimeConfig = new(
Schema: dabSchemaLink,
DataSource: dataSource,
Runtime: new(
Rest: new(restEnabled, restPath ?? RestRuntimeOptions.DEFAULT_PATH, options.RestRequestBodyStrict is CliBool.False ? false : true),
GraphQL: new(Enabled: graphQLEnabled, Path: graphQLPath, MultipleMutationOptions: multipleMutationOptions),
Host: new(
Cors: new(options.CorsOrigin?.ToArray() ?? Array.Empty<string>()),
Authentication: new(
Provider: options.AuthenticationProvider,
Jwt: (options.Audience is null && options.Issuer is null) ? null : new(options.Audience, options.Issuer)),
Mode: options.HostMode),
BaseRoute: runtimeBaseRoute
),
Entities: new RuntimeEntities(new Dictionary<string, Entity>()));
return true;
}