示例#1
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));
        }
示例#2
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));
        }
示例#3
0
        /// <inheritdoc />
        public async Task <IResult> Delete(EnvironmentIdentifier identifier)
        {
            _logger.LogDebug($"attempting to delete environment '{identifier}'");

            var envResult = await _domainObjectStore.ReplayObject(new ConfigEnvironment(identifier), identifier.ToString());

            if (envResult.IsError)
            {
                return(envResult);
            }

            var environment = envResult.Data;

            _logger.LogDebug("deleting environment");
            var createResult = environment.Delete();

            if (createResult.IsError)
            {
                return(createResult);
            }

            _logger.LogDebug("validating resulting events");
            var errors = environment.Validate(_validators);

            if (errors.Any())
            {
                return(Result.Error("failed to validate generated DomainEvents",
                                    ErrorCode.ValidationFailed,
                                    errors.Values
                                    .SelectMany(_ => _)
                                    .ToList()));
            }

            return(await environment.WriteRecordedEvents(_eventStore));
        }
示例#4
0
        /// <inheritdoc />
        public async Task <IResult> UpdateKeys(EnvironmentIdentifier identifier, ICollection <DtoConfigKey> keys)
        {
            _logger.LogDebug($"attempting to update {keys.Count} keys in '{identifier}'");

            var envResult = await _domainObjectStore.ReplayObject(new ConfigEnvironment(identifier), identifier.ToString());

            if (envResult.IsError)
            {
                return(envResult);
            }

            var environment = envResult.Data;

            if (!environment.Created)
            {
                return(Result.Error("environment does not exist", ErrorCode.NotFound));
            }

            _logger.LogDebug($"transforming DTOs to '{nameof(ConfigEnvironmentKey)}'");
            var updates = keys.Select(dto => new ConfigEnvironmentKey(dto.Key, dto.Value, dto.Type, dto.Description, 0))
                          .ToList();

            _logger.LogDebug("updating environment keys");
            var result = environment.UpdateKeys(updates);

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

            _logger.LogDebug("validating generated events");
            var errors = environment.Validate(_validators);

            if (errors.Any())
            {
                return(Result.Error("failed to validate generated DomainEvents",
                                    ErrorCode.ValidationFailed,
                                    errors.Values
                                    .SelectMany(_ => _)
                                    .ToList()));
            }

            return(await environment.WriteRecordedEvents(_eventStore));
        }
示例#5
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));
            }
        }
示例#6
0
        /// <inheritdoc />
        public async Task <IResult> Import(ConfigExport export)
        {
            if (export is null)
            {
                return(Result.Error($"{nameof(export)} must not be null", ErrorCode.InvalidData));
            }

            foreach (var envExport in export.Environments)
            {
                var identifier = new EnvironmentIdentifier(envExport.Category, envExport.Name);

                var envResult = await _domainObjectStore.ReplayObject(new ConfigEnvironment(identifier), identifier.ToString());

                if (envResult.IsError)
                {
                    return(envResult);
                }

                var environment = envResult.Data;

                environment.ImportKeys(envExport.Keys
                                       .Select(k => new ConfigEnvironmentKey(k.Key, k.Value, k.Type, k.Description, 0))
                                       .ToList());

                var errors = environment.Validate(_validators);
                if (errors.Any())
                {
                    var errorMessages = string.Join("\r\n", errors.Values
                                                    .SelectMany(_ => _)
                                                    .Select(r => r.Message));

                    return(Result.Error($"data-validation failed; {errorMessages}", ErrorCode.ValidationFailed));
                }

                var result = await environment.WriteRecordedEvents(_eventStore);

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

            return(Result.Success());
        }