event-catalog / generator-asyncapi

AsyncAPI generator for EventCatalog
https://www.eventcatalog.dev/docs/development/integrations/async-api/intro
Other
9 stars 4 forks source link

Updating the version of an Async API breaks the generator #68

Open demius opened 1 month ago

demius commented 1 month ago

I tried this:

In my own project I am experiencing issues with versioning. The problem occurs when messages are shared between services (sender -> receiver). I cloned the eventcatalog-asyncapi-example repository and attempted the same process there, with the same result.

Steps

  1. Clone the eventcatalog-asyncapi-example
  2. Run the generate command
  3. Update the version of the inventory-service to 1.0.1
  4. Run the generate command again
  5. Observe

This happened:

When the generator encounters the first shared message - in this case, shared between the inventory-service and the order-service - the generator fails:

Processing domain: Orders (v0.0.1)
 - Domain (v0.0.1) already exists, skipped creation...
Processing message: OrderCreated (v1.0.0)
 - Message (v1.0.0) created
 - Schema added to message (v1.0.0)
Processing message: OrderUpdated (v1.0.0)
 - Message (v1.0.0) created
 - Schema added to message (v1.0.0)
Processing message: OrderCancelled (v1.0.0)
 - Message (v1.0.0) created
 - Schema added to message (v1.0.0)
Processing message: OrderCompleted (v1.0.0)
 - Message (v1.0.0) created
 - Schema added to message (v1.0.0)
Processing message: PaymentProcessed (v1.0.0)
 - Message (v1.0.0) created
 - Schema added to message (v1.0.0)
Processing message: InventoryReserved (v1.0.0)
 - Versioned previous message: (v1.0.1)
Error loading plugin: Error: Failed to write event as the version 1.0.0 already exists
    at writeResource (/eventcatalog-asyncapi-example/node_modules/@eventcatalog/sdk/dist/index.js:160:11)
    at async src_default (/eventcatalog-asyncapi-example/node_modules/@eventcatalog/generator-asyncapi/dist/index.js:248:9)
    at async generate (file:///eventcatalog-asyncapi-example/.eventcatalog-core/scripts/generate.js:50:9)

I expected this:

No response

Is there a workaround?

No response

Anything else?

No response

EventCatalog Version

latest

Node.js Version

20.15.0

Platform(s)

MacOS

Community Notes

hpatoio commented 1 month ago

I dug into the issue and the problem is here

The actual code assumes that the version of an Event/Command it always increasing but when Events/Commands are shared between services this is not true.

Here a case:

We have 2 services OrderService at version 1.0.1 and InventoryService at version 1.0.0. They share the event InventoryReserved.

  1. Generator process order_service.yml and creates InventoryReserved with version 1.0.1
  2. Generator process inventory_service.yml. Search fo the latest version of OrderUpdate and it receives version 1.0.1.
  3. Since is not the same as the one he is trying to create (1.0.0) generates a version using the info in the file it reads from the disc (1.0.1) and try to save it

But on save it receive an error because the file already exists.

IMHO the problem is that we use the value of info.version as version for the models. We should find a way to define the version of a model from is definition or we can use a property.

demius commented 1 month ago

Since the AsyncAPI specification only supports service versioning, this issue will require an extension attribute to be introduced to either:

  1. Allow messages to be versioned independently; or
  2. Establish a service as an "owner" of a particular message (typically the producer). This becomes difficult when multiple services may produce the same event, so I think option (1) might be better.
XaaXaaX commented 1 month ago

@demius i m a bit confused and not sure i get the case exactly but i well understand the problem, I give my POV on both understandings

1 - If both services produce the same event you need to distinguish them, You can use both message ID and title, so you put a unique identifier for each message ( like invertory.InventoryReserved and orders. InventoryReserved ) this will resolve your error, but if you set the time as InventoryReserved at the same time you will have the InventoryReserved in documentation UI. ( note: this means you have two really distict events )

2 - If One service produces InventoryReserved and the other consumes, the problem is that Eventcatalog try to generate a message when it s consumed but this makes no sens in practice , the owner provide and the consumer consumes the event in under ownership of the producer , but this is diff for commands , the receiver is the owner of message and not consumers, we have already a discussion about this and you can find a RFC in this PR https://github.com/event-catalog/generator-asyncapi/pull/59

boyney123 commented 1 month ago

Hey folks!

Yeah everything makes total sense here, EC will just try and read the files and has no context really of any ownership levels etc. I think the PR and suggestion @XaaXaaX makes sense https://github.com/event-catalog/generator-asyncapi/pull/59

If we introduce this ownership extension would this work for you @demius ?

XaaXaaX commented 1 month ago

@boyney123 @demius @hpatoio Any comments or reviews that i can consider and apply on this PR?

demius commented 1 month ago

Hey folks!

Yeah everything makes total sense here, EC will just try and read the files and has no context really of any ownership levels etc. I think the PR and suggestion @XaaXaaX makes sense #59

If we introduce this ownership extension would this work for you @demius ?

I think adding an extension is the a sensible way to deal with the scenario, thanks for your inputs both.