Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/dzimchuk/book-fast-service-fabric

A sample demonstrating how to implement a multitenant facility management and accommodation booking application as native Azure Service Fabric reliable services.
https://github.com/dzimchuk/book-fast-service-fabric

azure-ad azure-search azure-services microservices microservices-architecture netcore service-fabric

Last synced: 4 months ago
JSON representation

A sample demonstrating how to implement a multitenant facility management and accommodation booking application as native Azure Service Fabric reliable services.

Lists

README

        

# Book Fast (Service Fabric)

A sample demonstrating how to implement a multitenant facility management and accommodation booking application as native Azure Service Fabric reliable services.

Here's the introductory blog [post](https://dzimchuk.net/microservices-primer-with-azure-service-fabric/).

> **Note**: An up-to-date containerized version of the sample is available [here](https://github.com/dzimchuk/book-fast-docker).

## Features

### Architecture
- 4 bounded contexts
- CQRS and DDD (with [reliable domain events](https://dzimchuk.net/reliable-domain-events/))
- Stateless and stateful services
- ASP.NET Core 2.x Web API and web frontend

### Service Fabric
- [Per environment configuration](https://dzimchuk.net/configuring-asp-net-core-applications-in-service-fabric/) integrated with ASP.NET Core infrastructure
- [ServicePartitionClient](https://dzimchuk.net/implementing-a-rest-client-for-internal-communication-in-service-fabric/) and Reverse Proxy based [service clients](https://dzimchuk.net/re-iterating-communication-options-in-service-fabric/)
- Application Insights
- EventFlow

### Security
- [Multitenant](https://dzimchuk.net/enabling-multitenant-support-in-you-azure-ad-protected-applications/) Azure AD organizational accounts
- [Azure AD B2C](https://dzimchuk.net/setting-up-your-asp-net-core-2-0-apps-and-services-for-azure-ad-b2c/) authentication for customers
- OpenID Connect and OAuth2

### Azure services
- Azure SQL databases
- Azure Storage
- Azure Service Bus
- Azure Search

### Misc
- [Swagger and AutoRest](https://dzimchuk.net/generating-clients-for-your-apis-with-autorest/)
- Redis cache
- [Circuit Breaker](https://dzimchuk.net/be-prepared-for-downstream-failures-by-implementing-the-circuit-breaker-pattern/)

![BookFast Service Fabric](BookFastServiceFabric.png)

## Configuration

BookFast.sfproj references `..\..\..\config\BookFast\Local.xml` that is used in local deployment profiles. This file is not included in the repository and you will need to provide your configuration overrides.

Here's a short description of configuration parameters:

```












































```

Please inspect service and application manifests to understand how these parameters are used to configure services.

### Azure AD

Azure AD is used for organizational accounts of facility providers. You will need two applications in Azure AD: one for the APIs (Book Fast API app) and one for the web (BookFast app). Both applications should have multitenant support enabled. BookFast should have a delegated permission to access BookFast API app. If you're new to Azure AD the following post are going to help you out:

- [Protecting your APIs with Azure Active Directory](https://dzimchuk.net/protecting-your-apis-with-azure-active-directory/)
- [Enabling multitenant support in you Azure AD protected applications](https://dzimchuk.net/enabling-multitenant-support-in-you-azure-ad-protected-applications/)

Both apps have a user role called 'Facility Provider' that should be assigned to users to enable them to edit facilities. Please have a look at this [post](https://dzimchuk.net/application-and-user-permissions-in-azure-ad/) to understand how application and user roles are configured in Azure AD.

### Azure AD B2C

Customer accounts are managed in Azure AD B2C. It supports self sign up, profile editing and 3rd part identity providers.

You will need to create a B2C tenant and an app. You will also need to policies:

1. Sign in or sign up policy
2. Profile edit policy

You may also find this [post](https://dzimchuk.net/setting-up-your-asp-net-core-2-0-apps-and-services-for-azure-ad-b2c/) useful when setting you your application.

### SQL Database

BookFast.Facility.Data contain EFCore migrations to set up you SQL database schema.

### Service Bus
Azure Service Bus is used as a message broker for integration events.

Please make sure to provision a single topic with 3 subscriptions:
- Booking
- Facility
- SearchIndexer

Also provision 2 notification queues:
- bookfast-facility-notifications
- bookfast-booking-notifications

### Azure Search

BookFast.Search.Adapter can be run from the command line as `dotnet run provision` in order to create an index in your Azure Search service. It will require the following parameters to be defined in [user secrets](https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets):

- Search:ServiceName
- Search:AdminKey
- Search:IndexName

### Circuit Breaker

[BookingProxy](/BookFast.Web.Proxy/CircuitBreakingBookingProxy.cs) (web app) implements a [Circuit Breaker](https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker) pattern. In order to test it, set `Test:FailRandom` parameter of the Booking service to `true`.

### Service clients

Each service provides a client library that makes it easier to consumers to communicate with them. The client libraries also implement necessary components for service endpoint resolution.

#### Using ServicePartitionClient

```
internal class FacilityProxy : IFacilityService
{
private readonly IFacilityMapper mapper;
private readonly IPartitionClientFactory> partitionClientFactory;

public FacilityProxy(IFacilityMapper mapper,
IPartitionClientFactory> partitionClientFactory)
{
this.mapper = mapper;
this.partitionClientFactory = partitionClientFactory;
}

public async Task FindAsync(Guid facilityId)
{
var result = await partitionClientFactory.CreatePartitionClient().InvokeWithRetryAsync(async client =>
{
var api = await client.CreateApiClient();
return await api.FindFacilityWithHttpMessagesAsync(facilityId);
});

if (result.Response.StatusCode == HttpStatusCode.NotFound)
{
throw new FacilityNotFoundException(facilityId);
}

return mapper.MapFrom(result.Body);
}
}
```

A consuming service should provide the following configuration section for the target service:

```


```

#### Using Reverse Proxy

```
internal class FacilityProxy : IFacilityService
{
private readonly IFacilityMapper mapper;
private readonly IApiClientFactory apiClientFactory;

public FacilityProxy(IFacilityMapper mapper,
IApiClientFactory apiClientFactory)
{
this.mapper = mapper;
this.apiClientFactory = apiClientFactory;
}

public async Task FindAsync(Guid facilityId)
{
var api = await apiClientFactory.CreateApiClientAsync();
var result = await api.FindFacilityWithHttpMessagesAsync(facilityId);

if (result.Response.StatusCode == HttpStatusCode.NotFound)
{
throw new FacilityNotFoundException(facilityId);
}

return mapper.MapFrom(result.Body);
}
}
```

The `ServiceUri` setting in this case points to the Reverse Proxy, e.g. `http://localhost:19081/BookFast/FacilityService/`.