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

Add ability to describe exchange and routing key for AMQP consumer and producer #69

Merged
merged 1 commit into from
May 31, 2022
Merged

Add ability to describe exchange and routing key for AMQP consumer and producer #69

merged 1 commit into from
May 31, 2022

Conversation

DmitriButorchin
Copy link
Contributor

related to #67

* @param payloadType type of the payload
* @return amqp producer data
*/
public static ProducerData createAMQPProducerData(String channelName,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Probably shouldn't be placed as a method on ProducerData since this is amqp-specific.

@DmitriButorchin DmitriButorchin marked this pull request as ready for review May 29, 2022 15:54
@stavshamir
Copy link
Member

I only had time to skim through, but this looks great. I will go over the finer details tomorrow and will probably have some comments, but again this looks great 🙂

@stavshamir stavshamir linked an issue May 29, 2022 that may be closed by this pull request
Copy link
Member

@stavshamir stavshamir left a comment

Choose a reason for hiding this comment

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

Thanks again @DmitriButorchin for providing this so quickly!
I really like the additions and it's great to have someone with the domain specific knowledge contributing to this project.
I have some few comments I would like you to address, and then I will merge the PR.

/**
* The class object of the payload published by this producer.
*/
private Class<?> payloadType;

/**
* The binding of the producer.
* The operation binding of the producer.
Copy link
Member

Choose a reason for hiding this comment

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

We should change the name of this field to operationBinding now that we have channelBinding. It's a breaking change but that's ok.

@@ -0,0 +1,27 @@
package io.github.stavshamir.springwolf.asyncapi.serializers;
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure we need this at this point - currently the binding tab in the UI displays only the operation binding, so this will appear only in the document itself. It's ok to have it serialized as it is without this custom serializer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added it because the endpoint wouldn't work, it resulted in a 500 internal error failing to serialize the channelBinding field. Is there other way to fix this problem?

Copy link
Member

Choose a reason for hiding this comment

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

Hmm ok, so let's keep it, I can figure it out later.

@@ -26,6 +28,7 @@ void postConstruct() {

private void registerKafkaOperationBindingSerializer() {
SimpleModule module = new SimpleModule();
module.addSerializer(KafkaChannelBinding.class, new KafkaChannelBindingSerializer());
Copy link
Member

Choose a reason for hiding this comment

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

See comment in KafkaChannelBindingSerializer.

@Override
protected Map<String, ? extends ChannelBinding> buildChannelBinding(RabbitListener annotation) {
AMQPChannelBinding.ExchangeProperties exchangeProperties = new AMQPChannelBinding.ExchangeProperties();
String exchangeName = Stream.of(annotation.bindings())
Copy link
Member

Choose a reason for hiding this comment

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

I think lines 79 to 89 should be extracted to another method getExchangeName

@Override
protected Map<String, ? extends OperationBinding> buildOperationBinding(RabbitListener annotation) {
return ImmutableMap.of("amqp", new AMQPOperationBinding());
/*
The routing key is taken from the binding. As the key field in the @QueueBinding can be an empty array,
Copy link
Member

Choose a reason for hiding this comment

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

Good comment, it's important to have this explanation here

Also in the case when there is no binding for the queue present at all, it means it uses the fact that
RabbitMQ automatically binds default exchange to a queue with queue's name as a routing key.
*/
List<String> routingKeys = Stream.of(annotation.bindings())
Copy link
Member

Choose a reason for hiding this comment

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

Like getExchangeName, I think lines 106 to 125 should be extracted to getRoutingKeys

this.rabbitTemplate = rabbitTemplate;
public SpringwolfAmqpProducer(ChannelsService channelsService, List<RabbitTemplate> rabbitTemplates) {
this.channelsService = channelsService;
this.rabbitTemplate = rabbitTemplates.get(0);
Copy link
Member

Choose a reason for hiding this comment

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

Could you please remind me again why it doesn't matter which template is used here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The difference between multiple rabbit template beans is preset default exchange and/or routing key. So you could use the overload .send method with just routingKey as param and payload, or just payload.
Because we're getting the exchange name and routing key from the context and we're using the method with all parameters (i.e. exchange, routing key and payload) we don't care which rabbit template to use.

Copy link
Member

Choose a reason for hiding this comment

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

Got it, thanks

}

public void send(String channelName, Map<String, Object> payload) {
rabbitTemplate.convertAndSend(channelName, payload);
ChannelItem channelItem = channelsService.getChannels().get(channelName);
String exchange = "";
Copy link
Member

Choose a reason for hiding this comment

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

Let's extract getExchange and getRoutingKey here as well

import java.util.Collections;

@UtilityClass
public class ProducerDataUtil {
Copy link
Member

Choose a reason for hiding this comment

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

I agree we should provide a convenient way to create the producer data, but I have a different idea that I prefer to implement (make ProducerData an interface, and have each plugin implement it with a builder that will map the input to the correct bindings). So please remove this file and I will add this after I merge your PR.

@DmitriButorchin
Copy link
Contributor Author

Thank you for the comments, I'll update the PR either later today or tomorrow.

…d producer.

Fix crash when having multiple instances of RabbitTemplate.

related to #67
@DmitriButorchin
Copy link
Contributor Author

I have applied the suggested comments :)

@stavshamir
Copy link
Member

Great job! I will add a convenient way to create amqp producer data and try to squeeze in support for class level RabbitListener and create a new release by Thursday.

@stavshamir stavshamir merged commit 07c7690 into springwolf:master May 31, 2022
@DmitriButorchin DmitriButorchin deleted the 67-amqp-exchange-routing-key branch June 3, 2022 21:59
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.

AMQP - Support multiple instances of RabbitTemplate
2 participants