diff --git a/src/Microsoft.OpenApi.Hidi/Handlers/TransformCommandHandler.cs b/src/Microsoft.OpenApi.Hidi/Handlers/TransformCommandHandler.cs new file mode 100644 index 000000000..e8d9431de --- /dev/null +++ b/src/Microsoft.OpenApi.Hidi/Handlers/TransformCommandHandler.cs @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.CommandLine; +using System.CommandLine.Invocation; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + +namespace Microsoft.OpenApi.Hidi.Handlers +{ + internal class TransformCommandHandler : ICommandHandler + { + public Option DescriptionOption { get; set; } + public Option CsdlOption { get; set; } + public Option CsdlFilterOption { get; set; } + public Option OutputOption { get; set; } + public Option CleanOutputOption { get; set; } + public Option VersionOption { get; set; } + public Option FormatOption { get; set; } + public Option TerseOutputOption { get; set; } + public Option LogLevelOption { get; set; } + public Option FilterByOperationIdsOption { get; set; } + public Option FilterByTagsOption { get; set; } + public Option FilterByCollectionOption { get; set; } + public Option InlineLocalOption { get; set; } + public Option InlineExternalOption { get; set; } + + public int Invoke(InvocationContext context) + { + return InvokeAsync(context).GetAwaiter().GetResult(); + } + public async Task InvokeAsync(InvocationContext context) + { + string openapi = context.ParseResult.GetValueForOption(DescriptionOption); + string csdlFilter = context.ParseResult.GetValueForOption(CsdlFilterOption); + string csdl = context.ParseResult.GetValueForOption(CsdlOption); + FileInfo output = context.ParseResult.GetValueForOption(OutputOption); + bool cleanOutput = context.ParseResult.GetValueForOption(CleanOutputOption); + string? version = context.ParseResult.GetValueForOption(VersionOption); + OpenApiFormat? format = context.ParseResult.GetValueForOption(FormatOption); + bool terseOutput = context.ParseResult.GetValueForOption(TerseOutputOption); + LogLevel logLevel = context.ParseResult.GetValueForOption(LogLevelOption); + bool inlineLocal = context.ParseResult.GetValueForOption(InlineLocalOption); + bool inlineExternal = context.ParseResult.GetValueForOption(InlineExternalOption); + string filterbyoperationids = context.ParseResult.GetValueForOption(FilterByOperationIdsOption); + string filterbytags = context.ParseResult.GetValueForOption(FilterByTagsOption); + string filterbycollection = context.ParseResult.GetValueForOption(FilterByCollectionOption); + CancellationToken cancellationToken = (CancellationToken)context.BindingContext.GetService(typeof(CancellationToken)); + + using var loggerFactory = Logger.ConfigureLogger(logLevel); + var logger = loggerFactory.CreateLogger(); + try + { + await OpenApiService.TransformOpenApiDocument(openapi, csdl, csdlFilter, output, cleanOutput, version, format, terseOutput, logLevel, inlineLocal, inlineExternal, filterbyoperationids, filterbytags, filterbycollection, cancellationToken); + + return 0; + } + catch (Exception ex) + { +#if DEBUG + logger.LogCritical(ex, ex.Message); + throw; // so debug tools go straight to the source of the exception when attached +#else + logger.LogCritical( ex.Message); + return 1; +#endif + } + } + } +} diff --git a/src/Microsoft.OpenApi.Hidi/Handlers/ValidateCommandHandler.cs b/src/Microsoft.OpenApi.Hidi/Handlers/ValidateCommandHandler.cs new file mode 100644 index 000000000..2faa771ea --- /dev/null +++ b/src/Microsoft.OpenApi.Hidi/Handlers/ValidateCommandHandler.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.CommandLine; +using System.CommandLine.Invocation; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + +namespace Microsoft.OpenApi.Hidi.Handlers +{ + internal class ValidateCommandHandler : ICommandHandler + { + public Option DescriptionOption { get; set; } + public Option LogLevelOption { get; set; } + + public int Invoke(InvocationContext context) + { + return InvokeAsync(context).GetAwaiter().GetResult(); + } + public async Task InvokeAsync(InvocationContext context) + { + string openapi = context.ParseResult.GetValueForOption(DescriptionOption); + LogLevel logLevel = context.ParseResult.GetValueForOption(LogLevelOption); + CancellationToken cancellationToken = (CancellationToken)context.BindingContext.GetService(typeof(CancellationToken)); + + + using var loggerFactory = Logger.ConfigureLogger(logLevel); + var logger = loggerFactory.CreateLogger(); + try + { + await OpenApiService.ValidateOpenApiDocument(openapi, logLevel, cancellationToken); + return 0; + } + catch (Exception ex) + { +#if DEBUG + logger.LogCritical(ex, ex.Message); + throw; // so debug tools go straight to the source of the exception when attached +#else + logger.LogCritical( ex.Message); + return 1; +#endif + } + } + } +} diff --git a/src/Microsoft.OpenApi.Hidi/Logger.cs b/src/Microsoft.OpenApi.Hidi/Logger.cs new file mode 100644 index 000000000..2b02e9600 --- /dev/null +++ b/src/Microsoft.OpenApi.Hidi/Logger.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using Microsoft.Extensions.Logging; + +namespace Microsoft.OpenApi.Hidi +{ + public class Logger + { + public static ILoggerFactory ConfigureLogger(LogLevel logLevel) + { + // Configure logger options +#if DEBUG + logLevel = logLevel > LogLevel.Debug ? LogLevel.Debug : logLevel; +#endif + + return LoggerFactory.Create((builder) => + { + builder + .AddSimpleConsole(c => + { + c.IncludeScopes = true; + }) +#if DEBUG + .AddDebug() +#endif + .SetMinimumLevel(logLevel); + }); + } + } +} diff --git a/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj b/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj index f9e1f0d9e..c35c40209 100644 --- a/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj +++ b/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj @@ -41,7 +41,7 @@ - + diff --git a/src/Microsoft.OpenApi.Hidi/OpenApiService.cs b/src/Microsoft.OpenApi.Hidi/OpenApiService.cs index d9f9887e1..c37c9479d 100644 --- a/src/Microsoft.OpenApi.Hidi/OpenApiService.cs +++ b/src/Microsoft.OpenApi.Hidi/OpenApiService.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; @@ -26,7 +26,6 @@ using System.Threading; using System.Xml.Xsl; using System.Xml; -using System.Runtime.CompilerServices; using System.Reflection; namespace Microsoft.OpenApi.Hidi @@ -36,7 +35,7 @@ public class OpenApiService /// /// Implementation of the transform command /// - public static async Task TransformOpenApiDocument( + public static async Task TransformOpenApiDocument( string openapi, string csdl, string csdlFilter, @@ -45,7 +44,7 @@ public static async Task TransformOpenApiDocument( string? version, OpenApiFormat? format, bool terseOutput, - LogLevel loglevel, + LogLevel logLevel, bool inlineLocal, bool inlineExternal, string filterbyoperationids, @@ -54,9 +53,8 @@ public static async Task TransformOpenApiDocument( CancellationToken cancellationToken ) { - using var loggerFactory = ConfigureLoggerInstance(loglevel); + using var loggerFactory = Logger.ConfigureLogger(logLevel); var logger = loggerFactory.CreateLogger(); - try { if (string.IsNullOrEmpty(openapi) && string.IsNullOrEmpty(csdl)) @@ -213,18 +211,11 @@ CancellationToken cancellationToken logger.LogTrace($"Finished serializing in {stopwatch.ElapsedMilliseconds}ms"); textWriter.Flush(); } - return 0; } catch (Exception ex) { -#if DEBUG - logger.LogCritical(ex, ex.Message); -#else - logger.LogCritical(ex.Message); - -#endif - return 1; - } + throw new InvalidOperationException($"Could not transform the document, reason: {ex.Message}", ex); + } } private static XslCompiledTransform GetFilterTransform() @@ -253,14 +244,13 @@ private static Stream ApplyFilter(string csdl, string entitySetOrSingleton, XslC /// /// Implementation of the validate command /// - public static async Task ValidateOpenApiDocument( + public static async Task ValidateOpenApiDocument( string openapi, - LogLevel loglevel, + LogLevel logLevel, CancellationToken cancellationToken) { - using var loggerFactory = ConfigureLoggerInstance(loglevel); + using var loggerFactory = Logger.ConfigureLogger(logLevel); var logger = loggerFactory.CreateLogger(); - try { if (string.IsNullOrEmpty(openapi)) @@ -307,19 +297,11 @@ public static async Task ValidateOpenApiDocument( logger.LogTrace("Finished walking through the OpenApi document. Generating a statistics report.."); logger.LogInformation(statsVisitor.GetStatisticsReport()); } - - return 0; } catch (Exception ex) { -#if DEBUG - logger.LogCritical(ex, ex.Message); -#else - logger.LogCritical(ex.Message); -#endif - return 1; + throw new InvalidOperationException($"Could not validate the document, reason: {ex.Message}", ex); } - } /// @@ -596,7 +578,7 @@ private static ILoggerFactory ConfigureLoggerInstance(LogLevel loglevel) loglevel = loglevel > LogLevel.Debug ? LogLevel.Debug : loglevel; #endif - return LoggerFactory.Create((builder) => { + return Microsoft.Extensions.Logging.LoggerFactory.Create((builder) => { builder .AddSimpleConsole(c => { c.IncludeScopes = true; diff --git a/src/Microsoft.OpenApi.Hidi/Program.cs b/src/Microsoft.OpenApi.Hidi/Program.cs index d19e48cf4..926c58deb 100644 --- a/src/Microsoft.OpenApi.Hidi/Program.cs +++ b/src/Microsoft.OpenApi.Hidi/Program.cs @@ -1,12 +1,11 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. -using System; using System.CommandLine; using System.IO; -using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Microsoft.OpenApi.Hidi.Handlers; namespace Microsoft.OpenApi.Hidi { @@ -66,7 +65,11 @@ static async Task Main(string[] args) logLevelOption }; - validateCommand.SetHandler(OpenApiService.ValidateOpenApiDocument, descriptionOption, logLevelOption); + validateCommand.Handler = new ValidateCommandHandler + { + DescriptionOption = descriptionOption, + LogLevelOption = logLevelOption + }; var transformCommand = new Command("transform") { @@ -86,8 +89,23 @@ static async Task Main(string[] args) inlineExternalOption }; - transformCommand.SetHandler ( - OpenApiService.TransformOpenApiDocument, descriptionOption, csdlOption, csdlFilterOption, outputOption, cleanOutputOption, versionOption, formatOption, terseOutputOption, logLevelOption, inlineLocalOption, inlineExternalOption, filterByOperationIdsOption, filterByTagsOption, filterByCollectionOption); + transformCommand.Handler = new TransformCommandHandler + { + DescriptionOption = descriptionOption, + CsdlOption = csdlOption, + CsdlFilterOption = csdlFilterOption, + OutputOption = outputOption, + CleanOutputOption = cleanOutputOption, + VersionOption = versionOption, + FormatOption = formatOption, + TerseOutputOption = terseOutputOption, + LogLevelOption = logLevelOption, + FilterByOperationIdsOption = filterByOperationIdsOption, + FilterByTagsOption = filterByTagsOption, + FilterByCollectionOption = filterByCollectionOption, + InlineLocalOption = inlineLocalOption, + InlineExternalOption = inlineExternalOption + }; rootCommand.Add(transformCommand); rootCommand.Add(validateCommand);