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

#1287 Docs: Example of custom aggregator #1330

Conversation

jlukawska
Copy link
Contributor

@jlukawska jlukawska commented Sep 2, 2020

Fixes #1287

Now it's not obvious how to access the response details in a custom aggregator.

Proposed Changes

@raman-m raman-m changed the title Docs/example of defined aggregator #1287 Docs/example of custom aggregator Jul 17, 2023
@raman-m raman-m changed the base branch from master to develop July 17, 2023 19:00
@raman-m raman-m force-pushed the docs/defined-aggregator-update branch from 6765365 to 9b62d30 Compare July 17, 2023 19:01
@raman-m raman-m self-requested a review July 17, 2023 19:04
@raman-m raman-m changed the title #1287 Docs/example of custom aggregator #1287 Docs: Example of custom aggregator Jul 17, 2023
@raman-m raman-m added bug Identified as a potential bug needs feedback Issue is waiting on feedback before acceptance documentation Needs a documentation update labels Aug 4, 2023
Copy link
Member

@raman-m raman-m left a comment

Choose a reason for hiding this comment

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

We cannot go with this sample to add to docs.
This sample is abstract and we need to develop it more.

@@ -108,6 +108,31 @@ In order to make an Aggregator you must implement this interface.

With this feature you can pretty much do whatever you want because the HttpContext objects contain the results of all the aggregate requests. Please note if the HttpClient throws an exception when making a request to a Route in the aggregate then you will not get a HttpContext for it but you would for any that succeed. If it does throw an exception this will be logged.
Copy link
Member

Choose a reason for hiding this comment

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

It is not clear, in case of downstream service failure, will we be able to process a HttpContext object in the Aggregate method?
Not an issue, just the question.

{
var responses = responseHttpContexts.Select(x => x.Items.DownstreamResponse());

var statusCodes = responses.Select(x => x.StatusCode);
Copy link
Member

Choose a reason for hiding this comment

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

Do we see non-20x status codes here, including 404, 50x, etc.?
So, Can we process failed responses in the method?


return new DownstreamResponse(
new StringContent(JsonConvert.SerializeObject(contentList)),
HttpStatusCode.OK,
Copy link
Member

Choose a reason for hiding this comment

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

🆗 It seems we return HttpStatusCode.OK status even all downstream services have failed...
Is that correct?

var responses = responseHttpContexts.Select(x => x.Items.DownstreamResponse());

var statusCodes = responses.Select(x => x.StatusCode);
var headers = responses.SelectMany(x => x.Headers).ToList();
Copy link
Member

Choose a reason for hiding this comment

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

Every downstream service response has own headers. In most of all services the headers can have the same names.
This simple SelectMany selector initializes one unsorted list of Header objects with a potential duplicated header names.
How to recognize that a header belongs to a particular service?

new StringContent(JsonConvert.SerializeObject(contentList)),
HttpStatusCode.OK,
headers,
"reason");
Copy link
Member

Choose a reason for hiding this comment

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

There is no merging of reasons from DownstreamResponse objects (aka ReasonPhrase string property).
We need to merge them somehow.
Simple returning of "reason" string is wrong!

Comment on lines +122 to +126
foreach (var response in responses)
{
var content = await response.Content.ReadAsStringAsync();
contentList.Add(content);
}
Copy link
Member

Choose a reason for hiding this comment

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

We process the responses content sequentially. And the reading operation is asynchronous.
Why not to make the processing parallel?
Tasks.WhenAll(tasks) should help.

}

return new DownstreamResponse(
new StringContent(JsonConvert.SerializeObject(contentList)),
Copy link
Member

Choose a reason for hiding this comment

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

For example Laura-key route has failed.
Do we return empty JSON-object {} or it will be absent at all?

{
  "Tom": {"Age": 19},
  "Laura": {}
}

@@ -108,6 +108,31 @@ In order to make an Aggregator you must implement this interface.

With this feature you can pretty much do whatever you want because the HttpContext objects contain the results of all the aggregate requests. Please note if the HttpClient throws an exception when making a request to a Route in the aggregate then you will not get a HttpContext for it but you would for any that succeed. If it does throw an exception this will be logged.

.. code-block:: csharp
Copy link
Member

Choose a reason for hiding this comment

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

There is no description of this sample!
Developers need to see some instructions and best design approaches while implementing a custom aggregator class.

Comment on lines +113 to +115
public class MyAggregator : IDefinedAggregator
{
public async Task<DownstreamResponse> Aggregate(List<HttpContext> responseHttpContexts)
Copy link
Member

Choose a reason for hiding this comment

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

There is no constructor definition!
It is better to inject common services including a IOcelotLoggerFactory logger.

@raman-m
Copy link
Member

raman-m commented Aug 4, 2023

@MJeorrett As an author of the issue #1287,
Could you review the code please?
I appreciate any feedback from you.

What I see, as developer you were confused during implementation of your custom aggregate, because the docs lacks instructions how to best to build the aggregate.
Are the proposed docs good for you?
What could we improve?

@ggnaegi
Copy link
Member

ggnaegi commented Feb 23, 2024

@jlukawska @raman-m Working on the Multiplexer refactoring, I realized this example is great ;-) Thanks!

@raman-m
Copy link
Member

raman-m commented Feb 27, 2024

@ggnaegi Should we prioritize this PR because of changes in multiplexer and add it to the current release?

@ggnaegi
Copy link
Member

ggnaegi commented Feb 27, 2024

@raman-m I have used the examples from @jlukawska in the Multiplexer documentation, so this PR could be closed.

raman-m added a commit that referenced this pull request Mar 1, 2024
…1826)

* Cleanup of Multiplexing middleware, avoiding creating copies of the Http context if only one downstream route.

* updating comments

* preparing rebase, it's a hack.

* fixing test case "Copy_User_ToTarget",  method name has changed.

* adding some unit tests, checking that if 1 route, ProcessSingleRoute is called and no copies of context are made, if more than 2 Map is called, then more than 2 copies are created.

* Applying refactoring suggested.

* some code cleanup

* Some code cleanup in Aggregate Logic

* Cleanup in Aggregate Tests, verifying multiplexer cleanup

* Finalizing unit test, with complex keys.

* some code refactoring and applying suggestions from reviews

* Update requestaggregation.rst

Recover docs

* updating docs

* Update requestaggregation.rst

* Update requestaggregation.rst

* Code review by @raman-m

* Inherit `Steps` functionality instead of private aggregation

---------

Co-authored-by: Raman Maksimchuk <[email protected]>
@raman-m
Copy link
Member

raman-m commented Mar 1, 2024

@jlukawska Hi J.!
As @ggnaegi said in his comment, we reused your idea and code snippet in PR #1826 and updated docs.
Thank you for your contribution!

@raman-m raman-m closed this Mar 1, 2024
@raman-m raman-m mentioned this pull request Mar 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Identified as a potential bug documentation Needs a documentation update needs feedback Issue is waiting on feedback before acceptance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Custom Aggregator does not receive downstream responses.
4 participants