Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Springwolf UI - Error parsing AsyncAPI message of channel io.eventuate.tram.spring.springwolf.events.Customer: Cannot read properties of undefined (reading '$ref') #1216

Open
cer opened this issue Mar 7, 2025 · 8 comments

Comments

@cer
Copy link

cer commented Mar 7, 2025

My service generates this Async API doc: https://gist.github.com/cer/ca1f729dbbc40ee417616d9e3dcefd59

https://studio.asyncapi.com/ says that it is valid.

But Springwolf UI displays the error

Error parsing AsyncAPI message of channel io.eventuate.tram.spring.springwolf.events.Customer: Cannot read properties of undefined (reading '$ref')

No operations are displayed.

I did notice, btw, that Springwolf UI requires channels to have an address property - otherwise the error message shows undefined as the channel name.

Suggestions?

Copy link

github-actions bot commented Mar 7, 2025

Welcome to Springwolf. Thanks a lot for reporting your first issue. Please check out our contributors guide and feel free to join us on discord.

@cer
Copy link
Author

cer commented Mar 7, 2025

It seems that the UI requires messages to have a "headers" property.
I've added that (see updated gist).
I'm now seeing these errors in the console:

Image

@cer
Copy link
Author

cer commented Mar 7, 2025

It seems that the UI requires messages to have a name and/or title property.

@timonback
Copy link
Member

Hi @cer,
Thank you for the report and versioned gists.

In the latest revision (2), springwolf-ui renders the messages and operations, only the binding is missing. You probably want to add one of binding annotations, see: https://www.springwolf.dev/docs/configuration/documenting-bindings/

Indeed, name, title and headers are mandatory fields in springwolf-ui at this point 1.
Did you generate the AsyncAPI using Springwolf (i.e. springwolf-kafka) or use springwolf-ui only 2?

@cer
Copy link
Author

cer commented Mar 7, 2025

@timonback Yes revision (2) worked. I will work on adding bindings.

The AsyncAPI doc is generated by an Eventuate-specific SpringWolf plugin - https://github.com/eventuate-platform/eventuate-tram-spring-wolf-support/

Thanks for the link to https://github.com/springwolf/springwolf-core/blob/master/springwolf-ui/src/app/models/message.model.ts - the challenge is that the UI is generating difficult to debug errors on AsyncAPI docs that are valid according to asyncapi validate

@cer
Copy link
Author

cer commented Mar 7, 2025

Here's a different doc - https://gist.github.com/cer/cba0099872915d8ec16fd89d0c7209d0
It uses request/reply.

SpringWolf UI seems require the reply channel to have an address property: https://gist.github.com/cer/cba0099872915d8ec16fd89d0c7209d0#file-request-reply-json-L29

AFAIK this contradicts the specification for operation reply objects

When address is specified, the address property of the channel referenced by this property MUST be either null or not defined.

Thoughts?

@timonback
Copy link
Member

timonback commented Mar 7, 2025

Hi @cer,
Great to see you building your custom plugins!

We started looking into how to validate the provided AsyncAPI files in springwolf-ui (#1219), so that better error messages are being displayed in the browser console as INFO. Currently we use a strict mode so that also additional properties that are no issue appear in the console.
We are about to merge a preview version as -SNAPSHOT so that you can continue testing. We will come back to improve it.


Regarding your second question of address in channels for request/reply semantics:
Stomp (WebSocket) uses the reply object:

"reply": {
"channel": {
"$ref": "#/channels/_app_topic_sendto-response-queue"
},
"messages": [
{
"$ref": "#/channels/_app_topic_sendto-response-queue/messages/io.github.springwolf.examples.stomp.dtos.ExamplePayloadDto"
}
]
}

We address your concern by writing the address always to the channel object and do not specify it as part of the reply object. Will that work for you too?

@cer
Copy link
Author

cer commented Mar 9, 2025

Regarding your second question of address in channels for request/reply semantics:
...
We address your concern by writing the address always to the channel object and do not specify it as part of the reply object. Will that work for you too?

I'm a bit confused about what you are asking.
In my scenario, the actual reply channel is specified by a header in the request message.

The spec says that this is specified using the reply.address.location property:

    "operations": {
        "io.eventuate.tram.spring.springwolf.commands.requestasyncresponse.CustomerCommandHandler.reserveCredit": {
            "action": "receive",
            ....
            "reply": {
                "address": {
                    "location": "$message.header#/command_reply_to"
                },
                "channel": {
                    "$ref": "#/channels/io.eventuate.tram.spring.springwolf.commands.requestasyncresponse.CustomerCommandHandler.reserveCredit-reply"
                },

Moreover, the specification for operation reply objects says:

When address is specified, the address property of the channel referenced by this property MUST be either null or not defined.

In other words, the reply channel's address property that the UI requires is not compliant:

    "channels": {
       ...
        "io.eventuate.tram.spring.springwolf.commands.requestasyncresponse.CustomerCommandHandler.reserveCredit-reply": {
            "address": "io.eventuate.tram.spring.springwolf.commands.requestasyncresponse.CustomerCommandHandler.reserveCredit-replyfoo",
            "messages": {

Please clarify.

PS. I'm a bit confused by the fact that asyncapi validate doesn't catch these errors.

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

No branches or pull requests

2 participants