-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
108 lines (84 loc) · 3.11 KB
/
Program.cs
File metadata and controls
108 lines (84 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
using Azure.Identity;
using Azure.Messaging.EventGrid;
using Azure.Security.KeyVault.Secrets;
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Cosmos.Linq;
using Microsoft.Net.Http.Headers;
using System.Net.Mail;
using Weather_API;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors();
builder.Configuration.AddAzureAppConfiguration(a =>
a.ConfigureKeyVault(c => c.Register(new SecretClient(new Uri(builder.Configuration["Endpoints:KeyVault"]!), new DefaultAzureCredential())))
.Connect(new Uri(builder.Configuration["Endpoints:AppConfiguration"]!), new DefaultAzureCredential()));
WebApplication app = builder.Build();
app.UseHttpsRedirection();
app.UseCors(c =>
c.SetIsOriginAllowed(a => new Uri(a).IsLoopback)
.WithHeaders(HeaderNames.ContentType)
);
CosmosClient client = new(
accountEndpoint: app.Configuration["Weather-Cosmos-URI"],
tokenCredential: new DefaultAzureCredential()
);
Database database = client.GetDatabase("Weather");
Container container = database.GetContainer("Users");
EventGridPublisherClient eventGridPublisherClient = new(new Uri(app.Configuration["Weather-Grid-Event-URI"]!), new DefaultAzureCredential());
app.MapPost("/subscribe", async (Subscription subscription) =>
{
if (!IsValidEmail(subscription.Email))
{
return Results.BadRequest("Wrong email format");
}
FeedIterator<WeatherUser> feed = container
.GetItemLinqQueryable<WeatherUser>()
.Where(s => s.Email == subscription.Email)
.ToFeedIterator();
if (feed.HasMoreResults)
{
FeedResponse<WeatherUser> response = await feed.ReadNextAsync();
WeatherUser? existingSubscription = response.FirstOrDefault(s => s.Email == subscription.Email);
if (existingSubscription is not null)
{
existingSubscription.NotificationTime = ExtractHours(subscription.NotificationTime);
existingSubscription.DeltaTemperature = subscription.DeltaTemperature;
await container.UpsertItemAsync(existingSubscription);
await eventGridPublisherClient.SendEventAsync(CreateEvent(true, subscription.Email));
return Results.Ok();
}
}
await container.UpsertItemAsync(new WeatherUser(Guid.NewGuid(), subscription.Email, subscription.DeltaTemperature, ExtractHours(subscription.NotificationTime)));
await eventGridPublisherClient.SendEventAsync(CreateEvent(false, subscription.Email));
return Results.Created();
});
static bool IsValidEmail(string email)
{
string trimmedEmail = email.Trim();
if (trimmedEmail.EndsWith('.'))
return false;
try
{
MailAddress addr = new(email);
return addr.Address == trimmedEmail;
}
catch
{
return false;
}
}
static int[] ExtractHours(TimeOnly[]? times)
{
if (times is null)
return [];
return times
.Select(t => t.Hour)
.ToArray();
}
static EventGridEvent CreateEvent(bool isUpdate, string email)
{
return new("WeatherContainerAPI",
isUpdate ? "UpdateSubscription" : "NewSubscription",
"1.0",
email);
}
app.Run();