Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade website functions to dotnet8-isolated #192

Merged
merged 2 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions WebsiteBackendFunctions/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace WebsiteBackendFunctions;

public class Program
{
public static void Main(string[] args)
{
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
})
.Build();

host.Run();
}
}
15 changes: 12 additions & 3 deletions WebsiteBackendFunctions/WebsiteBackendFunctions.csproj
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.21.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.2" />
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Sql" Version="3.0.534" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.1.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Sql" Version="3.0.534" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.3.0" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
Expand All @@ -18,4 +24,7 @@
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext"/>
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,79 +1,110 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using WebsiteBackendFunctions.Models;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.ComponentModel.DataAnnotations;
using System.Net;
using System.Text.Json;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Extensions.Sql;
using Microsoft.Azure.Functions.Worker.Http;

namespace WebsiteBackendFunctions.WebsiteFunctions
{
public static class CreateFreeBedNotificationSubscription
public class CreateFreeBedNotificationSubscription
{
[FunctionName(nameof(CreateFreeBedNotificationSubscription))]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "freebednotification/{hutId:int}")] HttpRequest req,
[Sql("SELECT * FROM [dbo].[Huts] WHERE id = @Id",
"DatabaseConnectionString",
CommandType.Text,
"@Id={hutId}")] IEnumerable<Hut> huts,
int hutId,
[Sql(commandText: "dbo.FreeBedUpdateSubscriptions",
connectionStringSetting: "DatabaseConnectionString")] IAsyncCollector<FreeBedUpdateSubscription> newItems,
ILogger log)
private readonly ILogger<CreateFreeBedNotificationSubscription> _logger;

public CreateFreeBedNotificationSubscription(ILogger<CreateFreeBedNotificationSubscription> logger)
{
_logger = logger;
}

[Function(nameof(CreateFreeBedNotificationSubscription))]
public async Task<OutputType> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "freebednotification/{hutId:int}")]
HttpRequestData req,
[SqlInput("SELECT * FROM [dbo].[Huts] WHERE id = @Id",
"DatabaseConnectionString",
CommandType.Text,
"@Id={hutId}")]
IEnumerable<Hut> huts,
int hutId)
{
log.LogInformation("New request to create a free bed notification");
_logger.LogInformation("New request to create a free bed notification");

var output = new OutputType();

var hut = huts.FirstOrDefault();
if (hut == null)
{
return new BadRequestObjectResult("Hut does not exist");
output.HttpResponse = req.CreateResponse(HttpStatusCode.BadRequest);
await output.HttpResponse.WriteStringAsync("Hut does not exist");
return output;
}

if (hut.Enabled == false)
{
return new BadRequestObjectResult("Hut is not enabled");
output.HttpResponse = req.CreateResponse(HttpStatusCode.BadRequest);
await output.HttpResponse.WriteStringAsync("Hut is not enabled");
return output;
}

string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var body = JsonSerializer.Deserialize<FreeBedUpdateSubscription>(requestBody, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
var body = JsonSerializer.Deserialize<FreeBedUpdateSubscription>(requestBody,
new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });

ICollection<ValidationResult> results = null;
if (!Validate(body, out results))
if (!Validate(body, out var results))
{
return new BadRequestObjectResult(results.Select(o => o.ErrorMessage));
output.HttpResponse = req.CreateResponse(HttpStatusCode.BadRequest);
await output.HttpResponse.WriteAsJsonAsync(results.Select(o => o.ErrorMessage));
return output;
}

if (body.Date < DateTime.Today)
{
return new BadRequestObjectResult("Date must not be in the past");
output.HttpResponse = req.CreateResponse(HttpStatusCode.BadRequest);
await output.HttpResponse.WriteStringAsync("Date must not be in the past");
return output;
}

if (body.Date > DateTime.Today.AddDays(90))
{
return new BadRequestObjectResult("Date must not be more than 90 days in the future");
output.HttpResponse = req.CreateResponse(HttpStatusCode.BadRequest);
await output.HttpResponse.WriteStringAsync("Date must not be more than 90 days in the future");
return output;
}

body.HutId = hutId;
body.Notified = false;

log.LogInformation("Adding subscription to the database for hut {hutId}, date {date}", hutId, body.Date);
await newItems.AddAsync(body);
_logger.LogInformation("Adding subscription to the database for hut {hutId}, date {date}", hutId,
body.Date);

output.Item = body;
output.HttpResponse = req.CreateResponse(HttpStatusCode.OK);

return new OkResult();
return output;
}

private static bool Validate<T>(T obj, out ICollection<ValidationResult> results)
{
results = new List<ValidationResult>();

return Validator.TryValidateObject(obj, new ValidationContext(obj), results, true);
}

public class OutputType
{
[SqlOutput(commandText: "dbo.FreeBedUpdateSubscriptions",
connectionStringSetting: "DatabaseConnectionString")]
public FreeBedUpdateSubscription Item { get; set; }

public HttpResponseData HttpResponse { get; set; }
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,42 @@
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Extensions.Sql;
using WebsiteBackendFunctions.Models;

namespace WebsiteBackendFunctions
{
public static class GetAllAvailabilityOnDateFunction
public class GetAllAvailabilityOnDateFunction
{
[FunctionName(nameof(GetAllAvailabilityOnDate))]
public static IActionResult GetAllAvailabilityOnDate(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "availability/{datefilter:regex(^\\d{{4}}-\\d{{2}}-\\d{{2}}$)}")] HttpRequest req,
[Sql("SELECT a.hutid as HutId, a.AvailabilityId as AvailabilityId, " +
"CASE WHEN bc.name IS NOT NULL THEN bc.name ELSE b.name END as BedCategory, " +
"a.Date as Date, a.FreeRoom as FreeRoom, a.TotalRoom as TotalRoom, a.LastUpdated as LastUpdated " +
"FROM dbo.Availability a " +
"JOIN dbo.BedCategories b on a.BedCategoryId = b.id " +
"LEFT OUTER JOIN dbo.BedCategories bc on b.SharesNameWithBedCateogryId = bc.id " +
"WHERE a.Date = @DateFilter ",
"DatabaseConnectionString",
CommandType.Text,
"@DateFilter={datefilter}" )] IEnumerable<AvailabilityIntermediaryModel> availabilityResult,
string dateFilter,
ILogger log)
private readonly ILogger<GetAllAvailabilityOnDateFunction> _logger;

public GetAllAvailabilityOnDateFunction(ILogger<GetAllAvailabilityOnDateFunction> logger)
{
_logger = logger;
}

[Function(nameof(GetAllAvailabilityOnDate))]
public IActionResult GetAllAvailabilityOnDate(
[HttpTrigger(AuthorizationLevel.Anonymous, "get",
Route = "availability/{datefilter:regex(^\\d{{4}}-\\d{{2}}-\\d{{2}}$)}")]
HttpRequest req,
[SqlInput("SELECT a.hutid as HutId, a.AvailabilityId as AvailabilityId, " +
"CASE WHEN bc.name IS NOT NULL THEN bc.name ELSE b.name END as BedCategory, " +
"a.Date as Date, a.FreeRoom as FreeRoom, a.TotalRoom as TotalRoom, a.LastUpdated as LastUpdated " +
"FROM dbo.Availability a " +
"JOIN dbo.BedCategories b on a.BedCategoryId = b.id " +
"LEFT OUTER JOIN dbo.BedCategories bc on b.SharesNameWithBedCateogryId = bc.id " +
"WHERE a.Date = @DateFilter ",
"DatabaseConnectionString",
CommandType.Text,
"@DateFilter={datefilter}")]
IEnumerable<AvailabilityIntermediaryModel> availabilityResult,
string dateFilter)
{
var date = DateTime.Parse(dateFilter);

Expand All @@ -40,15 +49,16 @@ public static IActionResult GetAllAvailabilityOnDate(
TotalFreeBeds = a.Sum(r => r.FreeRoom),
TotalBeds = a.Sum(r => r.TotalRoom),
HutClosed = a.Sum(r => r.TotalRoom) == 0,
RoomAvailabilities = a.Where(r => r.TotalRoom > 0).Select(r => new RoomAvailabilityViewModel() // Filter out "Hütte Geschlossen (0/0)
{
BedCategory = r.BedCategory,
FreeBeds = (int)r.FreeRoom,
TotalBeds = (int)r.TotalRoom
}).ToList()
RoomAvailabilities = a.Where(r => r.TotalRoom > 0).Select(r =>
new RoomAvailabilityViewModel() // Filter out "H�tte Geschlossen (0/0)
{
BedCategory = r.BedCategory,
FreeBeds = (int)r.FreeRoom,
TotalBeds = (int)r.TotalRoom
}).ToList()
}).ToList();

return new OkObjectResult(res);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,35 @@
using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Extensions.Sql;
using Microsoft.Extensions.Logging;
using WebsiteBackendFunctions.Models;

namespace WebsiteBackendFunctions
{
public static class GetAllBedCategoriesFunction
public class GetAllBedCategoriesFunction
{
[FunctionName(nameof(GetAllBedCategories))]
public static IActionResult GetAllBedCategories(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "bedcategory")] HttpRequest req,
[Sql("SELECT DISTINCT name FROM [dbo].[BedCategories] WHERE SharesNameWithBedCateogryId IS NULL AND Id <> -1",
"DatabaseConnectionString",
CommandType.Text)] IEnumerable<BedCategoryViewModel> result,
ILogger log)
private readonly ILogger<GetAllBedCategoriesFunction> _logger;

public GetAllBedCategoriesFunction(ILogger<GetAllBedCategoriesFunction> logger)
{
_logger = logger;
}

[Function(nameof(GetAllBedCategories))]
public IActionResult GetAllBedCategories(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "bedcategory")]
HttpRequest req,
[SqlInput(
"SELECT DISTINCT name FROM [dbo].[BedCategories] WHERE SharesNameWithBedCateogryId IS NULL AND Id <> -1",
"DatabaseConnectionString",
CommandType.Text, "")]
IEnumerable<BedCategoryViewModel> result)
{
log.LogInformation("Retrieved {count} bed categories from database", result?.Count());
_logger.LogInformation("Retrieved {count} bed categories from database", result?.Count());

return new OkObjectResult(result);
}
}
}
}
31 changes: 19 additions & 12 deletions WebsiteBackendFunctions/WebsiteFunctions/GetAllHutsFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,34 @@
using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Extensions.Sql;
using Microsoft.Extensions.Logging;
using WebsiteBackendFunctions.Models;

namespace WebsiteBackendFunctions
{
public static class GetAllHutsFunction
public class GetAllHutsFunction
{
private readonly ILogger<GetAllHutsFunction> _logger;

[FunctionName(nameof(GetAllHuts))]
public static IActionResult GetAllHuts(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "hut")] HttpRequest req,
[Sql("SELECT * FROM [dbo].[Huts]",
"DatabaseConnectionString",
CommandType.Text)] IEnumerable<Hut> result,
ILogger log)
public GetAllHutsFunction(ILogger<GetAllHutsFunction> logger)
{
log.LogInformation("Retrieved {count} huts from database", result?.Count());
_logger = logger;
}

[Function(nameof(GetAllHuts))]
public IActionResult GetAllHuts(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "hut")]
HttpRequest req,
[SqlInput("SELECT * FROM [dbo].[Huts]",
"DatabaseConnectionString",
CommandType.Text, "")]
IEnumerable<Hut> result)
{
_logger.LogInformation("Retrieved {count} huts from database", result?.Count());

return new OkObjectResult(result);
}
}
}
}
Loading
Loading