From c449650057f6e4c3bbb68389aa945b2c6192cd63 Mon Sep 17 00:00:00 2001 From: DzurahIvan <55486308+DzurahIvan@users.noreply.github.com> Date: Thu, 3 Feb 2022 22:18:57 +0200 Subject: [PATCH 01/25] Create OrderTimeOutService --- OrderTimeOutService/.gitignore | 264 ++++++++++++++++++ .../DataAccess/ITimeOutOrderRepository.cs | 15 + .../InMemoryTimeOutOrderRepository.cs | 30 ++ OrderTimeOutService/OrderTimeOutFunction.cs | 30 ++ .../OrderTimeOutService.csproj | 21 ++ .../Properties/serviceDependencies.json | 11 + .../Properties/serviceDependencies.local.json | 11 + OrderTimeOutService/host.json | 11 + Shellys.sln | 8 +- 9 files changed, 400 insertions(+), 1 deletion(-) create mode 100644 OrderTimeOutService/.gitignore create mode 100644 OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs create mode 100644 OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs create mode 100644 OrderTimeOutService/OrderTimeOutFunction.cs create mode 100644 OrderTimeOutService/OrderTimeOutService.csproj create mode 100644 OrderTimeOutService/Properties/serviceDependencies.json create mode 100644 OrderTimeOutService/Properties/serviceDependencies.local.json create mode 100644 OrderTimeOutService/host.json diff --git a/OrderTimeOutService/.gitignore b/OrderTimeOutService/.gitignore new file mode 100644 index 0000000..ff5b00c --- /dev/null +++ b/OrderTimeOutService/.gitignore @@ -0,0 +1,264 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# Azure Functions localsettings file +local.settings.json + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc \ No newline at end of file diff --git a/OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs b/OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs new file mode 100644 index 0000000..c291b59 --- /dev/null +++ b/OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs @@ -0,0 +1,15 @@ +using DataAccess.Domain; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + + +namespace OrderTimeOutService.DataAccess +{ + public interface ITimeOutOrderRepository + { + Task> Get(int orderStatus); + Task Update(Order order); + } +} diff --git a/OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs b/OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs new file mode 100644 index 0000000..8b0fc84 --- /dev/null +++ b/OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs @@ -0,0 +1,30 @@ +using DataAccess.Domain; +using System.Linq; +using System.Collections.Generic; +using System.Threading.Tasks; + + +namespace OrderTimeOutService.DataAccess +{ + public class InMemoryTimeOutOrderRepository : ITimeOutOrderRepository + { + private static readonly List _orders = new List(); + + public Task> Get(int orderStatus) + { + return Task.FromResult(_orders.Where(o => ((int)o.Status) == orderStatus)); + } + + public Task Update(Order order) + { + var index = _orders.FindIndex(o => o == order); + if (index == -1) + { + return Task.FromResult(-1); + } + order.Status = OrderStatus.Finalized; + _orders[index] = order; + return Task.FromResult(order.Id); + } + } +} diff --git a/OrderTimeOutService/OrderTimeOutFunction.cs b/OrderTimeOutService/OrderTimeOutFunction.cs new file mode 100644 index 0000000..88c0b88 --- /dev/null +++ b/OrderTimeOutService/OrderTimeOutFunction.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using DataAccess.Domain; +using Microsoft.Azure.WebJobs; +using Microsoft.Azure.WebJobs.Host; +using Microsoft.Extensions.Logging; +using OrderTimeOutService.DataAccess; + +namespace OrderTimeOutService +{ + public class OrderTimeOutFunction + { + private readonly ITimeOutOrderRepository _orders; + public OrderTimeOutFunction(ITimeOutOrderRepository orders) + { + _orders = orders; + } + [FunctionName("OrderTimeOut")] + public async Task RunAsync([TimerTrigger("0 0 0 * * *")] TimerInfo myTimer, ILogger log) + { + log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); + IEnumerable timeOutOrders = await _orders.Get(1); + foreach (Order ord in timeOutOrders) + { + await _orders.Update(ord); + } + } + } +} diff --git a/OrderTimeOutService/OrderTimeOutService.csproj b/OrderTimeOutService/OrderTimeOutService.csproj new file mode 100644 index 0000000..6eaab25 --- /dev/null +++ b/OrderTimeOutService/OrderTimeOutService.csproj @@ -0,0 +1,21 @@ + + + netcoreapp3.1 + v3 + + + + + + + + + + PreserveNewest + + + PreserveNewest + Never + + + diff --git a/OrderTimeOutService/Properties/serviceDependencies.json b/OrderTimeOutService/Properties/serviceDependencies.json new file mode 100644 index 0000000..df4dcc9 --- /dev/null +++ b/OrderTimeOutService/Properties/serviceDependencies.json @@ -0,0 +1,11 @@ +{ + "dependencies": { + "appInsights1": { + "type": "appInsights" + }, + "storage1": { + "type": "storage", + "connectionId": "AzureWebJobsStorage" + } + } +} \ No newline at end of file diff --git a/OrderTimeOutService/Properties/serviceDependencies.local.json b/OrderTimeOutService/Properties/serviceDependencies.local.json new file mode 100644 index 0000000..b804a28 --- /dev/null +++ b/OrderTimeOutService/Properties/serviceDependencies.local.json @@ -0,0 +1,11 @@ +{ + "dependencies": { + "appInsights1": { + "type": "appInsights.sdk" + }, + "storage1": { + "type": "storage.emulator", + "connectionId": "AzureWebJobsStorage" + } + } +} \ No newline at end of file diff --git a/OrderTimeOutService/host.json b/OrderTimeOutService/host.json new file mode 100644 index 0000000..beb2e40 --- /dev/null +++ b/OrderTimeOutService/host.json @@ -0,0 +1,11 @@ +{ + "version": "2.0", + "logging": { + "applicationInsights": { + "samplingSettings": { + "isEnabled": true, + "excludedTypes": "Request" + } + } + } +} \ No newline at end of file diff --git a/Shellys.sln b/Shellys.sln index c422ab8..d1e4084 100644 --- a/Shellys.sln +++ b/Shellys.sln @@ -9,7 +9,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrderingService", "Ordering EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnqueueCompleteOrderCommandApp", "EnqueueCompleteOrderCommandApp\EnqueueCompleteOrderCommandApp.csproj", "{0625C645-E362-483B-AD2C-884DC48E1BBA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataAccess", "DataAccess\DataAccess.csproj", "{C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataAccess", "DataAccess\DataAccess.csproj", "{C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrderTimeOutService", "OrderTimeOutService\OrderTimeOutService.csproj", "{19AF5413-122C-4A11-B6D7-E3A8BDEB8111}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -33,6 +35,10 @@ Global {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Debug|Any CPU.Build.0 = Debug|Any CPU {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Release|Any CPU.ActiveCfg = Release|Any CPU {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Release|Any CPU.Build.0 = Release|Any CPU + {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 5e86b126f3065e03cfbac899b1765fc72794154a Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Mon, 7 Feb 2022 01:44:27 +0200 Subject: [PATCH 02/25] Add Entities and DbContext Implement access to database with Entity Framework Core and rewrite BarAPI menu controller. --- BarAPI/BarAPI.csproj | 1 + BarAPI/Controllers/MenuController.cs | 93 ++++++++-- BarAPI/DataAccess/InMemoryRepository.cs | 53 ------ .../BarService - Zip Deploy/profile.arm.json | 175 ++++++++++++++++++ BarAPI/Startup.cs | 10 +- DataAccess/Data/BarDataBase.cs | 33 ++++ DataAccess/Data/MenuItem.cs | 13 ++ DataAccess/{Domain => Data}/Order.cs | 8 +- DataAccess/DataAccess.csproj | 1 + DataAccess/Domain/MenuItem.cs | 9 - DataAccess/IMenuRepository.cs | 13 -- DataAccess/MenuRepository.cs | 55 ------ DataAccess/OrderRepository.cs | 53 ------ DataAccess/Repository/IMenuRepository.cs | 15 ++ .../{ => Repository}/IOrderRepository.cs | 4 +- DataAccess/Repository/MenuRepository.cs | 75 ++++++++ DataAccess/Repository/OrderRepository.cs | 50 +++++ DataAccess/db.sql | 10 - 18 files changed, 448 insertions(+), 223 deletions(-) delete mode 100644 BarAPI/DataAccess/InMemoryRepository.cs create mode 100644 BarAPI/Properties/ServiceDependencies/BarService - Zip Deploy/profile.arm.json create mode 100644 DataAccess/Data/BarDataBase.cs create mode 100644 DataAccess/Data/MenuItem.cs rename DataAccess/{Domain => Data}/Order.cs (65%) delete mode 100644 DataAccess/Domain/MenuItem.cs delete mode 100644 DataAccess/IMenuRepository.cs delete mode 100644 DataAccess/MenuRepository.cs delete mode 100644 DataAccess/OrderRepository.cs create mode 100644 DataAccess/Repository/IMenuRepository.cs rename DataAccess/{ => Repository}/IOrderRepository.cs (74%) create mode 100644 DataAccess/Repository/MenuRepository.cs create mode 100644 DataAccess/Repository/OrderRepository.cs delete mode 100644 DataAccess/db.sql diff --git a/BarAPI/BarAPI.csproj b/BarAPI/BarAPI.csproj index 75daf3d..be0f976 100644 --- a/BarAPI/BarAPI.csproj +++ b/BarAPI/BarAPI.csproj @@ -5,6 +5,7 @@ + diff --git a/BarAPI/Controllers/MenuController.cs b/BarAPI/Controllers/MenuController.cs index b67abbb..0b8009e 100644 --- a/BarAPI/Controllers/MenuController.cs +++ b/BarAPI/Controllers/MenuController.cs @@ -1,10 +1,9 @@ -using System; -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; -using DataAccess; -using DataAccess.Domain; +using DataAccess.Data; +using DataAccess.Repository; +using System.Collections.Generic; -// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 namespace BarAPI.Controllers { @@ -21,37 +20,91 @@ public MenuController(IMenuRepository menuRepository) // GET: api/ [HttpGet] - public Task Get() + [ProducesResponseType(200, Type = typeof(List))] + public async Task> GetAll() { - return _menuRepository.Get(); + return await _menuRepository.GetAllItems(); } - // GET api//name - [HttpGet("{name}")] - public Task Get(string name) + // GET api//id + [HttpGet("{id}")] + [ProducesResponseType(200, Type = typeof(MenuItem))] + [ProducesResponseType(404)] + public async Task Get(int id) { - return _menuRepository.GetItem(name); + MenuItem menuItem = await _menuRepository.GetItem(id); + if(menuItem == null) + { + return NotFound(); + } + else + { + return Ok(menuItem); + } } // POST api/ [HttpPost] - public async Task Post([FromBody] MenuItem item) + [ProducesResponseType(201, Type = typeof(MenuItem))] + [ProducesResponseType(400)] + public async Task Post([FromBody] MenuItem item) { - await _menuRepository.Add(item); + if(item == null) + { + return BadRequest(); + } + if(!ModelState.IsValid) + { + return BadRequest(ModelState); + } + MenuItem exist = await _menuRepository.GetItem(item.Id); + if (exist != null) + { + return BadRequest($"Item with id= {item.Id} already exists"); + } + MenuItem menuItem = await _menuRepository.Add(item); + return CreatedAtAction(nameof(Post), menuItem); } // PUT api//5 - [HttpPut("{name}")] - public void Put(string name, [FromBody] string value) + [HttpPut("{id}")] + [ProducesResponseType(204)] + [ProducesResponseType(400)] + [ProducesResponseType(404)] + public async Task Update(int id, [FromBody] MenuItem item) { - throw new NotImplementedException("Our bar does not allow to modify a menu! (yet)"); + if(item.Id != id) + { + return BadRequest(); + } + if(!ModelState.IsValid) + { + return BadRequest(ModelState); + } + await _menuRepository.Update(item); + return new NoContentResult(); } - // DELETE api//name - [HttpDelete("{name}")] - public async Task Delete(string name) + // DELETE api//id + [HttpDelete("{id}")] + [ProducesResponseType(204)] + [ProducesResponseType(404)] + public async Task Delete(int id) { - await _menuRepository.Remove(name); + var exist = await _menuRepository.GetItem(id); + if(exist == null) + { + return NotFound(); + } + bool deleted = await _menuRepository.Remove(id); + if (deleted) + { + return new NoContentResult(); + } + else + { + return BadRequest($"Item with id={id} was found but faild to delete"); + } } } } diff --git a/BarAPI/DataAccess/InMemoryRepository.cs b/BarAPI/DataAccess/InMemoryRepository.cs deleted file mode 100644 index f35c638..0000000 --- a/BarAPI/DataAccess/InMemoryRepository.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using DataAccess; -using DataAccess.Domain; - -namespace BarAPI.DataAccess -{ - public class InMemoryRepository: IMenuRepository - { - private static List _positions = new() - { - new MenuItem - { - Name = "Negroni", - Price = 6.99 - }, - new MenuItem - { - Name = "Margarita", - Price = 8.99 - }, - new MenuItem - { - Name = "Apple Martini", - Price = 7 - } - }; - - public Task Add(MenuItem item) - { - _positions.Add(item); - return Task.CompletedTask; - } - - public Task Get() - { - return Task.FromResult(_positions.ToArray()); - } - - public Task GetItem(string name) - { - return Task.FromResult(_positions.FirstOrDefault(p => p.Name == name)); - } - - public Task Remove(string name) - { - _positions.RemoveAt(_positions.FindIndex(p=>p.Name==name)); - return Task.CompletedTask; - } - } -} diff --git a/BarAPI/Properties/ServiceDependencies/BarService - Zip Deploy/profile.arm.json b/BarAPI/Properties/ServiceDependencies/BarService - Zip Deploy/profile.arm.json new file mode 100644 index 0000000..a9efbb4 --- /dev/null +++ b/BarAPI/Properties/ServiceDependencies/BarService - Zip Deploy/profile.arm.json @@ -0,0 +1,175 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_dependencyType": "function.windows.appService" + }, + "parameters": { + "resourceGroupName": { + "type": "string", + "defaultValue": "Bar-Service-Group", + "metadata": { + "description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking." + } + }, + "resourceGroupLocation": { + "type": "string", + "defaultValue": "westeurope", + "metadata": { + "description": "Location of the resource group. Resource groups could have different location than resources, however by default we use API versions from latest hybrid profile which support all locations for resource types we support." + } + }, + "resourceName": { + "type": "string", + "defaultValue": "BarService", + "metadata": { + "description": "Name of the main resource to be created by this template." + } + }, + "resourceLocation": { + "type": "string", + "defaultValue": "[parameters('resourceGroupLocation')]", + "metadata": { + "description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there." + } + } + }, + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "name": "[parameters('resourceGroupName')]", + "location": "[parameters('resourceGroupLocation')]", + "apiVersion": "2019-10-01" + }, + { + "type": "Microsoft.Resources/deployments", + "name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "apiVersion": "2019-10-01", + "dependsOn": [ + "[parameters('resourceGroupName')]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "parameters": { + "resourceGroupName": { + "value": "[parameters('resourceGroupName')]" + }, + "resourceGroupLocation": { + "value": "[parameters('resourceGroupLocation')]" + }, + "resourceName": { + "value": "[parameters('resourceName')]" + }, + "resourceLocation": { + "value": "[parameters('resourceLocation')]" + } + }, + "template": { + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceGroupName": { + "type": "string" + }, + "resourceGroupLocation": { + "type": "string" + }, + "resourceName": { + "type": "string" + }, + "resourceLocation": { + "type": "string" + } + }, + "variables": { + "storage_name": "[toLower(concat('storage', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId))))]", + "appServicePlan_name": "[concat('Plan', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]", + "storage_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Storage/storageAccounts/', variables('storage_name'))]", + "appServicePlan_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/serverFarms/', variables('appServicePlan_name'))]", + "function_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/sites/', parameters('resourceName'))]" + }, + "resources": [ + { + "location": "[parameters('resourceLocation')]", + "name": "[parameters('resourceName')]", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "tags": { + "[concat('hidden-related:', variables('appServicePlan_ResourceId'))]": "empty" + }, + "dependsOn": [ + "[variables('appServicePlan_ResourceId')]", + "[variables('storage_ResourceId')]" + ], + "kind": "functionapp", + "properties": { + "name": "[parameters('resourceName')]", + "kind": "functionapp", + "httpsOnly": true, + "reserved": false, + "serverFarmId": "[variables('appServicePlan_ResourceId')]", + "siteConfig": { + "alwaysOn": true + } + }, + "identity": { + "type": "SystemAssigned" + }, + "resources": [ + { + "name": "appsettings", + "type": "config", + "apiVersion": "2015-08-01", + "dependsOn": [ + "[variables('function_ResourceId')]" + ], + "properties": { + "AzureWebJobsDashboard": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storage_name'), ';AccountKey=', listKeys(variables('storage_ResourceId'), '2017-10-01').keys[0].value, ';EndpointSuffix=', 'core.windows.net')]", + "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storage_name'), ';AccountKey=', listKeys(variables('storage_ResourceId'), '2017-10-01').keys[0].value, ';EndpointSuffix=', 'core.windows.net')]", + "FUNCTIONS_EXTENSION_VERSION": "~3", + "FUNCTIONS_WORKER_RUNTIME": "dotnet" + } + } + ] + }, + { + "location": "[parameters('resourceGroupLocation')]", + "name": "[variables('storage_name')]", + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2017-10-01", + "tags": { + "[concat('hidden-related:', concat('/providers/Microsoft.Web/sites/', parameters('resourceName')))]": "empty" + }, + "properties": { + "supportsHttpsTrafficOnly": true + }, + "sku": { + "name": "Standard_LRS" + }, + "kind": "Storage" + }, + { + "location": "[parameters('resourceGroupLocation')]", + "name": "[variables('appServicePlan_name')]", + "type": "Microsoft.Web/serverFarms", + "apiVersion": "2015-08-01", + "sku": { + "name": "S1", + "tier": "Standard", + "family": "S", + "size": "S1" + }, + "properties": { + "name": "[variables('appServicePlan_name')]" + } + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/BarAPI/Startup.cs b/BarAPI/Startup.cs index 2fc5280..75ce43d 100644 --- a/BarAPI/Startup.cs +++ b/BarAPI/Startup.cs @@ -1,12 +1,10 @@ -using System.Data; -using System.Data.SqlClient; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Models; -using BarAPI.DataAccess; -using DataAccess; +using DataAccess.Repository; +using DataAccess.Data; namespace BarAPI { @@ -24,11 +22,11 @@ public void ConfigureServices(IServiceCollection services) { services.AddControllers(); + services.AddScoped(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "BarAPI", Version = "v1" }); }); - services.AddScoped(); //services.AddScoped(sp => new SqlConnection("TMP")); //services.AddScoped(sp => sp.GetRequiredService()); } @@ -40,7 +38,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "BarAPI v1")); - + app.UseHttpsRedirection(); app.UseRouting(); diff --git a/DataAccess/Data/BarDataBase.cs b/DataAccess/Data/BarDataBase.cs new file mode 100644 index 0000000..42e45ae --- /dev/null +++ b/DataAccess/Data/BarDataBase.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; + +namespace DataAccess.Data +{ + public class BarDataBase : DbContext + { + public DbSet Menu { get; set; } + public DbSet Orders { get; set; } + + public BarDataBase () { } + + public BarDataBase(DbContextOptions options) : base(options) { } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (!optionsBuilder.IsConfigured) + { + optionsBuilder.UseSqlServer("Server=tcp:mybarsql.database.windows.net,1433;Initial Catalog=BarDataBase;Persist Security Info=False;User ID=bar_admin;Password=C#isTheBest;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"); + } + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity().Property(order => order.Id).IsRequired().ValueGeneratedOnAdd(); + modelBuilder.Entity().Property(order => order.Status).IsRequired(); + modelBuilder.Entity().Property(order => order.TotalPrice).IsRequired(); + modelBuilder.Entity().Property(menu => menu.Id).IsRequired().ValueGeneratedOnAdd(); + modelBuilder.Entity().Property(menuItem => menuItem.Name).IsRequired().HasMaxLength(50); + modelBuilder.Entity().Property(menuItem => menuItem.Price).IsRequired(); + } + } +} diff --git a/DataAccess/Data/MenuItem.cs b/DataAccess/Data/MenuItem.cs new file mode 100644 index 0000000..90e8ea9 --- /dev/null +++ b/DataAccess/Data/MenuItem.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DataAccess.Data +{ + public class MenuItem + { + public int Id { get; set; } + public string Name { get; set; } + public double Price { get; set; } + } +} diff --git a/DataAccess/Domain/Order.cs b/DataAccess/Data/Order.cs similarity index 65% rename from DataAccess/Domain/Order.cs rename to DataAccess/Data/Order.cs index e9b02c2..01592e4 100644 --- a/DataAccess/Domain/Order.cs +++ b/DataAccess/Data/Order.cs @@ -1,4 +1,8 @@ -namespace DataAccess.Domain +using System; +using System.Collections.Generic; +using System.Text; + +namespace DataAccess.Data { public class Order { @@ -9,7 +13,7 @@ public class Order public enum OrderStatus { - Initiated=1, + Initiated = 1, Finalized } } diff --git a/DataAccess/DataAccess.csproj b/DataAccess/DataAccess.csproj index 84900bb..8522e56 100644 --- a/DataAccess/DataAccess.csproj +++ b/DataAccess/DataAccess.csproj @@ -6,6 +6,7 @@ + diff --git a/DataAccess/Domain/MenuItem.cs b/DataAccess/Domain/MenuItem.cs deleted file mode 100644 index f3709e2..0000000 --- a/DataAccess/Domain/MenuItem.cs +++ /dev/null @@ -1,9 +0,0 @@ - -namespace DataAccess.Domain -{ - public class MenuItem - { - public string Name { get; set; } - public double Price { get; set; } - } -} diff --git a/DataAccess/IMenuRepository.cs b/DataAccess/IMenuRepository.cs deleted file mode 100644 index 96a231b..0000000 --- a/DataAccess/IMenuRepository.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Threading.Tasks; -using DataAccess.Domain; - -namespace DataAccess -{ - public interface IMenuRepository - { - public Task Add(MenuItem item); - public Task GetItem(string name); - public Task Get(); - public Task Remove(string name); - } -} diff --git a/DataAccess/MenuRepository.cs b/DataAccess/MenuRepository.cs deleted file mode 100644 index 0d7b45d..0000000 --- a/DataAccess/MenuRepository.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Data; -using System.Linq; -using System.Threading.Tasks; -using Dapper; -using DataAccess.Domain; - -namespace DataAccess -{ - public class MenuRepository: IMenuRepository - { - private readonly IDbConnection _databaseConnection; - - public MenuRepository(IDbConnection databaseConnection) - { - _databaseConnection = databaseConnection; - } - - public async Task Add(MenuItem item) - { - var query = @"INSERT INTO [dbo].[Menu] ([Name], [Price]) VALUES (@Name, @Price)"; - var queryParameters = new - { - item.Name, item.Price - }; - - await _databaseConnection.ExecuteScalarAsync(query, queryParameters); - } - - public Task GetItem(string name) - { - var query = @"SELECT * FROM [dbo].Menu WHERE Name=@Name"; - var queryParameters = new { Name = name }; - - return _databaseConnection.QueryFirstAsync(query, queryParameters); - } - - public async Task Get() - { - var query = @"SELECT * FROM [dbo].Menu"; - - return (await _databaseConnection.QueryAsync(query)).ToArray(); - } - - public Task Remove(string name) - { - var query = @"DELETE FROM [dbo].[Menu] WHERE Name=@Name"; - var queryParameters = new - { - Name=name - }; - - return _databaseConnection.ExecuteScalarAsync(query, queryParameters); - } - } -} diff --git a/DataAccess/OrderRepository.cs b/DataAccess/OrderRepository.cs deleted file mode 100644 index 8141c95..0000000 --- a/DataAccess/OrderRepository.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Data; -using System.Threading.Tasks; -using Dapper; -using DataAccess.Domain; - -namespace DataAccess -{ - public class OrderRepository:IOrderRepository - { - private readonly IDbConnection _databaseConnection; - - public OrderRepository(IDbConnection databaseConnection) - { - _databaseConnection = databaseConnection; - } - - public async Task Get(int id) - { - var query = @"SELECT * FROM [dbo].[Order] WHERE Id=@Id"; - var queryParameters = new { Id = id }; - return await _databaseConnection.QueryFirstAsync(query, queryParameters); - } - - public async Task Upsert(Order order) - { - var query = @" - UPDATE [dbo].[Order] - SET [TotalPrice] = @TotalPrice, - [Status] = @Status - WHERE [Id] = @Id - IF @@ROWCOUNT = 0 - BEGIN - INSERT INTO [dbo].[Order] ([TotalPrice], [Status]) VALUES (@TotalPrice, @Status) - SELECT SCOPE_IDENTITY() - END"; - - var queryParameters = new - { - order.Id, - TotalPrice = order.TotalPrice, - Status = (int)order.Status - }; - - int? id = await _databaseConnection.ExecuteScalarAsync(query, queryParameters); - if (id == null) - { - return order.Id; - } - - return id.Value; - } - } -} diff --git a/DataAccess/Repository/IMenuRepository.cs b/DataAccess/Repository/IMenuRepository.cs new file mode 100644 index 0000000..4481fd4 --- /dev/null +++ b/DataAccess/Repository/IMenuRepository.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using DataAccess.Data; + +namespace DataAccess.Repository +{ + public interface IMenuRepository + { + Task Add(MenuItem item); + Task GetItem(int id); + Task> GetAllItems(); + Task Update(MenuItem menuItem); + Task Remove(int id); + } +} diff --git a/DataAccess/IOrderRepository.cs b/DataAccess/Repository/IOrderRepository.cs similarity index 74% rename from DataAccess/IOrderRepository.cs rename to DataAccess/Repository/IOrderRepository.cs index ae30732..22a4508 100644 --- a/DataAccess/IOrderRepository.cs +++ b/DataAccess/Repository/IOrderRepository.cs @@ -1,7 +1,7 @@ using System.Threading.Tasks; -using DataAccess.Domain; +using DataAccess.Data; -namespace DataAccess +namespace DataAccess.Repository { public interface IOrderRepository { diff --git a/DataAccess/Repository/MenuRepository.cs b/DataAccess/Repository/MenuRepository.cs new file mode 100644 index 0000000..2d5c9b6 --- /dev/null +++ b/DataAccess/Repository/MenuRepository.cs @@ -0,0 +1,75 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Threading.Tasks; +using DataAccess.Data; +using Microsoft.EntityFrameworkCore.ChangeTracking; + +namespace DataAccess.Repository +{ + public class MenuRepository : IMenuRepository + { + private BarDataBase _barDataBase; + + public MenuRepository() + { + _barDataBase = new BarDataBase(); + } + + public async Task Add(MenuItem item) + { + if (item == null) throw new NullReferenceException(); + EntityEntry added = await _barDataBase.AddAsync(item); + int affacted = await _barDataBase.SaveChangesAsync(); + if(affacted == 1) + { + return item; + } + else + { + return null; + } + } + + public async Task GetItem(int id) + { + MenuItem menuItem = await _barDataBase.Menu.FindAsync(id); + return menuItem; + } + + public Task> GetAllItems() + { + return Task>.FromResult(_barDataBase.Menu.ToList()); + } + + public async Task Update (MenuItem menuItem) + { + _barDataBase.Menu.Update(menuItem); + int affected = await _barDataBase.SaveChangesAsync(); + if(affected == 1) + { + return true; + } + else + { + return false; + } + } + + public async Task Remove(int id) + { + MenuItem menuItem = _barDataBase.Menu.Find(id); + if (menuItem == null) throw new ArgumentException($"No items with id={id} was found"); + _barDataBase.Menu.Remove(menuItem); + int affected = await _barDataBase.SaveChangesAsync(); + if(affected == 1) + { + return true; + } + else + { + return false; + } + } + } +} diff --git a/DataAccess/Repository/OrderRepository.cs b/DataAccess/Repository/OrderRepository.cs new file mode 100644 index 0000000..978a00a --- /dev/null +++ b/DataAccess/Repository/OrderRepository.cs @@ -0,0 +1,50 @@ +using System; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using DataAccess.Data; +using Microsoft.EntityFrameworkCore.ChangeTracking; + +namespace DataAccess.Repository +{ + public class OrderRepository : IOrderRepository + { + private BarDataBase _barDataBase; + + public OrderRepository() + { + _barDataBase = new BarDataBase(); + } + + public async Task Get(int id) + { + Order order = await _barDataBase.Orders.FindAsync(id); + if(order == null) + { + throw new ArgumentException($"No order with {id} was found"); + } + else + { + return order; + } + } + + public async Task Upsert(Order order) + { + Order ord = _barDataBase.Orders.Find(order.Id); + int affrcted; + if (ord == null) + { + _barDataBase.Orders.Add(order); + affrcted = await _barDataBase.SaveChangesAsync(); + return affrcted; + } + else + { + _barDataBase.Orders.Update(order); + affrcted = await _barDataBase.SaveChangesAsync(); + return affrcted; + } + } + } +} diff --git a/DataAccess/db.sql b/DataAccess/db.sql deleted file mode 100644 index e65d4cd..0000000 --- a/DataAccess/db.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE [dbo].[Order]( - [Id] [int] NOT NULL IDENTITY(1,1) PRIMARY KEY, - [TotalPrice] float NOT NULL, - [Status] [int] NOT NULL -) - -CREATE TABLE [dbo].[Menu]( - [Name] [varchar](255) NOT NULL, - [Price] float NOT NULL -) ON [PRIMARY] From 430016c47c9a71dbb2ae208d1bf941051ee3e51d Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Mon, 7 Feb 2022 22:08:13 +0200 Subject: [PATCH 03/25] Add OrderController --- BarAPI/Controllers/MenuController.cs | 1 - BarAPI/Controllers/OrderController.cs | 62 ++++++++++++++++++++++++ BarAPI/Startup.cs | 1 + DataAccess/Repository/OrderRepository.cs | 8 +-- 4 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 BarAPI/Controllers/OrderController.cs diff --git a/BarAPI/Controllers/MenuController.cs b/BarAPI/Controllers/MenuController.cs index 0b8009e..750270e 100644 --- a/BarAPI/Controllers/MenuController.cs +++ b/BarAPI/Controllers/MenuController.cs @@ -70,7 +70,6 @@ public async Task Post([FromBody] MenuItem item) [HttpPut("{id}")] [ProducesResponseType(204)] [ProducesResponseType(400)] - [ProducesResponseType(404)] public async Task Update(int id, [FromBody] MenuItem item) { if(item.Id != id) diff --git a/BarAPI/Controllers/OrderController.cs b/BarAPI/Controllers/OrderController.cs new file mode 100644 index 0000000..87a7021 --- /dev/null +++ b/BarAPI/Controllers/OrderController.cs @@ -0,0 +1,62 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using DataAccess.Data; +using DataAccess.Repository; + +namespace BarAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class OrderController : Controller + { + private readonly IOrderRepository _orderRepository; + + public OrderController(IOrderRepository orderRepository) + { + _orderRepository = orderRepository; + } + + // GET: api//id + [HttpGet("{id}")] + [ProducesResponseType(200, Type = typeof(Order))] + [ProducesResponseType(404)] + public async Task Get(int id) + { + Order order = await _orderRepository.Get(id); + if(order == null) + { + return NotFound(); + } + else + { + return Ok(order); + } + } + + // POST: api// + [HttpPost] + [ProducesResponseType(201, Type = typeof(Order))] + [ProducesResponseType(204)] + [ProducesResponseType(400)] + public async Task Upsert([FromBody] Order item) + { + if (!ModelState.IsValid) + { + return BadRequest(ModelState); + } + int affacted = await _orderRepository.Upsert(item); + if(affacted == -201) + { + return CreatedAtAction(nameof(Upsert), item); + } + if(affacted == -204) + { + return new NoContentResult(); + } + return BadRequest(); + } + } +} diff --git a/BarAPI/Startup.cs b/BarAPI/Startup.cs index 75ce43d..2de8f96 100644 --- a/BarAPI/Startup.cs +++ b/BarAPI/Startup.cs @@ -23,6 +23,7 @@ public void ConfigureServices(IServiceCollection services) services.AddControllers(); services.AddScoped(); + services.AddScoped(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "BarAPI", Version = "v1" }); diff --git a/DataAccess/Repository/OrderRepository.cs b/DataAccess/Repository/OrderRepository.cs index 978a00a..62ea6d9 100644 --- a/DataAccess/Repository/OrderRepository.cs +++ b/DataAccess/Repository/OrderRepository.cs @@ -31,19 +31,19 @@ public async Task Get(int id) public async Task Upsert(Order order) { - Order ord = _barDataBase.Orders.Find(order.Id); + bool ord = _barDataBase.Orders.Contains(order); int affrcted; - if (ord == null) + if (ord == false) { _barDataBase.Orders.Add(order); affrcted = await _barDataBase.SaveChangesAsync(); - return affrcted; + return (affrcted == 1) ? -201 : affrcted; } else { _barDataBase.Orders.Update(order); affrcted = await _barDataBase.SaveChangesAsync(); - return affrcted; + return (affrcted == 1) ? -204 : affrcted; } } } From 6b7f514d7951e6efb9be9b3455228ed7e4689621 Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Tue, 8 Feb 2022 01:44:55 +0200 Subject: [PATCH 04/25] Downgrading EntityFramework Core to 3.1 package --- DataAccess/DataAccess.csproj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/DataAccess/DataAccess.csproj b/DataAccess/DataAccess.csproj index 8522e56..8b7073a 100644 --- a/DataAccess/DataAccess.csproj +++ b/DataAccess/DataAccess.csproj @@ -5,8 +5,7 @@ - - + From 178c2a06f90c615894dc54eebe98810c02a0d91b Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Tue, 8 Feb 2022 01:48:33 +0200 Subject: [PATCH 05/25] Downgrading project to .Net Core 3.1 --- .../DataAccess/ITimeOutOrderRepository.cs | 15 ---- .../InMemoryTimeOutOrderRepository.cs | 30 -------- OrderTimeOutService/OrderTimeOut.cs | 33 +++++++++ OrderTimeOutService/OrderTimeOutFunction.cs | 30 -------- .../storage1.arm.json | 70 +++++++++++++++++++ ...ependencies.OrderTimeOut - Zip Deploy.json | 9 +++ OrderingService/CompleteOrderFunction.cs | 4 +- .../DataAccess/InMemoryOrderRepository.cs | 4 +- Shellys.sln | 10 +-- 9 files changed, 121 insertions(+), 84 deletions(-) delete mode 100644 OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs delete mode 100644 OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs create mode 100644 OrderTimeOutService/OrderTimeOut.cs delete mode 100644 OrderTimeOutService/OrderTimeOutFunction.cs create mode 100644 OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json create mode 100644 OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json diff --git a/OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs b/OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs deleted file mode 100644 index c291b59..0000000 --- a/OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs +++ /dev/null @@ -1,15 +0,0 @@ -using DataAccess.Domain; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; - - -namespace OrderTimeOutService.DataAccess -{ - public interface ITimeOutOrderRepository - { - Task> Get(int orderStatus); - Task Update(Order order); - } -} diff --git a/OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs b/OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs deleted file mode 100644 index 8b0fc84..0000000 --- a/OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs +++ /dev/null @@ -1,30 +0,0 @@ -using DataAccess.Domain; -using System.Linq; -using System.Collections.Generic; -using System.Threading.Tasks; - - -namespace OrderTimeOutService.DataAccess -{ - public class InMemoryTimeOutOrderRepository : ITimeOutOrderRepository - { - private static readonly List _orders = new List(); - - public Task> Get(int orderStatus) - { - return Task.FromResult(_orders.Where(o => ((int)o.Status) == orderStatus)); - } - - public Task Update(Order order) - { - var index = _orders.FindIndex(o => o == order); - if (index == -1) - { - return Task.FromResult(-1); - } - order.Status = OrderStatus.Finalized; - _orders[index] = order; - return Task.FromResult(order.Id); - } - } -} diff --git a/OrderTimeOutService/OrderTimeOut.cs b/OrderTimeOutService/OrderTimeOut.cs new file mode 100644 index 0000000..b08021b --- /dev/null +++ b/OrderTimeOutService/OrderTimeOut.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using DataAccess.Data; +using Microsoft.Azure.WebJobs; +using Microsoft.Azure.WebJobs.Host; +using Microsoft.Extensions.Logging; + +namespace OrderTimeOutService +{ + public class OrderTimeOut + { + private readonly BarDataBase _barDataBase; + + public OrderTimeOut() + { + _barDataBase = new BarDataBase(); + } + + [FunctionName("OrderTimeOut")] + public void Run([TimerTrigger("0 0 0 * * *")]TimerInfo myTimer, ILogger log) + { + log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); + IEnumerable orders = _barDataBase.Orders.Where(ord => ord.Status == OrderStatus.Initiated); + foreach (var ord in orders) + { + ord.Status = OrderStatus.Finalized; + _barDataBase.Orders.Update(ord); + } + _barDataBase.SaveChanges(); + } + } +} diff --git a/OrderTimeOutService/OrderTimeOutFunction.cs b/OrderTimeOutService/OrderTimeOutFunction.cs deleted file mode 100644 index 88c0b88..0000000 --- a/OrderTimeOutService/OrderTimeOutFunction.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using DataAccess.Domain; -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Host; -using Microsoft.Extensions.Logging; -using OrderTimeOutService.DataAccess; - -namespace OrderTimeOutService -{ - public class OrderTimeOutFunction - { - private readonly ITimeOutOrderRepository _orders; - public OrderTimeOutFunction(ITimeOutOrderRepository orders) - { - _orders = orders; - } - [FunctionName("OrderTimeOut")] - public async Task RunAsync([TimerTrigger("0 0 0 * * *")] TimerInfo myTimer, ILogger log) - { - log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); - IEnumerable timeOutOrders = await _orders.Get(1); - foreach (Order ord in timeOutOrders) - { - await _orders.Update(ord); - } - } - } -} diff --git a/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json b/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json new file mode 100644 index 0000000..b9b614e --- /dev/null +++ b/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json @@ -0,0 +1,70 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceGroupName": { + "type": "string", + "defaultValue": "Bar-Service-Group", + "metadata": { + "_parameterType": "resourceGroup", + "description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking." + } + }, + "resourceGroupLocation": { + "type": "string", + "defaultValue": "westeurope", + "metadata": { + "_parameterType": "location", + "description": "Location of the resource group. Resource groups could have different location than resources." + } + }, + "resourceLocation": { + "type": "string", + "defaultValue": "[parameters('resourceGroupLocation')]", + "metadata": { + "_parameterType": "location", + "description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there." + } + } + }, + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "name": "[parameters('resourceGroupName')]", + "location": "[parameters('resourceGroupLocation')]", + "apiVersion": "2019-10-01" + }, + { + "type": "Microsoft.Resources/deployments", + "name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat('storageaccountbarse99a3', subscription().subscriptionId)))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "apiVersion": "2019-10-01", + "dependsOn": [ + "[parameters('resourceGroupName')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "sku": { + "name": "Standard_LRS", + "tier": "Standard" + }, + "kind": "Storage", + "name": "storageaccountbarse99a3", + "type": "Microsoft.Storage/storageAccounts", + "location": "[parameters('resourceLocation')]", + "apiVersion": "2017-10-01" + } + ] + } + } + } + ], + "metadata": { + "_dependencyType": "storage.azure" + } +} \ No newline at end of file diff --git a/OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json b/OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json new file mode 100644 index 0000000..586e945 --- /dev/null +++ b/OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "storage1": { + "resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroupName')]/providers/Microsoft.Storage/storageAccounts/storageaccountbarse99a3", + "type": "storage.azure", + "connectionId": "AzureWebJobsStorage" + } + } +} \ No newline at end of file diff --git a/OrderingService/CompleteOrderFunction.cs b/OrderingService/CompleteOrderFunction.cs index 1175df2..ab1f0bd 100644 --- a/OrderingService/CompleteOrderFunction.cs +++ b/OrderingService/CompleteOrderFunction.cs @@ -1,7 +1,7 @@ using System; using System.Threading.Tasks; -using DataAccess; -using DataAccess.Domain; +using DataAccess.Repository; +using DataAccess.Data; using Microsoft.Azure.WebJobs; using Microsoft.Extensions.Logging; diff --git a/OrderingService/DataAccess/InMemoryOrderRepository.cs b/OrderingService/DataAccess/InMemoryOrderRepository.cs index 920a435..5052a70 100644 --- a/OrderingService/DataAccess/InMemoryOrderRepository.cs +++ b/OrderingService/DataAccess/InMemoryOrderRepository.cs @@ -3,8 +3,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using DataAccess; -using DataAccess.Domain; +using DataAccess.Data; +using DataAccess.Repository; namespace OrderingService.DataAccess { diff --git a/Shellys.sln b/Shellys.sln index d1e4084..14b5804 100644 --- a/Shellys.sln +++ b/Shellys.sln @@ -11,7 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnqueueCompleteOrderCommand EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataAccess", "DataAccess\DataAccess.csproj", "{C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrderTimeOutService", "OrderTimeOutService\OrderTimeOutService.csproj", "{19AF5413-122C-4A11-B6D7-E3A8BDEB8111}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrderTimeOutService", "OrderTimeOutService\OrderTimeOutService.csproj", "{5C481AE0-DE38-48CB-84C6-43EECCC24BE0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -35,10 +35,10 @@ Global {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Debug|Any CPU.Build.0 = Debug|Any CPU {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Release|Any CPU.ActiveCfg = Release|Any CPU {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Release|Any CPU.Build.0 = Release|Any CPU - {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Debug|Any CPU.Build.0 = Debug|Any CPU - {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Release|Any CPU.ActiveCfg = Release|Any CPU - {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Release|Any CPU.Build.0 = Release|Any CPU + {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 5c61161caad4e579c723baf0053b0e5b2b338acc Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Tue, 8 Feb 2022 01:59:28 +0200 Subject: [PATCH 06/25] Revert "Downgrading project to .Net Core 3.1" This reverts commit 178c2a06f90c615894dc54eebe98810c02a0d91b. --- .../DataAccess/ITimeOutOrderRepository.cs | 15 ++++ .../InMemoryTimeOutOrderRepository.cs | 30 ++++++++ OrderTimeOutService/OrderTimeOut.cs | 33 --------- OrderTimeOutService/OrderTimeOutFunction.cs | 30 ++++++++ .../storage1.arm.json | 70 ------------------- ...ependencies.OrderTimeOut - Zip Deploy.json | 9 --- OrderingService/CompleteOrderFunction.cs | 4 +- .../DataAccess/InMemoryOrderRepository.cs | 4 +- Shellys.sln | 10 +-- 9 files changed, 84 insertions(+), 121 deletions(-) create mode 100644 OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs create mode 100644 OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs delete mode 100644 OrderTimeOutService/OrderTimeOut.cs create mode 100644 OrderTimeOutService/OrderTimeOutFunction.cs delete mode 100644 OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json delete mode 100644 OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json diff --git a/OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs b/OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs new file mode 100644 index 0000000..c291b59 --- /dev/null +++ b/OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs @@ -0,0 +1,15 @@ +using DataAccess.Domain; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + + +namespace OrderTimeOutService.DataAccess +{ + public interface ITimeOutOrderRepository + { + Task> Get(int orderStatus); + Task Update(Order order); + } +} diff --git a/OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs b/OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs new file mode 100644 index 0000000..8b0fc84 --- /dev/null +++ b/OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs @@ -0,0 +1,30 @@ +using DataAccess.Domain; +using System.Linq; +using System.Collections.Generic; +using System.Threading.Tasks; + + +namespace OrderTimeOutService.DataAccess +{ + public class InMemoryTimeOutOrderRepository : ITimeOutOrderRepository + { + private static readonly List _orders = new List(); + + public Task> Get(int orderStatus) + { + return Task.FromResult(_orders.Where(o => ((int)o.Status) == orderStatus)); + } + + public Task Update(Order order) + { + var index = _orders.FindIndex(o => o == order); + if (index == -1) + { + return Task.FromResult(-1); + } + order.Status = OrderStatus.Finalized; + _orders[index] = order; + return Task.FromResult(order.Id); + } + } +} diff --git a/OrderTimeOutService/OrderTimeOut.cs b/OrderTimeOutService/OrderTimeOut.cs deleted file mode 100644 index b08021b..0000000 --- a/OrderTimeOutService/OrderTimeOut.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using DataAccess.Data; -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Host; -using Microsoft.Extensions.Logging; - -namespace OrderTimeOutService -{ - public class OrderTimeOut - { - private readonly BarDataBase _barDataBase; - - public OrderTimeOut() - { - _barDataBase = new BarDataBase(); - } - - [FunctionName("OrderTimeOut")] - public void Run([TimerTrigger("0 0 0 * * *")]TimerInfo myTimer, ILogger log) - { - log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); - IEnumerable orders = _barDataBase.Orders.Where(ord => ord.Status == OrderStatus.Initiated); - foreach (var ord in orders) - { - ord.Status = OrderStatus.Finalized; - _barDataBase.Orders.Update(ord); - } - _barDataBase.SaveChanges(); - } - } -} diff --git a/OrderTimeOutService/OrderTimeOutFunction.cs b/OrderTimeOutService/OrderTimeOutFunction.cs new file mode 100644 index 0000000..88c0b88 --- /dev/null +++ b/OrderTimeOutService/OrderTimeOutFunction.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using DataAccess.Domain; +using Microsoft.Azure.WebJobs; +using Microsoft.Azure.WebJobs.Host; +using Microsoft.Extensions.Logging; +using OrderTimeOutService.DataAccess; + +namespace OrderTimeOutService +{ + public class OrderTimeOutFunction + { + private readonly ITimeOutOrderRepository _orders; + public OrderTimeOutFunction(ITimeOutOrderRepository orders) + { + _orders = orders; + } + [FunctionName("OrderTimeOut")] + public async Task RunAsync([TimerTrigger("0 0 0 * * *")] TimerInfo myTimer, ILogger log) + { + log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); + IEnumerable timeOutOrders = await _orders.Get(1); + foreach (Order ord in timeOutOrders) + { + await _orders.Update(ord); + } + } + } +} diff --git a/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json b/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json deleted file mode 100644 index b9b614e..0000000 --- a/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "resourceGroupName": { - "type": "string", - "defaultValue": "Bar-Service-Group", - "metadata": { - "_parameterType": "resourceGroup", - "description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking." - } - }, - "resourceGroupLocation": { - "type": "string", - "defaultValue": "westeurope", - "metadata": { - "_parameterType": "location", - "description": "Location of the resource group. Resource groups could have different location than resources." - } - }, - "resourceLocation": { - "type": "string", - "defaultValue": "[parameters('resourceGroupLocation')]", - "metadata": { - "_parameterType": "location", - "description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there." - } - } - }, - "resources": [ - { - "type": "Microsoft.Resources/resourceGroups", - "name": "[parameters('resourceGroupName')]", - "location": "[parameters('resourceGroupLocation')]", - "apiVersion": "2019-10-01" - }, - { - "type": "Microsoft.Resources/deployments", - "name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat('storageaccountbarse99a3', subscription().subscriptionId)))]", - "resourceGroup": "[parameters('resourceGroupName')]", - "apiVersion": "2019-10-01", - "dependsOn": [ - "[parameters('resourceGroupName')]" - ], - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - { - "sku": { - "name": "Standard_LRS", - "tier": "Standard" - }, - "kind": "Storage", - "name": "storageaccountbarse99a3", - "type": "Microsoft.Storage/storageAccounts", - "location": "[parameters('resourceLocation')]", - "apiVersion": "2017-10-01" - } - ] - } - } - } - ], - "metadata": { - "_dependencyType": "storage.azure" - } -} \ No newline at end of file diff --git a/OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json b/OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json deleted file mode 100644 index 586e945..0000000 --- a/OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "dependencies": { - "storage1": { - "resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroupName')]/providers/Microsoft.Storage/storageAccounts/storageaccountbarse99a3", - "type": "storage.azure", - "connectionId": "AzureWebJobsStorage" - } - } -} \ No newline at end of file diff --git a/OrderingService/CompleteOrderFunction.cs b/OrderingService/CompleteOrderFunction.cs index ab1f0bd..1175df2 100644 --- a/OrderingService/CompleteOrderFunction.cs +++ b/OrderingService/CompleteOrderFunction.cs @@ -1,7 +1,7 @@ using System; using System.Threading.Tasks; -using DataAccess.Repository; -using DataAccess.Data; +using DataAccess; +using DataAccess.Domain; using Microsoft.Azure.WebJobs; using Microsoft.Extensions.Logging; diff --git a/OrderingService/DataAccess/InMemoryOrderRepository.cs b/OrderingService/DataAccess/InMemoryOrderRepository.cs index 5052a70..920a435 100644 --- a/OrderingService/DataAccess/InMemoryOrderRepository.cs +++ b/OrderingService/DataAccess/InMemoryOrderRepository.cs @@ -3,8 +3,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using DataAccess.Data; -using DataAccess.Repository; +using DataAccess; +using DataAccess.Domain; namespace OrderingService.DataAccess { diff --git a/Shellys.sln b/Shellys.sln index 14b5804..d1e4084 100644 --- a/Shellys.sln +++ b/Shellys.sln @@ -11,7 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnqueueCompleteOrderCommand EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataAccess", "DataAccess\DataAccess.csproj", "{C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrderTimeOutService", "OrderTimeOutService\OrderTimeOutService.csproj", "{5C481AE0-DE38-48CB-84C6-43EECCC24BE0}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrderTimeOutService", "OrderTimeOutService\OrderTimeOutService.csproj", "{19AF5413-122C-4A11-B6D7-E3A8BDEB8111}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -35,10 +35,10 @@ Global {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Debug|Any CPU.Build.0 = Debug|Any CPU {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Release|Any CPU.ActiveCfg = Release|Any CPU {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Release|Any CPU.Build.0 = Release|Any CPU - {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Release|Any CPU.Build.0 = Release|Any CPU + {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From f396842e3a82a2ff3f02ac7489dba5067575df02 Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Tue, 8 Feb 2022 02:03:03 +0200 Subject: [PATCH 07/25] Revert "Revert "Downgrading project to .Net Core 3.1"" This reverts commit 5c61161caad4e579c723baf0053b0e5b2b338acc. --- .../DataAccess/ITimeOutOrderRepository.cs | 15 ---- .../InMemoryTimeOutOrderRepository.cs | 30 -------- OrderTimeOutService/OrderTimeOut.cs | 33 +++++++++ OrderTimeOutService/OrderTimeOutFunction.cs | 30 -------- .../storage1.arm.json | 70 +++++++++++++++++++ ...ependencies.OrderTimeOut - Zip Deploy.json | 9 +++ OrderingService/CompleteOrderFunction.cs | 4 +- .../DataAccess/InMemoryOrderRepository.cs | 4 +- Shellys.sln | 10 +-- 9 files changed, 121 insertions(+), 84 deletions(-) delete mode 100644 OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs delete mode 100644 OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs create mode 100644 OrderTimeOutService/OrderTimeOut.cs delete mode 100644 OrderTimeOutService/OrderTimeOutFunction.cs create mode 100644 OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json create mode 100644 OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json diff --git a/OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs b/OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs deleted file mode 100644 index c291b59..0000000 --- a/OrderTimeOutService/DataAccess/ITimeOutOrderRepository.cs +++ /dev/null @@ -1,15 +0,0 @@ -using DataAccess.Domain; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; - - -namespace OrderTimeOutService.DataAccess -{ - public interface ITimeOutOrderRepository - { - Task> Get(int orderStatus); - Task Update(Order order); - } -} diff --git a/OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs b/OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs deleted file mode 100644 index 8b0fc84..0000000 --- a/OrderTimeOutService/DataAccess/InMemoryTimeOutOrderRepository.cs +++ /dev/null @@ -1,30 +0,0 @@ -using DataAccess.Domain; -using System.Linq; -using System.Collections.Generic; -using System.Threading.Tasks; - - -namespace OrderTimeOutService.DataAccess -{ - public class InMemoryTimeOutOrderRepository : ITimeOutOrderRepository - { - private static readonly List _orders = new List(); - - public Task> Get(int orderStatus) - { - return Task.FromResult(_orders.Where(o => ((int)o.Status) == orderStatus)); - } - - public Task Update(Order order) - { - var index = _orders.FindIndex(o => o == order); - if (index == -1) - { - return Task.FromResult(-1); - } - order.Status = OrderStatus.Finalized; - _orders[index] = order; - return Task.FromResult(order.Id); - } - } -} diff --git a/OrderTimeOutService/OrderTimeOut.cs b/OrderTimeOutService/OrderTimeOut.cs new file mode 100644 index 0000000..b08021b --- /dev/null +++ b/OrderTimeOutService/OrderTimeOut.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using DataAccess.Data; +using Microsoft.Azure.WebJobs; +using Microsoft.Azure.WebJobs.Host; +using Microsoft.Extensions.Logging; + +namespace OrderTimeOutService +{ + public class OrderTimeOut + { + private readonly BarDataBase _barDataBase; + + public OrderTimeOut() + { + _barDataBase = new BarDataBase(); + } + + [FunctionName("OrderTimeOut")] + public void Run([TimerTrigger("0 0 0 * * *")]TimerInfo myTimer, ILogger log) + { + log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); + IEnumerable orders = _barDataBase.Orders.Where(ord => ord.Status == OrderStatus.Initiated); + foreach (var ord in orders) + { + ord.Status = OrderStatus.Finalized; + _barDataBase.Orders.Update(ord); + } + _barDataBase.SaveChanges(); + } + } +} diff --git a/OrderTimeOutService/OrderTimeOutFunction.cs b/OrderTimeOutService/OrderTimeOutFunction.cs deleted file mode 100644 index 88c0b88..0000000 --- a/OrderTimeOutService/OrderTimeOutFunction.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using DataAccess.Domain; -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Host; -using Microsoft.Extensions.Logging; -using OrderTimeOutService.DataAccess; - -namespace OrderTimeOutService -{ - public class OrderTimeOutFunction - { - private readonly ITimeOutOrderRepository _orders; - public OrderTimeOutFunction(ITimeOutOrderRepository orders) - { - _orders = orders; - } - [FunctionName("OrderTimeOut")] - public async Task RunAsync([TimerTrigger("0 0 0 * * *")] TimerInfo myTimer, ILogger log) - { - log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); - IEnumerable timeOutOrders = await _orders.Get(1); - foreach (Order ord in timeOutOrders) - { - await _orders.Update(ord); - } - } - } -} diff --git a/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json b/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json new file mode 100644 index 0000000..b9b614e --- /dev/null +++ b/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json @@ -0,0 +1,70 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceGroupName": { + "type": "string", + "defaultValue": "Bar-Service-Group", + "metadata": { + "_parameterType": "resourceGroup", + "description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking." + } + }, + "resourceGroupLocation": { + "type": "string", + "defaultValue": "westeurope", + "metadata": { + "_parameterType": "location", + "description": "Location of the resource group. Resource groups could have different location than resources." + } + }, + "resourceLocation": { + "type": "string", + "defaultValue": "[parameters('resourceGroupLocation')]", + "metadata": { + "_parameterType": "location", + "description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there." + } + } + }, + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "name": "[parameters('resourceGroupName')]", + "location": "[parameters('resourceGroupLocation')]", + "apiVersion": "2019-10-01" + }, + { + "type": "Microsoft.Resources/deployments", + "name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat('storageaccountbarse99a3', subscription().subscriptionId)))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "apiVersion": "2019-10-01", + "dependsOn": [ + "[parameters('resourceGroupName')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "sku": { + "name": "Standard_LRS", + "tier": "Standard" + }, + "kind": "Storage", + "name": "storageaccountbarse99a3", + "type": "Microsoft.Storage/storageAccounts", + "location": "[parameters('resourceLocation')]", + "apiVersion": "2017-10-01" + } + ] + } + } + } + ], + "metadata": { + "_dependencyType": "storage.azure" + } +} \ No newline at end of file diff --git a/OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json b/OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json new file mode 100644 index 0000000..586e945 --- /dev/null +++ b/OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "storage1": { + "resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroupName')]/providers/Microsoft.Storage/storageAccounts/storageaccountbarse99a3", + "type": "storage.azure", + "connectionId": "AzureWebJobsStorage" + } + } +} \ No newline at end of file diff --git a/OrderingService/CompleteOrderFunction.cs b/OrderingService/CompleteOrderFunction.cs index 1175df2..ab1f0bd 100644 --- a/OrderingService/CompleteOrderFunction.cs +++ b/OrderingService/CompleteOrderFunction.cs @@ -1,7 +1,7 @@ using System; using System.Threading.Tasks; -using DataAccess; -using DataAccess.Domain; +using DataAccess.Repository; +using DataAccess.Data; using Microsoft.Azure.WebJobs; using Microsoft.Extensions.Logging; diff --git a/OrderingService/DataAccess/InMemoryOrderRepository.cs b/OrderingService/DataAccess/InMemoryOrderRepository.cs index 920a435..5052a70 100644 --- a/OrderingService/DataAccess/InMemoryOrderRepository.cs +++ b/OrderingService/DataAccess/InMemoryOrderRepository.cs @@ -3,8 +3,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using DataAccess; -using DataAccess.Domain; +using DataAccess.Data; +using DataAccess.Repository; namespace OrderingService.DataAccess { diff --git a/Shellys.sln b/Shellys.sln index d1e4084..14b5804 100644 --- a/Shellys.sln +++ b/Shellys.sln @@ -11,7 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnqueueCompleteOrderCommand EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataAccess", "DataAccess\DataAccess.csproj", "{C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrderTimeOutService", "OrderTimeOutService\OrderTimeOutService.csproj", "{19AF5413-122C-4A11-B6D7-E3A8BDEB8111}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrderTimeOutService", "OrderTimeOutService\OrderTimeOutService.csproj", "{5C481AE0-DE38-48CB-84C6-43EECCC24BE0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -35,10 +35,10 @@ Global {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Debug|Any CPU.Build.0 = Debug|Any CPU {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Release|Any CPU.ActiveCfg = Release|Any CPU {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Release|Any CPU.Build.0 = Release|Any CPU - {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Debug|Any CPU.Build.0 = Debug|Any CPU - {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Release|Any CPU.ActiveCfg = Release|Any CPU - {19AF5413-122C-4A11-B6D7-E3A8BDEB8111}.Release|Any CPU.Build.0 = Release|Any CPU + {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 08f5d42530f34ff6a05ed8ef28b4025d0d768e2b Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Tue, 8 Feb 2022 10:25:48 +0200 Subject: [PATCH 08/25] Update BarDataBase.cs --- DataAccess/Data/BarDataBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DataAccess/Data/BarDataBase.cs b/DataAccess/Data/BarDataBase.cs index 42e45ae..fa24f06 100644 --- a/DataAccess/Data/BarDataBase.cs +++ b/DataAccess/Data/BarDataBase.cs @@ -16,7 +16,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { - optionsBuilder.UseSqlServer("Server=tcp:mybarsql.database.windows.net,1433;Initial Catalog=BarDataBase;Persist Security Info=False;User ID=bar_admin;Password=C#isTheBest;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"); + optionsBuilder.UseSqlServer(""); } } From fc75e73d9f3f8363b89f726722024a55b17d562f Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Sun, 13 Feb 2022 17:26:50 +0200 Subject: [PATCH 09/25] Update IMenuRepository.cs --- DataAccess/Repository/IMenuRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DataAccess/Repository/IMenuRepository.cs b/DataAccess/Repository/IMenuRepository.cs index 4481fd4..acea6c2 100644 --- a/DataAccess/Repository/IMenuRepository.cs +++ b/DataAccess/Repository/IMenuRepository.cs @@ -6,7 +6,7 @@ namespace DataAccess.Repository { public interface IMenuRepository { - Task Add(MenuItem item); + Task Add(MenuItem item); Task GetItem(int id); Task> GetAllItems(); Task Update(MenuItem menuItem); From 49e8c01ae05c457c15bd0a0185954dbf3cce10d2 Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Sun, 13 Feb 2022 17:27:30 +0200 Subject: [PATCH 10/25] Update MenuRepository.cs --- DataAccess/Repository/MenuRepository.cs | 53 ++++++++----------------- 1 file changed, 17 insertions(+), 36 deletions(-) diff --git a/DataAccess/Repository/MenuRepository.cs b/DataAccess/Repository/MenuRepository.cs index 2d5c9b6..9f58473 100644 --- a/DataAccess/Repository/MenuRepository.cs +++ b/DataAccess/Repository/MenuRepository.cs @@ -16,25 +16,18 @@ public MenuRepository() _barDataBase = new BarDataBase(); } - public async Task Add(MenuItem item) + public Task Add(MenuItem item) { - if (item == null) throw new NullReferenceException(); - EntityEntry added = await _barDataBase.AddAsync(item); - int affacted = await _barDataBase.SaveChangesAsync(); - if(affacted == 1) - { - return item; - } - else - { - return null; - } + EntityEntry added = _barDataBase.Add(item); + int affected = _barDataBase.SaveChanges(); + bool isAdded = (affected == 1) ? true : false; + return Task.FromResult(isAdded); } - public async Task GetItem(int id) + public Task GetItem(int id) { - MenuItem menuItem = await _barDataBase.Menu.FindAsync(id); - return menuItem; + MenuItem menuItem = _barDataBase.Menu.Find(id); + return Task.FromResult(menuItem); } public Task> GetAllItems() @@ -42,34 +35,22 @@ public Task> GetAllItems() return Task>.FromResult(_barDataBase.Menu.ToList()); } - public async Task Update (MenuItem menuItem) + public Task Update (MenuItem menuItem) { _barDataBase.Menu.Update(menuItem); - int affected = await _barDataBase.SaveChangesAsync(); - if(affected == 1) - { - return true; - } - else - { - return false; - } + int affected = _barDataBase.SaveChanges(); + bool isUpdate = (affected == 1) ? true : false; + return Task.FromResult(isUpdate); } - public async Task Remove(int id) + public Task Remove(int id) { MenuItem menuItem = _barDataBase.Menu.Find(id); - if (menuItem == null) throw new ArgumentException($"No items with id={id} was found"); + if (menuItem == null) return Task.FromResult(false); _barDataBase.Menu.Remove(menuItem); - int affected = await _barDataBase.SaveChangesAsync(); - if(affected == 1) - { - return true; - } - else - { - return false; - } + int affected = _barDataBase.SaveChanges(); + bool isRemove = (affected == 1) ? true : false; + return Task.FromResult(isRemove); } } } From 2d627d9baa2145c6e546dbbcbcf7cf002485cfe5 Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Sun, 13 Feb 2022 17:28:14 +0200 Subject: [PATCH 11/25] Update MenuController.cs --- BarAPI/Controllers/MenuController.cs | 48 ++++++++++++++-------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/BarAPI/Controllers/MenuController.cs b/BarAPI/Controllers/MenuController.cs index 750270e..4e0c1b8 100644 --- a/BarAPI/Controllers/MenuController.cs +++ b/BarAPI/Controllers/MenuController.cs @@ -49,21 +49,21 @@ public async Task Get(int id) [ProducesResponseType(400)] public async Task Post([FromBody] MenuItem item) { - if(item == null) - { - return BadRequest(); - } - if(!ModelState.IsValid) + if(item == null) return BadRequest(); + if(!ModelState.IsValid) return BadRequest(ModelState); + MenuItem exist = await _menuRepository.GetItem(item.Id); + if (string.IsNullOrWhiteSpace(item.Name)) return BadRequest("Item name is Null or contain only WhiteSpace"); + if (item.Price <= 0) return BadRequest("Item price must be above zero"); + if (exist != null) return BadRequest($"Item with id = {item.Id} already exists"); + bool isAdded = await _menuRepository.Add(item); + if (isAdded) { - return BadRequest(ModelState); + return CreatedAtAction(nameof(Post), item); } - MenuItem exist = await _menuRepository.GetItem(item.Id); - if (exist != null) + else { - return BadRequest($"Item with id= {item.Id} already exists"); + return BadRequest(); } - MenuItem menuItem = await _menuRepository.Add(item); - return CreatedAtAction(nameof(Post), menuItem); } // PUT api//5 @@ -72,16 +72,19 @@ public async Task Post([FromBody] MenuItem item) [ProducesResponseType(400)] public async Task Update(int id, [FromBody] MenuItem item) { - if(item.Id != id) + if(item.Id != id) return BadRequest(); + if(!ModelState.IsValid) return BadRequest(ModelState); + if (string.IsNullOrWhiteSpace(item.Name)) return BadRequest("Item name is Null or contain only WhiteSpace"); + if (item.Price <= 0) return BadRequest("Item price must be above zero"); + bool isUpdate = await _menuRepository.Update(item); + if(isUpdate) { - return BadRequest(); + return new NoContentResult(); } - if(!ModelState.IsValid) + else { - return BadRequest(ModelState); + return BadRequest(); } - await _menuRepository.Update(item); - return new NoContentResult(); } // DELETE api//id @@ -91,18 +94,15 @@ public async Task Update(int id, [FromBody] MenuItem item) public async Task Delete(int id) { var exist = await _menuRepository.GetItem(id); - if(exist == null) - { - return NotFound(); - } - bool deleted = await _menuRepository.Remove(id); - if (deleted) + if(exist == null) return NotFound(); + bool isDelete = await _menuRepository.Remove(id); + if (isDelete) { return new NoContentResult(); } else { - return BadRequest($"Item with id={id} was found but faild to delete"); + return BadRequest($"Item with id = {id} was found but faild to delete"); } } } From 15b9dd22e73c1b44b154d76b729e83650f5860ac Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Sun, 13 Feb 2022 18:25:10 +0200 Subject: [PATCH 12/25] Add method GetOrdersByStatus --- DataAccess/Repository/IOrderRepository.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/DataAccess/Repository/IOrderRepository.cs b/DataAccess/Repository/IOrderRepository.cs index 22a4508..d171979 100644 --- a/DataAccess/Repository/IOrderRepository.cs +++ b/DataAccess/Repository/IOrderRepository.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using DataAccess.Data; namespace DataAccess.Repository @@ -6,6 +7,7 @@ namespace DataAccess.Repository public interface IOrderRepository { Task Get(int id); - Task Upsert(Order order); + Task> GetOrdersByStatus(OrderStatus status); + Task Upsert(Order order); } } From bfc07700b91b245cfc9289c860abe3a9d060191f Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Sun, 13 Feb 2022 18:26:36 +0200 Subject: [PATCH 13/25] Implement GetOrdersByStatus --- DataAccess/Repository/OrderRepository.cs | 31 +++++++++++------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/DataAccess/Repository/OrderRepository.cs b/DataAccess/Repository/OrderRepository.cs index 62ea6d9..f35fb5a 100644 --- a/DataAccess/Repository/OrderRepository.cs +++ b/DataAccess/Repository/OrderRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Data; using System.Linq; using System.Threading.Tasks; @@ -16,35 +17,31 @@ public OrderRepository() _barDataBase = new BarDataBase(); } - public async Task Get(int id) + public Task Get(int id) { - Order order = await _barDataBase.Orders.FindAsync(id); - if(order == null) - { - throw new ArgumentException($"No order with {id} was found"); - } - else - { - return order; - } + Order order = _barDataBase.Orders.Find(id); + return Task.FromResult(order); + } + + public Task> GetOrdersByStatus(OrderStatus status) + { + return Task>.FromResult(_barDataBase.Orders.Where(order => order.Status == status).ToList()); } - public async Task Upsert(Order order) + public Task Upsert(Order order) { - bool ord = _barDataBase.Orders.Contains(order); - int affrcted; + bool ord = _barDataBase.Orders.Contains(order); if (ord == false) { _barDataBase.Orders.Add(order); - affrcted = await _barDataBase.SaveChangesAsync(); - return (affrcted == 1) ? -201 : affrcted; } else { _barDataBase.Orders.Update(order); - affrcted = await _barDataBase.SaveChangesAsync(); - return (affrcted == 1) ? -204 : affrcted; } + int affected = _barDataBase.SaveChanges(); + bool isUpsert = (affected == 1) ? true : false; + return Task.FromResult(isUpsert); } } } From 15a58442ece2bbc2fd334aa707c0b6a609a5faf0 Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Sun, 13 Feb 2022 18:27:09 +0200 Subject: [PATCH 14/25] Update OrderController.cs --- BarAPI/Controllers/OrderController.cs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/BarAPI/Controllers/OrderController.cs b/BarAPI/Controllers/OrderController.cs index 87a7021..08a5945 100644 --- a/BarAPI/Controllers/OrderController.cs +++ b/BarAPI/Controllers/OrderController.cs @@ -38,25 +38,20 @@ public async Task Get(int id) // POST: api// [HttpPost] - [ProducesResponseType(201, Type = typeof(Order))] - [ProducesResponseType(204)] + [ProducesResponseType(200, Type = typeof(Order))] [ProducesResponseType(400)] public async Task Upsert([FromBody] Order item) { - if (!ModelState.IsValid) - { - return BadRequest(ModelState); - } - int affacted = await _orderRepository.Upsert(item); - if(affacted == -201) + if (!ModelState.IsValid) return BadRequest(ModelState); + bool isUpsert = await _orderRepository.Upsert(item); + if (isUpsert) { - return CreatedAtAction(nameof(Upsert), item); + return Ok(item); } - if(affacted == -204) + else { - return new NoContentResult(); + return BadRequest(); } - return BadRequest(); } } } From a4ecb76e652c0cb6472bacccf1a1b470954b4274 Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Sun, 13 Feb 2022 18:28:39 +0200 Subject: [PATCH 15/25] Update OrderTimeOut.cs --- OrderTimeOutService/OrderTimeOut.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/OrderTimeOutService/OrderTimeOut.cs b/OrderTimeOutService/OrderTimeOut.cs index b08021b..25466aa 100644 --- a/OrderTimeOutService/OrderTimeOut.cs +++ b/OrderTimeOutService/OrderTimeOut.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using DataAccess.Data; +using DataAccess.Repository; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Host; using Microsoft.Extensions.Logging; @@ -10,24 +12,23 @@ namespace OrderTimeOutService { public class OrderTimeOut { - private readonly BarDataBase _barDataBase; + private readonly OrderRepository _orderRepository; public OrderTimeOut() { - _barDataBase = new BarDataBase(); + _orderRepository = new OrderRepository(); } [FunctionName("OrderTimeOut")] - public void Run([TimerTrigger("0 0 0 * * *")]TimerInfo myTimer, ILogger log) + public async Task Run([TimerTrigger("0 0 0 * * *")]TimerInfo myTimer, ILogger log) { log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); - IEnumerable orders = _barDataBase.Orders.Where(ord => ord.Status == OrderStatus.Initiated); - foreach (var ord in orders) + List initiatedOrders = await _orderRepository.GetOrdersByStatus(OrderStatus.Initiated); + foreach (var order in initiatedOrders) { - ord.Status = OrderStatus.Finalized; - _barDataBase.Orders.Update(ord); + order.Status = OrderStatus.Finalized; + await _orderRepository.Upsert(order); } - _barDataBase.SaveChanges(); } } } From 42975451bac7def772c673fe450f1572f7f12184 Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Wed, 16 Feb 2022 01:14:33 +0200 Subject: [PATCH 16/25] Implement method UploadContentBlobAsync --- .../BlobService/BlobStorage.cs | 29 +++++++++++++++++++ .../BlobService/IBlobStorage.cs | 12 ++++++++ 2 files changed, 41 insertions(+) create mode 100644 OrderTimeOutService/BlobService/BlobStorage.cs create mode 100644 OrderTimeOutService/BlobService/IBlobStorage.cs diff --git a/OrderTimeOutService/BlobService/BlobStorage.cs b/OrderTimeOutService/BlobService/BlobStorage.cs new file mode 100644 index 0000000..8b96f3f --- /dev/null +++ b/OrderTimeOutService/BlobService/BlobStorage.cs @@ -0,0 +1,29 @@ +using Azure.Storage.Blobs; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using System.Text; +using System.IO; + +namespace OrderTimeOutService.BlobService +{ + public class BlobStorage : IBlobStorage + { + private readonly BlobServiceClient _blobServiceClient; + private readonly string _blobContainerName; + + public BlobStorage(IConfigurationBuilder configuration) + { + _blobServiceClient = new BlobServiceClient(configuration.Build().GetConnectionString("BlobStorage")); + _blobContainerName = configuration.Build().GetSection("Containers").GetSection("OrderTimeOutReport").Value; + } + + public async Task UploadContentBlobAsync(string content, string fileName) + { + BlobContainerClient containerClient = _blobServiceClient.GetBlobContainerClient(_blobContainerName); + BlobClient blobClient = containerClient.GetBlobClient(fileName); + byte[] bytes = Encoding.UTF8.GetBytes(content); + MemoryStream memoryStream = new MemoryStream(bytes); + await blobClient.UploadAsync(memoryStream); + } + } +} diff --git a/OrderTimeOutService/BlobService/IBlobStorage.cs b/OrderTimeOutService/BlobService/IBlobStorage.cs new file mode 100644 index 0000000..2091d1d --- /dev/null +++ b/OrderTimeOutService/BlobService/IBlobStorage.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace OrderTimeOutService.BlobService +{ + public interface IBlobStorage + { + Task UploadContentBlobAsync(string content, string fileName); + } +} From 3f018dcf9e06736dd0ece765f3208976b277acc8 Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Wed, 16 Feb 2022 01:22:42 +0200 Subject: [PATCH 17/25] Implement report feature --- OrderTimeOutService/OrderTimeOut.cs | 18 ++++++++++++++++-- OrderTimeOutService/OrderTimeOutService.csproj | 14 +++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/OrderTimeOutService/OrderTimeOut.cs b/OrderTimeOutService/OrderTimeOut.cs index 25466aa..447ed0e 100644 --- a/OrderTimeOutService/OrderTimeOut.cs +++ b/OrderTimeOutService/OrderTimeOut.cs @@ -1,22 +1,30 @@ using System; +using System.IO; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using DataAccess.Data; using DataAccess.Repository; using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Host; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; +using OrderTimeOutService.BlobService; +using System.Globalization; namespace OrderTimeOutService { public class OrderTimeOut { private readonly OrderRepository _orderRepository; + private readonly BlobStorage _blobStorage; + private readonly IConfigurationBuilder _configuration; public OrderTimeOut() { _orderRepository = new OrderRepository(); + _configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); + _blobStorage = new BlobStorage(_configuration); } [FunctionName("OrderTimeOut")] @@ -24,11 +32,17 @@ public async Task Run([TimerTrigger("0 0 0 * * *")]TimerInfo myTimer, ILogger lo { log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); List initiatedOrders = await _orderRepository.GetOrdersByStatus(OrderStatus.Initiated); + double finalizedOrdersSum = 0; foreach (var order in initiatedOrders) { order.Status = OrderStatus.Finalized; + finalizedOrdersSum += order.TotalPrice; await _orderRepository.Upsert(order); } + string reportData = $"{initiatedOrders.Count},{finalizedOrdersSum.ToString(new CultureInfo("en-us",false))}"; + DateTime dateTime = DateTime.Now; + string reportFileName = $"{dateTime.Day}_{dateTime.Month}_{dateTime.Year}_report.csv"; + await _blobStorage.UploadContentBlobAsync(reportData, reportFileName); } } } diff --git a/OrderTimeOutService/OrderTimeOutService.csproj b/OrderTimeOutService/OrderTimeOutService.csproj index 6eaab25..4005bae 100644 --- a/OrderTimeOutService/OrderTimeOutService.csproj +++ b/OrderTimeOutService/OrderTimeOutService.csproj @@ -1,9 +1,21 @@ - + netcoreapp3.1 v3 + + + + + PreserveNewest + + + + + + + From f3fbb58dac8179a46ef2d38e56422f6ce7270fae Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Wed, 16 Feb 2022 01:39:36 +0200 Subject: [PATCH 18/25] Create profile.arm.json --- .../profile.arm.json | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/profile.arm.json diff --git a/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/profile.arm.json b/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/profile.arm.json new file mode 100644 index 0000000..d9cbd9b --- /dev/null +++ b/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/profile.arm.json @@ -0,0 +1,175 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_dependencyType": "function.windows.appService" + }, + "parameters": { + "resourceGroupName": { + "type": "string", + "defaultValue": "Bar-Service-Group", + "metadata": { + "description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking." + } + }, + "resourceGroupLocation": { + "type": "string", + "defaultValue": "westeurope", + "metadata": { + "description": "Location of the resource group. Resource groups could have different location than resources, however by default we use API versions from latest hybrid profile which support all locations for resource types we support." + } + }, + "resourceName": { + "type": "string", + "defaultValue": "OrderTimeOut", + "metadata": { + "description": "Name of the main resource to be created by this template." + } + }, + "resourceLocation": { + "type": "string", + "defaultValue": "[parameters('resourceGroupLocation')]", + "metadata": { + "description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there." + } + } + }, + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "name": "[parameters('resourceGroupName')]", + "location": "[parameters('resourceGroupLocation')]", + "apiVersion": "2019-10-01" + }, + { + "type": "Microsoft.Resources/deployments", + "name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "apiVersion": "2019-10-01", + "dependsOn": [ + "[parameters('resourceGroupName')]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "parameters": { + "resourceGroupName": { + "value": "[parameters('resourceGroupName')]" + }, + "resourceGroupLocation": { + "value": "[parameters('resourceGroupLocation')]" + }, + "resourceName": { + "value": "[parameters('resourceName')]" + }, + "resourceLocation": { + "value": "[parameters('resourceLocation')]" + } + }, + "template": { + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceGroupName": { + "type": "string" + }, + "resourceGroupLocation": { + "type": "string" + }, + "resourceName": { + "type": "string" + }, + "resourceLocation": { + "type": "string" + } + }, + "variables": { + "storage_name": "[toLower(concat('storage', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId))))]", + "appServicePlan_name": "[concat('Plan', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]", + "storage_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Storage/storageAccounts/', variables('storage_name'))]", + "appServicePlan_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/serverFarms/', variables('appServicePlan_name'))]", + "function_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/sites/', parameters('resourceName'))]" + }, + "resources": [ + { + "location": "[parameters('resourceLocation')]", + "name": "[parameters('resourceName')]", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "tags": { + "[concat('hidden-related:', variables('appServicePlan_ResourceId'))]": "empty" + }, + "dependsOn": [ + "[variables('appServicePlan_ResourceId')]", + "[variables('storage_ResourceId')]" + ], + "kind": "functionapp", + "properties": { + "name": "[parameters('resourceName')]", + "kind": "functionapp", + "httpsOnly": true, + "reserved": false, + "serverFarmId": "[variables('appServicePlan_ResourceId')]", + "siteConfig": { + "alwaysOn": true + } + }, + "identity": { + "type": "SystemAssigned" + }, + "resources": [ + { + "name": "appsettings", + "type": "config", + "apiVersion": "2015-08-01", + "dependsOn": [ + "[variables('function_ResourceId')]" + ], + "properties": { + "AzureWebJobsDashboard": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storage_name'), ';AccountKey=', listKeys(variables('storage_ResourceId'), '2017-10-01').keys[0].value, ';EndpointSuffix=', 'core.windows.net')]", + "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storage_name'), ';AccountKey=', listKeys(variables('storage_ResourceId'), '2017-10-01').keys[0].value, ';EndpointSuffix=', 'core.windows.net')]", + "FUNCTIONS_EXTENSION_VERSION": "~3", + "FUNCTIONS_WORKER_RUNTIME": "dotnet" + } + } + ] + }, + { + "location": "[parameters('resourceGroupLocation')]", + "name": "[variables('storage_name')]", + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2017-10-01", + "tags": { + "[concat('hidden-related:', concat('/providers/Microsoft.Web/sites/', parameters('resourceName')))]": "empty" + }, + "properties": { + "supportsHttpsTrafficOnly": true + }, + "sku": { + "name": "Standard_LRS" + }, + "kind": "Storage" + }, + { + "location": "[parameters('resourceGroupLocation')]", + "name": "[variables('appServicePlan_name')]", + "type": "Microsoft.Web/serverFarms", + "apiVersion": "2015-08-01", + "sku": { + "name": "S1", + "tier": "Standard", + "family": "S", + "size": "S1" + }, + "properties": { + "name": "[variables('appServicePlan_name')]" + } + } + ] + } + } + } + ] +} \ No newline at end of file From ec714ddc1241211a2b718e43fe01daf07d5eedd8 Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Wed, 16 Feb 2022 01:40:29 +0200 Subject: [PATCH 19/25] Update Program.cs --- EnqueueCompleteOrderCommandApp/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/EnqueueCompleteOrderCommandApp/Program.cs b/EnqueueCompleteOrderCommandApp/Program.cs index 13abab7..09b674b 100644 --- a/EnqueueCompleteOrderCommandApp/Program.cs +++ b/EnqueueCompleteOrderCommandApp/Program.cs @@ -1,5 +1,4 @@ using System; -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; From 6d863930e99b68f9d06f47ba7f46517561064a09 Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Wed, 16 Feb 2022 01:40:41 +0200 Subject: [PATCH 20/25] Update EnqueueCompleteOrderCommandApp.csproj --- .../EnqueueCompleteOrderCommandApp.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/EnqueueCompleteOrderCommandApp/EnqueueCompleteOrderCommandApp.csproj b/EnqueueCompleteOrderCommandApp/EnqueueCompleteOrderCommandApp.csproj index 8282e8f..2c2e2ce 100644 --- a/EnqueueCompleteOrderCommandApp/EnqueueCompleteOrderCommandApp.csproj +++ b/EnqueueCompleteOrderCommandApp/EnqueueCompleteOrderCommandApp.csproj @@ -9,5 +9,4 @@ - From 9ce03a964e60ce0db5d25e799f316bcbea96988d Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Wed, 16 Feb 2022 01:42:12 +0200 Subject: [PATCH 21/25] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dfcfd56..7c26839 100644 --- a/.gitignore +++ b/.gitignore @@ -348,3 +348,4 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ +OrderTimeOutService/appsettings.json From 65c507e48f66bbde319c365d0a57dc2bdc3e7cad Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Wed, 16 Feb 2022 02:53:20 +0200 Subject: [PATCH 22/25] Revert "Update .gitignore" This reverts commit 9ce03a964e60ce0db5d25e799f316bcbea96988d. --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7c26839..dfcfd56 100644 --- a/.gitignore +++ b/.gitignore @@ -348,4 +348,3 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ -OrderTimeOutService/appsettings.json From 6f87b9a0b50ba62b53865f451f34b4b79ac72cdf Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Wed, 16 Feb 2022 12:21:50 +0200 Subject: [PATCH 23/25] Update BlobStorage.cs --- OrderTimeOutService/BlobService/BlobStorage.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/OrderTimeOutService/BlobService/BlobStorage.cs b/OrderTimeOutService/BlobService/BlobStorage.cs index 8b96f3f..7a3024e 100644 --- a/OrderTimeOutService/BlobService/BlobStorage.cs +++ b/OrderTimeOutService/BlobService/BlobStorage.cs @@ -3,6 +3,8 @@ using Microsoft.Extensions.Configuration; using System.Text; using System.IO; +using System; +using static System.Environment; namespace OrderTimeOutService.BlobService { @@ -10,11 +12,12 @@ public class BlobStorage : IBlobStorage { private readonly BlobServiceClient _blobServiceClient; private readonly string _blobContainerName; + - public BlobStorage(IConfigurationBuilder configuration) + public BlobStorage() { - _blobServiceClient = new BlobServiceClient(configuration.Build().GetConnectionString("BlobStorage")); - _blobContainerName = configuration.Build().GetSection("Containers").GetSection("OrderTimeOutReport").Value; + _blobServiceClient = new BlobServiceClient(GetEnvironmentVariable("BlobStorageConnectionString", EnvironmentVariableTarget.Process)); + _blobContainerName = GetEnvironmentVariable("OrderTimeOutReportContainer", EnvironmentVariableTarget.Process); } public async Task UploadContentBlobAsync(string content, string fileName) From cdaa1a646beccc194903ea252b5ce8b911843359 Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Wed, 16 Feb 2022 12:21:54 +0200 Subject: [PATCH 24/25] Update OrderTimeOut.cs --- OrderTimeOutService/OrderTimeOut.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/OrderTimeOutService/OrderTimeOut.cs b/OrderTimeOutService/OrderTimeOut.cs index 447ed0e..31a3fcb 100644 --- a/OrderTimeOutService/OrderTimeOut.cs +++ b/OrderTimeOutService/OrderTimeOut.cs @@ -1,34 +1,31 @@ using System; -using System.IO; using System.Collections.Generic; using System.Threading.Tasks; using DataAccess.Data; using DataAccess.Repository; using Microsoft.Azure.WebJobs; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using OrderTimeOutService.BlobService; using System.Globalization; +using static System.Environment; + namespace OrderTimeOutService { public class OrderTimeOut { private readonly OrderRepository _orderRepository; private readonly BlobStorage _blobStorage; - private readonly IConfigurationBuilder _configuration; public OrderTimeOut() { _orderRepository = new OrderRepository(); - _configuration = new ConfigurationBuilder() - .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); - _blobStorage = new BlobStorage(_configuration); + _blobStorage = new BlobStorage(); + } [FunctionName("OrderTimeOut")] - public async Task Run([TimerTrigger("0 0 0 * * *")]TimerInfo myTimer, ILogger log) + public async Task Run([TimerTrigger("0 0 0 * * *")]TimerInfo myTimer, ILogger log) { log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); List initiatedOrders = await _orderRepository.GetOrdersByStatus(OrderStatus.Initiated); @@ -39,7 +36,7 @@ public async Task Run([TimerTrigger("0 0 0 * * *")]TimerInfo myTimer, ILogger lo finalizedOrdersSum += order.TotalPrice; await _orderRepository.Upsert(order); } - string reportData = $"{initiatedOrders.Count},{finalizedOrdersSum.ToString(new CultureInfo("en-us",false))}"; + string reportData = $"{initiatedOrders.Count},{finalizedOrdersSum.ToString(new CultureInfo("en-us", false))}"; DateTime dateTime = DateTime.Now; string reportFileName = $"{dateTime.Day}_{dateTime.Month}_{dateTime.Year}_report.csv"; await _blobStorage.UploadContentBlobAsync(reportData, reportFileName); From 4d98d1c527b72afe47440736839f70980db2c77d Mon Sep 17 00:00:00 2001 From: DzurahIvan Date: Wed, 16 Feb 2022 12:21:59 +0200 Subject: [PATCH 25/25] Update OrderTimeOutService.csproj --- OrderTimeOutService/OrderTimeOutService.csproj | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/OrderTimeOutService/OrderTimeOutService.csproj b/OrderTimeOutService/OrderTimeOutService.csproj index 4005bae..52542f0 100644 --- a/OrderTimeOutService/OrderTimeOutService.csproj +++ b/OrderTimeOutService/OrderTimeOutService.csproj @@ -3,14 +3,6 @@ netcoreapp3.1 v3 - - - - - - PreserveNewest - - @@ -22,6 +14,9 @@ + + PreserveNewest + PreserveNewest