diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..2d15e48
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,20 @@
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.vs
+**/.vscode
+**/*.*proj.user
+**/azds.yaml
+**/charts
+**/bin
+**/obj
+**/Dockerfile
+**/Dockerfile.develop
+**/docker-compose.yml
+**/docker-compose.*.yml
+**/*.dbmdl
+**/*.jfm
+**/secrets.dev.yaml
+**/values.dev.yaml
+**/.toolstarget
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/.gitignore b/.gitignore
index 3e759b7..4ce6fdd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
+*.rsuser
*.suo
*.user
*.userosscache
@@ -19,6 +20,8 @@
[Rr]eleases/
x64/
x86/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
@@ -52,7 +55,6 @@ BenchmarkDotNet.Artifacts/
project.lock.json
project.fragment.lock.json
artifacts/
-**/Properties/launchSettings.json
# StyleCop
StyleCopReport.xml
@@ -60,7 +62,7 @@ StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
-*_i.h
+*_h.h
*.ilk
*.meta
*.obj
@@ -77,6 +79,7 @@ StyleCopReport.xml
*.tlh
*.tmp
*.tmp_proj
+*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
@@ -208,7 +211,7 @@ _pkginfo.txt
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
-!*.[Cc]ache/
+!?*.[Cc]ache/
# Others
ClientBin/
@@ -221,7 +224,7 @@ ClientBin/
*.publishsettings
orleans.codegen.cs
-# Including strong name files can present a security risk
+# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
@@ -252,6 +255,7 @@ ServiceFabricBackup/
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
+*- Backup*.rdl
# Microsoft Fakes
FakesAssemblies/
@@ -291,8 +295,8 @@ paket-files/
.idea/
*.sln.iml
-# CodeRush
-.cr/
+# CodeRush personal settings
+.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
@@ -317,7 +321,7 @@ __pycache__/
# OpenCover UI analysis results
OpenCover/
-# Azure Stream Analytics local run output
+# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
@@ -326,5 +330,11 @@ ASALocalRun/
# NVidia Nsight GPU debugger configuration file
*.nvuser
-# MFractors (Xamarin productivity tool) working folder
+# MFractors (Xamarin productivity tool) working folder
.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
\ No newline at end of file
diff --git a/DomainModel/HealthChecks.Configuration/HealthChecks.Configuration.csproj b/DomainModel/HealthChecks.Configuration/HealthChecks.Configuration.csproj
new file mode 100644
index 0000000..8d5269c
--- /dev/null
+++ b/DomainModel/HealthChecks.Configuration/HealthChecks.Configuration.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp2.2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DomainModel/HealthChecks.Configuration/IdentityConfiguration.cs b/DomainModel/HealthChecks.Configuration/IdentityConfiguration.cs
new file mode 100644
index 0000000..e91c961
--- /dev/null
+++ b/DomainModel/HealthChecks.Configuration/IdentityConfiguration.cs
@@ -0,0 +1,15 @@
+namespace HealthChecks.Configuration
+{
+ ///
+ /// Represents the identity and Access Control Configuration
+ ///
+ public class IdentityConfiguration
+ {
+ public bool Enabled { get; set; }
+ public string ServerUrl { get; set; }
+ public string Audience { get; set; }
+ public bool RequireHttpsMetadata { get; set; }
+
+ public string TransportStorageDirectory { get; set; }
+ }
+}
diff --git a/DomainModel/HealthChecks.Configuration/LocalStackConfiguration.cs b/DomainModel/HealthChecks.Configuration/LocalStackConfiguration.cs
new file mode 100644
index 0000000..4c9d870
--- /dev/null
+++ b/DomainModel/HealthChecks.Configuration/LocalStackConfiguration.cs
@@ -0,0 +1,7 @@
+namespace HealthChecks.Configuration
+{
+ public class LocalStackConfiguration
+ {
+ public string SqsUrl { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DomainModel/HealthChecks.Configuration/Logging/LoggingExtensions.cs b/DomainModel/HealthChecks.Configuration/Logging/LoggingExtensions.cs
new file mode 100644
index 0000000..24219b6
--- /dev/null
+++ b/DomainModel/HealthChecks.Configuration/Logging/LoggingExtensions.cs
@@ -0,0 +1,208 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+
+namespace HealthChecks.Configuration.Logging
+{
+ ///
+ /// Extension methods to log in our standard JSON format
+ ///
+ public static class LoggingExtensions
+ {
+ ///
+ /// Log a message in JSON format
+ ///
+ ///
+ /// Message to log
+ /// Data to log with message
+ /// Log with date/level or raw data
+ public static void LogInformationJson(this ILogger logger, string message, dynamic data = null, bool withMetaData = true)
+ {
+ var formattedMessage = GetFormattedMessage(
+ logger,
+ LogLevel.Information,
+ withMetaData,
+ message,
+ data
+ );
+
+ if(formattedMessage != null)
+ {
+ logger.LogInformation(message = formattedMessage);
+ }
+ }
+
+ ///
+ /// Log a message in JSON format
+ ///
+ ///
+ /// Message to log
+ /// Data to log with message
+ /// Log with date/level or raw data
+ public static void LogDebugJson(this ILogger logger, string message, object data = null, bool withMetaData = true)
+ {
+ var formattedMessage = GetFormattedMessage(
+ logger,
+ LogLevel.Debug,
+ withMetaData,
+ message,
+ data
+ );
+
+ if (formattedMessage != null)
+ {
+ logger.LogDebug(message = formattedMessage);
+ }
+ }
+
+ ///
+ /// Log a message in JSON format
+ ///
+ ///
+ /// Message to log
+ /// Data to log with message
+ /// Log with date/level or raw data
+ public static void LogWarningJson(this ILogger logger, string message, dynamic data = null, bool withMetaData = true)
+ {
+ var formattedMessage = GetFormattedMessage(
+ logger,
+ LogLevel.Warning,
+ withMetaData,
+ message,
+ data
+ );
+
+ if (formattedMessage != null)
+ {
+ logger.LogWarning(message = formattedMessage);
+ }
+ }
+
+ ///
+ /// Log a message in JSON format
+ ///
+ ///
+ /// Message to log
+ /// Data to log with message
+ /// Log with date/level or raw data
+ public static void LogTraceJson(this ILogger logger, string message, dynamic data = null, bool withMetaData = true)
+ {
+ var formattedMessage = GetFormattedMessage(
+ logger,
+ LogLevel.Trace,
+ withMetaData,
+ message,
+ data
+ );
+
+ if (formattedMessage != null)
+ {
+ logger.LogTrace(message = formattedMessage);
+ }
+ }
+
+ ///
+ /// Log a message in JSON format
+ ///
+ ///
+ /// Message to log
+ /// Data to log with message
+ /// Log with date/level or raw data
+ public static void LogCriticalJson(this ILogger logger, string message, dynamic data = null, bool withMetaData = true)
+ {
+ var formattedMessage = GetFormattedMessage(
+ logger,
+ LogLevel.Critical,
+ withMetaData,
+ message,
+ data
+ );
+
+ if (formattedMessage != null)
+ {
+ logger.LogCritical(message = formattedMessage);
+ }
+ }
+
+ ///
+ /// Log a message in JSON format
+ ///
+ ///
+ /// Message to log
+ /// Data to log with message
+ /// Log with date/level or raw data
+ public static void LogErrorJson(this ILogger logger, string message, dynamic data = null, bool withMetaData = true)
+ {
+ var formattedMessage = GetFormattedMessage(
+ logger,
+ LogLevel.Error,
+ withMetaData,
+ message,
+ data
+ );
+
+ if (formattedMessage != null)
+ {
+ logger.LogError(message = formattedMessage);
+ }
+ }
+
+ private static string GetFormattedMessage(
+ ILogger logger,
+ LogLevel level,
+ bool withMetaData,
+ string message,
+ dynamic data = null)
+ {
+ if (withMetaData)
+ {
+ data = new
+ {
+ LongDate = DateTime.Now,
+ LongDateUtc = DateTime.UtcNow,
+ Level = level.ToString(),
+ Message = message,
+ Data = data
+ };
+ }
+ else
+ {
+ data = new
+ {
+ Message = message,
+ Data = data
+ };
+ }
+
+ return SerializeMessage(logger, data);
+ }
+
+ private static string SerializeMessage(ILogger logger, dynamic message)
+ {
+ var serializationErrors = new List();
+
+ var serializedMessage = JsonConvert.SerializeObject(
+ message,
+ new JsonSerializerSettings
+ {
+ ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
+ StringEscapeHandling = StringEscapeHandling.EscapeNonAscii,
+ Error = delegate (object sender, ErrorEventArgs args)
+ {
+ serializationErrors.Add(args.ErrorContext.Error.Message);
+ // Mark the serialization error as handled so it does not throw an exception up the call stack
+ args.ErrorContext.Handled = true;
+ }
+ });
+
+ if (serializationErrors.Count > 0)
+ {
+ logger.LogWarning(JsonConvert.SerializeObject(serializationErrors));
+ }
+
+ return serializedMessage;
+ }
+ }
+}
diff --git a/DomainModel/HealthChecks.ServiceBus/Base/SqsListener.cs b/DomainModel/HealthChecks.ServiceBus/Base/SqsListener.cs
new file mode 100644
index 0000000..080ce79
--- /dev/null
+++ b/DomainModel/HealthChecks.ServiceBus/Base/SqsListener.cs
@@ -0,0 +1,153 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Amazon.SQS;
+using Amazon.SQS.Model;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
+
+namespace HealthChecks.ServiceBus.Base
+{
+ ///
+ /// The SqsListener represents a long-running service in your API which is
+ /// SQS queue aware. It will listen to messages of type T which are routed on the queue
+ /// Remember that this contract is OWNED by the API, and should not be a shared contract between the
+ /// recipient and sender, as this leads to tight-coupling.
+ ///
+ /// The type of class to receive from your queue
+ public abstract class SqsListener : IHostedService, IDisposable where T: class
+ {
+ private readonly string _queueName;
+ protected readonly ILogger> Logger;
+ private readonly IAmazonSQS _sqsClient;
+ private GetQueueUrlResponse _queueDetails;
+
+ public bool Shutdown { get; set; }
+ public bool Started { get; set; }
+
+ public abstract Task HandleMessageAsync(
+ T constructedMessage);
+
+ protected SqsListener(
+ string queueName,
+ IAmazonSQS sqsClient,
+ ILogger> logger)
+ {
+ Logger = logger;
+ _queueName = queueName;
+ _sqsClient = sqsClient;
+ }
+
+ #region Implementation of IHostedService
+
+ public Task StartAsync(CancellationToken cancellationToken)
+ {
+ return Task.Run(StartListeningAsync, cancellationToken);
+ }
+
+ public Task StopAsync(CancellationToken cancellationToken)
+ {
+ Shutdown = true;
+ return Task.CompletedTask;
+ }
+
+ #endregion
+
+ protected void GetQueueDetailsFromAws()
+ {
+ Logger.LogDebug("Getting SQS queue URL...");
+ _queueDetails = _sqsClient.GetQueueUrlAsync(_queueName).Result;
+ Logger.LogDebug($"SQS queue URL retrieved: {_queueDetails.QueueUrl}");
+ }
+
+ public async Task StartListeningAsync()
+ {
+ Logger.LogDebug("Starting SQS listener...");
+
+ GetQueueDetailsFromAws();
+
+ var request = new ReceiveMessageRequest
+ {
+ AttributeNames = new List { "All" },
+ MaxNumberOfMessages = 5,
+ QueueUrl = _queueDetails.QueueUrl,
+ VisibilityTimeout = (int)TimeSpan.FromMinutes(2).TotalSeconds,
+ WaitTimeSeconds = (int)TimeSpan.FromSeconds(20).TotalSeconds
+ };
+
+ Started = true;
+
+ while (!Shutdown)
+ {
+ Logger.LogDebug("Checking for new SQS messages...");
+ var response = _sqsClient.ReceiveMessageAsync(request).Result;
+
+ if (response.Messages.Count > 0)
+ {
+ Logger.LogDebug($"Received {response.Messages.Count} messages from SQS");
+ foreach (var message in response.Messages)
+ {
+ Logger.LogDebug($"Processing message {message.MessageId}");
+ Logger.LogDebug($"Message contents: {message.Body.Replace("{", "{{").Replace("}", "}}")}");
+
+ T constructedMessage;
+ try
+ {
+ Logger.LogDebug($"Deserialising message body...");
+ constructedMessage = JsonConvert.DeserializeObject(message.Body);
+ Logger.LogDebug($"Deserialised message {message.MessageId} successfully.");
+ Logger.LogDebug("Sanity check re-serialised:");
+ Logger.LogDebug(JsonConvert.SerializeObject(constructedMessage).Replace("{", "{{").Replace("}", "}}"));
+ }
+ catch (JsonReaderException ex)
+ {
+ Logger.LogError(ex, "Unknown message type.");
+
+ // Bad message, delete it from the queue.
+ Logger.LogError($"Deleting bad message from queue with ID {message.MessageId}");
+ Logger.LogError("Message body:");
+ Logger.LogError(message.Body);
+ var deleteMessageRequest = new DeleteMessageRequest(_queueDetails.QueueUrl, message.ReceiptHandle);
+ _sqsClient.DeleteMessageAsync(deleteMessageRequest).Wait();
+
+ continue;
+ }
+
+ try
+ {
+ await HandleMessageAsync(constructedMessage);
+ // Message handled, delete it from the queue.
+ var deleteMessageRequest = new DeleteMessageRequest(_queueDetails.QueueUrl, message.ReceiptHandle);
+ await _sqsClient.DeleteMessageAsync(deleteMessageRequest);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogDebug($"Processing of message failed. Release message {message.MessageId} back to queue.");
+ Logger.LogDebug($"Error was: {ex.Message}");
+ Logger.LogDebug(ex.StackTrace);
+
+ var changeMessageRequest = new ChangeMessageVisibilityRequest(_queueDetails.QueueUrl, message.ReceiptHandle, 0);
+ await _sqsClient.ChangeMessageVisibilityAsync(changeMessageRequest);
+ }
+ }
+ }
+ else
+ {
+ Logger.LogDebug("No sqs messages received.");
+ }
+ }
+
+ Logger.LogDebug("Shutting down");
+ Started = false;
+
+ await Task.CompletedTask;
+ }
+
+ public void Dispose()
+ {
+ _sqsClient?.Dispose();
+ }
+ }
+}
diff --git a/DomainModel/HealthChecks.ServiceBus/Base/SqsSender.cs b/DomainModel/HealthChecks.ServiceBus/Base/SqsSender.cs
new file mode 100644
index 0000000..9786572
--- /dev/null
+++ b/DomainModel/HealthChecks.ServiceBus/Base/SqsSender.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Threading.Tasks;
+using Amazon.SQS;
+using Amazon.SQS.Model;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
+
+namespace HealthChecks.ServiceBus.Base
+{
+ ///
+ /// A sender of messages to an SQS queue of type T.
+ ///
+ /// The type of class to send to your queue
+ public abstract class SqsSender
+ where T : class
+ {
+ private readonly string _queueName;
+ private readonly ILogger> _logger;
+ private readonly IAmazonSQS _sqsClient;
+ private GetQueueUrlResponse _queueDetails;
+
+ protected SqsSender(
+ string queueName,
+ IAmazonSQS amazonSqs,
+ ILogger> logger)
+ {
+ _queueName = queueName;
+ _sqsClient = amazonSqs;
+ _logger = logger;
+ GetQueueDetailsFromAwsAsync().Wait();
+ }
+
+ protected async Task GetQueueDetailsFromAwsAsync()
+ {
+ try {
+ _logger.LogDebug("Getting SQS queue URL...");
+ _queueDetails = await _sqsClient.GetQueueUrlAsync(_queueName);
+ _logger.LogDebug($"SQS queue URL retrieved: {_queueDetails.QueueUrl}");
+ } catch(Exception ex)
+ {
+ throw ex;
+ }
+ }
+
+
+ public async Task Send(T message)
+ {
+ var messageBody = JsonConvert.SerializeObject(message);
+ _logger.LogDebug($"Sending SQS message: {messageBody} on queue {_queueDetails.QueueUrl}");
+ var sendMessageRequest = new SendMessageRequest
+ {
+ MessageBody = messageBody,
+ QueueUrl = _queueDetails.QueueUrl
+ };
+
+ await _sqsClient.SendMessageAsync(sendMessageRequest);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DomainModel/HealthChecks.ServiceBus/HealthChecks.ServiceBus.csproj b/DomainModel/HealthChecks.ServiceBus/HealthChecks.ServiceBus.csproj
new file mode 100644
index 0000000..b58dab5
--- /dev/null
+++ b/DomainModel/HealthChecks.ServiceBus/HealthChecks.ServiceBus.csproj
@@ -0,0 +1,14 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
diff --git a/HealthChecks.SomeModelService/AppServices/SomeModel/ISomeModelApplicationService.cs b/HealthChecks.SomeModelService/AppServices/SomeModel/ISomeModelApplicationService.cs
new file mode 100644
index 0000000..40c7c16
--- /dev/null
+++ b/HealthChecks.SomeModelService/AppServices/SomeModel/ISomeModelApplicationService.cs
@@ -0,0 +1,21 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using HealthChecks.SomeModelService.Contracts.Models.SomeModel;
+
+namespace HealthChecks.SomeModelService.AppServices.SomeModel
+{
+ public interface ISomeModelApplicationService
+ {
+ Task CreateAsync(SomeModelContract model);
+
+ Task UpdateAsync(
+ SomeModelContract model);
+
+ Task GetAsync(long id);
+
+ Task> ListAllAsync();
+
+ Task DeleteAsync(long id);
+
+ }
+}
\ No newline at end of file
diff --git a/HealthChecks.SomeModelService/AppServices/SomeModel/SomeModelApplicationService.cs b/HealthChecks.SomeModelService/AppServices/SomeModel/SomeModelApplicationService.cs
new file mode 100644
index 0000000..a1fcd2f
--- /dev/null
+++ b/HealthChecks.SomeModelService/AppServices/SomeModel/SomeModelApplicationService.cs
@@ -0,0 +1,100 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using HealthChecks.SomeModelService.Contracts.Models.SomeModel;
+using HealthChecks.SomeModelService.Repositories.SomeModel;
+using Microsoft.Extensions.Logging;
+using Nelibur.ObjectMapper;
+using Newtonsoft.Json;
+using SomeModelModel = HealthChecks.SomeModelService.Models.SomeModel.SomeModel;
+
+namespace HealthChecks.SomeModelService.AppServices.SomeModel
+{
+ public class SomeModelApplicationService : ISomeModelApplicationService
+ {
+ private readonly ILogger _logger;
+
+ private readonly ISomeModelRepository _somemodelRepository;
+
+
+ public SomeModelApplicationService(
+ ILogger logger,
+ ISomeModelRepository somemodelRepository)
+ {
+ _logger = logger;
+ _somemodelRepository = somemodelRepository;
+ }
+
+ public async Task CreateAsync(SomeModelContract model)
+ {
+ var mappedData = CastToDomainModel(model);
+ var returnedData = await _somemodelRepository.CreateAsync(mappedData);
+ return CastToContract(returnedData);
+ }
+
+ public async Task UpdateAsync(
+ SomeModelContract model)
+ {
+ _logger.LogTrace(
+ $"Updating a SomeModel with Id {model.Id} based on the command data sent: " +
+ $"{JsonConvert.SerializeObject(model)}");
+
+ var storedModel = _somemodelRepository.GetAsync(model.Id);
+ if (storedModel == null)
+ {
+ _logger.LogWarning($"No such SomeModel model with Id {model.Id} found. Doing nothing.");
+ return model;
+ }
+
+ var result = await _somemodelRepository.UpdateAsync(CastToDomainModel(model));
+
+ return CastToContract(result);
+ }
+
+ public async Task GetAsync(long id)
+ {
+ _logger.LogDebug($"Retrieving SomeModel with Id of {id}");
+ var somemodelFound = await _somemodelRepository.GetAsync(id);
+ if(somemodelFound != null)
+ {
+ _logger.LogDebug($"No SomeModel with Id of {id} found. Returning null");
+ }
+
+ return CastToContract(somemodelFound);
+ }
+
+ public async Task> ListAllAsync()
+ {
+ var results = await _somemodelRepository.ListAllAsync();
+ return await Task.FromResult(CastAllToContracts(results));
+ }
+
+ public async Task DeleteAsync(long id)
+ {
+ _logger.LogDebug($"Deleting SomeModel with Id of {id}");
+ await _somemodelRepository.DeleteAsync(id);
+ }
+
+ public static IEnumerable CastAllToContracts(
+ IEnumerable models)
+ {
+ return models.Select(CastToContract).ToList();
+ }
+
+ public static SomeModelContract CastToContract(
+ SomeModelModel model)
+ {
+ TinyMapper.Bind();
+ TinyMapper.Bind();
+ return TinyMapper.Map(model);
+ }
+
+ public static SomeModelModel CastToDomainModel(
+ SomeModelContract model)
+ {
+ TinyMapper.Bind();
+ TinyMapper.Bind();
+ return TinyMapper.Map(model);
+ }
+ }
+}
\ No newline at end of file
diff --git a/HealthChecks.SomeModelService/Contracts/Models/SomeModel/SomeModelContract.cs b/HealthChecks.SomeModelService/Contracts/Models/SomeModel/SomeModelContract.cs
new file mode 100644
index 0000000..8c34cff
--- /dev/null
+++ b/HealthChecks.SomeModelService/Contracts/Models/SomeModel/SomeModelContract.cs
@@ -0,0 +1,10 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace HealthChecks.SomeModelService.Contracts.Models.SomeModel
+{
+ public class SomeModelContract
+ {
+ [Required]
+ public long Id { get; set; }
+ }
+}
diff --git a/HealthChecks.SomeModelService/Controllers/SomeModelController.cs b/HealthChecks.SomeModelService/Controllers/SomeModelController.cs
new file mode 100644
index 0000000..0d68ec6
--- /dev/null
+++ b/HealthChecks.SomeModelService/Controllers/SomeModelController.cs
@@ -0,0 +1,100 @@
+using System.Threading.Tasks;
+using HealthChecks.Configuration.Logging;
+using HealthChecks.SomeModelService.AppServices.SomeModel;
+using HealthChecks.SomeModelService.Contracts.Models.SomeModel;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace HealthChecks.SomeModelService.Controllers
+{
+ [Route("somemodels")]
+ [ApiController]
+ public class SomeModelController : ControllerBase
+ {
+ private readonly ISomeModelApplicationService _somemodelApplicationService;
+
+ private readonly ILogger _logger;
+
+ public SomeModelController(
+ ISomeModelApplicationService somemodelApplicationService,
+ ILogger logger)
+ {
+ _somemodelApplicationService = somemodelApplicationService;
+ _logger = logger;
+ }
+
+
+ [HttpPost]
+ public async Task CreateAsync(SomeModelContract model)
+ {
+ _logger.LogTraceJson("Starting SomeModel create", model);
+ if (!ModelState.IsValid)
+ {
+ _logger.LogErrorJson(
+ "SomeModel model is not valid",
+ model);
+
+ return BadRequest(ModelState);
+ }
+
+ var newSomeModel = await _somemodelApplicationService.CreateAsync(model);
+ _logger.LogTraceJson("Completing SomeModel create");
+ return Ok(newSomeModel);
+ }
+
+ [HttpGet]
+ public async Task ListAllAsync()
+ {
+ _logger.LogTraceJson("ListAll SomeModels");
+ var SomeModels = await _somemodelApplicationService.ListAllAsync();
+ _logger.LogTraceJson("Completing ListAll SomeModels", SomeModels);
+ return Ok(SomeModels);
+ }
+
+ [HttpGet]
+ [Route("{id}")]
+ public async Task GetAsync([FromRoute]long id)
+ {
+ _logger.LogTraceJson($"Starting Get SomeModel: {id}");
+ var SomeModel = await _somemodelApplicationService.GetAsync(id);
+
+ if (SomeModel == null)
+ {
+ _logger.LogTraceJson($"SomeModel not found: {id}");
+ return NotFound();
+ }
+ _logger.LogTraceJson($"Completing Get SomeModel: {id}");
+ return Ok(SomeModel);
+ }
+
+
+ [HttpPut]
+ public async Task UpdateAsync(
+ [FromBody] SomeModelContract model)
+ {
+ _logger.LogTraceJson("Starting SomeModel update", model);
+ if (!ModelState.IsValid)
+ {
+ _logger.LogErrorJson(
+ "SomeModel model is not valid",
+ model);
+
+ return BadRequest(ModelState);
+ }
+
+ var updatedSomeModel = await _somemodelApplicationService.UpdateAsync(model);
+ _logger.LogTraceJson("Completing SomeModel update");
+ return Ok(updatedSomeModel);
+ }
+
+ [HttpDelete]
+ [Route("{id}")]
+ public async Task DeleteAsync(long id)
+ {
+ _logger.LogTraceJson($"Starting deletion of SomeModel: {id}");
+ await _somemodelApplicationService.DeleteAsync(id);
+ _logger.LogTraceJson($"Completing deletion of SomeModel: {id}");
+ return Ok();
+ }
+ }
+}
\ No newline at end of file
diff --git a/HealthChecks.SomeModelService/DependencyModule.cs b/HealthChecks.SomeModelService/DependencyModule.cs
new file mode 100644
index 0000000..3d14393
--- /dev/null
+++ b/HealthChecks.SomeModelService/DependencyModule.cs
@@ -0,0 +1,16 @@
+using Autofac;
+using HealthChecks.SomeModelService.AppServices.SomeModel;
+using HealthChecks.SomeModelService.Repositories.SomeModel;
+
+namespace HealthChecks.SomeModelService
+{
+ public class DependencyModule : Module
+ {
+ protected override void Load(ContainerBuilder builder)
+ {
+ builder.RegisterType().As();
+ builder.RegisterType().As();
+
+ }
+ }
+}
diff --git a/HealthChecks.SomeModelService/Dockerfile b/HealthChecks.SomeModelService/Dockerfile
new file mode 100644
index 0000000..d6a034c
--- /dev/null
+++ b/HealthChecks.SomeModelService/Dockerfile
@@ -0,0 +1,19 @@
+FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
+WORKDIR /app
+EXPOSE 54411
+
+FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
+WORKDIR /src
+COPY ["HealthChecks.SomeModelService/HealthChecks.SomeModelService.csproj", "HealthChecks.SomeModelService/"]
+RUN dotnet restore "HealthChecks.SomeModelService/HealthChecks.SomeModelService.csproj"
+COPY . .
+WORKDIR "/src/HealthChecks.SomeModelService"
+RUN dotnet build "HealthChecks.SomeModelService.csproj" -c Release -o /app
+
+FROM build AS publish
+RUN dotnet publish "HealthChecks.SomeModelService.csproj" -c Release -o /app
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app .
+ENTRYPOINT ["dotnet", "HealthChecks.SomeModelService.dll"]
diff --git a/HealthChecks.SomeModelService/Health/ApiHealthCheck.cs b/HealthChecks.SomeModelService/Health/ApiHealthCheck.cs
new file mode 100644
index 0000000..b6eb77f
--- /dev/null
+++ b/HealthChecks.SomeModelService/Health/ApiHealthCheck.cs
@@ -0,0 +1,23 @@
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Diagnostics.HealthChecks;
+
+namespace HealthChecks.SomeModelService.Health
+{
+ public class ApiHealthCheck : IHealthCheck
+ {
+ public Task CheckHealthAsync(
+ HealthCheckContext context,
+ CancellationToken cancellationToken = new CancellationToken())
+ {
+ //TODO: Implement your own healthcheck logic here
+ var isHealthy = true;
+ if(isHealthy)
+ {
+ return Task.FromResult(HealthCheckResult.Healthy("healthy"));
+ }
+
+ return Task.FromResult(HealthCheckResult.Unhealthy("unhealthy"));
+ }
+ }
+}
\ No newline at end of file
diff --git a/HealthChecks.SomeModelService/HealthChecks.SomeModelService.csproj b/HealthChecks.SomeModelService/HealthChecks.SomeModelService.csproj
new file mode 100644
index 0000000..82e1a33
--- /dev/null
+++ b/HealthChecks.SomeModelService/HealthChecks.SomeModelService.csproj
@@ -0,0 +1,46 @@
+
+
+
+ netcoreapp2.2
+ InProcess
+ Linux
+ ..\docker-compose.dcproj
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+
diff --git a/HealthChecks.SomeModelService/Models/SomeModel/ISomeModel.cs b/HealthChecks.SomeModelService/Models/SomeModel/ISomeModel.cs
new file mode 100644
index 0000000..66aab5b
--- /dev/null
+++ b/HealthChecks.SomeModelService/Models/SomeModel/ISomeModel.cs
@@ -0,0 +1,7 @@
+namespace HealthChecks.SomeModelService.Models.SomeModel
+{
+ public interface ISomeModel
+ {
+ long Id { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/HealthChecks.SomeModelService/Models/SomeModel/SomeModel.cs b/HealthChecks.SomeModelService/Models/SomeModel/SomeModel.cs
new file mode 100644
index 0000000..dbea1e3
--- /dev/null
+++ b/HealthChecks.SomeModelService/Models/SomeModel/SomeModel.cs
@@ -0,0 +1,7 @@
+namespace HealthChecks.SomeModelService.Models.SomeModel
+{
+ public class SomeModel : ISomeModel
+ {
+ public long Id { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/HealthChecks.SomeModelService/NLog.Release.config b/HealthChecks.SomeModelService/NLog.Release.config
new file mode 100644
index 0000000..df7ec2e
--- /dev/null
+++ b/HealthChecks.SomeModelService/NLog.Release.config
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+ #{if Log.File.Enable}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{/if}
+
+ #{if Log.EventLog.Enable}
+
+
+ #{/if}
+
+
+
+
+
+ #{if Log.File.Enable}
+
+
+
+
+
+
+ #{/if}
+
+ #{if Log.EventLog.Enable}
+
+ #{/if}
+
+
\ No newline at end of file
diff --git a/HealthChecks.SomeModelService/NLog.config b/HealthChecks.SomeModelService/NLog.config
new file mode 100644
index 0000000..f0956fe
--- /dev/null
+++ b/HealthChecks.SomeModelService/NLog.config
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HealthChecks.SomeModelService/Program.cs b/HealthChecks.SomeModelService/Program.cs
new file mode 100644
index 0000000..db0457e
--- /dev/null
+++ b/HealthChecks.SomeModelService/Program.cs
@@ -0,0 +1,61 @@
+using System;
+using System.IO;
+using Autofac.Extensions.DependencyInjection;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using NLog.Web;
+
+namespace HealthChecks.SomeModelService
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ var logger = NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger();
+ try
+ {
+ logger.Debug("inititalising Microservice.Restful");
+ var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
+
+ var host = new WebHostBuilder()
+ .UseKestrel()
+ .ConfigureServices(services => services.AddAutofac())
+ .UseContentRoot(Directory.GetCurrentDirectory())
+ .UseIISIntegration()
+ .ConfigureAppConfiguration((hostingContext, config) =>
+ {
+ config.SetBasePath(Directory.GetCurrentDirectory());
+ config.AddJsonFile("appsettings.json",true,reloadOnChange: true);
+ config.AddJsonFile($"appsettings.{environmentName}.json",optional: true, reloadOnChange:true);
+ })
+ .ConfigureLogging((hostingContext, logging) =>
+ {
+ logging.ClearProviders();
+ logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
+ logging.AddConsole();
+ logging.AddDebug();
+ logging.SetMinimumLevel(LogLevel.Trace);
+ })
+ .UseNLog()
+ .UseStartup()
+ .Build();
+
+ host.Run();
+ }
+ catch (Exception ex)
+ {
+ //NLog: catch setup errors
+ logger.Error(ex, "Stopped program because of exception");
+ throw;
+ }
+ finally
+ {
+ // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
+ NLog.LogManager.Shutdown();
+ }
+
+ }
+
+ }
+}
diff --git a/HealthChecks.SomeModelService/Properties/launchSettings.json b/HealthChecks.SomeModelService/Properties/launchSettings.json
new file mode 100644
index 0000000..a3fadd4
--- /dev/null
+++ b/HealthChecks.SomeModelService/Properties/launchSettings.json
@@ -0,0 +1,35 @@
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:50939",
+ "sslPort": 0
+ }
+ },
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "SomeModels",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "HealthChecks.ExampleCrud.Api": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "SomeModels",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "http://localhost:5000"
+ },
+ "Docker": {
+ "commandName": "Docker",
+ "launchBrowser": true,
+ "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/SomeModels"
+ }
+ }
+}
\ No newline at end of file
diff --git a/HealthChecks.SomeModelService/Repositories/SomeModel/ISomeModelRepository.cs b/HealthChecks.SomeModelService/Repositories/SomeModel/ISomeModelRepository.cs
new file mode 100644
index 0000000..121a0ff
--- /dev/null
+++ b/HealthChecks.SomeModelService/Repositories/SomeModel/ISomeModelRepository.cs
@@ -0,0 +1,21 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using SomeModelModel = HealthChecks.SomeModelService.Models.SomeModel.SomeModel;
+
+namespace HealthChecks.SomeModelService.Repositories.SomeModel
+{
+ public interface ISomeModelRepository
+ {
+ Task CreateAsync(SomeModelModel model);
+
+ Task UpdateAsync(
+ SomeModelModel model);
+
+ Task GetAsync(long id);
+
+ Task> ListAllAsync();
+
+ Task DeleteAsync(long id);
+
+ }
+}
\ No newline at end of file
diff --git a/HealthChecks.SomeModelService/Repositories/SomeModel/SomeModelRepository.cs b/HealthChecks.SomeModelService/Repositories/SomeModel/SomeModelRepository.cs
new file mode 100644
index 0000000..c162f0a
--- /dev/null
+++ b/HealthChecks.SomeModelService/Repositories/SomeModel/SomeModelRepository.cs
@@ -0,0 +1,90 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
+using SomeModelModel = HealthChecks.SomeModelService.Models.SomeModel.SomeModel;
+
+namespace HealthChecks.SomeModelService.Repositories.SomeModel
+{
+ public class SomeModelRepository : ISomeModelRepository
+ {
+ private static readonly List SomeModels = new List();
+
+ private readonly ILogger _logger;
+
+ public SomeModelRepository(
+ ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ public async Task CreateAsync(SomeModelModel model)
+ {
+
+ var nextId = SomeModels.Count + 1;
+ model.Id = nextId;
+ _logger.LogTrace(
+ $"Creating an SomeModel with Id {nextId} based on the command data sent: " +
+ $"{JsonConvert.SerializeObject(model)}");
+ SomeModels.Add(model);
+
+ return model;
+ }
+
+ public async Task UpdateAsync(
+ SomeModelModel model)
+ {
+ _logger.LogTrace(
+ $"Updating a SomeModel with Id {model.Id} based on the command data sent: " +
+ $"{JsonConvert.SerializeObject(model)}");
+
+ var storedModel = SomeModels.Find(g => g.Id.Equals(model.Id));
+ if (storedModel == null)
+ {
+ _logger.LogWarning($"No such SomeModel model with Id {model.Id} found. Doing nothing.");
+ return model;
+ }
+
+ SomeModels.Remove(storedModel);
+
+ SomeModels.Add(model);
+
+ return model;
+ }
+
+ public async Task GetAsync(long id)
+ {
+ _logger.LogDebug($"Retrieving SomeModel with Id of {id}");
+ var model = SomeModels.FirstOrDefault(i => i.Id.Equals(id));
+
+ if (model != null)
+ {
+ return model;
+ }
+ _logger.LogDebug($"No SomeModel with Id of {id} found. Returning null");
+ return null;
+ }
+
+ public async Task> ListAllAsync()
+ {
+ return SomeModels.AsEnumerable();
+ }
+
+ public async Task DeleteAsync(long id)
+ {
+ _logger.LogDebug($"Deleting SomeModel with Id of {id}");
+ var modelFound = SomeModels.Find(g => g.Id.Equals(id));
+ if (modelFound != null)
+ {
+ SomeModels.Remove(modelFound);
+ _logger.LogDebug($"SomeModel with Id of {id} Deleted");
+ }
+ else
+ {
+ _logger.LogDebug($"No SomeModel with Id of {id} found to delete. Returning");
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/HealthChecks.SomeModelService/Startup.cs b/HealthChecks.SomeModelService/Startup.cs
new file mode 100644
index 0000000..486e12c
--- /dev/null
+++ b/HealthChecks.SomeModelService/Startup.cs
@@ -0,0 +1,118 @@
+using Autofac;
+using HealthChecks.Configuration;
+using HealthChecks.SomeModelService.Health;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Diagnostics.HealthChecks;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using IHostingEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment;
+
+namespace HealthChecks.SomeModelService
+{
+ public class Startup
+ {
+ public IConfiguration Configuration { get; }
+
+ public Startup(IConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ ///
+ /// Set up any services and other general configuration here
+ ///
+ ///
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddCors();
+ services.AddHealthChecks()
+ .AddCheck("api");
+ //add additional healthchecks here, as needed
+ //as described here https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks
+
+
+ //Api Base Configuration
+ services.AddMvcCore()
+ .AddAuthorization()
+ .AddJsonFormatters();
+
+ //add the overall configuration to the IoC
+ services.AddSingleton(Configuration);
+
+ //add our specific configurations to the IoC
+ var identityConfiguration = new IdentityConfiguration();
+ Configuration.GetSection("Identity").Bind(identityConfiguration);
+ services.AddSingleton(identityConfiguration);
+
+ if (identityConfiguration.Enabled)
+ {
+ services
+ .AddAuthentication("Bearer")
+ .AddJwtBearer(
+ "Bearer",
+ options =>
+ {
+ options.Authority = identityConfiguration.ServerUrl;
+ options.RequireHttpsMetadata = identityConfiguration.RequireHttpsMetadata;
+ options.Audience = identityConfiguration.Audience;
+ });
+ }
+
+ var awsOptions = Configuration.GetAWSOptions();
+ services.AddDefaultAWSOptions(awsOptions);
+ ConfigureAwsServices(services);
+ }
+
+ private void ConfigureAwsServices(
+ IServiceCollection services)
+ {
+ var localStackConfiguration = new LocalStackConfiguration();
+ Configuration.GetSection("LocalStack").Bind(localStackConfiguration);
+
+ //SQS
+ var awsSqsOptions = Configuration.GetAWSOptions();
+ //if (localStackConfiguration.SqsUrl != null)
+ //{
+ // awsSqsOptions.DefaultClientConfig.ServiceURL = localStackConfiguration.SqsUrl;
+ //}
+ }
+
+
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime applicationLifetime)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+
+ app.UseCors(builder =>
+ builder
+ .AllowAnyOrigin()
+ .AllowAnyHeader()
+ .AllowAnyMethod()
+ );
+
+ app.UseHealthChecks("/health", new HealthCheckOptions()
+ {
+ Predicate = _ => true
+ });
+
+ //Use Identity and Access Control
+ app.UseAuthentication();
+
+ //Use MVC / API
+ app.UseMvc();
+ }
+
+ ///
+ /// Used to configure your container as needed.
+ ///
+ ///
+ public void ConfigureContainer(ContainerBuilder builder)
+ {
+ builder.RegisterModule(new DependencyModule());
+ }
+ }
+}
diff --git a/HealthChecks.SomeModelService/appsettings.Development.json b/HealthChecks.SomeModelService/appsettings.Development.json
new file mode 100644
index 0000000..0c5f7d6
--- /dev/null
+++ b/HealthChecks.SomeModelService/appsettings.Development.json
@@ -0,0 +1,23 @@
+{
+ "AWS": {
+ "Profile": "default",
+ "Region": "us-west-2",
+ "ProfileLocation": "/root/.aws"
+ },
+ "LocalStack": {
+ "SqsUrl": "http://localstack:4576"
+ },
+ "Identity": {
+ "Enabled": false,
+ "ServerUrl": "http://localhost:5000",
+ "RequireHttpsMetadata": false,
+ "Audience": "Api1"
+ },
+ "Logging": {
+ "LogLevel": {
+ "Default": "Debug",
+ "System": "Information",
+ "Microsoft": "Information"
+ }
+ }
+}
diff --git a/HealthChecks.SomeModelService/appsettings.json b/HealthChecks.SomeModelService/appsettings.json
new file mode 100644
index 0000000..1a0acdb
--- /dev/null
+++ b/HealthChecks.SomeModelService/appsettings.json
@@ -0,0 +1,16 @@
+{
+ "Identity": {
+ "Enabled": false,
+ "ServerUrl": "http://localhost:5000",
+ "RequireHttpsMetadata": false,
+ "Audience": "Api1"
+ },
+
+ "Logging": {
+ "LogLevel": {
+ "Default": "Trace"
+ }
+ },
+
+ "AllowedHosts": "*"
+}
diff --git a/HealthChecks.sln b/HealthChecks.sln
new file mode 100644
index 0000000..e2668ff
--- /dev/null
+++ b/HealthChecks.sln
@@ -0,0 +1,49 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29020.237
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tooling", "Tooling", "{A205C45D-DE59-4833-A3C0-81414F1D9E76}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.Configuration", "DomainModel\HealthChecks.Configuration\HealthChecks.Configuration.csproj", "{3D99E2E2-8501-4A95-9A6A-054DB3B3DD29}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.ServiceBus", "DomainModel\HealthChecks.ServiceBus\HealthChecks.ServiceBus.csproj", "{95953674-DAE8-4DD0-8DE2-3FDF3A8FD590}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.SomeModelService", "HealthChecks.SomeModelService\HealthChecks.SomeModelService.csproj", "{7050B3EB-FBAC-4BD2-9526-44859073F32E}"
+EndProject
+Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{5C57D5E1-F715-47CA-827E-A92DF9880E41}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3D99E2E2-8501-4A95-9A6A-054DB3B3DD29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3D99E2E2-8501-4A95-9A6A-054DB3B3DD29}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3D99E2E2-8501-4A95-9A6A-054DB3B3DD29}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3D99E2E2-8501-4A95-9A6A-054DB3B3DD29}.Release|Any CPU.Build.0 = Release|Any CPU
+ {95953674-DAE8-4DD0-8DE2-3FDF3A8FD590}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {95953674-DAE8-4DD0-8DE2-3FDF3A8FD590}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {95953674-DAE8-4DD0-8DE2-3FDF3A8FD590}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {95953674-DAE8-4DD0-8DE2-3FDF3A8FD590}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7050B3EB-FBAC-4BD2-9526-44859073F32E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7050B3EB-FBAC-4BD2-9526-44859073F32E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7050B3EB-FBAC-4BD2-9526-44859073F32E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7050B3EB-FBAC-4BD2-9526-44859073F32E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5C57D5E1-F715-47CA-827E-A92DF9880E41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5C57D5E1-F715-47CA-827E-A92DF9880E41}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5C57D5E1-F715-47CA-827E-A92DF9880E41}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5C57D5E1-F715-47CA-827E-A92DF9880E41}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {3D99E2E2-8501-4A95-9A6A-054DB3B3DD29} = {A205C45D-DE59-4833-A3C0-81414F1D9E76}
+ {95953674-DAE8-4DD0-8DE2-3FDF3A8FD590} = {A205C45D-DE59-4833-A3C0-81414F1D9E76}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {068E1943-FABE-4C1B-A4E9-CE3050BE7BF0}
+ EndGlobalSection
+EndGlobal
diff --git a/Tests/HealthChecks.ComponentTests/ComponentTest.cs b/Tests/HealthChecks.ComponentTests/ComponentTest.cs
new file mode 100644
index 0000000..84ffa11
--- /dev/null
+++ b/Tests/HealthChecks.ComponentTests/ComponentTest.cs
@@ -0,0 +1,18 @@
+using NUnit.Framework;
+
+namespace HealthChecks.ExampleCrud.ComponentTests
+{
+ public class ComponentTest
+ {
+ [SetUp]
+ public void Setup()
+ {
+ }
+
+ [Test]
+ public void Test1()
+ {
+ Assert.Pass();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Tests/HealthChecks.ComponentTests/HealthChecks.ComponentTests.csproj b/Tests/HealthChecks.ComponentTests/HealthChecks.ComponentTests.csproj
new file mode 100644
index 0000000..ba1718d
--- /dev/null
+++ b/Tests/HealthChecks.ComponentTests/HealthChecks.ComponentTests.csproj
@@ -0,0 +1,17 @@
+
+
+
+ netcoreapp2.2
+
+ false
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/HealthChecks.IntegrationTests/HealthChecks.IntegrationTests.csproj b/Tests/HealthChecks.IntegrationTests/HealthChecks.IntegrationTests.csproj
new file mode 100644
index 0000000..ba1718d
--- /dev/null
+++ b/Tests/HealthChecks.IntegrationTests/HealthChecks.IntegrationTests.csproj
@@ -0,0 +1,17 @@
+
+
+
+ netcoreapp2.2
+
+ false
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/HealthChecks.Tests/ApplicationServices/create-all-appservice-tests.cmd b/Tests/HealthChecks.Tests/ApplicationServices/create-all-appservice-tests.cmd
new file mode 100644
index 0000000..c215652
--- /dev/null
+++ b/Tests/HealthChecks.Tests/ApplicationServices/create-all-appservice-tests.cmd
@@ -0,0 +1 @@
+dotnet new ptml-appserv-tests --model SomeModel --name SomeModel --base-namespace HealthChecks.ExampleCrud --force
\ No newline at end of file
diff --git a/Tests/HealthChecks.Tests/Controllers/create-all-controller-tests.cmd b/Tests/HealthChecks.Tests/Controllers/create-all-controller-tests.cmd
new file mode 100644
index 0000000..32384a3
--- /dev/null
+++ b/Tests/HealthChecks.Tests/Controllers/create-all-controller-tests.cmd
@@ -0,0 +1 @@
+dotnet new ptml-controller-tests --model SomeModel --name SomeModel --base-namespace HealthChecks.ExampleCrud --force
\ No newline at end of file
diff --git a/Tests/HealthChecks.Tests/HealthChecks.Tests.csproj b/Tests/HealthChecks.Tests/HealthChecks.Tests.csproj
new file mode 100644
index 0000000..09e93f5
--- /dev/null
+++ b/Tests/HealthChecks.Tests/HealthChecks.Tests.csproj
@@ -0,0 +1,19 @@
+
+
+
+ netcoreapp2.2
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/HealthChecks.Tests/Repositories/create-all-repo-tests.cmd b/Tests/HealthChecks.Tests/Repositories/create-all-repo-tests.cmd
new file mode 100644
index 0000000..117d29d
--- /dev/null
+++ b/Tests/HealthChecks.Tests/Repositories/create-all-repo-tests.cmd
@@ -0,0 +1 @@
+dotnet new ptml-repo-tests --model SomeModel --name SomeModel --base-namespace HealthChecks.ExampleCrud --force
\ No newline at end of file
diff --git a/create-my-apis.cmd b/create-my-apis.cmd
new file mode 100644
index 0000000..553a8c9
--- /dev/null
+++ b/create-my-apis.cmd
@@ -0,0 +1,5 @@
+dotnet new ptml-micro-ddd --model-name SomeModel --name HealthChecks.ExampleCrud.SomeModelService --base-namespace HealthChecks.ExampleCrud --force
+
+dotnet sln ./HealthChecks.ExampleCrud.sln add ./HealthChecks.ExampleCrud.SomeModelService/HealthChecks.ExampleCrud.SomeModelService.csproj
+
+dotnet add ./Tests/HealthChecks.ExampleCrud.Tests/HealthChecks.ExampleCrud.Tests.csproj reference ./HealthChecks.ExampleCrud.SomeModelService/HealthChecks.ExampleCrud.SomeModelService.csproj
\ No newline at end of file
diff --git a/docker-compose.dcproj b/docker-compose.dcproj
new file mode 100644
index 0000000..7b0379c
--- /dev/null
+++ b/docker-compose.dcproj
@@ -0,0 +1,18 @@
+
+
+
+ 2.1
+ Linux
+ 5c57d5e1-f715-47ca-827e-a92df9880e41
+ LaunchBrowser
+ {Scheme}://localhost:{ServicePort}/SomeModels
+ healthchecks.somemodelservice
+
+
+
+ docker-compose.yml
+
+
+
+
+
\ No newline at end of file
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
new file mode 100644
index 0000000..70c7dfe
--- /dev/null
+++ b/docker-compose.override.yml
@@ -0,0 +1,7 @@
+version: '3.4'
+services:
+ healthchecks.somemodelservice:
+ environment:
+ - ASPNETCORE_ENVIRONMENT=Development
+ ports:
+ - 54411:80
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..d8e1802
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,8 @@
+version: '3.4'
+
+services:
+ healthchecks.somemodelservice:
+ image: ${DOCKER_REGISTRY-}healthcheckssomemodelservice
+ build:
+ context: .
+ dockerfile: HealthChecks.SomeModelService/Dockerfile
\ No newline at end of file