Skip to content

Commit 426a3d6

Browse files
committed
Merge branch 'master' into features/readme
2 parents 2f42d5c + 4d7b9fa commit 426a3d6

24 files changed

Lines changed: 509 additions & 38 deletions

azure-pipelines.yml

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,56 @@ pool:
66

77
name: $(BuildID)
88

9-
steps:
10-
- task: DotNetCoreCLI@2
11-
displayName: 'dotnet restore'
12-
inputs:
13-
command: 'restore'
14-
projects: 'src'
15-
feedsToUse: 'select'
16-
versioningScheme: 'off'
17-
- task: DotNetCoreCLI@2
18-
displayName: 'dotnet publish'
19-
inputs:
20-
command: publish
21-
publishWebProjects: false
22-
projects: src/EmailService/EmailService.csproj
23-
arguments: '--no-restore -o $(Build.ArtifactStagingDirectory)'
24-
zipAfterPublish: false
25-
modifyOutputPath: false
9+
variables:
10+
nuget_package_number: '1.0.$(Build.BuildId)'
2611

27-
- task: PublishBuildArtifacts@1
28-
displayName: 'Publish Artifact: emailservice-build'
29-
inputs:
30-
ArtifactName: 'emailservice-build'
12+
jobs:
3113

32-
- task: CopyFiles@2
33-
displayName: 'copy deploy artifact'
34-
inputs:
35-
SourceFolder: 'deploy'
36-
Contents: '**'
37-
TargetFolder: '$(Build.ArtifactStagingDirectory)'
38-
CleanTargetFolder: true
14+
- job: Nuget
15+
steps:
16+
- task: DotNetCoreCLI@2
17+
displayName: 'pack projects'
18+
inputs:
19+
command: 'pack'
20+
packagesToPack: 'src/Client/Client.csproj;src/PublicAPI/PublicAPI.csproj'
21+
versioningScheme: 'byEnvVar'
22+
versionEnvVar: 'nuget_package_number'
23+
- task: PublishBuildArtifacts@1
24+
inputs:
25+
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
26+
ArtifactName: 'emailservice-nuget'
27+
publishLocation: 'Container'
3928

40-
- task: PublishBuildArtifacts@1
41-
displayName: 'Publish Artifact: emailservice-deploy'
42-
inputs:
43-
ArtifactName: 'emailservice-deploy'
29+
- job: Backend
30+
steps:
31+
- task: DotNetCoreCLI@2
32+
displayName: 'dotnet restore'
33+
inputs:
34+
command: 'restore'
35+
projects: 'src'
36+
feedsToUse: 'select'
37+
versioningScheme: 'off'
38+
- task: DotNetCoreCLI@2
39+
displayName: 'dotnet publish'
40+
inputs:
41+
command: publish
42+
publishWebProjects: false
43+
projects: src/EmailService/EmailService.csproj
44+
arguments: '--no-restore -o $(Build.ArtifactStagingDirectory)'
45+
zipAfterPublish: false
46+
modifyOutputPath: false
47+
- task: PublishBuildArtifacts@1
48+
displayName: 'Publish Artifact: emailservice-build'
49+
inputs:
50+
ArtifactName: 'emailservice-build'
51+
- task: CopyFiles@2
52+
displayName: 'copy deploy artifact'
53+
inputs:
54+
SourceFolder: 'deploy'
55+
Contents: '**'
56+
TargetFolder: '$(Build.ArtifactStagingDirectory)'
57+
CleanTargetFolder: true
58+
- task: PublishBuildArtifacts@1
59+
displayName: 'Publish Artifact: emailservice-deploy'
60+
inputs:
61+
ArtifactName: 'emailservice-deploy'

src/Client/Client.csproj

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<UserSecretsId>f38081dd-cff7-4d02-b211-8d019ec1c3d3</UserSecretsId>
6+
<RootNamespace>RTUITLab.EmailService.Client</RootNamespace>
7+
<PackageId>RTUITLab.EmailService.Client</PackageId>
8+
<Authors>RTUITLab</Authors>
9+
<Product>EmailService.Client</Product>
10+
<AssemblyName>RTUITLab.EmailService.Client</AssemblyName>
11+
<Description>Client for sending emails though the EmailService</Description>
12+
<PackageProjectUrl>https://github.com/RTUITLab/EmailService</PackageProjectUrl>
13+
<RepositoryUrl>https://github.com/RTUITLab/EmailService</RepositoryUrl>
14+
</PropertyGroup>
15+
16+
<ItemGroup>
17+
<PackageReference Include="Microsoft.Extensions.Http" Version="2.2.0" />
18+
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
19+
</ItemGroup>
20+
21+
</Project>

src/Client/EmailSenderExtension.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
using System;
3+
4+
namespace RTUITLab.EmailService.Client
5+
{
6+
public static class EmailSenderExtension
7+
{
8+
public static IServiceCollection AddEmailSender(this IServiceCollection services, EmailSenderOptions emailSenderOptions)
9+
{
10+
if (services == null)
11+
{
12+
throw new ArgumentNullException(nameof(services));
13+
}
14+
15+
services.AddHttpClient(HttpEmailSender.HttpClientName, cfg =>
16+
{
17+
cfg.BaseAddress = new Uri(emailSenderOptions.BaseAddress);
18+
cfg.DefaultRequestHeaders.Add("Authorization", emailSenderOptions.Key);
19+
});
20+
return services.AddTransient<IEmailSender, HttpEmailSender>();
21+
}
22+
}
23+
}

src/Client/EmailSenderOptions.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace RTUITLab.EmailService.Client
2+
{
3+
public class EmailSenderOptions
4+
{
5+
public string BaseAddress { get; set; }
6+
public string Key { get; set; }
7+
}
8+
}

src/Client/HttpEmailSender.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using Newtonsoft.Json;
2+
using System;
3+
using System.Net.Http;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace RTUITLab.EmailService.Client
8+
{
9+
internal class HttpEmailSender : IEmailSender
10+
{
11+
public const string HttpClientName = nameof(HttpEmailSender) + nameof(HttpClientName);
12+
private readonly HttpClient client;
13+
14+
public HttpEmailSender(IHttpClientFactory httpClientFactory)
15+
{
16+
client = httpClientFactory.CreateClient(HttpClientName);
17+
}
18+
19+
public async Task SendEmailAsync(string email, string subject, string body)
20+
{
21+
try
22+
{
23+
var request = await client.PostAsync("/api/email/send", new StringContent(
24+
JsonConvert.SerializeObject(
25+
new SendEmailRequest
26+
{
27+
Email = email,
28+
Subject = subject,
29+
Body = body
30+
}
31+
), Encoding.UTF8, "application/json")
32+
);
33+
if (request.StatusCode == System.Net.HttpStatusCode.OK)
34+
return;
35+
throw new Exception(await request.Content.ReadAsStringAsync());
36+
}
37+
catch (Exception ex)
38+
{
39+
throw new Exception("Something went wrong while sending email", ex);
40+
}
41+
}
42+
}
43+
}

src/Client/IEmailSender.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System.Threading.Tasks;
2+
3+
namespace RTUITLab.EmailService.Client
4+
{
5+
public interface IEmailSender
6+
{
7+
Task SendEmailAsync(string email, string subject, string body);
8+
}
9+
}

src/Client/SendEmailRequest.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.ComponentModel.DataAnnotations;
2+
3+
namespace RTUITLab.EmailService.Client
4+
{
5+
public class SendEmailRequest
6+
{
7+
[Required]
8+
[EmailAddress]
9+
public string Email { get; set; }
10+
[Required]
11+
public string Subject { get; set; }
12+
[Required]
13+
public string Body { get; set; }
14+
}
15+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp3.1</TargetFramework>
6+
<StartupObject>EmailService.LogsViewer.Program</StartupObject>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<ProjectReference Include="..\Models\Models.csproj" />
15+
</ItemGroup>
16+
17+
</Project>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using Models.Logs;
2+
using Newtonsoft.Json;
3+
using System;
4+
using System.Net.WebSockets;
5+
using System.Text;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
9+
namespace EmailService.LogsViewer
10+
{
11+
class Program
12+
{
13+
public const string URL = "";
14+
public const string KEY = "";
15+
static async Task Main(string[] args)
16+
{
17+
var wsClient = new ClientWebSocket();
18+
19+
wsClient.Options.SetRequestHeader("Authorization", KEY);
20+
await wsClient.ConnectAsync(new Uri(URL), CancellationToken.None);
21+
22+
var array = new byte[4096];
23+
Console.WriteLine($"Ready to listen\t\t{URL}\n");
24+
while (true)
25+
{
26+
var result = await wsClient.ReceiveAsync(array, CancellationToken.None);
27+
if (result.MessageType != WebSocketMessageType.Text)
28+
{
29+
Console.WriteLine("Not text received");
30+
continue;
31+
}
32+
var text = Encoding.UTF8.GetString(array, 0, result.Count);
33+
var logMessage = JsonConvert.DeserializeObject<LogMessage>(text);
34+
WriteReport(logMessage);
35+
}
36+
}
37+
38+
private static void WriteReport(LogMessage logMessage)
39+
{
40+
Console.ForegroundColor = logMessage.ForegroundColor;
41+
Console.BackgroundColor = ConsoleColor.Black;
42+
Console.Write($"{logMessage.LogLevel}:");
43+
Console.ResetColor();
44+
Console.ForegroundColor = ConsoleColor.DarkGray;
45+
Console.Write(' ' + logMessage.DateTimeNormalized);
46+
Console.ResetColor();
47+
Console.WriteLine($" {logMessage.Category}[{logMessage.EventId.Id}]");
48+
Console.WriteLine('\t' + logMessage.Message.Replace("\n", "\n\t"));
49+
}
50+
}
51+
}

src/EmailService.sln

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,15 @@ Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio Version 16
44
VisualStudioVersion = 16.0.29905.134
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmailService", "EmailService\EmailService.csproj", "{B5045CB1-D33E-452C-8B1A-A515CBC0CF67}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EmailService", "EmailService\EmailService.csproj", "{B5045CB1-D33E-452C-8B1A-A515CBC0CF67}"
77
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Models", "Models\Models.csproj", "{F3C853FD-5509-4803-AEF4-820BF87F640E}"
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Models", "Models\Models.csproj", "{F3C853FD-5509-4803-AEF4-820BF87F640E}"
9+
EndProject
10+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client\Client.csproj", "{090F3095-5A51-436B-B539-46041D63E1A8}"
11+
EndProject
12+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PublicAPI", "PublicAPI\PublicAPI.csproj", "{D092C687-8707-4D0C-AD8A-F4F1FB1718F2}"
13+
EndProject
14+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmailService.LogsViewer", "EmailService.LogsViewer\EmailService.LogsViewer.csproj", "{5AD09402-E028-4541-B765-9253BE73F3C0}"
915
EndProject
1016
Global
1117
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -21,6 +27,18 @@ Global
2127
{F3C853FD-5509-4803-AEF4-820BF87F640E}.Debug|Any CPU.Build.0 = Debug|Any CPU
2228
{F3C853FD-5509-4803-AEF4-820BF87F640E}.Release|Any CPU.ActiveCfg = Release|Any CPU
2329
{F3C853FD-5509-4803-AEF4-820BF87F640E}.Release|Any CPU.Build.0 = Release|Any CPU
30+
{090F3095-5A51-436B-B539-46041D63E1A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31+
{090F3095-5A51-436B-B539-46041D63E1A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
32+
{090F3095-5A51-436B-B539-46041D63E1A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
33+
{090F3095-5A51-436B-B539-46041D63E1A8}.Release|Any CPU.Build.0 = Release|Any CPU
34+
{D092C687-8707-4D0C-AD8A-F4F1FB1718F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35+
{D092C687-8707-4D0C-AD8A-F4F1FB1718F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
36+
{D092C687-8707-4D0C-AD8A-F4F1FB1718F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
37+
{D092C687-8707-4D0C-AD8A-F4F1FB1718F2}.Release|Any CPU.Build.0 = Release|Any CPU
38+
{5AD09402-E028-4541-B765-9253BE73F3C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39+
{5AD09402-E028-4541-B765-9253BE73F3C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
40+
{5AD09402-E028-4541-B765-9253BE73F3C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
41+
{5AD09402-E028-4541-B765-9253BE73F3C0}.Release|Any CPU.Build.0 = Release|Any CPU
2442
EndGlobalSection
2543
GlobalSection(SolutionProperties) = preSolution
2644
HideSolutionNode = FALSE

0 commit comments

Comments
 (0)