Skip to content

Commit

Permalink
#371 Add UserRoleAssignment to example projects.
Browse files Browse the repository at this point in the history
  • Loading branch information
adamjstone committed Aug 31, 2020
1 parent 1cca248 commit 92b5ca5
Show file tree
Hide file tree
Showing 61 changed files with 2,675 additions and 147 deletions.
48 changes: 24 additions & 24 deletions cicd/modules/BuildAndDeployment.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ $SolutionConfigurationDebug = "Debug";
$SolutionConfigurationRelease = "Release";

# Namespaces
$ExampleServiceApplicationNamespace = "RapidField.SolidInstruments.Example.ServiceApplication";
$ExampleWebApplicationNamespace = "RapidField.SolidInstruments.Example.WebApplication";
$ExampleAccessControlServiceApplicationNamespace = "RapidField.SolidInstruments.Example.Domain.AccessControl.Service";
$ExampleBeaconServiceApplicationNamespace = "RapidField.SolidInstruments.Example.BeaconService";

# Regular expressions
$ValidCommitMessageRegularExpressionPattern = "^(#[1-9][0-9]{0,4} )?[A-Z][A-Za-z0-9\,\.\!\;\:\'\""\@\#\$\%\^\&\*\-\+\=_\(\)\[\]\{\}\|\\\/\s]{8,144}$";
Expand Down Expand Up @@ -609,76 +609,76 @@ Function SignPackages

<#
.Synopsis
Starts the example service application.
Starts the example access control service application.
#>
Function StartExampleServiceApplication
Function StartExampleAccessControlServiceApplication
{
Param
(
[Parameter(Mandatory = $true, Position = 0)]
[String] $SolutionConfiguration
)

ComposeStart "Starting the example service application using $SolutionConfiguration configuration.";
$BinaryFilePath = Join-Path -Path "$DirectoryPathForExample" -ChildPath "$ExampleServiceApplicationNamespace\bin\$SolutionConfiguration\$TargetFrameworkForExampleServiceApplication\$ExampleServiceApplicationNamespace.dll";
ComposeStart "Starting the example access control service application using $SolutionConfiguration configuration.";
$BinaryFilePath = Join-Path -Path "$DirectoryPathForExample" -ChildPath "$ExampleServiceApplicationNamespace\bin\$SolutionConfiguration\$TargetFrameworkForExampleServiceApplication\$ExampleAccessControlServiceApplicationNamespace.dll";
ComposeNormal "Using binary path: $BinaryFilePath";
Start-Process -ArgumentList "$BinaryFilePath" -FilePath "dotnet" -WindowStyle Minimized;
ComposeFinish "Finished starting the application.";
}

<#
.Synopsis
Starts the example service application in debug mode.
Starts the example access control service application in debug mode.
#>
Function StartExampleServiceApplicationDebug
Function StartExampleAccessControlServiceApplicationDebug
{
StartExampleServiceApplication -SolutionConfiguration $SolutionConfigurationDebug;
StartExampleAccessControlServiceApplication -SolutionConfiguration $SolutionConfigurationDebug;
}

<#
.Synopsis
Starts the example service application in release mode.
Starts the example access control service application in release mode.
#>
Function StartExampleServiceApplicationRelease
Function StartExampleAccessControlServiceApplicationRelease
{
StartExampleServiceApplication -SolutionConfiguration $SolutionConfigurationRelease;
StartExampleAccessControlServiceApplication -SolutionConfiguration $SolutionConfigurationRelease;
}

<#
.Synopsis
Starts the example web application.
Starts the example beacon service application.
#>
Function StartExampleWebApplication
Function StartExampleBeaconServiceApplication
{
Param
(
[Parameter(Mandatory = $true, Position = 0)]
[String] $SolutionConfiguration
)

ComposeStart "Starting the example web application using $SolutionConfiguration configuration.";
$ProjectFilePath = Join-Path -Path "$DirectoryPathForExample" -ChildPath "$ExampleWebApplicationNamespace\$ExampleWebApplicationNamespace.csproj";
ComposeNormal "Using project path: $ProjectFilePath";
Start-Process -ArgumentList "run --project ""$ProjectFilePath"" --configuration $SolutionConfiguration" -FilePath "dotnet" -WindowStyle Minimized;
ComposeStart "Starting the example beacon service application using $SolutionConfiguration configuration.";
$BinaryFilePath = Join-Path -Path "$DirectoryPathForExample" -ChildPath "$ExampleServiceApplicationNamespace\bin\$SolutionConfiguration\$TargetFrameworkForExampleServiceApplication\$ExampleBeaconServiceApplicationNamespace.dll";
ComposeNormal "Using binary path: $BinaryFilePath";
Start-Process -ArgumentList "$BinaryFilePath" -FilePath "dotnet" -WindowStyle Minimized;
ComposeFinish "Finished starting the application.";
}

<#
.Synopsis
Starts the example web application in debug mode.
Starts the example beacon service application in debug mode.
#>
Function StartExampleWebApplicationDebug
Function StartExampleBeaconServiceApplicationDebug
{
StartExampleWebApplication -SolutionConfiguration $SolutionConfigurationDebug;
StartExampleBeaconServiceApplication -SolutionConfiguration $SolutionConfigurationDebug;
}

<#
.Synopsis
Starts the example web application in release mode.
Starts the example beacon service application in release mode.
#>
Function StartExampleWebApplicationRelease
Function StartExampleBeaconServiceApplicationRelease
{
StartExampleWebApplication -SolutionConfiguration $SolutionConfigurationRelease;
StartExampleBeaconServiceApplication -SolutionConfiguration $SolutionConfigurationRelease;
}

<#
Expand Down
1 change: 1 addition & 0 deletions en-US_User.dic
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ unencrypted
unformatted
uninstallation
unmanaged
untracked
uref
url
usings
Expand Down
9 changes: 4 additions & 5 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@ This document describes the purpose of the [`example`]() directory.

This path contains sample projects that utilize the **Solid Instruments** [constituent libraries](/../src).

- [`RapidField.SolidInstruments.Example.Contracts`](/example/RapidField.SolidInstruments.Example.Contracts) exposes sample contracts that are used to demonstrate the **Solid Instruments** [messaging](../src/RapidField.SolidInstruments.Messaging/README.md) constructs.
- [`RapidField.SolidInstruments.Example.DatabaseModel`](/example/RapidField.SolidInstruments.Example.DatabaseModel) serves as a sample data access API that is modeled using the **Solid Instruments** [**Entity Framework**](https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ef/overview) abstractions.
- [`RapidField.SolidInstruments.Example.Domain`](/example/RapidField.SolidInstruments.Example.Domain) houses sample domain machinery that utilizes the **Solid Instruments** [data access](../src/RapidField.SolidInstruments.DataAccess/README.md) and [messaging](../src/RapidField.SolidInstruments.Messaging/README.md) constructs.
- [`RapidField.SolidInstruments.Example.ServiceApplication`](/example/RapidField.SolidInstruments.Example.ServiceApplication) serves as a sample service application that employs the **Solid Instruments** [messaging](../src/RapidField.SolidInstruments.Messaging/README.md) and [dependency injection](../src/RapidField.SolidInstruments.InversionOfControl/README.md) abstractions.
- [`RapidField.SolidInstruments.Example.WebApplication`](/example/RapidField.SolidInstruments.Example.WebApplication) serves as a sample web application that employs the **Solid Instruments** [dependency injection](../src/RapidField.SolidInstruments.InversionOfControl/README.md) abstractions.
- [`RapidField.SolidInstruments.Example.BeaconService`](/example/RapidField.SolidInstruments.Example.BeaconService) demonstrates a utility service that publishes scheduled heartbeat messages.
- [`RapidField.SolidInstruments.Example.Domain`](/example/RapidField.SolidInstruments.Example.Domain) houses a sample collection of shared domain models that utilize the **Solid Instruments** [messaging](../src/RapidField.SolidInstruments.Messaging/README.md) constructs.
- [`RapidField.SolidInstruments.Example.Domain.AccessControl`](/example/RapidField.SolidInstruments.Example.Domain.AccessControl) demonstrates access control domain logic utilizing the **Solid Instruments** [data access](../src/RapidField.SolidInstruments.DataAccess/README.md) constructs.
- [`RapidField.SolidInstruments.Example.Domain.AccessControl.Service`](/example/RapidField.SolidInstruments.Example.Domain.AccessControl.Service) demonstrates an access control domain service utilizing the **Solid Instruments** [data access](../src/RapidField.SolidInstruments.DataAccess/README.md) and [messaging](../src/RapidField.SolidInstruments.Messaging/README.md) constructs.

## License

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!--
Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
-->

[![Solid Instruments](../../SolidInstruments.Logo.Color.Transparent.500w.png)](../../README.md)
- - -

# RapidField.SolidInstruments.Example.BeaconService

This document describes the purpose of the [`RapidField.SolidInstruments.Example.BeaconService`]() project.

## Purpose

This project demonstrates a utility service that publishes scheduled heartbeat messages.

## License

[![License](https://img.shields.io/github/license/rapidfield/solid-instruments?style=flat&color=lightseagreen&label=license&logo=open-access&logoColor=lightgrey)](../../LICENSE.txt)

**Solid Instruments** is [MIT-licensed](https://en.wikipedia.org/wiki/MIT_License). Review the [license terms](../../LICENSE.txt) for more information.

<br />

- - -

<br />

[![RapidField](../../RapidField.Logo.Color.Black.Transparent.200w.png)](https://www.rapidfield.com)

###### Copyright (c) RapidField LLC. All rights reserved. "RapidField" and "Solid Instruments" are trademarks of RapidField LLC.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
using RapidField.SolidInstruments.Messaging.Service;
using RapidField.SolidInstruments.Service;
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;

namespace RapidField.SolidInstruments.Example.Domain.AccessControl.Service
{
Expand Down Expand Up @@ -65,6 +67,9 @@ protected override void AddListeners(IMessageListeningProfile listeningProfile,
listeningProfile.AddCommandListener<Commands.ModelState.UserRole.CreateDomainModelCommand, Messages.Command.ModelState.UserRole.CreateDomainModelCommandMessage>();
listeningProfile.AddCommandListener<Commands.ModelState.UserRole.DeleteDomainModelCommand, Messages.Command.ModelState.UserRole.DeleteDomainModelCommandMessage>();
listeningProfile.AddCommandListener<Commands.ModelState.UserRole.UpdateDomainModelCommand, Messages.Command.ModelState.UserRole.UpdateDomainModelCommandMessage>();
listeningProfile.AddCommandListener<Commands.ModelState.UserRoleAssignment.CreateDomainModelCommand, Messages.Command.ModelState.UserRoleAssignment.CreateDomainModelCommandMessage>();
listeningProfile.AddCommandListener<Commands.ModelState.UserRoleAssignment.DeleteDomainModelCommand, Messages.Command.ModelState.UserRoleAssignment.DeleteDomainModelCommandMessage>();
listeningProfile.AddCommandListener<Commands.ModelState.UserRoleAssignment.UpdateDomainModelCommand, Messages.Command.ModelState.UserRoleAssignment.UpdateDomainModelCommandMessage>();

// Add event listeners.
listeningProfile.AddEventListener<Events.ModelState.User.DomainModelCreatedEvent, Messages.Event.ModelState.User.DomainModelCreatedEventMessage>();
Expand All @@ -73,6 +78,9 @@ protected override void AddListeners(IMessageListeningProfile listeningProfile,
listeningProfile.AddEventListener<Events.ModelState.UserRole.DomainModelCreatedEvent, Messages.Event.ModelState.UserRole.DomainModelCreatedEventMessage>();
listeningProfile.AddEventListener<Events.ModelState.UserRole.DomainModelDeletedEvent, Messages.Event.ModelState.UserRole.DomainModelDeletedEventMessage>();
listeningProfile.AddEventListener<Events.ModelState.UserRole.DomainModelUpdatedEvent, Messages.Event.ModelState.UserRole.DomainModelUpdatedEventMessage>();
listeningProfile.AddEventListener<Events.ModelState.UserRoleAssignment.DomainModelCreatedEvent, Messages.Event.ModelState.UserRoleAssignment.DomainModelCreatedEventMessage>();
listeningProfile.AddEventListener<Events.ModelState.UserRoleAssignment.DomainModelDeletedEvent, Messages.Event.ModelState.UserRoleAssignment.DomainModelDeletedEventMessage>();
listeningProfile.AddEventListener<Events.ModelState.UserRoleAssignment.DomainModelUpdatedEvent, Messages.Event.ModelState.UserRoleAssignment.DomainModelUpdatedEventMessage>();
}
finally
{
Expand Down Expand Up @@ -123,41 +131,88 @@ protected override void OnExecutionStarting(IDependencyScope dependencyScope, IC
try
{
var mediator = dependencyScope.Resolve<ICommandMediator>();
TestServiceBusConnectivity(mediator);
MigrateDatabaseSchema(dependencyScope);
HydrateNamedEntities(mediator);
}
finally
{
base.OnExecutionStarting(dependencyScope, applicationConfiguration, executionLifetime);
}
}

/// <summary>
/// Creates or updates all named domain models.
/// </summary>
/// <param name="mediator">
/// A mediator that is used to issue commands.
/// </param>
[DebuggerHidden]
private static void HydrateNamedEntities(ICommandMediator mediator)
{
foreach (var domainModel in Models.User.DomainModel.Named.All())
{
mediator.Process(new Messages.Command.ModelState.User.CreateDomainModelCommandMessage(new Commands.ModelState.User.CreateDomainModelCommand(domainModel)));
}

// Create or update the database schema.
var databaseContext = dependencyScope.Resolve<DatabaseContext>();
databaseContext.Database.EnsureCreated();
Thread.Sleep(610);

foreach (var domainModel in Models.User.DomainModel.Named.All())
{
mediator.Process(new Messages.Command.ModelState.User.CreateDomainModelCommandMessage(new Commands.ModelState.User.CreateDomainModelCommand(domainModel)));
}
foreach (var domainModel in Models.UserRole.DomainModel.Named.All())
{
mediator.Process(new Messages.Command.ModelState.UserRole.CreateDomainModelCommandMessage(new Commands.ModelState.UserRole.CreateDomainModelCommand(domainModel)));
}

foreach (var domainModel in Models.UserRole.DomainModel.Named.All())
{
mediator.Process(new Messages.Command.ModelState.UserRole.CreateDomainModelCommandMessage(new Commands.ModelState.UserRole.CreateDomainModelCommand(domainModel)));
}
Thread.Sleep(610);

try
{
// Test service bus connectivity.
var pingRequestCorrelationIdentifier = Guid.NewGuid();
var pingResponseMessage = mediator.Process<PingResponseMessage>(new PingRequestMessage(pingRequestCorrelationIdentifier));

if (pingResponseMessage is null || pingResponseMessage.CorrelationIdentifier != pingRequestCorrelationIdentifier)
{
throw new ServiceExectuionException("The service was unable to verify service bus connectivity.");
}
}
catch (CommandHandlingException exception)
foreach (var domainModel in Models.UserRoleAssignment.DomainModel.Named.All())
{
mediator.Process(new Messages.Command.ModelState.UserRoleAssignment.CreateDomainModelCommandMessage(new Commands.ModelState.UserRoleAssignment.CreateDomainModelCommand(domainModel)));
}

Thread.Sleep(610);
Console.WriteLine("Database entities created/updated.");
}

/// <summary>
/// Creates or updates the database schema.
/// </summary>
/// <param name="dependencyScope">
/// A scope that is used to resolve service dependencies.
/// </param>
[DebuggerHidden]
private static void MigrateDatabaseSchema(IDependencyScope dependencyScope)
{
var databaseContext = dependencyScope.Resolve<DatabaseContext>();
databaseContext.Database.EnsureCreated();
Thread.Sleep(610);
Console.WriteLine("Database schema created/updated.");
}

/// <summary>
/// Raises an exception if a service bus connection is unavailable.
/// </summary>
/// <param name="mediator">
/// A mediator that is used to issue commands.
/// </param>
[DebuggerHidden]
private static void TestServiceBusConnectivity(ICommandMediator mediator)
{
try
{
var pingRequestCorrelationIdentifier = Guid.NewGuid();
var pingResponseMessage = mediator.Process<PingResponseMessage>(new PingRequestMessage(pingRequestCorrelationIdentifier));

if (pingResponseMessage is null || pingResponseMessage.CorrelationIdentifier != pingRequestCorrelationIdentifier)
{
throw new ServiceExectuionException("The service was unable to verify service bus connectivity. See inner exception.", exception);
throw new ServiceExectuionException("The service was unable to verify service bus connectivity.");
}
}
finally
catch (CommandHandlingException exception)
{
base.OnExecutionStarting(dependencyScope, applicationConfiguration, executionLifetime);
throw new ServiceExectuionException("The service was unable to verify service bus connectivity. See inner exception.", exception);
}

Console.WriteLine("Service bus connectivity verified.");
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// =================================================================================================================================
// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
// =================================================================================================================================

using RapidField.SolidInstruments.Command;
using RapidField.SolidInstruments.DataAccess;
using System;
using DataAccessModel = RapidField.SolidInstruments.Example.Domain.Models.UserRoleAssignment.AggregateDataAccessModel;
using DomainModel = RapidField.SolidInstruments.Example.Domain.Models.UserRoleAssignment.DomainModel;
using DomainModelCommand = RapidField.SolidInstruments.Example.Domain.Commands.ModelState.UserRoleAssignment.CreateDomainModelCommand;

namespace RapidField.SolidInstruments.Example.Domain.AccessControl.CommandHandlers.ModelState.UserRoleAssignment
{
/// <summary>
/// Processes a single <see cref="DomainModelCommand" />.
/// </summary>
public sealed class CreateDomainModelCommandHandler : CreateDomainModelCommandHandler<Guid, DomainModel, DataAccessModel, DomainModelCommand>
{
/// <summary>
/// Initializes a new instance of the <see cref="CreateDomainModelCommandHandler" /> class.
/// </summary>
/// <param name="mediator">
/// A processing intermediary that is used to process sub-commands.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="mediator" /> is <see langword="null" />.
/// </exception>
public CreateDomainModelCommandHandler(ICommandMediator mediator)
: base(mediator)
{
return;
}

/// <summary>
/// Releases all resources consumed by the current <see cref="CreateDomainModelCommandHandler" />.
/// </summary>
/// <param name="disposing">
/// A value indicating whether or not managed resources should be released.
/// </param>
protected override void Dispose(Boolean disposing) => base.Dispose(disposing);
}
}
Loading

0 comments on commit 92b5ca5

Please sign in to comment.