From 94364d17d6a73da46a01e4ac88ce5c58bddab394 Mon Sep 17 00:00:00 2001 From: Mikayla Dobson Date: Tue, 21 Nov 2023 09:35:42 -0600 Subject: [PATCH] wip: troubleshooting docker flow --- .gitignore | 6 ++- Unbinder/.dockerignore | 1 + Unbinder/Controllers/HomeController.cs | 17 +++++++- Unbinder/Controllers/RecipeController.cs | 3 +- Unbinder/DB/SQL/create_database.sql | 25 ++++++++++++ Unbinder/Docker/DOTNET.Dockerfile | 18 +++++++++ Unbinder/Docker/MSSQL.Dockerfile | 16 ++++++++ Unbinder/Program.cs | 7 ++++ Unbinder/Services/S3Service.cs | 50 +++++++++++++++++++----- Unbinder/Unbinder.csproj | 2 + Unbinder/Views/Recipe/Search.cshtml | 19 +++------ Unbinder/docker-compose.yaml | 24 ++++++++++++ 12 files changed, 162 insertions(+), 26 deletions(-) create mode 100644 Unbinder/.dockerignore create mode 100644 Unbinder/DB/SQL/create_database.sql create mode 100644 Unbinder/Docker/DOTNET.Dockerfile create mode 100644 Unbinder/Docker/MSSQL.Dockerfile create mode 100644 Unbinder/docker-compose.yaml diff --git a/.gitignore b/.gitignore index ba22a70..9df718e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,10 @@ ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore +# GITIGNORE FILES ADDED BY MIKAYLA +__notes__ +*.env + # User-specific files *.rsuser *.suo @@ -360,4 +364,4 @@ MigrationBackup/ .ionide/ # Fody - auto-generated XML schema -FodyWeavers.xsd \ No newline at end of file +FodyWeavers.xsd diff --git a/Unbinder/.dockerignore b/Unbinder/.dockerignore new file mode 100644 index 0000000..114f161 --- /dev/null +++ b/Unbinder/.dockerignore @@ -0,0 +1 @@ +__notes__ \ No newline at end of file diff --git a/Unbinder/Controllers/HomeController.cs b/Unbinder/Controllers/HomeController.cs index c5dc2a7..4ea6e7b 100644 --- a/Unbinder/Controllers/HomeController.cs +++ b/Unbinder/Controllers/HomeController.cs @@ -1,11 +1,26 @@ using Microsoft.AspNetCore.Mvc; +using Unbinder.Services; namespace Unbinder.Controllers { public class HomeController : Controller { - public IActionResult Index() + public async Task Index() { + var objects = await S3Service.ListObjects(); + + if (objects != null) + { + foreach (var entry in objects.S3Objects) + { + Console.WriteLine(entry.Key); + } + } + else + { + Console.WriteLine("Did not find results in S3"); + } + return View(); } } diff --git a/Unbinder/Controllers/RecipeController.cs b/Unbinder/Controllers/RecipeController.cs index 03d7514..4087836 100644 --- a/Unbinder/Controllers/RecipeController.cs +++ b/Unbinder/Controllers/RecipeController.cs @@ -33,7 +33,8 @@ namespace Unbinder.Controllers { if (q == null && category == null) return View(_recipeRepository.GetAll); - var result = _recipeRepository.GetAll?.Where(r => r.Name.Contains(q, StringComparison.OrdinalIgnoreCase)); + var result = _recipeRepository.GetAll?.Where(r => r.Name.Contains(q!, StringComparison.OrdinalIgnoreCase)); + ViewBag.Query = q; return result == null ? NotFound() diff --git a/Unbinder/DB/SQL/create_database.sql b/Unbinder/DB/SQL/create_database.sql new file mode 100644 index 0000000..307d788 --- /dev/null +++ b/Unbinder/DB/SQL/create_database.sql @@ -0,0 +1,25 @@ +IF NOT EXISTS(SELECT name FROM sys.databases WHERE name = 'Unbinder') +BEGIN + CREATE DATABASE Unbinder; + + USE Unbinder; + + CREATE TABLE [dbo].Recipes ( + [Id] INT IDENTITY(1,1) NOT NULL, + [Name] NVARCHAR(50) NOT NULL, + [ShortDescription] NVARCHAR(1000) NULL, + [Author] NVARCHAR(100) NULL, + [RecipeText] NVARCHAR(8000) NULL, + [ImageUrl] NVARCHAR(1000) NULL, + [Created] DATETIME NOT NULL, + [Updated] DATETIME NOT NULL, + CONSTRAINT [PK_Recipes] PRIMARY KEY CLUSTERED ([Id] ASC) + ); + + CREATE TABLE [dbo].Ingredients ( + [Id] INT IDENTITY(1,1) NOT NULL, + [Name] NVARCHAR(50) NOT NULL, + [Description] NVARCHAR(1000) NULL, + CONSTRAINT [PK_Ingredients] PRIMARY KEY CLUSTERED ([Id] ASC) + ); +END \ No newline at end of file diff --git a/Unbinder/Docker/DOTNET.Dockerfile b/Unbinder/Docker/DOTNET.Dockerfile new file mode 100644 index 0000000..6818813 --- /dev/null +++ b/Unbinder/Docker/DOTNET.Dockerfile @@ -0,0 +1,18 @@ +# get .net 8 +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build + +COPY . ./src +WORKDIR /src + +RUN dotnet build -o /app +RUN dotnet publish -o /publish + +ENV AWS_S3_URL=$AWS_S3_URL +ENV AWS_ACCESS_KEY=$AWS_ACCESS_KEY +ENV AWS_SECRET_KEY=$AWS_SECRET_KEY +ENV AWS_BUCKET_NAME=$AWS_BUCKET_NAME + +WORKDIR /publish + +EXPOSE 80 +ENTRYPOINT ["./Unbinder"] \ No newline at end of file diff --git a/Unbinder/Docker/MSSQL.Dockerfile b/Unbinder/Docker/MSSQL.Dockerfile new file mode 100644 index 0000000..69a7c2e --- /dev/null +++ b/Unbinder/Docker/MSSQL.Dockerfile @@ -0,0 +1,16 @@ +# build from sql server image +FROM mcr.microsoft.com/mssql/server:2022-latest + +# set environment variables +ENV ACCEPT_EULA=Y +ENV MSSQL_PID Express +ENV SA_PASSWORD=$DB_PASSWORD + +# WORKDIR /db +# COPY ../DB/SQL/create_database.sql . + +# run the sql script +# CMD /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P fhhwergaiuh12480y53 -d master -i create_database.sql + +# run the command to start sql server +CMD /opt/mssql/bin/sqlservr diff --git a/Unbinder/Program.cs b/Unbinder/Program.cs index f7af1ff..36816d5 100644 --- a/Unbinder/Program.cs +++ b/Unbinder/Program.cs @@ -8,6 +8,9 @@ using Microsoft.Identity.Web.UI; using Unbinder.DB; using Unbinder.Models; using Unbinder.Repositories; +using Unbinder.Services; +using Amazon.S3; +using Microsoft.Extensions.Azure; var builder = WebApplication.CreateBuilder(args); var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); @@ -43,6 +46,10 @@ builder.Services.AddScoped(); builder.Services.AddHttpContextAccessor(); builder.Services.AddServerSideBlazor(); + +// include extra services +//builder.Services.AddSingleton(S3Service.Client); + var app = builder.Build(); // Configure the HTTP request pipeline. diff --git a/Unbinder/Services/S3Service.cs b/Unbinder/Services/S3Service.cs index ac79a55..b7666a3 100644 --- a/Unbinder/Services/S3Service.cs +++ b/Unbinder/Services/S3Service.cs @@ -2,22 +2,54 @@ using Amazon.S3; using Amazon.S3.Transfer; using Amazon.Runtime; +using System.Net; +using Amazon.S3.Model; namespace Unbinder.Services { - public class S3Service + public sealed class S3Service { - public static AWSCredentials Credentials => - new BasicAWSCredentials( - Environment.GetEnvironmentVariable("AWS_ACCESS_KEY"), - Environment.GetEnvironmentVariable("AWS_SECRET_KEY")); + private static AWSCredentials Credentials + { + get + { + string? accessKey = Environment.GetEnvironmentVariable("AWS_ACCESS_KEY"); + string? secret = Environment.GetEnvironmentVariable("AWS_SECRET_KEY"); - public static AmazonS3Client Client => new(Credentials, RegionEndpoint.USEast1); + Console.WriteLine(accessKey ?? "(none)", secret ?? "(none)"); + + if (accessKey == null || secret == null) + { + throw new Exception("AWS credentials not found"); + } + + return new BasicAWSCredentials(accessKey, secret); + } + } + + private static AmazonS3Config Config => new() + { + RegionEndpoint = RegionEndpoint.USEast2 + }; + + private static AmazonS3Client Client => new(Credentials); + private static readonly AmazonS3Client client = Client; + private static readonly string? BucketName = Environment.GetEnvironmentVariable("AWS_BUCKET_NAME"); + + public static async Task ListObjects(string? prefix = "") + { + var bucketName = BucketName; + var request = new ListObjectsRequest + { + BucketName = bucketName, + Prefix = prefix + }; + + return await client.ListObjectsAsync(request); + } public async Task UploadFileAsync(IFormFile file) { - using IAmazonS3 client = Client; - if (file == null || file.Length == 0) { return null; @@ -34,8 +66,6 @@ namespace Unbinder.Services public async Task GetFile(string path, string outFile) { - using IAmazonS3 client = Client; - var bucketName = "unbinder-recipe-images"; using var fileTransferUtility = new TransferUtility(client); await fileTransferUtility.DownloadAsync(outFile, bucketName, path); diff --git a/Unbinder/Unbinder.csproj b/Unbinder/Unbinder.csproj index 6eee0b0..876938d 100644 --- a/Unbinder/Unbinder.csproj +++ b/Unbinder/Unbinder.csproj @@ -24,6 +24,8 @@ + + diff --git a/Unbinder/Views/Recipe/Search.cshtml b/Unbinder/Views/Recipe/Search.cshtml index d5fef27..7211df1 100644 --- a/Unbinder/Views/Recipe/Search.cshtml +++ b/Unbinder/Views/Recipe/Search.cshtml @@ -1,9 +1,13 @@ @model IEnumerable +@{ + string InputValue = ViewBag.Query ?? String.Empty; +} +

- +
@@ -26,11 +30,7 @@ console.log(query); // set initial message value - if (query) { - message.innerHTML = `Viewing ${@Model.ToArray().Length} results for: ${query}`; - } else { - message.innerHTML = "Enter a new search term below:"; - } + message.innerHTML = query ? `Viewing ${@Model.ToArray().Length} results for: ${query}` : "Enter a new search term below:"; // handle search updates on client side searchButton.onclick = async () => { @@ -40,13 +40,6 @@ const newResultJson = await newResult.json(); window.location.search = `?q=${textField.value}`; - searchResultsContainer.innerHTML = `@{ - foreach (var recipe in @Model) - { -

@recipe.Name

-

@recipe.RecipeText

- } - }`; } }); \ No newline at end of file diff --git a/Unbinder/docker-compose.yaml b/Unbinder/docker-compose.yaml new file mode 100644 index 0000000..1045d4d --- /dev/null +++ b/Unbinder/docker-compose.yaml @@ -0,0 +1,24 @@ +version: '3.8' + +services: + client: + build: + context: . + dockerfile: ./Docker/DOTNET.Dockerfile + args: + AWS_S3_URL: ${AWS_S3_URL} + AWS_ACCESS_KEY: ${AWS_ACCESS_KEY} + AWS_SECRET_KEY: ${AWS_SECRET_KEY} + AWS_BUCKET_NAME: ${AWS_BUCKET_NAME} + ports: + - 80:80 + depends_on: + - db + db: + build: + context: . + dockerfile: ./Docker/MSSQL.Dockerfile + args: + DB_PASSWORD: ${DB_PASSWORD} + ports: + - 1433:1433 \ No newline at end of file