:toc: macro
toc::[]
:icons: font
:iconfont-remote!:
:iconfont-name: font-awesome
:stylesdir: css

= Samples

== My Thai Star Restaurant
icon:= fa-floppy-o[]  link:resources/samples/mts/MyThaiStar.zip[My Thai Star (.Net Core Server + Angular client)]


video::videos/mts_startup.mp4[width=640, start=0, options=autoplay]

=== Angular requirements

* https://nodejs.org/es/download/[Node]
* https://cli.angular.io/[Angular CLI]
* https://yarnpkg.com/lang/en/docs/install/[Yarn]

=== Angular client

. Install Node.js LTS version
. Install Angular CLI from command line:

** npm install -g @angular/cli
. Install Yarn
. Go to Angular client from command line
. Execute : _yarn install_
. Launch the app from command line: _ng serve_ and check _http://localhost:4200_
. You are ready


=== .Net Core server

==== Basic architecture details

Following the devonfw conventions the .Net Core 2.0 My Thai Star backend is going to be developed dividing the application in _Components_ and using a n-layer architecture.

image::images/project_modules.png[, link="images/project_modules.png"]

==== Components

The application is going to be divided in different components to encapsulate the different domains of the application functionalities.

image::images/mtsn_components.png[, link="images/mtsn_components.png"]

As _main components_ we will find:

- `_BookingService`: Manages the bookings part of the application. With this component the users (anonymous/logged in) can create new bookings or cancel an existing booking. The users with waiter role can see all scheduled bookings.

-`_OrderService_`: This component handles the process to order dishes (related to bookings). A user (as a host or as a guest) can create orders (that contain dishes) or cancel an existing one. The users with waiter role can see all ordered orders.

- `_DishService_`: This component groups the logic related to the menu (dishes) view. Its main feature is to provide the client with the data of the available dishes but also can be used by other components (Ordermanagement) as a data provider in some processes.

- `_UserService_`: Takes care of the User Profile management, allowing to create and update the data profiles.

As _common components_ (that don't exactly represent an application's area but provide functionalities that can be used by the _main components_):

- _Mailservice_: with this service we will provide the functionality for sending email notifications. This is a shared service between different app components such as _bookingmanagement_ or _ordercomponent_.

Other components:

- Security (will manage the access to the _private_ part of the application using a https://jwt.io/[jwt] implementation).

- Twitter integration: planned as a _Microservice_ will provide the twitter integration needed for some specific functionalities of the application. 


=== Layers
==== Introduction
The .Net Core backend for My Thai Star application is going to be based on:

- *devon4NET* as the .Net Core framework
- *VSCode* as the Development environment
- *TOBAGO* as code generation tool

==== Application layer
This layer will expose the REST api to exchange information with the client applications.

The application will expose the services on port 8081 and it can be launched as a self host console application (microservice approach) and as a Web Api application hosted on IIS/IIS Express.

==== Business layer
This layer will define the controllers which will be used on the application layer to expose the different services. Also, will define the swagger contract making use of summary comments and framework attributes. 

This layer also includes the object response classes in order to interact with external clients. 

==== Service layer
The layer in charge of hosting the business logic of the application. Also orchestrates the object conversion between object response and entity objects defined in _Data layer_.

==== Data layer
The layer to communicate with the data base.

Data layer makes use of _Entity Framework_.
The Database context is defined on `_DataAccessLayer_` assembly (`ModelContext`). 

This layer makes use of the _Repository pattern_ and _Unit of work_ in order to encapsulate the complexity. Making use of this combined patterns we ensure an organized and easy work model.


As in the previous layers, the _data access_ layer will have both _interface_ and _implementation_ tiers. However, in this case, the implementation will be slightly different due to the use of _generics_.

==== Cross-Cutting concerns
the layer to make use of transversal components such JWT and mailing.

=== Jwt basics

- A user will provide a username / password combination to our auth server.

- The auth server will try to identify the user and, if the credentials match, will issue a token.

- The user will send the token as the _Authorization_ header to access resources on server protected by  JWT Authentication.

image::images/jwt_schema.png[, link="images/jwt_schema.png"]

=== Jwt implementation details

The _Json Web Token_ pattern will be implemented based on the https://blogs.msdn.microsoft.com/webdev/2017/04/06/jwt-validation-and-authorization-in-asp-net-core/[_jwt on .net core_] framework that is provided by default in the _devon4Net_ projects.


=== Authentication

Based on _Microsoft_ approach, we will implement a class to define the security _entry point_ and filters. Also, as _My Thai Star_ is a mainly _public_ application, we will define here the resources that won't be secured.

On devon4Net.Infrastructure.JWT assembly is defined a subset of _Microsoft's authorization schema_ Database. It is started up the first time the application launches.

You can read more about _Authorization on: 

https://docs.microsoft.com/en-us/aspnet/core/security/authorization/[Authorization in ASP.NET Core]


https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims[Claim based authorization]

=== Dependency injection

As it is explained in the https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection[Microsoft documentation] we are going to implement the _dependency injection_ pattern basing our solution on _.Net Core_.

image::images/dependency_injection.png[, link="images/dependency_injection.png"]

- Separation of API and implementation: Inside each layer we will separate the elements in different tiers: _interface_ and _implementation_. The _interface_ tier will store the _interface_ with the methods definition and inside the _implementation_ we will store the class that implements the _interface_.


=== Layer communication method

The connection between layers, to access to the functionalities of each one, will be solved using the _dependency injection_.

image::images/layer_impl.png[, link="images/layer_impl.png"]

*Connection `BookingService` - Logic*
[source, c#]
----
 public class BookingService : EntityService<Booking>, IBookingService
    {
        private readonly IBookingRepository _bookingRepository;
        private readonly IRepository<Order> _orderRepository;
        private readonly IRepository<InvitedGuest> _invitedGuestRepository;
        private readonly IOrderLineRepository _orderLineRepository;
        private readonly IUnitOfWork _unitOfWork;

        public BookingService(IUnitOfWork unitOfWork,
            IBookingRepository repository,
            IRepository<Order> orderRepository,
            IRepository<InvitedGuest> invitedGuestRepository,
            IOrderLineRepository orderLineRepository) : base(unitOfWork, repository)
        {
            _unitOfWork = unitOfWork;
            _bookingRepository = repository;
            _orderRepository = orderRepository;
            _invitedGuestRepository = invitedGuestRepository;
            _orderLineRepository = orderLineRepository;
        }
}
----

To give service to the defined _User Stories_ we will need to implement the following services:

- provide all available dishes.

- save a booking.

- save an order.

- provide a list of bookings (only for waiters) and allow filtering.

- provide a list of orders (only for waiters) and allow filtering.

- login service (see the _Security_ section).

- provide the _current user_ data (see the _Security_ section)


Following the [naming conventions] proposed for _devon4Net_ applications we will define the following _end points_ for the listed services.

- (POST) `/mythaistar/services/rest/dishmanagement/v1/dish/search`.

- (POST) `/mythaistar/services/rest/bookingmanagement/v1/booking`.

- (POST) `/mythaistar/services/rest/ordermanagement/v1/order`.

- (POST) `/mythaistar/services/rest/bookingmanagement/v1/booking/search`.

- (POST) `/mythaistar/services/rest/ordermanagement/v1/order/search`.

- (POST) `/mythaistar/services/rest/ordermanagement/v1/order/filter` (to filter with fields that does not belong to the Order entity).

- (POST) `/mythaistar/login`.

- (GET) `/mythaistar/services/rest/security/v1/currentuser/`.


You can find all the details for the services implementation in the https://github.com/devonfw/my-thai-star/blob/develop/swagger/mythaistar.yaml[Swagger definition] included in the My Thai Star project on Github.

=== Api Exposed

The _devon4Net.Business.Controller_ assembly in the _business_ layer of a _component_ will store the definition of the service by a  _interface_. In this definition of the service we will set-up the _endpoints_ of the service, the type of data expected and returned, the _HTTP_ method for each endpoint of the service and other configurations if needed.

[source, c#]
----
        /// <summary>
        /// Method to make a reservation with potential guests. The method returns the reservation token with the format: {(CB_|GB_)}{now.Year}{now.Month:00}{now.Day:00}{_}{MD5({Host/Guest-email}{now.Year}{now.Month:00}{now.Day:00}{now.Hour:00}{now.Minute:00}{now.Second:00})}
        /// </summary>

        /// <param name="bookingView"></param>
        /// <response code="201">Ok.</response>
        /// <response code="400">Bad request. Parser data error.</response>
        /// <response code="401">Unauthorized. Authentication fail.</response>
        /// <response code="403">Forbidden. Authorization error.</response>
        /// <response code="500">Internal Server Error. The search process ended with error.</response>
        [HttpPost]
        [HttpOptions]
        [Route("/mythaistar/services/rest/bookingmanagement/v1/booking")]
        [AllowAnonymous]
        [EnableCors("CorsPolicy")]
        public IActionResult BookingBooking([FromBody]BookingView bookingView)
        {
...
----

Using the summary annotations and attributes will tell to swagger the contract via the XML doc generated on compiling time. This doc will be stored in `_XmlDocumentation_` folder.

The Api methods will be exposed on the application layer.

== Google Mail API Consumer
icon:= fa-floppy-o[]  link:resources/samples/components/GMailAPIConsumer.zip[Google Mail API Consumer]




[options=""]
|=======================
|Application| `MyThaiStarEmailService.exe`
|Config file| `MyThaiStarEmailService.exe.Config`
|Default port|8080
|=======================

=== Overview
. Execute `MyThaiStarEmailService.exe`.
. The first time google will ask you for credentials
(just one time) in your default browser:

* Account: mythaistarrestaurant@gmail.com
* Password: mythaistarrestaurant2501

. Visit the url: http://localhost:8080/swagger
. Your server is ready!

[[img-t-architecture]]
.GMail Server Swagger contract page
image::images/email_swagger.png["GMail Service", width="820", link="images/email_swagger.png"]

=== JSON Example
This is the JSON example to test with swagger client. Please read the swagger documentation.

[source,json]
----
{  
   "EmailFrom":"mythaistarrestaurant@gmail.com",
   "EmailAndTokenTo":{  
      "MD5Token1":" Email_Here!@gmail.com",
      "MD5Token2":" Email_Here!@gmail.com"
   },
   "EmailType":0,
   "DetailMenu":[  
      "Thai Spicy Basil Fried Rice x2",
      "Thai green chicken curry x2"
   ],
   "BookingDate":"2017-05-31T12:53:39.7864723+02:00",
   "Assistants":2,
   "BookingToken":"MD5Booking",
   "Price":20.0,
   "ButtonActionList":{  
      "http://accept.url":"Accept",
      "http://cancel.url":"Cancel"
   },
   "Host":{  
      " Email_Here!@gmail.com":"José Manuel"
   }
}

----
=== Configure the service port

If you want to change the default port, please edit the config file and
change the next entry in `appSettings` node:

[source,xml]
----
<appSettings>
   <add key="LocalListenPort" value="8080" />
</appSettings>
----

==== External links

https://console.developers.google.com/flows/enableapi?apiid=gmail[Google API Account Configuration]

https://developers.google.com/gmail/api/auth/scopes[About Scopes]



== Downloads

icon:= fa-floppy-o[]  link:https://github.com/devonfw/my-thai-star/tree/develop/net[My Thai Star (.Net Core Server + Angular client)]
