diff --git a/src/LittleBlocks.sln b/src/LittleBlocks.sln index 3c9d8ba..94e751b 100644 --- a/src/LittleBlocks.sln +++ b/src/LittleBlocks.sln @@ -82,6 +82,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extras", "Extras", "{B2C58A ..\GitVersion.yml = ..\GitVersion.yml EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LittleBlocks.Sample.Minimal.WebAPI", "Samples\LittleBlocks.Sample.MinimalApi..WebAPI\LittleBlocks.Sample.Minimal.WebAPI.csproj", "{22C0106F-3EFC-46E4-863C-4861F794F917}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -216,6 +218,10 @@ Global {0A9E6275-2F18-43DC-86DC-C3F3F37FB177}.Debug|Any CPU.Build.0 = Debug|Any CPU {0A9E6275-2F18-43DC-86DC-C3F3F37FB177}.Release|Any CPU.ActiveCfg = Release|Any CPU {0A9E6275-2F18-43DC-86DC-C3F3F37FB177}.Release|Any CPU.Build.0 = Release|Any CPU + {22C0106F-3EFC-46E4-863C-4861F794F917}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {22C0106F-3EFC-46E4-863C-4861F794F917}.Debug|Any CPU.Build.0 = Debug|Any CPU + {22C0106F-3EFC-46E4-863C-4861F794F917}.Release|Any CPU.ActiveCfg = Release|Any CPU + {22C0106F-3EFC-46E4-863C-4861F794F917}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -255,6 +261,7 @@ Global {74F7FFB2-57CB-4217-976A-B0916B20AD05} = {C6B49B11-8BC9-4A68-9238-85BECC4BDF97} {15A17D77-C9BE-4ADE-A42A-0DB5C88D4A0C} = {C6B49B11-8BC9-4A68-9238-85BECC4BDF97} {0A9E6275-2F18-43DC-86DC-C3F3F37FB177} = {709EFF89-FE7B-4818-B435-856741E1C21B} + {22C0106F-3EFC-46E4-863C-4861F794F917} = {709EFF89-FE7B-4818-B435-856741E1C21B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {AD317B39-D1E3-4033-A80A-C5F8CACAAF2C} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/AuthenticationController.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/AuthenticationController.cs new file mode 100644 index 0000000..e6904ce --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/AuthenticationController.cs @@ -0,0 +1,41 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Controllers; + +[Route("api/[controller]")] +public class AuthenticationController : Controller +{ + public AuthenticationController(ILogger logger) + { + Log = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + private ILogger Log { get; } + + [HttpGet("secured")] + [Authorize] + public IActionResult GetSecured() + { + return Ok(); + } + + [HttpGet("unsecured")] + public IActionResult GetUnsecured() + { + return Ok(); + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/AutomapperController.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/AutomapperController.cs new file mode 100644 index 0000000..6846dd2 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/AutomapperController.cs @@ -0,0 +1,56 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +using LittleBlocks.Sample.Minimal.WebAPI.Domain; + +namespace LittleBlocks.Sample.Minimal.WebAPI.Controllers; + +[Route("api/[controller]")] +public class AutomapperController : Controller +{ + private readonly ITypeMapper _mapper; + + public AutomapperController(ITypeMapper mapper) + { + if (mapper == null) throw new ArgumentNullException(nameof(mapper)); + _mapper = mapper; + } + + [HttpGet("person/{firstname}/{lastname}")] + public IActionResult GetPerson(string firstname, string lastname) + { + var personToMap = new PersonEntity + { + FirstName = firstname, + LastName = lastname + }; + + var person = _mapper.Map(personToMap); + return new ObjectResult(person); + } + + [HttpGet("asset/{assetid}")] + public IActionResult GetAsset(string assetid) + { + var assetToMap = new AssetEntity + { + Id = assetid + }; + + var asset = _mapper.Map(assetToMap); + return new ObjectResult(asset); + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ConfigurationController.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ConfigurationController.cs new file mode 100644 index 0000000..c3fd6fa --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ConfigurationController.cs @@ -0,0 +1,38 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Controllers; + +[Route("api/[controller]")] +public class ConfigurationController : Controller +{ + private readonly IConfiguration _configuration; + + public ConfigurationController(IConfiguration configuration) + { + _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); + } + + [HttpGet("environment/{name}")] + public IActionResult GetValidEnvironmentConfig(string name) + { + var configItem = _configuration[name]; + if (string.IsNullOrWhiteSpace(configItem)) + return NotFound(); + + return Ok(configItem); + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ErrorsController.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ErrorsController.cs new file mode 100644 index 0000000..f42b9df --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ErrorsController.cs @@ -0,0 +1,46 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +using LittleBlocks.Sample.Minimal.WebAPI.Domain; + +namespace LittleBlocks.Sample.Minimal.WebAPI.Controllers; + +[Route("api/[controller]")] +public class ErrorsController : Controller +{ + [HttpGet("{data}")] + public IActionResult Get(string data) + { + if (data == "throwFriendly") + throw new OurApplicationException(); + if (data == "throwUnfriendly") + throw new Exception("Very bad exception!"); + if (data == "throwThirdParty") + throw new ThirdPartyPluginFailedException(); + if (data == "throwHierarchy") + { + var leafException1 = new OurApplicationException("My friendly leaf1!"); + var leafException2 = new Exception("Security critical super secret!"); + var leafException4 = new ThirdPartyPluginFailedException(); + var leafException3 = new Exception("Security critical super secret #2!", leafException4); + var aggregate = new AggregateException("Should not see me! (aggregate)", leafException1, leafException2, + leafException3); + throw new OurApplicationException("Admin root thrown!", aggregate); + } + + return new ObjectResult(data); + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/FeatureController.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/FeatureController.cs new file mode 100644 index 0000000..8851c22 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/FeatureController.cs @@ -0,0 +1,21 @@ +namespace LittleBlocks.Sample.Minimal.WebAPI.Controllers; + +[Route("api/[controller]")] +public class FeatureController : Controller +{ + private readonly IFeatureManager _featureManager; + + public FeatureController(IFeatureManager featureManager) + { + _featureManager = featureManager ?? throw new ArgumentNullException(nameof(featureManager)); + } + + [HttpGet("{name}")] + public async Task GetFeatureAvailability(string name) + { + if (!await _featureManager.GetFeatureNamesAsync().AnyAsync(m => m == name)) + return NotFound(false); + + return Ok(await _featureManager.IsEnabledAsync(name)); + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/LogsController.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/LogsController.cs new file mode 100644 index 0000000..9ba98e0 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/LogsController.cs @@ -0,0 +1,41 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Controllers; + +[Route("api/[controller]")] +public class LogsController : Controller +{ + public LogsController(ILogger logger) + { + Log = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + private ILogger Log { get; } + + [HttpGet] + public IActionResult Get() + { + Log.LogTrace("Trace"); + Log.LogDebug("Debug"); + Log.LogInformation("Information"); + Log.LogWarning("Warning"); + Log.LogError("Error"); + Log.LogCritical("Critical"); + + return Ok(); + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ServiceController.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ServiceController.cs new file mode 100644 index 0000000..46c50e6 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ServiceController.cs @@ -0,0 +1,36 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +using LittleBlocks.Sample.Minimal.WebAPI.Core; + +namespace LittleBlocks.Sample.Minimal.WebAPI.Controllers; + +[Route("api/[controller]")] +public class ServiceController : Controller +{ + private readonly IMyService _service; + + public ServiceController(IMyService service) + { + _service = service ?? throw new ArgumentNullException(nameof(service)); + } + + [HttpGet("{data}")] + public string Get(string data) + { + return _service.Process(data); + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ValidationController.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ValidationController.cs new file mode 100644 index 0000000..b3e8d2e --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ValidationController.cs @@ -0,0 +1,30 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +using LittleBlocks.Sample.Minimal.WebAPI.Domain; + +namespace LittleBlocks.Sample.Minimal.WebAPI.Controllers; + +[Route("api/[controller]")] +public sealed class ValidationController : Controller +{ + [Route("")] + [HttpPost] + public async Task Post([FromBody] StoreDocumentsRequest request) + { + return await Task.FromResult(Ok()); + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ValuesConsumerController.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ValuesConsumerController.cs new file mode 100644 index 0000000..294beeb --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ValuesConsumerController.cs @@ -0,0 +1,60 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +using LittleBlocks.Sample.Minimal.WebAPI.Core; + +namespace LittleBlocks.Sample.Minimal.WebAPI.Controllers; + +[Route("api/[controller]")] +public class ValuesConsumerController : Controller +{ + private readonly IValuesClient _valuesClient; + + public ValuesConsumerController(IValuesClient valuesClient) + { + _valuesClient = valuesClient ?? throw new ArgumentNullException(nameof(valuesClient)); + } + + [HttpGet] + public async Task> Get() + { + return await _valuesClient.GetValuesAsync(); + } + + [HttpGet("{id}")] + public async Task Get(int id) + { + return await _valuesClient.GetValueAsync(id); + } + + [HttpPost] + public async Task Post([FromBody] string value) + { + await _valuesClient.GetValuesAsync(); + } + + [HttpPut("{id}")] + public async Task Put(int id, [FromBody] string value) + { + await _valuesClient.GetValuesAsync(); + } + + [HttpDelete("{id}")] + public async Task Delete(int id) + { + await _valuesClient.GetValuesAsync(); + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ValuesController.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ValuesController.cs new file mode 100644 index 0000000..19a19a5 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Controllers/ValuesController.cs @@ -0,0 +1,53 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Controllers; + +[Route("api/[controller]")] +public class ValuesController : Controller +{ + // GET api/values + [HttpGet] + public IEnumerable Get() + { + return new[] {"value1", "value2"}; + } + + // GET api/values/5 + [HttpGet("{id}")] + public string Get(int id) + { + return "value"; + } + + // POST api/values + [HttpPost] + public void Post([FromBody] string value) + { + } + + // PUT api/values/5 + [HttpPut("{id}")] + public void Put(int id, [FromBody] string value) + { + } + + // DELETE api/values/5 + [HttpDelete("{id}")] + public void Delete(int id) + { + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/IMyService.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/IMyService.cs new file mode 100644 index 0000000..ef9f6c0 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/IMyService.cs @@ -0,0 +1,22 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Core; + +public interface IMyService +{ + string Process(string param1); +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/IValuesClient.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/IValuesClient.cs new file mode 100644 index 0000000..0b6881b --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/IValuesClient.cs @@ -0,0 +1,35 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Core; + +public interface IValuesClient : IRestClient +{ + [Get("api/Values")] + Task> GetValuesAsync(); + + [Get("api/Values/{id}")] + Task GetValueAsync([Path] int id); + + [Post("api/Values/{id}")] + Task PostValueAsync([Path] int id, [Body] string value); + + [Put("api/Values/{id}")] + Task PutValueAsync([Path] int id, [Body] string value); + + [Delete("api/Values/{id}")] + Task DeleteValueAsync([Path] int id); +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Mappings/AssetConverter.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Mappings/AssetConverter.cs new file mode 100644 index 0000000..a2a7d92 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Mappings/AssetConverter.cs @@ -0,0 +1,40 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +using LittleBlocks.Sample.Minimal.WebAPI.Domain; + +namespace LittleBlocks.Sample.Minimal.WebAPI.Core.Mappings; + +public sealed class AssetConverter : ITypeConverter +{ + private readonly IRateProvider _rateProvider; + + public AssetConverter(IRateProvider rateProvider) + { + _rateProvider = rateProvider ?? throw new ArgumentNullException(nameof(rateProvider)); + } + + public AssetDo Convert(AssetEntity source, AssetDo destination, ResolutionContext context) + { + if (source == null) return null; + + return new AssetDo + { + Id = source.Id, + Rating = _rateProvider.GetRating(source.Id) + }; + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Mappings/DummyRateProvider.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Mappings/DummyRateProvider.cs new file mode 100644 index 0000000..acd8469 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Mappings/DummyRateProvider.cs @@ -0,0 +1,25 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Core.Mappings; + +public sealed class DummyRateProvider : IRateProvider +{ + public string GetRating(string assetId) + { + return "AAA"; + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Mappings/IRateProvider.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Mappings/IRateProvider.cs new file mode 100644 index 0000000..92140db --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Mappings/IRateProvider.cs @@ -0,0 +1,22 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Core.Mappings; + +public interface IRateProvider +{ + string GetRating(string assetId); +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/MyService.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/MyService.cs new file mode 100644 index 0000000..2021bb1 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/MyService.cs @@ -0,0 +1,25 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Core; + +public class MyService : IMyService +{ + public string Process(string param1) + { + return $"Processed {param1}"; + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Validators/DocumentValidator.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Validators/DocumentValidator.cs new file mode 100644 index 0000000..f35f057 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Validators/DocumentValidator.cs @@ -0,0 +1,23 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +using LittleBlocks.Sample.Minimal.WebAPI.Domain; + +namespace LittleBlocks.Sample.Minimal.WebAPI.Core.Validators; + +public sealed class DocumentValidator : AbstractValidator +{ +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Validators/OwnerValidator.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Validators/OwnerValidator.cs new file mode 100644 index 0000000..631b3e9 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Validators/OwnerValidator.cs @@ -0,0 +1,23 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +using LittleBlocks.Sample.Minimal.WebAPI.Domain; + +namespace LittleBlocks.Sample.Minimal.WebAPI.Core.Validators; + +public sealed class OwnerValidator : AbstractValidator +{ +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Validators/StoreDocumentRequestValidator.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Validators/StoreDocumentRequestValidator.cs new file mode 100644 index 0000000..2a146a2 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Core/Validators/StoreDocumentRequestValidator.cs @@ -0,0 +1,52 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +using LittleBlocks.Extensions; +using LittleBlocks.Sample.Minimal.WebAPI.Domain; + +namespace LittleBlocks.Sample.Minimal.WebAPI.Core.Validators; + +public sealed class StoreDocumentRequestValidator : AbstractValidator +{ + private readonly HashSet _supportedOperations = new HashSet(new List + { + "Validate", + "Process", + "Publish" + }); + + public StoreDocumentRequestValidator() + { + RuleFor(m => m.RequestId).NotEmpty(); + RuleFor(m => m.Operation).Must(OneOfSupportedOperations).WithMessage(GetValidOperationsMessage); + RuleFor(c => c.Owner).NotNull().SetValidator(new OwnerValidator()); + RuleForEach(c => c.Documents).NotNull().NotEmpty().SetValidator(new DocumentValidator()); + } + + private string GetValidOperationsMessage(StoreDocumentsRequest request) + { + if (request.Operation.AnyValue()) + return + $"'{request.Operation}' is not supported. Supported operations are: {string.Join(", ", _supportedOperations)}."; + + return $"Operation must be supplied! Supported operations are: {string.Join(", ", _supportedOperations)}."; + } + + private bool OneOfSupportedOperations(string operation) + { + return _supportedOperations.Contains(operation); + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/AssetDO.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/AssetDO.cs new file mode 100644 index 0000000..2939325 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/AssetDO.cs @@ -0,0 +1,23 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public class AssetDo +{ + public string Id { get; set; } + public string Rating { get; set; } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/AssetEntity.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/AssetEntity.cs new file mode 100644 index 0000000..8495bd2 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/AssetEntity.cs @@ -0,0 +1,22 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public class AssetEntity +{ + public string Id { get; set; } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Clients.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Clients.cs new file mode 100644 index 0000000..f4e6b0d --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Clients.cs @@ -0,0 +1,22 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public class Clients +{ + public string ProducerClientUrl { get; set; } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Document.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Document.cs new file mode 100644 index 0000000..3129df4 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Document.cs @@ -0,0 +1,22 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public class Document +{ + public string Path { get; set; } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/OurApplicationException.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/OurApplicationException.cs new file mode 100644 index 0000000..039e14a --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/OurApplicationException.cs @@ -0,0 +1,32 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public sealed class OurApplicationException : TemplateApiApplicationException +{ + public OurApplicationException() : base("I am a user friendly exception message") + { + } + + public OurApplicationException(string message) : base(message) + { + } + + public OurApplicationException(string message, Exception exception) : base(message, exception) + { + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Owner.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Owner.cs new file mode 100644 index 0000000..8bfe92a --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Owner.cs @@ -0,0 +1,23 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public class Owner +{ + public string FirstName { get; set; } + public string LastName { get; set; } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/PersonDO.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/PersonDO.cs new file mode 100644 index 0000000..878b7e5 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/PersonDO.cs @@ -0,0 +1,23 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public class PersonDo +{ + public string FirstName { get; set; } + public string LastName { get; set; } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/PersonEntity.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/PersonEntity.cs new file mode 100644 index 0000000..c056e73 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/PersonEntity.cs @@ -0,0 +1,23 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public class PersonEntity +{ + public string FirstName { get; set; } + public string LastName { get; set; } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Section1.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Section1.cs new file mode 100644 index 0000000..3477da1 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Section1.cs @@ -0,0 +1,23 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public class Section1 +{ + public string Value1 { get; set; } + public string Value2 { get; set; } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Section2.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Section2.cs new file mode 100644 index 0000000..1f162e9 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/Section2.cs @@ -0,0 +1,23 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public class Section2 +{ + public string Value3 { get; set; } + public string Value4 { get; set; } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/StoreDocuments.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/StoreDocuments.cs new file mode 100644 index 0000000..22ec9b8 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/StoreDocuments.cs @@ -0,0 +1,23 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public class StoreDocuments +{ + public Guid RequestId { get; set; } + public string StoreOperation { get; set; } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/StoreDocumentsRequest.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/StoreDocumentsRequest.cs new file mode 100644 index 0000000..3d9f81c --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/StoreDocumentsRequest.cs @@ -0,0 +1,31 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public class StoreDocumentsRequest +{ + public StoreDocumentsRequest() + { + Documents = new List(); + } + + public Guid RequestId { get; set; } + public string Operation { get; set; } + + public Owner Owner { get; set; } + public IEnumerable Documents { get; set; } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/TemplateApiApplicationException.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/TemplateApiApplicationException.cs new file mode 100644 index 0000000..5b3721f --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/TemplateApiApplicationException.cs @@ -0,0 +1,28 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public abstract class TemplateApiApplicationException : Exception +{ + protected TemplateApiApplicationException(string message) : base(message) + { + } + + protected TemplateApiApplicationException(string message, Exception exception) : base(message, exception) + { + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/ThirdPartyPluginException.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/ThirdPartyPluginException.cs new file mode 100644 index 0000000..d73dbcb --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/ThirdPartyPluginException.cs @@ -0,0 +1,24 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public abstract class ThirdPartyPluginException : Exception +{ + protected ThirdPartyPluginException(string message) : base(message) + { + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/ThirdPartyPluginFailedException.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/ThirdPartyPluginFailedException.cs new file mode 100644 index 0000000..7f2ccb4 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Domain/ThirdPartyPluginFailedException.cs @@ -0,0 +1,24 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace LittleBlocks.Sample.Minimal.WebAPI.Domain; + +public sealed class ThirdPartyPluginFailedException : ThirdPartyPluginException +{ + public ThirdPartyPluginFailedException() : base("Third party plugin has failed!") + { + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Extensions/ConfigurationBuilderExtensions.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Extensions/ConfigurationBuilderExtensions.cs new file mode 100644 index 0000000..fba6467 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Extensions/ConfigurationBuilderExtensions.cs @@ -0,0 +1,9 @@ +namespace LittleBlocks.Sample.Minimal.WebAPI.Extensions; + +public static class ConfigurationBuilderExtensions +{ + public static IConfigurationBuilder CustomizeBuilder(this IConfigurationBuilder builder) + { + return builder ?? throw new ArgumentNullException(nameof(builder)); + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/LittleBlocks.Sample.Minimal.WebAPI.csproj b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/LittleBlocks.Sample.Minimal.WebAPI.csproj new file mode 100644 index 0000000..7fa924e --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/LittleBlocks.Sample.Minimal.WebAPI.csproj @@ -0,0 +1,37 @@ + + + net8.0 + False + 12 + enable + enable + Linux + + + + + + + + + + + + + + + + Always + true + PreserveNewest + + + appsettings.PROD.json + + + + + Always + + + diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Program.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Program.cs new file mode 100644 index 0000000..1c544d3 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Program.cs @@ -0,0 +1,100 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +using System.Text.Json.Serialization; +using AutoMapper.Features; +using FluentValidation.AspNetCore; +using LittleBlocks.AspNetCore.Documentation; +using LittleBlocks.AspNetCore.RequestCorrelation; +using LittleBlocks.Sample.Minimal.WebAPI.Extensions; +using Serilog; + +namespace LittleBlocks.Sample.Minimal.WebAPI; + +var builder = WebApplication.CreateBuilder(args); + +var applicationInfo = builder.GetApplicationInfo(); +var hostInfo = builder.GetHostInfo(); +var loggingContext = builder.GetLoggingContext(); + +builder.Host.UseSerilog((context, configuration) => (context, configuration).ConfigureSerilog(loggingContext)); +builder.Services.AddControllers().AddJsonOptions(o => +{ + o.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); +}).AddFluentValidation(); +builder.Services.AddValidatorsFromAssemblyContaining(); + +builder.Services.AddApiVersioning(o => +{ + o.ReportApiVersions = true; + o.ApiVersionReader = new MediaTypeApiVersionReader(); + o.AssumeDefaultVersionWhenUnspecified = true; + o.ApiVersionSelector = new CurrentImplementationApiVersionSelector(o); +}); + +builder.Services.AddDependencyHealthChecks(); +builder.Services.AddFeatures>(builder.Configuration); + +builder.Services + .AddSingleton(applicationInfo) + .AddRouting(o => o.LowercaseUrls = true) + .AddMediatR(typeof(Program)) + .AddEndpointsApiExplorer() + .AddOpenApiDocumentation(applicationInfo) + .AddRequestCorrelation() + .AddCorsWithDefaultPolicy() + .AddTypeMapping(c => c.AddProfile()); + +var app = builder.Build(); +app.UseRequestCorrelation(); + +app.UseOpenApiDocumentation(applicationInfo); +if (!app.Environment.IsDevelopment()) +{ + app.UseGlobalExceptionAndLoggingHandler(); + app.UseHsts(); +} + +app.UseCors(); +app.UseSerilogRequestLogging(m => +{ + m.IncludeQueryInRequestPath = true; + m.EnrichDiagnosticContext = (context, httpContext) => { }; +}); +app.UseHttpsRedirection(hostInfo); +app.UseAuthorization(); +app.MapDependencyHealthChecks(); +app.MapControllers(); +app.MapStartPage(applicationInfo.Name); + +app.Run(); + +public class Program +{ + public static void Main(string[] args) + { + // HostAsWeb.Run( + // builder => builder.CustomizeBuilder(), + // s => + // { + // if (s.Environment.IsDevelopment() || s.Environment.IsEnvironment("INT")) + // return s.ConfigureLogger(c => c.UseSeq(s.Configuration.GetSection("Logging:Seq"))); + // + // return s.ConfigureLogger(c => + // c.UseLoggly(s.Configuration.GetSection("Logging:Loggly"))); + // }, args); + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Startup.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Startup.cs new file mode 100644 index 0000000..406678a --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Startup.cs @@ -0,0 +1,80 @@ +// This software is part of the LittleBlocks framework +// Copyright (C) 2024 LittleBlocks +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +using LittleBlocks.Sample.Minimal.WebAPI.Core; +using LittleBlocks.Sample.Minimal.WebAPI.Core.Mappings; +using LittleBlocks.Sample.Minimal.WebAPI.Domain; + +namespace LittleBlocks.Sample.Minimal.WebAPI; + +public class Startup +{ + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + private IConfiguration Configuration { get; } + + public void ConfigureServices(IServiceCollection services) + { + services.BootstrapApp(Configuration, + app => app + .AddConfigSection() + .AndSection() + .AndSection() + .HandleApplicationException() + .ConfigureCorrelation(m => m.AutoCorrelateRequests()) + .ConfigureHealthChecks(c => + { + c.AddUrlGroup(new Uri("http://www.google.com"), HttpMethod.Get, "google"); + c.AddUrlGroup(new Uri("http://www.Microsoft.com"), HttpMethod.Get, "microsoft"); + c.AddUrlGroup(new Uri("https://github.com/littleblocks"), HttpMethod.Get, "LittleBlocks"); + c.AddSeqPublisher(setup => + { + setup.Endpoint = Configuration["Logging:Seq:ServerUrl"]; + setup.ApiKey = Configuration["Logging:Seq:ApiKey"]; + }); + }) + .ConfigureMappings(c => + { + c.CreateMap(); + c.CreateMap().ConvertUsing(); + }) + .AddServices((container, config) => + { + container.AddRestClient(c => c.ProducerClientUrl); + container.AddTransientWithInterception(by => + by.InterceptBy()); + container.AddTransientWithInterception(by => + by.InterceptBy()); + container.AddSingleton, AssetConverter>(); + services + .AddHealthChecksUI() + .AddInMemoryStorage(); + }) + ); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) + { + app.UseDefaultApiPipeline(Configuration, env, loggerFactory); + app.UseEndpoints(config => + { + config.MapHealthChecksUI(m => m.AddCustomStylesheet("health-ui.css")); + }); + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Usings.cs b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Usings.cs new file mode 100644 index 0000000..3f5bafb --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/Usings.cs @@ -0,0 +1,27 @@ +global using System; +global using System.Linq; +global using System.Threading.Tasks; +global using System.Collections.Generic; +global using System.Net.Http; +global using LittleBlocks.RestEase.Client; +global using LittleBlocks.AspNetCore; +global using LittleBlocks.Logging.SeriLog.Loggly; +global using LittleBlocks.Logging.SeriLog.Seq; +global using LittleBlocks.AspNetCore.Bootstrap; +global using LittleBlocks.AspNetCore.Bootstrap.Extensions; +global using LittleBlocks.AspNetCore.Logging.SeriLog; +global using LittleBlocks.RestEase; +global using Microsoft.Extensions.Hosting; +global using Microsoft.AspNetCore.Authorization; +global using Microsoft.AspNetCore.Mvc; +global using Microsoft.Extensions.Logging; +global using Microsoft.Extensions.Configuration; +global using Microsoft.FeatureManagement; +global using Microsoft.AspNetCore.Builder; +global using Microsoft.AspNetCore.Hosting; +global using Microsoft.Extensions.DependencyInjection; + +global using AutoMapper; +global using FluentValidation; +global using RestEase; +global using Foil; diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/appsettings.Development.json b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/appsettings.Development.json new file mode 100644 index 0000000..7755d7f --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/appsettings.Development.json @@ -0,0 +1,15 @@ +{ + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + }, + "Seq": { + "ServerUrl": "http://localhost:8089", + "ApiKey": "pb6zPcoknbcRdKu2VtqL", + "AllowLogLevelToBeControlledRemotely": true + } + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/appsettings.json b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/appsettings.json new file mode 100644 index 0000000..31b00b8 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/appsettings.json @@ -0,0 +1,72 @@ +{ + "Logging": { + "IncludeScopes": false, + "LogFilePath": "", + "Serilog": { + "MinimumLevel": "Trace" + }, + "Loggly": { + "IsEnabled": "false", + "ServerUrl": "https://logs-01.loggly.com/", + "CustomerToken": "LogglyCustomerToken", + "BufferBaseFilename": "logs\\loggly-buffer", + "NumberOfEventsInSingleBatch": 50, + "BatchPostingIntervalInSeconds": 2, + "EventBodyLimitKb": 10, + "RetainedInvalidPayloadsLimitMb": 100, + "AllowLogLevelToBeControlledRemotely": false + }, + "Seq": { + "ServerUrl": "http://localhost:8089", + "ApiKey": "pb6zPcoknbcRdKu2VtqL", + "AllowLogLevelToBeControlledRemotely": true + } + }, + "ApplicationInsights": { + "InstrumentationKey": "Instrument Key Here" + }, + "AuthOptions": { + "AuthenticationMode": "OAuth2", + "Authentication": { + "Authority": "https://login.microsoftonline.com/31d4ce72-dfb2-4be8-b876-3278f8641754", + "Audience": "f7748175-fc0b-4982-8539-070199f3e768" + } + }, + "HealthChecksUI": { + "HealthChecks": [ + { + "Name": "API health endpoint", + "Uri": "https://localhost:5001/health" + } + ], + "Webhooks": [], + "EvaluationTimeinSeconds": 10, + "MinimumSecondsBetweenFailureNotifications": 60 + }, + "Application": { + "Name": "Sample API", + "Version": "1.0", + "Url": "", + "Environment": { + "Name": "Integration", + "Prefix": "int" + } + }, + "Section1": { + "Value1": "1", + "Value2": "2" + }, + "Section2": { + "Value3": "3", + "Value4": "4", + "Section3": { + "Value1": "1", + "Value2": "2", + "Value3": "3", + "Value4": "4" + } + }, + "Clients": { + "ProducerClientUrl": "https://localhost:5001/" + } +} diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/health-ui.css b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/health-ui.css new file mode 100644 index 0000000..5c10e01 --- /dev/null +++ b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/health-ui.css @@ -0,0 +1,8 @@ +:root { + --primaryColor: #192544; + --secondaryColor: #f4f4f4; + --bgMenuActive: #3f5a9a; + --bgButton: #2c4272; + --bgAside: var(--primaryColor); + --logoImageUrl: url('sample.png'); +} \ No newline at end of file diff --git a/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/sample.png b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/sample.png new file mode 100644 index 0000000..c8db6c8 Binary files /dev/null and b/src/Samples/LittleBlocks.Sample.MinimalApi..WebAPI/sample.png differ