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

Java Spring generator 2.0.0 #188

Closed

Conversation

nickspacek
Copy link

@nickspacek nickspacek commented Dec 2, 2019

I've updated the Java Spring template to work with AsyncApi 2.0.0. I tried to follow the existing formatting but let me know if I wandered or if you notice any inconsistencies.

This should address #134

Converts previous mapping of AsyncApi 1.0.0 topics to AsyncApi 2.0.0
channels in some basic form for the PublisherService.java template.

Bug: asyncapi#134
Discovered the operationId field and replaced the x-service-name from
1.0.0 schemas in the PublisherService template. Updated logic in the
MessageHandlerService template to bring in channels instead of topics.
Updates the command line tool from using topics to using channels. Also
unified the way that the publishing method names are generated to reduce
the chances of mistakes in other templates that reference the publish method.
Fixed generation of the MQTT config file; part of this change also
specifies that the template parameter "server" must be specified
(similar to the nodejs generator). If the AsyncApi spec file has
multiple servers, this allows the generation step to find the right one
to use.

Also centralizes handler method naming for consistency.
Converted the AmqpConfig.java template to 2.0.0 schema. Added some
convenience filters: publishTopics and subscribeTopics and will likely
update the other tepmlates to use them.
Updated the application.yml template to support the AsyncApi 2.0.0
schema.
README.md and settings.gradle needed to be updated for the 2.0.0 schema.
Added a post-generation hook that will remove the trailing ":{port}"
from the generated MQTT host configuration parameter in the
application.yml. Also changed the semantics of that host configuration
parameter by removing the prepended "tcp://" from the template and
adding a broker.scheme configuration parameter.
Copy link
Member

@fmvilas fmvilas left a comment

Choose a reason for hiding this comment

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

This is great stuff man. Thanks for taking the time to fix it! I've been trying your code and there are a few things I'd like to give feedback:

  1. Port variable is assumed in server object. It might not exist and it will fail to generate the code.
  2. It's automatically publishing messages. For instance, when generating streetlights.yaml, it calls publisherService.publishReceiveLightMeasurement("Hello World from receiveLightMeasurement"). It would be great to have the code there ready to be called but do not decide when to send the message, as this is really dependent on your business logic.
  3. It's getting the publish/subscribe verbs the other way around. This is tricky when you're working on a code generator (I know 😅) but when you see publish your code should actually subscribe and viceversa. Publish and subscribe do not represent what your code does but instead what consumers/clients can do with your code.
  4. Also, when the url is like mqtt://test.mosquitto.org it tries to connect to tcp://mqtt://test.mosquitto.org. You may want to use a filter like this one: https://github.com/asyncapi/generator/blob/master/templates/nodejs/.filters/all.js#L144.

Hope it helps!

port: {{server.variables.port.default}}
scheme: tcp
host: {{server.url()}}
port: {{server.variable('port').defaultValue()}}
Copy link
Member

Choose a reason for hiding this comment

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

This is failing for me. It's assuming there will be a port variable and it might not exist.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for the feedback, I'll have a go over and make sure that the pub/sub is logical! I thought I had followed what was there but perhaps the semantics changed some with channels vs. topics; I should have paid more attention to what the templates were actually outputting! I should be able to get those changes in shortly.

Copy link
Member

Choose a reason for hiding this comment

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

No worries, it happens to me all the time when working on the code generators.

Copy link
Author

Choose a reason for hiding this comment

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

Hmm, after reviewing things I'm less comfortable making changes 2 and 3. It seems that the intent of the original author was to have the java-spring generator create client code, so it's written from the perspective of "I downloaded someone else's AsyncApi document and I want to communicate with their API". So, the document indicating that there is a channel that can be published to results in generating code that can indeed publish to the channel, instead of creating code that can receive messages.

I think it's a great idea to have both, similar to OpenAPI: https://openapi-generator.tech/docs/generators.html. In my case, I actually am trying to generate the server side, so I will probably go ahead and create a new template that has the reverse logic as you had suggested. That will be a template that takes the specification and serves the specification, as well as the endpoints it is describing for consumers of the API.

Now, another issue I'm seeing is mostly to do with item 4, but also 1. The AsyncApi specification seems to be unclear in regards to the server.url. The examples given on XXX do not illustrate proper URLs; in fact, I don't see how you could tell whether some of them are supposed to be "relative URLs" or host names. I'm in favor of supporting proper URLs as you have illustrated over schema-less ones; it is unfortunate that the official examples do not follow this (I found asyncapi/spec#274 that raises this concern).

I think what I am going to is treat the example schema I've been using as an example of a relative URL. In my opinion, the generator framework itself should be taking care of passing a proper JS URL entity to the templates. In the case of relative URLs it would require the user to specify a base URL as a command line option. I would be wiling to explore this concept in a branch.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry for the delay. I agree with you. My recommendation is that you forget about the intent of the original author because this template was always a proof of concept and was never completed. I'd go directly for the "server" implementation first as that's what the other templates are doing. We'll work on the perspective of "this is someone else's AsyncAPI document" later. In regard to the URLs, feel free to treat them as absolute URLs for now meanwhile we fix the other issue, which will probably require a new version of the spec.

@jonaslagoni
Copy link
Member

jonaslagoni commented Dec 10, 2019

Hey @nickspacek, can you fix the following spelling mistakes suggested by @RobertDiebels in
#191 (comment)? Or should it be in another PR?

@jonaslagoni jonaslagoni mentioned this pull request Dec 10, 2019
@nickspacek
Copy link
Author

I can, although I was hoping to have some feedback from @fmvilas on my wall of text above.

I also neglected to re-incorporate the x-service-name as a naming option and opted to just rely on the operation ID, so I'll have to fix that to allow x-service-name as the primary source of the method name when it is present.

@fmvilas
Copy link
Member

fmvilas commented Dec 15, 2019

I also neglected to re-incorporate the x-service-name as a naming option and opted to just rely on the operation ID, so I'll have to fix that to allow x-service-name as the primary source of the method name when it is present.

In Java, don't you think it makes more sense if you use x-service-name as a class name and operationId as the method name? IIRC that's how Swagger Codegen was using it.

@github-actions
Copy link
Contributor

This pull request has been automatically marked as stale because it has not had recent activity 😴
It will be closed in 30 days if no further activity occurs. To unstale this pull request, add a comment with detailed explanation.
Thank you for your contributions ❤️

@github-actions github-actions bot added the stale label Mar 12, 2020
@fmvilas fmvilas added keep-open and removed stale labels Mar 14, 2020
@Tenischev Tenischev mentioned this pull request Apr 26, 2020
@fmvilas
Copy link
Member

fmvilas commented Apr 27, 2020

I'm closing since it's no longer needed. The current Java Spring generator already supports AsyncAPI 2.0.0 and a bunch of more features (kudos to @Tenischev). Thanks anyway, @nickspacek. Feel free to reopen if you think it makes sense.

@fmvilas fmvilas closed this Apr 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants