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 sample application #527

Merged
merged 1 commit into from
Apr 18, 2019
Merged

Add sample application #527

merged 1 commit into from
Apr 18, 2019

Conversation

PeterKneale
Copy link
Contributor

@PeterKneale PeterKneale commented Mar 16, 2019

Added a sample application consisting of three projects

  • a web api that publishes from a controller and subscribes via a background service

  • a console application that subscribes via a background service and publishes within an event handler

  • a shared models assembly containing event dto's

  • Further work required:

    • Demonstrate use of PublishMetaData
    • Demonstrate integration with CorrelationId
    • Demonstrate use of Cancellation Tokens
    • Add acceptance tests project
    • Add dockerfiles for api, console, aws and tests
    • Demonstrate docker-compose executing acceptance tests against api / console while using mocked aws environment

relates to issue #476

@PeterKneale PeterKneale requested a review from a team as a code owner March 16, 2019 11:57
@codecov
Copy link

codecov bot commented Mar 16, 2019

Codecov Report

Merging #527 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #527   +/-   ##
=======================================
  Coverage   37.64%   37.64%           
=======================================
  Files          78       78           
  Lines        2614     2614           
  Branches      458      458           
=======================================
  Hits          984      984           
  Misses       1485     1485           
  Partials      145      145

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5e24a34...35d8568. Read the comment docs.

@martincostello martincostello added this to the v7.0.0 milestone Mar 16, 2019
Copy link
Member

@martincostello martincostello 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 a great start - thanks for picking up this issue 😃

JustSaying.Sample.Restaurant.KitchenConsole/Program.cs Outdated Show resolved Hide resolved
JustSaying.Sample.Restaurant.KitchenConsole/Program.cs Outdated Show resolved Hide resolved
JustSaying.Sample.Restaurant.KitchenConsole/Program.cs Outdated Show resolved Hide resolved
JustSaying.Sample.Restaurant.OrderingApi/Program.cs Outdated Show resolved Hide resolved
JustSaying.Sample.Restaurant.OrderingApi/Startup.cs Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Show resolved Hide resolved
README.md Show resolved Hide resolved
@martincostello martincostello changed the title Add sample application [WIP] Add sample application Mar 16, 2019
Copy link
Member

@slang25 slang25 left a comment

Choose a reason for hiding this comment

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

Great start 👍

@PeterKneale
Copy link
Contributor Author

  • Have pushed, can squash if required.
  • Have had to add suppression in order to remove the ConfigureAwait
    [assembly: SuppressMessage("Reliability", "CA2007:Do not directly await a Task", Justification = "Console application do not have a SynchronizationContext")]

JustSaying.Sample.Restaurant.KitchenConsole/Program.cs Outdated Show resolved Hide resolved
JustSaying.Sample.Restaurant.KitchenConsole/Program.cs Outdated Show resolved Hide resolved
else
{
// The real AWS environment will require some means of authentication
//x.WithBasicCredentials("###", "###");
Copy link
Member

Choose a reason for hiding this comment

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

If you add UserSecrets to the config providers, you could load these from config without needing to have it commented-out with placeholders.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah im a bit torn - im trying to be careful to leave the sample app in the simplest possible state where people can easily see what they might need to do or change in order to get it running on their box. Some have keys, others env variables etc. Not sure whats best.
Can go with the secrets if you think that's best but I think its a bit of a distraction from demonstrating the bus.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

on a similar note i was thinking of leaving a line like this for those who configure the region via environment variables too..?

//x.WithRegion(new Amazon.Runtime.EnvironmentVariableAWSRegion().Region);

Copy link
Member

Choose a reason for hiding this comment

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

I guess that's more of an advanced use case? We wouldn't want to balloon the samples too much with all the possible things you could do. Also if you were using environment variables, you'd probably be using the .NET provider for that and binding them to IConfiguration somehow I'd have thought.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah and it feels a bit orthogonal to the actual demonstration of your library. Its more demonstrating aspnet core configuration and the aws sdk

JustSaying.Sample.Restaurant.OrderingApi/Program.cs Outdated Show resolved Hide resolved
JustSaying.Sample.Restaurant.OrderingApi/Startup.cs Outdated Show resolved Hide resolved
JustSaying.Sample.Restaurant.OrderingApi/Startup.cs Outdated Show resolved Hide resolved
else
{
// The real AWS environment will require some means of authentication
//x.WithBasicCredentials("###", "###");
Copy link
Member

Choose a reason for hiding this comment

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

As above regarding user secrets.

@PeterKneale
Copy link
Contributor Author

Further feedback welcome

@martincostello
Copy link
Member

@PeterKneale Thanks for your work on this. When I get some time today or tomorrow, I'll pull your branch locally and have a play around with what's there so far. 👍

@PeterKneale
Copy link
Contributor Author

Sure thing. Thanks for a great library

README.md Outdated Show resolved Hide resolved
JustSaying.Sample.Restaurant.KitchenConsole/Program.cs Outdated Show resolved Hide resolved
JustSaying.Sample.Restaurant.KitchenConsole/Program.cs Outdated Show resolved Hide resolved
JustSaying.Sample.Restaurant.OrderingApi/Startup.cs Outdated Show resolved Hide resolved
JustSaying.Sample.Restaurant.OrderingApi/Startup.cs Outdated Show resolved Hide resolved
JustSaying.Sample.Restaurant.OrderingApi/Startup.cs Outdated Show resolved Hide resolved
JustSaying.Sample.Restaurant.OrderingApi/Startup.cs Outdated Show resolved Hide resolved
JustSaying.Sample.Restaurant.OrderingApi/Subscriber.cs Outdated Show resolved Hide resolved
@martincostello
Copy link
Member

I've cloned the the sample locally and had a play around with it. Here's a few bits of feedback on specifics, but overall this is pretty good.

I think rather than Swagger and an "API", we should have a simple one-page MVC app with Bootstrap added, then when you run the sample it can present a UI where the order can be picked from a few options (e.g. pizza, curry, burger, etc.) with a few simple JavaScript calls to post the order and poll for and update (simple meta refresh?) when the "kitchen" says it is ready.

This is more natural to navigate that doing a manual HTTP POST in the Swagger UI and provides feedback that's a bit more visual that watching two consoles, though that's still there for a more "low level" view.

I'd also add some additional handlers that simulates payment and store the order in an in-memory database in the web app to persist things. Then if messages fail the process can be potentially recovered by leveraging the reliability of building on top of a messaging system. This would also demonstrate things like have multiple subscriptions to the same queue for different purposes.

Then we can flesh out the sample with a few extra handlers/processes, something like:

  • User creates order in UI via POST to back-end
  • UI back-end publishes "placed" message to queue
  • UI back-end receives "placed" message and stores in in-memory database
  • User "pays" for the order in the UI via POST to back-end
  • UI back-end publishes "paid" message to topic
  • UI back-end receives "paid" message and updates order in in-memory database with new state
  • UI updates to show the user payment made and restaurant is awaiting confirmation
  • Separate handler receives "paid" message and sends order to restaurant queue.
  • Restaurant handler receives "order" message and sends "accepted" message to topic
  • UI back-end receives "accepted" message and updates order in in-memory database with new state
  • UI updates to show the user the order has been "accepted" by the restaurant to be cooked

@PeterKneale
Copy link
Contributor Author

I've addressed your basic feedback. I like the idea about building the web frontend and demonstrating a more thorough workflow.. I'm wondering what delivers the most advantage because I've got limited time.

An area that I think also really needs to be added is an example of how to build dockerised system tests.
ie:

  • A docker compose file/s consisting of

    • p4tin/goaws
    • sql
    • OrderingApi
    • KitchenConsole
    • XUnit System Tests
  • The system tests can publish an event, then patiently await an expected outcome in the database for a few seconds.

  • The tests could perform a HTTP POST to the API, then patiently await an expected outcome in the database for a few seconds.

  • I'm doing this at work at the moment and it feels like one of the only ways to test the interaction of multiple services but would welcome any other ideas.

@martincostello
Copy link
Member

I think it's fine to keep the scope more confined here, than my original suggestion/comments. That way this delivers value into master sooner, and then it can be iterated on over time to have the option of a more "interactive" sample as well as the lower-level one here.

Otherwise what you've alluded to above sounds reasonable. Often the acceptance/integration/system tests for our own workers that use JustSaying involve observing the side effects of the implementation details for message publishing and consumption (e.g. a record appears in a database).

await new HostBuilder()
.ConfigureAppConfiguration((hostContext, config) =>
{
config.SetBasePath(AppContext.BaseDirectory);
Copy link
Member

Choose a reason for hiding this comment

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

Is there a method on HostBuilder anywhere that does all this by default? WebHostBuilder does similar (or comes preconfigured that way), so would shave off a few lines of code if it's not needed or there's a one-liner.

Copy link
Contributor Author

@PeterKneale PeterKneale Apr 13, 2019

Choose a reason for hiding this comment

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

Just removing it seems to work...
executing this from the projects folder works
dotnet run
as does this from the solution root
dotnet run --project samples/JustSaying.Sample.Restaurant.KitchenConsole/JustSaying.Sample.Restaurant.KitchenConsole.csproj

@martincostello
Copy link
Member

@PeterKneale Just some minor comments around naming and comments, otherwise this looks really good.

We're planning on moving the code around soon to tidy up the mess of folders that's arisen over time into a src, tests structure as has become a .NET Core "standard" recently. As an initial step towards that, could you move all the new things into a samples folder in the repo root please, instead of putting them directly at the root? That'll save the extra churn later when we shift things around.

Again, thanks for all your work on this! 👍

@PeterKneale
Copy link
Contributor Author

  • moved to samples folder
  • addressed feedback
  • squashed & pushed
  • will add bootstrap skeleton and remove swashbuckle in another PR later tonight if i get a chance and start iterating towards a more complete sample over time

Added a sample application consisting of three projects
- a web api that publishes from a controller and subscribes via a background service
- a console application that subscribes via a background service and publishes within an event handler
- a shared models assembly containing messages
"AWSRegion": "eu-west-1",
"AWSServiceUrl": "http://localhost:4100",
"Logging": {
"LogLevel": {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should I be able to add "EventLog": "Trace" here and have the messages contents logged?

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 so - at some point in v7 we need to rename that, because it's easy to confuse with the Windows Event Log.

"AWSRegion": "eu-west-1",
"AWSServiceUrl": "http://localhost:4100",
"Logging": {
"LogLevel": {
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 so - at some point in v7 we need to rename that, because it's easy to confuse with the Windows Event Log.

@martincostello
Copy link
Member

I think I'm happy with this as it is as a starting point. If the rest of the maintainers are happy, I think we could get this merged next week and further changes can be done in follow-up PRs over time.

@PeterKneale
Copy link
Contributor Author

👍

Copy link
Member

@slang25 slang25 left a comment

Choose a reason for hiding this comment

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

I'm more than happy with this, fantastic work!

@martincostello
Copy link
Member

@PeterKneale Is there any more you're planning to do as part of this PR to justify the WIP status still, or should we merge this?

@PeterKneale PeterKneale changed the title [WIP] Add sample application Add sample application Apr 17, 2019
@PeterKneale
Copy link
Contributor Author

Ready to merge - I cant remove the WIP label.

@slang25 slang25 removed the WIP label Apr 17, 2019
@martincostello
Copy link
Member

Excellent work @PeterKneale! :shipit:

@martincostello martincostello merged commit f3a05e3 into justeattakeaway:master Apr 18, 2019
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.

5 participants