Skip to content

GH 3936 : Request attribute for webclient in webflux integration has been added #3950

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

Closed
wants to merge 6 commits into from

Conversation

saxenaj
Copy link
Contributor

@saxenaj saxenaj commented Nov 17, 2022

No description provided.

Copy link
Member

@artembilan artembilan 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 good so far.
Not too much, but having a proper test would be great.

Also, please, consider to add [[x6.0-webflux]] entry into whats-new.adoc in the end.
And mention this new feature in the webflux.adoc.

Thank you!


if (hasAttibuteVariablesExpression) {
builder.addPropertyValue("attributeVariablesExpression",
BeanDefinitionBuilder.rootBeanDefinition(ExpressionFactoryBean.class)
Copy link
Member

Choose a reason for hiding this comment

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

See IntegrationNamespaceUtils.createExpressionDefIfAttributeDefined() instead for convenience.

Copy link
Contributor Author

@saxenaj saxenaj Nov 18, 2022

Choose a reason for hiding this comment

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

Code has been updated to use IntegrationNamespaceUtils.createExpressionDefIfAttributeDefined()

Copy link
Member

Choose a reason for hiding this comment

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

@saxenaj ,

you know, there is no reason to add this kind of comments if you agree with us: we just simply will see that in the next commit you add to the PR.
Otherwise I got at a bout 10 emails from you instead of just one about a new commit. 😄

@Override
protected final void doInit() {
BeanFactory beanFactory = getBeanFactory();
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(beanFactory);
Copy link
Member

Choose a reason for hiding this comment

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

You can just have a single line here: doesn't look like there is a reason in extracting beanFactory variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

beanFactory variable has been removed and code has been updated to single line

import static org.assertj.core.api.Assertions.assertThat;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
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 wrong imports re-order according our new code style.
Please, rebase to the latest main and see src/idea or src/eclipse for editor configs to import into your IDE.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Import sequence has been updated to follow code style

@@ -214,6 +218,10 @@ void testFluxReply() {
reactiveHandler.setExpectedResponseType(String.class);
reactiveHandler.setReplyPayloadToFlux(true);

reactiveHandler.setAttributeVariablesExpression(new SpelExpressionParser().parseExpression("{name:{first:'Nikola',last:'Tesla'},dob:{day:10,month:'July',year:1856}}"));
Copy link
Member

Choose a reason for hiding this comment

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

We prefer no more than 120 symbols in one code line.

Copy link
Member

Choose a reason for hiding this comment

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

Also, doesn't look like you do some verification for those attributes to propagate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

New test case has been added to check the propagation of attributes. Also code has been changes to keep less than 120 char in one line.

@@ -376,4 +384,8 @@ void testMaxInMemorySizeExceeded() {
.isEqualTo("Exceeded limit on max bytes to buffer : 1");
}

private void setBeanFactory(WebFluxRequestExecutingMessageHandler handler) {
Copy link
Member

Choose a reason for hiding this comment

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

Not sure why we need this method, if you simply can do that directly in a line of code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Code has been updated accordingly.

@saxenaj
Copy link
Contributor Author

saxenaj commented Nov 17, 2022

Thanks for quick turnaround. I will take a look on review comments.

@saxenaj saxenaj marked this pull request as draft November 18, 2022 03:58
@saxenaj saxenaj marked this pull request as ready for review November 18, 2022 05:55
@saxenaj
Copy link
Contributor Author

saxenaj commented Nov 18, 2022

This is good so far. Not too much, but having a proper test would be great.

Also, please, consider to add [[x6.0-webflux]] entry into whats-new.adoc in the end. And mention this new feature in the webflux.adoc.

Thank you!

New test case has been added to check for request attribute. Also the whats-new.adoc and webflux.adoc has been updated.

@saxenaj saxenaj requested a review from artembilan November 18, 2022 06:04
Copy link
Member

@artembilan artembilan left a comment

Choose a reason for hiding this comment

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

There is a Checkstyle error in the CI build for this PR.
I'm not sure why you didn't receive a respective email to fix already.
Consider to run ./gradlew clean :spring-integration-webflux:check locally to be sure that you don't have Checkstyle violations and don't introduce new compilation warnings or tests are passing.


if(attributeVariablesExpression != null) {
Map<String, Object> attributeMap = evaluateAttributeVariables(requestMessage);
requestSpec = requestSpec.attributes(map -> map.putAll(attributeMap));
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 do some optimization not calling this method if attributeMap.isEmpty()!

reactiveHandler.setOutputChannel(replyChannel);
reactiveHandler.setExpectedResponseType(String.class);
reactiveHandler.setReplyPayloadToFlux(true);
Expression expr = new SpelExpressionParser().parseExpression("{name:{first:'Nikola'}}");
Copy link
Member

Choose a reason for hiding this comment

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

Just for your knowledge: there is a FunctionExpression impl to be able to call as a lamda.
So, this one would be as simple as: Expression expr = new FunctionExpression<Object>(o -> Map.of("first", "Nikola")).
and much faster than SpEL parsing and its evaluation via reflection 😄

[[webflux-request-attribute]]
=== WebFlux Request Attribute

Starting with Version 6, Webflux outbound request can have request attribute which can be specified in `attribute-variables-expression` attribute. This attribute will take an `expression` that should be evaluated in `Map`.
Copy link
Member

Choose a reason for hiding this comment

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

"Version" word not capitalized.
Version number is 6.0.
One sentence per line rule, please: https://asciidoctor.org/docs/asciidoc-recommended-practices/#one-sentence-per-line.

I wouldn't imply an XML config. Better to say WebFluxRequestExecutingMessageHandler and setAttributeVariablesExpression().
The XML configuration is really left in a maintenance mode and better to move away from it, more over with modern trends about native images.

Would be great to have some sample configuration and the reasoning behind this feature.

Copy link
Contributor Author

Choose a reason for hiding this comment

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


[[x6.0-webflux]]

=== Webflux request attribute support
Copy link
Member

Choose a reason for hiding this comment

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

Blank line here between name and section body.

[[x6.0-webflux]]

=== Webflux request attribute support
Webclient Request attribute support has been added for outbound request.See <<./webflux.adoc#webflux-request-attribute,WebFlux Request Attribute>> for more information.
Copy link
Member

Choose a reason for hiding this comment

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

One sentence per line, please.

@saxenaj
Copy link
Contributor Author

saxenaj commented Nov 18, 2022

tests

@saxenaj saxenaj closed this Nov 18, 2022
@saxenaj saxenaj reopened this Nov 18, 2022
* Configure expression to evaluate request attribute which will be added to webclient request attribute.
* @param attributeVariablesExpression the expression to evaluate request attribute.
* @since 6.0
* @see WebFluxRequestExecutingMessageHandler#evaluateAttributeVariables(Message)
Copy link
Member

Choose a reason for hiding this comment

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

You are pointing here to private method which is out of end-user interest.
I'd say @see WebClient.RequestBodySpec#attributes

@@ -323,4 +323,5 @@ See <<./http.adoc#http-header-mapping,HTTP Header Mappings>> for more possible o
[[webflux-request-attribute]]
=== WebFlux Request Attribute
Copy link
Member

Choose a reason for hiding this comment

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

Attributes

=== Webflux request attribute support
Webclient Request attribute support has been added for outbound request.See <<./webflux.adoc#webflux-request-attribute,WebFlux Request Attribute>> for more information.

Webclient Request attribute support has been added for outbound request.
Copy link
Member

Choose a reason for hiding this comment

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

attributes and probably better to mention a WebFluxRequestExecutingMessageHandler.
That "outbound request" is too vague from Spring Integration context.

Webclient Request attribute support has been added for outbound request.See <<./webflux.adoc#webflux-request-attribute,WebFlux Request Attribute>> for more information.

Webclient Request attribute support has been added for outbound request.
See <<./webflux.adoc#webflux-request-attribute,WebFlux Request Attribute>> for more information.
Copy link
Member

Choose a reason for hiding this comment

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

Attributes


if (this.attributeVariablesExpression != null) {
Map<String, Object> attributeMap = evaluateAttributeVariables(requestMessage);
if (attributeMap != null && !attributeMap.isEmpty()) {
Copy link
Member

Choose a reason for hiding this comment

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

!CollectionUtils.isEmpty(attributeMap)

=== WebFlux Request Attributes

Starting with version 6.0, Webflux outbound request `WebFluxRequestExecutingMessageHandler` can have request attributes which can be specified in `setAttributeVariablesExpression()`.
This will take an `expression` that should be evaluated in `Map`.
Copy link
Member

Choose a reason for hiding this comment

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

I still would like to see a general sentence for reasoning behind these attributes.
Doesn't look like this is a common feature since we haven't bumped to its missing support for since version 5.0.
Probably the security would be a great sample to carry on some info from message to the request where downstream filter would expect an attribute to be able to authorize a principal or so.

My point is that you need to convince me somehow in using this new feature from the doc.
No one is going to look into those tests in the project.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

how about this?

Starting with version 6.0, Webflux outbound request WebFluxRequestExecutingMessageHandler can have request attributes which can be specified in setAttributeVariablesExpression().
This will take an expression that should be evaluated in Map.
This will be helpful if an information in form of key-value object needs be passed from Message to request and downstream filter will get access to this attribute for further processing.

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good!
👍

@saxenaj saxenaj requested a review from artembilan November 18, 2022 20:15
Copy link
Member

@artembilan artembilan left a comment

Choose a reason for hiding this comment

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

Pulling locally for the final review, clean up and merge.

@artembilan
Copy link
Member

Merged as ddddd1d after some refactoring.

@saxenaj ,

thank you very much for the contribution; looking forward for more!

@artembilan
Copy link
Member

Was missed to be closed after merge into main.

@artembilan artembilan closed this Nov 28, 2022
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.

2 participants