/// <summary> /// validate each build-option and return the appropriate error, or null if everything is valid /// </summary> /// <param name="buildOptions"></param> /// <returns></returns> private IActionResult ValidateBuildOptions(ConfigurationBuildOptions buildOptions) { if (buildOptions is null) { return(BadRequest("no build-options received")); } // if both ValidFrom and ValidTo are set, we make sure that they're valid if (!(buildOptions.ValidFrom is null) && !(buildOptions.ValidTo is null)) { if (buildOptions.ValidFrom > buildOptions.ValidTo) { return(BadRequest($"{nameof(buildOptions.ValidFrom)} can't be later than {nameof(buildOptions.ValidTo)}")); } var minimumActiveTime = TimeSpan.FromMinutes(1.0d); if (buildOptions.ValidTo - buildOptions.ValidFrom < minimumActiveTime) { return(BadRequest("the configuration needs to be valid for at least " + $"'{minimumActiveTime:g}' ({buildOptions.ValidTo - buildOptions.ValidFrom})")); } } return(null); }
public async Task <IActionResult> BuildConfiguration([FromRoute] string environmentCategory, [FromRoute] string environmentName, [FromRoute] string structureName, [FromRoute] int structureVersion, [FromBody] ConfigurationBuildOptions buildOptions) { var buildError = ValidateBuildOptions(buildOptions); if (!(buildError is null)) { return(buildError); } var availableStructures = await _store.Structures.GetAvailable(QueryRange.All); if (availableStructures.IsError) { return(ProviderError(availableStructures)); } var availableEnvironments = await _store.Environments.GetAvailable(QueryRange.All); if (availableEnvironments.IsError) { return(ProviderError(availableEnvironments)); } var environment = availableEnvironments.Data .FirstOrDefault(e => e.Category.Equals(environmentCategory, StringComparison.InvariantCultureIgnoreCase) && e.Name.Equals(environmentName, StringComparison.InvariantCultureIgnoreCase)); if (environment is null) { return(NotFound($"no environment '{environmentCategory}/{environmentName}' found")); } var structure = availableStructures.Data .FirstOrDefault(s => s.Name.Equals(structureName) && s.Version == structureVersion); if (structure is null) { return(NotFound($"no versions of structure '{structureName}' found")); } var configId = new ConfigurationIdentifier(environment, structure, 0); var stalenessResult = await _store.Configurations.IsStale(configId); if (stalenessResult.IsError) { return(ProviderError(stalenessResult)); } bool requestApproved; if (stalenessResult.Data) { var result = await _store.Configurations.Build(configId, buildOptions?.ValidFrom, buildOptions?.ValidTo); if (result.IsError) { return(ProviderError(result)); } requestApproved = true; } else { Logger.LogInformation($"request for new Configuration ({configId}) denied due to it not being stale"); requestApproved = false; } // add a header indicating if a new Configuration was actually built or not HttpContext.Response.OnStarting(state => Task.FromResult(HttpContext.Response.Headers.TryAdd("x-built", ((bool)state).ToString())), requestApproved); return(AcceptedAtAction( nameof(GetConfiguration), RouteUtilities.ControllerName <ConfigurationController>(), new { version = ApiVersions.V1, environmentCategory = environment.Category, environmentName = environment.Name, structureName = structure.Name, structureVersion = structure.Version, when = DateTime.MinValue, offset = -1, length = -1 })); }