示例#1
0
        private async Task <IDictionary <string, string> > ResolveEnvironmentPreview(EnvironmentPreview environment)
        {
            // if there is a reference to an existing Environment, retrieve its keys
            if (!string.IsNullOrWhiteSpace(environment.Category) && !string.IsNullOrWhiteSpace(environment.Name))
            {
                var id     = new EnvironmentIdentifier(environment.Category, environment.Name);
                var result = await _store.Environments.GetKeys(new EnvironmentKeyQueryParameters
                {
                    Environment = id,
                    Range       = QueryRange.All
                });

                if (!result.IsError)
                {
                    return(result.Data);
                }

                Logger.LogWarning($"could not retrieve referenced environment '{id}' for preview: {result.Message}");
            }

            // if no reference or couldn't retrieve keys - fall back to custom-keys
            return(environment.Keys ?? new Dictionary <string, string>());
        }
示例#2
0
        /// <inheritdoc />
        public ConfigEnvironment(EnvironmentIdentifier identifier)
        {
            if (identifier is null)
            {
                throw new ArgumentNullException(nameof(identifier));
            }

            if (string.IsNullOrWhiteSpace(identifier.Category))
            {
                throw new ArgumentNullException(nameof(identifier), $"{nameof(identifier.Category)} is null or empty");
            }

            if (string.IsNullOrWhiteSpace(identifier.Name))
            {
                throw new ArgumentNullException(nameof(identifier), $"{nameof(identifier.Name)} is null or empty");
            }

            Created    = false;
            Deleted    = false;
            Identifier = new EnvironmentIdentifier(identifier.Category, identifier.Name);
            IsDefault  = false;
            Keys       = new Dictionary <string, ConfigEnvironmentKey>(StringComparer.OrdinalIgnoreCase);
        }
示例#3
0
        public async Task <IActionResult> GetVersion([FromRoute] string environmentCategory,
                                                     [FromRoute] string environmentName,
                                                     [FromRoute] string structureName,
                                                     [FromRoute] int structureVersion,
                                                     [FromQuery] DateTime when)
        {
            try
            {
                var envIdentifier       = new EnvironmentIdentifier(environmentCategory, environmentName);
                var structureIdentifier = new StructureIdentifier(structureName, structureVersion);

                var configId = new ConfigurationIdentifier(envIdentifier, structureIdentifier, default);

                var version = await _store.Configurations.GetVersion(configId, when);

                if (version.IsError)
                {
                    return(ProviderError(version));
                }

                // add version to the response-headers
                Response.Headers.Add("x-version", version.Data);

                return(Result(version));
            }
            catch (Exception e)
            {
                KnownMetrics.Exception.WithLabels(e.GetType().Name).Inc();
                Logger.LogError(e, "failed to add new environment at (" +
                                $"{nameof(environmentCategory)}: {environmentCategory}; " +
                                $"{nameof(environmentName)}: {environmentName}; " +
                                $"{nameof(structureName)}: {structureName}; " +
                                $"{nameof(structureVersion)}: {structureVersion}; " +
                                $"{nameof(when)}: {when})");
                return(StatusCode(HttpStatusCode.InternalServerError, "failed to retrieve configuration-version"));
            }
        }
示例#4
0
        public async Task <IActionResult> GetUsedKeysPerStructureAll([FromRoute] string environmentCategory,
                                                                     [FromRoute] string environmentName)
        {
            if (string.IsNullOrWhiteSpace(environmentCategory))
            {
                return(BadRequest("no environment-category given"));
            }

            if (string.IsNullOrWhiteSpace(environmentName))
            {
                return(BadRequest("no environment-name given"));
            }

            var envId = new EnvironmentIdentifier(environmentCategory, environmentName);

            var envKeyResult = await _store.Environments.GetKeys(new EnvironmentKeyQueryParameters
            {
                Environment = envId,
                Range       = QueryRange.All
            });

            if (envKeyResult.IsError)
            {
                return(ProviderError(envKeyResult));
            }

            var envKeys = envKeyResult.Data;

            var configResult = await _store.Configurations.GetAvailableWithEnvironment(envId, DateTime.MinValue, QueryRange.All);

            if (configResult.IsError)
            {
                return(ProviderError(configResult));
            }

            return(Result(await AnnotateEnvironmentKeys(envKeys, configResult.Data)));
        }
        /// <summary>
        ///     extract the actual desired environment out of the Environment-Export
        /// </summary>
        /// <param name="export"></param>
        /// <returns></returns>
        private EnvironmentExport GetExportedEnvironment(ConfigExport export)
        {
            if (export.Environments.Length > 1)
            {
                if (string.IsNullOrWhiteSpace(UseInputEnvironment))
                {
                    Output.WriteError("multiple Environments defined in given export, but no '-u|--use-environment' parameter given");
                    return(null);
                }

                var useSplit          = UseInputEnvironment.Split('/');
                var usedEnvironmentId = new EnvironmentIdentifier(useSplit[0], useSplit[1]);

                return(export.Environments
                       .FirstOrDefault(e => string.Equals(e.Category,
                                                          usedEnvironmentId.Category,
                                                          StringComparison.OrdinalIgnoreCase) &&
                                       string.Equals(e.Name,
                                                     usedEnvironmentId.Name,
                                                     StringComparison.OrdinalIgnoreCase)));
            }

            return(export.Environments.FirstOrDefault());
        }
 /// <inheritdoc />
 public EnvironmentKeysModified(EnvironmentIdentifier identifier, ConfigKeyAction[] modifiedKeys)
 {
     Identifier   = identifier;
     ModifiedKeys = modifiedKeys;
 }
示例#7
0
 /// <inheritdoc />
 public DefaultEnvironmentCreated(EnvironmentIdentifier identifier)
 {
     Identifier = identifier;
 }
示例#8
0
        public async Task <IActionResult> InspectUploadedStructure([FromRoute] string environmentCategory,
                                                                   [FromRoute] string environmentName,
                                                                   [FromBody] DtoStructure structure)
        {
            if (string.IsNullOrWhiteSpace(environmentCategory))
            {
                return(BadRequest("no environment-category given"));
            }

            if (string.IsNullOrWhiteSpace(environmentName))
            {
                return(BadRequest("no environment-name given"));
            }

            if (structure is null)
            {
                return(BadRequest("no structure was uploaded"));
            }

            switch (structure.Structure.ValueKind)
            {
            case JsonValueKind.Object:
                if (!structure.Structure.EnumerateObject().Any())
                {
                    return(BadRequest("empty structure-body given"));
                }
                break;

            case JsonValueKind.Array:
                if (!structure.Structure.EnumerateArray().Any())
                {
                    return(BadRequest("empty structure-body given"));
                }
                break;

            default:
                return(BadRequest("invalid structure-body given (invalid type or null)"));
            }

            IDictionary <string, string> structKeys;

            try
            {
                structKeys = _translator.ToDictionary(structure.Structure);
            }
            catch (Exception e)
            {
                Logger.LogWarning(e, "could not translate given json.Structure to dictionary");
                return(BadRequest("structure could not be mapped to a dictionary ($.Structure)"));
            }

            var envId = new EnvironmentIdentifier(environmentCategory, environmentName);

            var envKeysResult = await _store.Environments.GetKeys(new EnvironmentKeyQueryParameters
            {
                Environment = envId,
                Range       = QueryRange.All
            });

            if (envKeysResult.IsError)
            {
                return(ProviderError(envKeysResult));
            }

            var envKeys = envKeysResult.Data;

            CompilationResult compilationResult;

            try
            {
                compilationResult = _compiler.Compile(
                    new EnvironmentCompilationInfo
                {
                    Keys = envKeys,
                    Name = envId.ToString()
                }, new StructureCompilationInfo
                {
                    Name      = structure.Name ?? "Inspected Structure",
                    Keys      = structKeys,
                    Variables = (structure.Variables
                                 ?? new Dictionary <string, object>()).ToDictionary(kvp => kvp.Key,
                                                                                    kvp => kvp.Value?.ToString())
                },
                    _parser);
            }
            catch (Exception e)
            {
                Logger.LogWarning(e, $"structure could not be inspected in context of '{envId}'; compilation failed");
                return(Ok(new StructureInspectionResult
                {
                    CompilationSuccessful = false
                }));
            }

            var result = AnalyzeCompilation(compilationResult);

            return(Ok(result));
        }
示例#9
0
        public async Task <IActionResult> InspectStructure([FromRoute] string environmentCategory,
                                                           [FromRoute] string environmentName,
                                                           [FromRoute] string structureName,
                                                           [FromRoute] int structureVersion)
        {
            if (string.IsNullOrWhiteSpace(environmentCategory))
            {
                return(BadRequest("no environment-category given"));
            }

            if (string.IsNullOrWhiteSpace(environmentName))
            {
                return(BadRequest("no environment-name given"));
            }

            if (string.IsNullOrWhiteSpace(structureName))
            {
                return(BadRequest("no structure-name was given"));
            }

            if (structureVersion <= 0)
            {
                return(BadRequest("structure-version invalid"));
            }

            var envId    = new EnvironmentIdentifier(environmentCategory, environmentName);
            var structId = new StructureIdentifier(structureName, structureVersion);

            var envKeysResult = await _store.Environments.GetKeys(new EnvironmentKeyQueryParameters
            {
                Environment = envId,
                Range       = QueryRange.All
            });

            if (envKeysResult.IsError)
            {
                return(ProviderError(envKeysResult));
            }

            var envKeys = envKeysResult.Data;

            IDictionary <string, string> structKeys;
            IDictionary <string, string> structVars;

            try
            {
                var keyResult = await _store.Structures.GetKeys(structId, QueryRange.All);

                if (keyResult.IsError)
                {
                    return(ProviderError(keyResult));
                }

                var varResult = await _store.Structures.GetVariables(structId, QueryRange.All);

                if (varResult.IsError)
                {
                    return(ProviderError(varResult));
                }

                structKeys = keyResult.Data;
                structVars = varResult.Data;
            }
            catch (Exception e)
            {
                Logger.LogWarning(e, "could not retrieve structure-data or -variables");
                return(BadRequest("could not retrieve structure-data or -variables"));
            }

            CompilationResult compilationResult;

            try
            {
                compilationResult = _compiler.Compile(
                    new EnvironmentCompilationInfo
                {
                    Keys = envKeys,
                    Name = envId.ToString()
                },
                    new StructureCompilationInfo
                {
                    Name      = structureName,
                    Keys      = structKeys,
                    Variables = structVars
                },
                    _parser);
            }
            catch (Exception e)
            {
                Logger.LogWarning(e, $"structure could not be inspected in context of '{envId}'; compilation failed");
                return(Ok(new StructureInspectionResult
                {
                    CompilationSuccessful = false
                }));
            }

            var result = AnalyzeCompilation(compilationResult);

            return(Ok(result));
        }
示例#10
0
        public async Task <IActionResult> PreviewConfiguration([FromRoute] string environmentCategory,
                                                               [FromRoute] string environmentName,
                                                               [FromRoute] string structureName,
                                                               [FromRoute] int structureVersion)
        {
            var envId    = new EnvironmentIdentifier(environmentCategory, environmentName);
            var structId = new StructureIdentifier(structureName, structureVersion);

            var structureKeyResult = await _store.Structures.GetKeys(structId, QueryRange.All);

            if (structureKeyResult.IsError)
            {
                return(ProviderError(structureKeyResult));
            }

            var structureVariableResult = await _store.Structures.GetVariables(structId, QueryRange.All);

            if (structureVariableResult.IsError)
            {
                return(ProviderError(structureVariableResult));
            }

            var environmentResult = await _store.Environments.GetKeys(new EnvironmentKeyQueryParameters
            {
                Environment = envId,
                Range       = QueryRange.All
            });

            if (environmentResult.IsError)
            {
                return(ProviderError(environmentResult));
            }

            var structureSnapshot   = structureKeyResult.Data;
            var variableSnapshot    = structureVariableResult.Data;
            var environmentSnapshot = environmentResult.Data;

            var environmentInfo = new EnvironmentCompilationInfo
            {
                Name = $"{envId.Category}/{envId.Name}",
                Keys = environmentSnapshot
            };
            var structureInfo = new StructureCompilationInfo
            {
                Name      = $"{structId.Name}/{structId.Version}",
                Keys      = structureSnapshot,
                Variables = variableSnapshot
            };

            try
            {
                var compiled = _compiler.Compile(environmentInfo,
                                                 structureInfo,
                                                 _parser);

                var json = _translator.ToJson(compiled.CompiledConfiguration);

                return(Ok(json));
            }
            catch (Exception e)
            {
                KnownMetrics.Exception.WithLabels(e.GetType().Name).Inc();
                Logger.LogError(e, "failed to add new environment at (" +
                                $"{nameof(environmentCategory)}: {environmentCategory}; " +
                                $"{nameof(environmentName)}: {environmentName}; " +
                                $"{nameof(structureName)}: {structureName}; " +
                                $"{nameof(structureVersion)}: {structureVersion})");
                return(Ok(JsonDocument.Parse("{}").RootElement));
            }
        }
 /// <inheritdoc />
 public ConfigurationIdentifier(EnvironmentIdentifier environment, StructureIdentifier structure, long version)
 {
     Environment = environment;
     Structure   = structure;
     Version     = version;
 }
示例#12
0
        /// <inheritdoc />
        public async Task <IResult <IList <DtoConfigKeyCompletion> > > GetKeyAutoComplete(EnvironmentIdentifier identifier,
                                                                                          string key,
                                                                                          QueryRange range,
                                                                                          long version)
        {
            try
            {
                _logger.LogDebug($"attempting to retrieve next paths in '{identifier}' for path '{key}', range={range}");

                _logger.LogDebug($"removing escape-sequences from key");
                key = Uri.UnescapeDataString(key ?? string.Empty);
                _logger.LogDebug($"using new key='{key}'");

                var envResult = await(version <= 0
                                           ? _domainObjectStore.ReplayObject(new ConfigEnvironment(identifier), identifier.ToString())
                                           : _domainObjectStore.ReplayObject(new ConfigEnvironment(identifier), identifier.ToString(), version));

                if (envResult.IsError)
                {
                    return(Result.Error <IList <DtoConfigKeyCompletion> >(
                               "no environment found with (" +
                               $"{nameof(identifier.Category)}: {identifier.Category}; " +
                               $"{nameof(identifier.Name)}: {identifier.Name})",
                               ErrorCode.NotFound));
                }

                var environment = envResult.Data;
                var paths       = environment.KeyPaths;

                // send auto-completion data for all roots
                if (string.IsNullOrWhiteSpace(key))
                {
                    _logger.LogDebug("early-exit, sending root-paths because key was empty");
                    return(Result.Success <IList <DtoConfigKeyCompletion> >(
                               paths.Select(p => new DtoConfigKeyCompletion
                    {
                        HasChildren = p.Children.Any(),
                        FullPath = p.FullPath,
                        Completion = p.Path
                    })
                               .OrderBy(p => p.Completion)
                               .ToList()));
                }

                var parts = new Queue <string>(key.Contains('/')
                                                  ? key.Split('/')
                                                  : new[] { key });

                var rootPart = parts.Dequeue();

                _logger.LogDebug($"starting with path '{rootPart}'");

                // if the user is searching within the roots
                if (!parts.Any())
                {
                    _logger.LogDebug($"no further parts found, returning direct children");

                    var possibleRoots = paths.Where(p => p.Path.Contains(rootPart))
                                        .ToList();

                    // if there is only one possible root, and that one matches what were searching for
                    // we're returning all paths directly below that one
                    List <ConfigEnvironmentKeyPath> selectedRoots;
                    if (possibleRoots.Count == 1 &&
                        possibleRoots.First()
                        .Path
                        .Equals(rootPart, StringComparison.OrdinalIgnoreCase))
                    {
                        _logger.LogDebug("selecting children of only root for further processing");
                        selectedRoots = paths.First().Children;
                    }
                    else
                    {
                        _logger.LogDebug("selecting original matches for further processing");
                        selectedRoots = paths;
                    }

                    return(Result.Success <IList <DtoConfigKeyCompletion> >(
                               selectedRoots.Select(p => new DtoConfigKeyCompletion
                    {
                        HasChildren = p.Children.Any(),
                        FullPath = p.Children.Any() ? p.FullPath + '/' : p.FullPath,
                        Completion = p.Path
                    })
                               .OrderBy(p => p.Completion)
                               .ToList()));
                }

                var root = paths.FirstOrDefault(p => p.Path == rootPart);

                if (root is null)
                {
                    _logger.LogDebug($"no path found that matches '{rootPart}'");
                    return(Result.Error <IList <DtoConfigKeyCompletion> >(
                               $"key '{key}' is ambiguous, root does not match anything",
                               ErrorCode.NotFound));
                }

                var result = GetKeyAutoCompleteInternal(root, parts.ToList(), range);

                return(result);
            }
            catch (Exception e)
            {
                _logger.LogError(e, $"failed to get autocomplete data for '{key}' in " +
                                 $"({nameof(identifier.Category)}: {identifier.Category}; {nameof(identifier.Name)}: {identifier.Name})");

                return(Result.Error <IList <DtoConfigKeyCompletion> >($"failed to get autocomplete data for '{key}' in " +
                                                                      $"({nameof(identifier.Category)}: {identifier.Category}; {nameof(identifier.Name)}: {identifier.Name}): {e}",
                                                                      ErrorCode.DbQueryError));
            }
        }
示例#13
0
 /// <inheritdoc />
 public Task <IResult <IList <DtoConfigKeyCompletion> > > GetKeyAutoComplete(EnvironmentIdentifier identifier,
                                                                             string key,
                                                                             QueryRange range)
 => GetKeyAutoComplete(identifier, key, range, long.MaxValue);
        /// <inheritdoc />
        public async Task <IResult <IList <ConfigurationIdentifier> > > GetAvailableWithEnvironment(EnvironmentIdentifier environment,
                                                                                                    DateTime when,
                                                                                                    QueryRange range)
        {
            try
            {
                _logger.LogDebug($"collecting available configurations at '{when:O}', range={range}");

                var list = await _domainObjectStore.ReplayObject <PreparedConfigurationList>();

                if (list.IsError)
                {
                    return(Result.Success <IList <ConfigurationIdentifier> >(new List <ConfigurationIdentifier>()));
                }

                var utcWhen = when.ToUniversalTime();
                _logger.LogDebug($"using utc-time={utcWhen:O}");

                var identifiers =
                    list.Data
                    .GetIdentifiers()
                    .Where(pair => (pair.Value.ValidFrom ?? DateTime.MinValue) <= utcWhen &&
                           (pair.Value.ValidTo ?? DateTime.MaxValue) >= utcWhen)
                    .Where(pair => pair.Key.Environment.Category == environment.Category &&
                           pair.Key.Environment.Name == environment.Name)
                    .OrderBy(pair => pair.Key.Environment.Category)
                    .ThenBy(pair => pair.Key.Environment.Name)
                    .ThenBy(pair => pair.Key.Structure.Name)
                    .ThenByDescending(s => s.Key.Structure.Version)
                    .Skip(range.Offset)
                    .Take(range.Length)
                    .Select(pair => pair.Key)
                    .ToList();

                _logger.LogDebug($"collected '{identifiers.Count}' identifiers");

                return(Result.Success <IList <ConfigurationIdentifier> >(identifiers));
            }
            catch (Exception e)
            {
                _logger.LogError(e, "failed to retrieve projected configurations");
                return(Result.Error <IList <ConfigurationIdentifier> >("failed to retrieve projected configurations", ErrorCode.DbQueryError));
            }
        }
 /// <inheritdoc />
 public EnvironmentDeleted(EnvironmentIdentifier identifier)
 {
     Identifier = identifier;
 }