-
Notifications
You must be signed in to change notification settings - Fork 52
Морозов Сергей Лаб. 3 Группа 6513 #123
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
Closed
Closed
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
fbefd84
базовое изменение
kingtuler1454 b8e2953
последние штрихи
kingtuler1454 c3caebc
Исправление огрешностей
kingtuler1454 57a4928
правки v2
kingtuler1454 a0d4e27
исправление сервиса
kingtuler1454 1bcc9fb
оформление
kingtuler1454 a7da401
2 лабораторная
kingtuler1454 4fa4350
3 л/р последние шртихи
kingtuler1454 8bab162
исправления
kingtuler1454 1a9973a
помарочки
kingtuler1454 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,5 +6,5 @@ | |
| } | ||
| }, | ||
| "AllowedHosts": "*", | ||
| "BaseAddress": "" | ||
| "BaseAddress": "https://localhost:7163/vehicles" | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| using System.Text.Json.Nodes; | ||
| using File.Service.Storage; | ||
| using Microsoft.AspNetCore.Mvc; | ||
|
|
||
| namespace File.Service.Controllers; | ||
|
|
||
| /// <summary> | ||
| /// HTTP-интерфейс на чтение содержимого бакета Minio. | ||
| /// Используется интеграционными тестами и для ручной проверки состояния хранилища | ||
| /// </summary> | ||
| /// <param name="s3Service">Сервис доступа к бакету</param> | ||
| /// <param name="logger">Логгер HTTP-обращений</param> | ||
| [ApiController] | ||
| [Route("api/s3")] | ||
| public class S3Controller(IS3Service s3Service, ILogger<S3Controller> logger) : ControllerBase | ||
| { | ||
| /// <summary> | ||
| /// Возвращает список ключей всех объектов в бакете | ||
| /// </summary> | ||
| [HttpGet] | ||
| public async Task<ActionResult<List<string>>> ListFiles() | ||
| { | ||
| logger.LogInformation("ListFiles was called"); | ||
| var list = await s3Service.GetFileList(); | ||
| return Ok(list); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Возвращает содержимое объекта по ключу. Если объекта нет — 404 | ||
| /// </summary> | ||
| /// <param name="key">Ключ объекта в бакете, например <c>vehicle_42.json</c></param> | ||
| [HttpGet("{key}")] | ||
| public async Task<ActionResult<JsonNode>> GetFile(string key) | ||
| { | ||
| logger.LogInformation("GetFile was called for {key}", key); | ||
| try | ||
| { | ||
| var node = await s3Service.DownloadFile(key); | ||
| return Ok(node); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| logger.LogWarning(ex, "Failed to download {key}", key); | ||
| return NotFound(); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| using System.Text; | ||
| using Amazon.SimpleNotificationService.Util; | ||
| using File.Service.Storage; | ||
| using Microsoft.AspNetCore.Mvc; | ||
|
|
||
| namespace File.Service.Controllers; | ||
|
|
||
| /// <summary> | ||
| /// Эндпоинт, на который SNS отправляет запросы подтверждения подписки и уведомления | ||
| /// </summary> | ||
| /// <param name="s3Service">Сервис записи в Minio</param> | ||
| /// <param name="logger">Логгер входящих сообщений</param> | ||
| [ApiController] | ||
| [Route("api/sns")] | ||
| public class SnsWebhookController(IS3Service s3Service, ILogger<SnsWebhookController> logger) : ControllerBase | ||
| { | ||
| /// <summary> | ||
| /// Обрабатывает тело SNS-запроса. Для <c>SubscriptionConfirmation</c> выполняет GET | ||
| /// по <c>SubscribeURL</c> (с переписыванием адреса на LocalStack). Для <c>Notification</c> | ||
| /// передаёт сообщение в <see cref="IS3Service.UploadFile"/>. Всегда отвечает 200, | ||
| /// чтобы SNS не помечал подписчика как недоступного | ||
| /// </summary> | ||
| [HttpPost] | ||
| public async Task<IActionResult> ReceiveMessage() | ||
| { | ||
| logger.LogInformation("SNS webhook was called"); | ||
| using var reader = new StreamReader(Request.Body, Encoding.UTF8); | ||
| var body = await reader.ReadToEndAsync(); | ||
|
|
||
| try | ||
| { | ||
| var message = Message.ParseMessage(body); | ||
|
|
||
| if (message.Type == "SubscriptionConfirmation") | ||
| { | ||
| logger.LogInformation("Received SubscriptionConfirmation, confirming"); | ||
| using var http = new HttpClient(); | ||
| var builder = new UriBuilder(new Uri(message.SubscribeURL)) | ||
| { | ||
| Scheme = "http", | ||
| Host = "localhost", | ||
| Port = 4566 | ||
| }; | ||
| var confirmation = await http.GetAsync(builder.Uri); | ||
| if (!confirmation.IsSuccessStatusCode) | ||
| { | ||
| var text = await confirmation.Content.ReadAsStringAsync(); | ||
| logger.LogError("SubscriptionConfirmation returned {code}: {body}", confirmation.StatusCode, text); | ||
| } | ||
| else | ||
| { | ||
| logger.LogInformation("Subscription confirmed"); | ||
| } | ||
| return Ok(); | ||
| } | ||
|
|
||
| if (message.Type == "Notification") | ||
| { | ||
| await s3Service.UploadFile(message.MessageText); | ||
| logger.LogInformation("Notification was processed and uploaded to Minio"); | ||
| } | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| logger.LogError(ex, "Failed to process SNS message"); | ||
| } | ||
| return Ok(); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>net8.0</TargetFramework> | ||
| <Nullable>enable</Nullable> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <GenerateDocumentationFile>true</GenerateDocumentationFile> | ||
| <NoWarn>$(NoWarn);1591</NoWarn> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="AWSSDK.SimpleNotificationService" Version="4.0.2.17" /> | ||
| <PackageReference Include="CommunityToolkit.Aspire.Minio.Client" Version="9.9.0" /> | ||
| <PackageReference Include="LocalStack.Client" Version="2.0.0" /> | ||
| <PackageReference Include="LocalStack.Client.Extensions" Version="2.0.0" /> | ||
| <PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.4" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\VehicleApp\VehicleApp.ServiceDefaults\VehicleApp.ServiceDefaults.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| using System.Net; | ||
| using Amazon.SimpleNotificationService; | ||
| using Amazon.SimpleNotificationService.Model; | ||
|
|
||
| namespace File.Service.Messaging; | ||
|
|
||
| /// <summary> | ||
| /// На старте приложения регистрирует HTTP-вебхук File.Service в SNS-топике | ||
| /// </summary> | ||
| /// <param name="snsClient">SNS-клиент для вызова <c>Subscribe</c></param> | ||
| /// <param name="configuration">Источник ARN топика и URL подписчика</param> | ||
| /// <param name="logger">Логгер</param> | ||
| public class SnsSubscriptionService( | ||
| IAmazonSimpleNotificationService snsClient, | ||
| IConfiguration configuration, | ||
| ILogger<SnsSubscriptionService> logger) | ||
| { | ||
| private readonly string _topicArn = configuration["AWS:Resources:SNSTopicArn"] | ||
| ?? throw new KeyNotFoundException("SNS topic ARN was not found in configuration"); | ||
| private readonly string _endpoint = configuration["AWS:Resources:SNSUrl"] | ||
| ?? throw new KeyNotFoundException("SNS subscriber endpoint was not found in configuration"); | ||
|
|
||
| /// <summary> | ||
| /// Отправляет в SNS запрос <c>Subscribe</c>. Подтверждение подписки | ||
| /// выполняется позже в <see cref="Controllers.SnsWebhookController"/> | ||
| /// </summary> | ||
| public async Task SubscribeEndpoint() | ||
| { | ||
| logger.LogInformation("Subscribing endpoint {endpoint} to topic {topic}", _endpoint, _topicArn); | ||
| var request = new SubscribeRequest | ||
| { | ||
| TopicArn = _topicArn, | ||
| Protocol = "http", | ||
| Endpoint = _endpoint, | ||
| ReturnSubscriptionArn = true | ||
| }; | ||
| var response = await snsClient.SubscribeAsync(request); | ||
| if (response.HttpStatusCode != HttpStatusCode.OK) | ||
| logger.LogError("Failed to subscribe to {topic}: {code}", _topicArn, response.HttpStatusCode); | ||
| else | ||
| logger.LogInformation("Subscription request for {topic} accepted; awaiting confirmation", _topicArn); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| using Amazon.SimpleNotificationService; | ||
| using File.Service.Messaging; | ||
| using File.Service.Storage; | ||
| using LocalStack.Client.Extensions; | ||
| using System.Reflection; | ||
|
|
||
| var builder = WebApplication.CreateBuilder(args); | ||
|
|
||
| builder.AddServiceDefaults(); | ||
| builder.Services.AddSwaggerGen(options => | ||
| { | ||
| var assembly = Assembly.GetExecutingAssembly(); | ||
| options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{assembly.GetName().Name}.xml")); | ||
| }); | ||
|
|
||
| builder.Services.AddControllers(); | ||
|
|
||
| builder.Services.AddLocalStack(builder.Configuration); | ||
| builder.Services.AddAwsService<IAmazonSimpleNotificationService>(); | ||
| builder.Services.AddScoped<SnsSubscriptionService>(); | ||
|
|
||
| builder.AddMinioClient("vehicle-minio"); | ||
| builder.Services.AddScoped<IS3Service, MinioS3Service>(); | ||
|
|
||
| var app = builder.Build(); | ||
|
|
||
| if (app.Environment.IsDevelopment()) | ||
| { | ||
| app.UseSwagger(); | ||
| app.UseSwaggerUI(); | ||
| } | ||
|
|
||
| app.MapDefaultEndpoints(); | ||
|
|
||
| using var scope = app.Services.CreateScope(); | ||
|
|
||
| var s3 = scope.ServiceProvider.GetRequiredService<IS3Service>(); | ||
| await s3.EnsureBucketExists(); | ||
| var subscription = scope.ServiceProvider.GetRequiredService<SnsSubscriptionService>(); | ||
| await subscription.SubscribeEndpoint(); | ||
|
|
||
|
|
||
| app.MapControllers(); | ||
| app.Run(); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| { | ||
| "profiles": { | ||
| "http": { | ||
| "commandName": "Project", | ||
| "dotnetRunMessages": true, | ||
| "launchBrowser": true, | ||
| "applicationUrl": "http://localhost:5280", | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development" | ||
| }, | ||
| "launchUrl": "swagger" | ||
| }, | ||
| "https": { | ||
| "commandName": "Project", | ||
| "dotnetRunMessages": true, | ||
| "launchBrowser": true, | ||
| "applicationUrl": "https://localhost:7017;http://localhost:5280", | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development" | ||
| }, | ||
| "launchUrl": "swagger" | ||
| }, | ||
| "IIS Express": { | ||
| "commandName": "IISExpress", | ||
| "launchBrowser": true, | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development" | ||
| } | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| using System.Text.Json.Nodes; | ||
|
|
||
| namespace File.Service.Storage; | ||
|
|
||
| /// <summary> | ||
| /// Сервис работы с Minio-бакетом, в который сохраняются ТС из SNS-уведомлений | ||
| /// </summary> | ||
| public interface IS3Service | ||
| { | ||
| /// <summary> | ||
| /// Создаёт бакет, если его ещё нет | ||
| /// </summary> | ||
| Task EnsureBucketExists(); | ||
|
|
||
| /// <summary> | ||
| /// Сохраняет JSON-тело SNS-сообщения в бакет под ключом <c>vehicle_{id}.json</c> | ||
| /// </summary> | ||
| /// <param name="fileData">Сериализованное ТС</param> | ||
| /// <returns><c>true</c> при успешной загрузке</returns> | ||
| Task<bool> UploadFile(string fileData); | ||
|
|
||
| /// <summary> | ||
| /// Возвращает список ключей всех объектов в бакете | ||
| /// </summary> | ||
| Task<List<string>> GetFileList(); | ||
|
|
||
| /// <summary> | ||
| /// Читает объект из бакета и парсит его как JSON | ||
| /// </summary> | ||
| /// <param name="key">Ключ объекта</param> | ||
| Task<JsonNode> DownloadFile(string key); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.