Skip to content

#196 Publish a global dotnet tool (AsyncAPI.Saunter.Generator.Cli)#217

Open
smoerijf wants to merge 37 commits intoasyncapi:mainfrom
smoerijf:#196-Publish-a-global-dotnet-tool
Open

#196 Publish a global dotnet tool (AsyncAPI.Saunter.Generator.Cli)#217
smoerijf wants to merge 37 commits intoasyncapi:mainfrom
smoerijf:#196-Publish-a-global-dotnet-tool

Conversation

@smoerijf
Copy link
Contributor

@smoerijf smoerijf commented Jul 6, 2024

Description
tool to generate an asyncApi spec from a startup assembly.
Implementation inspired by https://www.nuget.org/packages/Swashbuckle.AspNetCore.Cli

I already took the freedom to upload to nuget: https://www.nuget.org/packages/AsyncAPI.Saunter.Generator.Cli

Uses the Lego AsyncApi.net nuget packages to also export yml spec files.

Related issue(s)
#196

# XML project files
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
indent_size = 4
indent_size = 2
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

current files were using a size of 2 and lf line endings, so I changed it (because my VS defaults are different)

@smoerijf smoerijf marked this pull request as ready for review July 6, 2024 18:17
Copy link
Collaborator

@yurvon-screamo yurvon-screamo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a great decision, and you're well on your way, but the product is not yet ready for release to users.

@smoerijf
Copy link
Contributor Author

smoerijf commented Jul 8, 2024

I'm happy to comply with the new formatting style rules or with changes from PRs like #201

@yurvon-screamo is it possible to assign issues to me? #196 #197 #207 (Or can you assign rights if I may do that myself?)

@yurvon-screamo
Copy link
Collaborator

I'm happy to comply with the new formatting style rules or with changes from PRs like #201

@yurvon-screamo is it possible to assign issues to me? #196 #197 #207 (Or can you assign rights if I may do that myself?)

don't rush too much, I'm finishing the translation to the LEGO library, better wait for it so as not to solve a million conflicts...

@smoerijf
Copy link
Contributor Author

smoerijf commented Jul 8, 2024

I didn't know you were working on the LEGO migration, just saw your draft PR. Very nice to see!

If any more conflicts arise, I'll resolve them too.

@smoerijf smoerijf requested a review from yurvon-screamo July 11, 2024 21:25
@smoerijf
Copy link
Contributor Author

I think all remarks have been addressed. All the working parts are unit tested. I've also made changes to the ci workflows to run all tests (not just the 2 projects that already existed.) and to also release based on the solution, not just the main Saunter csproj (release pipeline changes are not tested)

@smoerijf smoerijf changed the title #196 Publish a global dotnet tool #196 Publish a global dotnet tool (AsyncAPI.Saunter.Generator.Cli) Jul 13, 2024
…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
<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>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added 2nd example project (also to be used in integration test) because Top Level Statement projects initially didn't work with the Generator.Cli tool. Now it does work too. And proves using integration test that both NET6 & NET8 targets work.

@7CLewis
Copy link

7CLewis commented Aug 7, 2024

@yurvon-screamo Any idea when this might get merged and added? Would love to be able to use this tool.

@7CLewis
Copy link

7CLewis commented Aug 10, 2024

@smoerijf Your prerelease version on NuGet does not work with function apps. They do not have a standard Startup.cs file, and it seems to be having issues with that.
image

@smoerijf
Copy link
Contributor Author

@smoerijf Your prerelease version on NuGet does not work with function apps. They do not have a standard Startup.cs file, and it seems to be having issues with that. image

Thank you for trying the prerelease. I've never worked with function apps, is that the same as Azure functions? Don't those apps have a Main or ServiceProvider?

How this tools works: Inspect the DLL to find the main entrypoint and build the IServiceProvider. That IServiceProvider is used to create instances of Saunter's IAsyncApiDocumentProvider class. This is the same approach as Entity Framework Migrations (I'm using an EF nuget package to extract the IServiceProvider from the DLL). So this tool should support the same type of apps as EF does.

As I've no experience at all with function apps, I've no idea how they are structured or how Saunter library integrates with them. If they work with EF migrations, could you share a (minimal) example with Saunter?

@7CLewis
Copy link

7CLewis commented Aug 12, 2024

@smoerijf Your prerelease version on NuGet does not work with function apps. They do not have a standard Startup.cs file, and it seems to be having issues with that.

Thank you for trying the prerelease. I've never worked with function apps, is that the same as Azure functions? Don't those apps have a Main or ServiceProvider?

How this tools works: Inspect the DLL to find the main entrypoint and build the IServiceProvider. That IServiceProvider is used to create instances of Saunter's IAsyncApiDocumentProvider class. This is the same approach as Entity Framework Migrations (I'm using an EF nuget package to extract the IServiceProvider from the DLL). So this tool should support the same type of apps as EF does.

As I've no experience at all with function apps, I've no idea how they are structured or how Saunter library integrates with them. If they work with EF migrations, could you share a (minimal) example with Saunter?

Here's a minimal example: https://github.com/7CLewis/SaunterFunctionApp. If you Build that and then try to run dotnet asyncapi tofile [path_to_repo]\bin\Debug\net6.0\SaunterFunctionApp.dll --format "json", it'll give that error I mentioned.

Azure Function apps do not have a normal Startup like regular apps, as you can see from that example. I haven't tried EF Migrations with AzFuncs, so I can't speak to that.

@drdamour
Copy link

@smoerijf when u do ef core in AzF where startup doesn't exists you have to offer up a Design Time Factory as doc'd here https://learn.microsoft.com/en-us/ef/core/cli/dbcontext-creation?tabs=dotnet-core-cli#from-a-design-time-factory

could something similar be done in saunter where before looking for startup stuff...it would look for a specific public type implementing an interface.

@mrfelton
Copy link

Any chance of publishing a newer/alternatve (prerelease) version of this that targets net9.0?


var schema = documentProvider.GetDocument(asyncApiOptions, prototype);
var asyncApiSchemaJson = documentSerializer.Serialize(schema);
var asyncApiDocument = new AsyncApiStringReader().Read(asyncApiSchemaJson, out var diagnostic);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that this technically read 2.6 and not 2.4 which has 'some' discrepancies.
Not that there is much to do about it.
Hopefully ill be able to get some time in to work on moving saunter forward to V3 (which is now supported by AsyncAPI.Net)

}
else
{
logger.LogCritical($"AsyncAPI documents found. Known named document(s): {string.Join(", ", asyncApiOptions.NamedApis.Keys)}.");
Copy link

@mrfelton mrfelton Apr 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're not using AssemblyMarkerTypes to define our APIs, but rather we are using Saunter to build up the document dynamically based on inspecting our own EventBus implementation, via a custom document generator. This isn't working for that use case.

@mrfelton
Copy link

mrfelton commented Apr 24, 2025

This seems to be stripping out the messageId property from the message definitions, which is a required property in the 2.x version of asyncapi and so the output produced from the cli is an invalid document. The messageId is included when my app renders the document. The messageId is required for various sets of tooling to work with v2.x schemas

@VisualBean
Copy link
Contributor

VisualBean commented Apr 24, 2025

This seems to be stripping out the messageId property from the message definitions, which is a required property in the 2.x version of asyncapi and so the output produced from the cli is an invalid document. The messageId is included when my app renders the document. The messageId is required for various sets of tooling to work with v2.x schemas

MessageId has never been required as far as I know. In terms of the specification itself.

Docs specifically state "Tools and libraries MAY use messageId to..."

But this is somewhat besides the point. It shouldn't be stripping anything. My point is that its technically not invalid documents without messageId

@mrfelton
Copy link

mrfelton commented Apr 24, 2025

It looks like it's not being included in the serialised output, upstream, here: https://github.com/LEGO/AsyncAPI.NET/blob/main/src/LEGO.AsyncAPI/Models/AsyncApiMessage.cs#L118

MessageId has never been required as far as I know. In terms of the specification itself.

I see. So I think there is also an issue in the tool I'm using - The EventCatalog asyncapi generator. Specifically, here https://github.com/event-catalog/generators/blob/85f04c0086e6eac77c3023de8cc5dc3051df5d0b/packages/generator-asyncapi/src/index.ts#L296, where it's expected that messageid is set.

@VisualBean
Copy link
Contributor

VisualBean commented Apr 24, 2025

It looks like it's not being included in the serialised output, upstream, here: https://github.com/LEGO/AsyncAPI.NET/blob/main/src/LEGO.AsyncAPI/Models/AsyncApiMessage.cs#L118

MessageId has never been required as far as I know. In terms of the specification itself.

I see. So think there is also an issue in the tool I'm using - The EventCatalog asyncapi generator. Specifically, here https://github.com/event-catalog/generators/blob/85f04c0086e6eac77c3023de8cc5dc3051df5d0b/packages/generator-asyncapi/src/index.ts#L296, where it's expected that messageid is set.

Definitely a bug in asyncapi.net.
I'll go and fix this within an hour or so.

Has been fixed now here as of 1.0.1. (The 2.0.0 preview has AsyncAPI V3 support. )
https://www.nuget.org/packages/ByteBard.AsyncAPI.NET/

@@ -0,0 +1,72 @@
using LEGO.AsyncAPI.Models;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new repo for this is under bytebard rather than LEGO.
Same codebase (direct fork) but actively maintained again (as I'm not at LEGO anymore, and they have dropped maintaining my baby)

Preview has v3 support, while main has a few bug fixes not in the LEGO repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

Comments