Skip to content

Commit

Permalink
asyncapi#196 Add example project with top level statement, because th…
Browse files Browse the repository at this point in the history
…at failed to generate specs, fixed now.

Added an external nuget dependancy to the example project (nlog) because that made spec generation fail, fixed now. And now also testing both .NET6 & .NET8
  • Loading branch information
Senn Geerts authored and Senn Geerts committed Jul 13, 2024
1 parent 72dc742 commit 7b22ce0
Show file tree
Hide file tree
Showing 16 changed files with 442 additions and 178 deletions.
18 changes: 18 additions & 0 deletions Saunter.sln
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Saunter.Tests", "test\Saunter.Tests\Saunter.Tests.csproj", "{3ADB27EF-7C80-40EB-AFC6-5D06D415FFAB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{6ABD4842-47AF-49A5-B057-0EBA64416789}"
ProjectSection(SolutionItems) = preProject
examples\.gitignore = examples\.gitignore
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StreetlightsAPI", "examples\StreetlightsAPI\StreetlightsAPI.csproj", "{F188D4A7-BBCB-464F-A370-2BD84D18EA79}"
EndProject
Expand Down Expand Up @@ -48,6 +51,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AsyncAPI.Saunter.Generator.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AsyncAPI.Saunter.Generator.Cli.Tests", "test\AsyncAPI.Saunter.Generator.Cli.Tests\AsyncAPI.Saunter.Generator.Cli.Tests.csproj", "{18AD0249-0436-4A26-9972-B97BA6905A54}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StreetlightsAPI.TopLevelStatement", "examples\StreetlightsAPI.TopLevelStatement\StreetlightsAPI.TopLevelStatement.csproj", "{6F6B8B03-9045-46EC-AE12-E7ADA492F9FA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -142,6 +147,18 @@ Global
{18AD0249-0436-4A26-9972-B97BA6905A54}.Release|x64.Build.0 = Release|Any CPU
{18AD0249-0436-4A26-9972-B97BA6905A54}.Release|x86.ActiveCfg = Release|Any CPU
{18AD0249-0436-4A26-9972-B97BA6905A54}.Release|x86.Build.0 = Release|Any CPU
{6F6B8B03-9045-46EC-AE12-E7ADA492F9FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6F6B8B03-9045-46EC-AE12-E7ADA492F9FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6F6B8B03-9045-46EC-AE12-E7ADA492F9FA}.Debug|x64.ActiveCfg = Debug|Any CPU
{6F6B8B03-9045-46EC-AE12-E7ADA492F9FA}.Debug|x64.Build.0 = Debug|Any CPU
{6F6B8B03-9045-46EC-AE12-E7ADA492F9FA}.Debug|x86.ActiveCfg = Debug|Any CPU
{6F6B8B03-9045-46EC-AE12-E7ADA492F9FA}.Debug|x86.Build.0 = Debug|Any CPU
{6F6B8B03-9045-46EC-AE12-E7ADA492F9FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6F6B8B03-9045-46EC-AE12-E7ADA492F9FA}.Release|Any CPU.Build.0 = Release|Any CPU
{6F6B8B03-9045-46EC-AE12-E7ADA492F9FA}.Release|x64.ActiveCfg = Release|Any CPU
{6F6B8B03-9045-46EC-AE12-E7ADA492F9FA}.Release|x64.Build.0 = Release|Any CPU
{6F6B8B03-9045-46EC-AE12-E7ADA492F9FA}.Release|x86.ActiveCfg = Release|Any CPU
{6F6B8B03-9045-46EC-AE12-E7ADA492F9FA}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -156,6 +173,7 @@ Global
{E8FACA22-CFED-4710-89E4-D55F31BF96B3} = {D8CB9C0D-9605-457B-979F-C8994B20A926}
{6C102D4D-3DA4-4763-B75E-C15E33E7E94A} = {28D4C365-FDED-49AE-A97D-36202E24A55A}
{18AD0249-0436-4A26-9972-B97BA6905A54} = {6491E321-2D02-44AB-9116-D722FE169595}
{6F6B8B03-9045-46EC-AE12-E7ADA492F9FA} = {6ABD4842-47AF-49A5-B057-0EBA64416789}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2F85D9DA-DBCF-4F13-8C42-5719F1469B2E}
Expand Down
4 changes: 4 additions & 0 deletions examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
specs/
streetlights.json
streetlights.yml
streetlights.yaml
76 changes: 76 additions & 0 deletions examples/StreetlightsAPI.TopLevelStatement/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NLog;
using NLog.Web;
using Saunter;
using Saunter.AsyncApiSchema.v2;
using StreetlightsAPI;

LogManager.Setup().LoadConfigurationFromAppSettings();

var builder = WebApplication.CreateBuilder(args);
builder.Host.ConfigureLogging(logging => logging.AddSimpleConsole(console => console.SingleLine = true));
builder.Host.UseNLog();

// Add Saunter to the application services.
builder.Services.AddAsyncApiSchemaGeneration(options =>
{
options.AssemblyMarkerTypes = [typeof(StreetlightMessageBus)];

options.Middleware.UiTitle = "Streetlights API";

options.AsyncApi = new AsyncApiDocument
{
Info = new Info("Streetlights API", "1.0.0")
{
Description = "The Smartylighting Streetlights API allows you to remotely manage the city lights.",
License = new License("Apache 2.0")
{
Url = "https://www.apache.org/licenses/LICENSE-2.0"
}
},
Servers =
{
["mosquitto"] = new Server("test.mosquitto.org", "mqtt"),
["webapi"] = new Server("localhost:5000", "http"),
},
};
});

builder.Services.AddScoped<IStreetlightMessageBus, StreetlightMessageBus>();
builder.Services.AddControllers();

var app = builder.Build();

app.UseDeveloperExceptionPage();

app.UseRouting();
app.UseCors(configure => configure.AllowAnyOrigin().AllowAnyMethod());

app.UseEndpoints(endpoints =>
{
endpoints.MapAsyncApiDocuments();
endpoints.MapAsyncApiUi();

endpoints.MapControllers();
});

await app.StartAsync();

// Print the AsyncAPI doc location
var logger = app.Services.GetService<ILoggerFactory>().CreateLogger<Program>();
var options = app.Services.GetService<IOptions<AsyncApiOptions>>();
var addresses = app.Urls;
logger.LogInformation("AsyncAPI doc available at: {URL}", $"{addresses.FirstOrDefault()}{options.Value.Middleware.Route}");
logger.LogInformation("AsyncAPI UI available at: {URL}", $"{addresses.FirstOrDefault()}{options.Value.Middleware.UiBaseRoute}");

// Redirect base url to AsyncAPI UI
app.Map("/", () => Results.Redirect("index.html"));
app.Map("/index.html", () => Results.Redirect(options.Value.Middleware.UiBaseRoute));

await app.WaitForShutdownAsync();
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<!-- This project is targeting .NET8 intentionally (The 'old school' Startup-class project is .NET6), to prove that
the AsyncAPI.Saunter.Generator.Cli tool can generate specs for projects targetting .NET6 and .NET8. -->
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>

<!-- Example settings for "AsyncAPI.Saunter.Generator.Build", they are all option though -->
<AsyncAPIGenerateDocumentsOnBuild>true</AsyncAPIGenerateDocumentsOnBuild>
<AsyncAPIDocumentFormats>json,yml</AsyncAPIDocumentFormats>
<AsyncAPIDocumentFilename>streetlights.{extension}</AsyncAPIDocumentFilename>
<AsyncAPIDocumentOutputPath>specs</AsyncAPIDocumentOutputPath>
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DocumentationFile>bin\Debug\StreetlightsAPI.TopLevelStatement.xml</DocumentationFile>
<NoWarn>1701;1702;1591</NoWarn>
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DocumentationFile>bin\Release\StreetlightsAPI.TopLevelStatement.xml</DocumentationFile>
<NoWarn>1701;1702;1591</NoWarn>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Saunter\Saunter.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="specs\" />

<Compile Include="../StreetlightsAPI/API.cs" />
<Compile Include="../StreetlightsAPI/Messaging.cs" />

<None Include="../StreetlightsAPI/nlog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

<ItemGroup>
<PackageReference Include="NLog" Version="5.3.2" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.11" />
</ItemGroup>

</Project>
19 changes: 19 additions & 0 deletions examples/StreetlightsAPI.TopLevelStatement/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},

"AllowedHosts": "*",

"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://localhost:5001"
}
}
}
}
7 changes: 6 additions & 1 deletion examples/StreetlightsAPI/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NLog;
using NLog.Web;
using Saunter;
using Saunter.AsyncApiSchema.v2;

Expand All @@ -15,17 +17,20 @@ public class Program
{
public static void Main(string[] args)
{
LogManager.Setup().LoadConfigurationFromAppSettings();

CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging => logging.AddSimpleConsole(console => console.SingleLine = true))
.UseNLog()
.ConfigureWebHostDefaults(web =>
{
web.UseStartup<Startup>();
web.UseUrls("http://localhost:5000");
web.UseUrls("http://localhost:5001");
});
}
}
Expand Down
15 changes: 15 additions & 0 deletions examples/StreetlightsAPI/StreetlightsAPI.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<!-- This project is targeting .NET6 intentionally (The top level statement project is .NET8), to prove that
the AsyncAPI.Saunter.Generator.Cli tool can generate specs for projects targetting .NET6 and .NET8. -->
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
Expand All @@ -19,4 +21,17 @@
<ProjectReference Include="..\..\src\Saunter\Saunter.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="specs\" />

<Content Update="nlog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup>
<PackageReference Include="NLog" Version="5.3.2" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.11" />
</ItemGroup>

</Project>
23 changes: 23 additions & 0 deletions examples/StreetlightsAPI/nlog.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true">

<variable name="BaseDir" value="./" />

<!-- the targets to write to -->
<targets>
<!-- File Target for all log messages with basic details -->
<target xsi:type="File" name="allfile" fileName="${BaseDir}/streetlights.nlog"
layout="${longdate}|${level:uppercase=true}|${activity:property=TraceId}|${logger}|${message} ${exception:format=tostring}"
maxArchiveFiles="5" archiveAboveSize="104857600" archiveNumbering="DateAndSequence" archiveDateFormat="yyyy-MM-dd" archiveFileName="${BaseDir}/streetlights-{#}.nlog" />

<!--Console Target for hosting lifetime messages to improve Docker / Visual Studio startup detection -->
<target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" />
</targets>

<!-- rules to map from logger name to target -->
<rules>
<logger name="*" minlevel="Debug" writeTo="allfile" />
</rules>
</nlog>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>12</LangVersion>
<RootNamespace>AsyncAPI.Saunter.Generator.Cli</RootNamespace>
<NoWarn>$(NoWarn);EF1001</NoWarn>

<Description>AsyncAPI Command Line Tools: Dotnet tool to generate AsyncAPI spec file from dotnet startup assembly.</Description>
<Authors>AsyncAPI Initiative</Authors>
Expand Down Expand Up @@ -40,8 +41,8 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.7" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="NSwag.Commands" Version="14.0.8" />
</ItemGroup>

<ItemGroup>
Expand Down
22 changes: 22 additions & 0 deletions src/AsyncAPI.Saunter.Generator.Cli/ToFile/DependencyResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Reflection;

namespace AsyncAPI.Saunter.Generator.Cli.ToFile;

internal static class DependencyResolver
{
public static void Init(string startupAssemblyBasePath)
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
var requestedAssembly = new AssemblyName(args.Name);
var fullPath = Path.Combine(startupAssemblyBasePath, $"{requestedAssembly.Name}.dll");
if (File.Exists(fullPath))
{
var assembly = Assembly.LoadFile(fullPath);
return assembly;
}
Console.WriteLine($"Could not resolve assembly: {args.Name}, requested by {args.RequestingAssembly?.FullName}");
return default;
};
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Reflection;
using System.Runtime.Loader;
using System.Runtime.Loader;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Design.Internal;
using Microsoft.Extensions.Logging;

namespace AsyncAPI.Saunter.Generator.Cli.ToFile;
Expand All @@ -13,12 +14,20 @@ internal class ServiceProviderBuilder(ILogger<ServiceProviderBuilder> logger) :
{
public IServiceProvider BuildServiceProvider(string startupAssembly)
{
var fullPath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), startupAssembly));
var fullPath = Path.GetFullPath(startupAssembly);
var basePath = Path.GetDirectoryName(fullPath);
DependencyResolver.Init(basePath);

logger.LogInformation($"Loading startup assembly: {fullPath}");
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(fullPath);
var nswagCommandsAssembly = Assembly.LoadFrom("NSwag.Commands.dll");
var nswagServiceProvider = nswagCommandsAssembly.GetType("NSwag.Commands.ServiceProviderResolver");
var serviceProvider = (IServiceProvider)nswagServiceProvider.InvokeMember("GetServiceProvider", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, null, [assembly]);
var reporter = new OperationReporter(new OperationReportHandler(
m => logger.LogError(m),
m => logger.LogWarning(m),
m => logger.LogInformation(m),
m => logger.LogDebug(m)));
var appServiceProvider = new AppServiceProviderFactory(assembly, reporter);
var serviceProvider = appServiceProvider.Create([]);

return serviceProvider;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,13 @@
<Using Include="Xunit" />
</ItemGroup>

<ItemGroup>
<None Update="Specs\streetlights_v2.6.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Specs\streetlights_v2.6.yml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Loading

0 comments on commit 7b22ce0

Please sign in to comment.