Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7e92a0d
создание проекта
ZamotohinaMaria Mar 14, 2026
0bacc4c
Реализована 1 лаба
ZamotohinaMaria Mar 14, 2026
9d5edc1
Update Readme
ZamotohinaMaria Mar 14, 2026
2566b27
Update Readme and .gitignore
ZamotohinaMaria Mar 14, 2026
4f54d1c
undate .gitignore
ZamotohinaMaria Mar 14, 2026
cf5044b
update images
ZamotohinaMaria Mar 14, 2026
97a2696
Update README.md
ZamotohinaMaria Mar 14, 2026
37e4251
mini update
ZamotohinaMaria Mar 14, 2026
585b448
Пакет правок по ЛР 1 - 1
ZamotohinaMaria Mar 19, 2026
450d621
Правка ЛР 1 №2: убрала папку wwwroot, настроила логи
ZamotohinaMaria Mar 27, 2026
27cdb95
Создана ветка для второй лабы и новый проект ApiGateway
ZamotohinaMaria Apr 6, 2026
b953be1
2 лаба готовченко
ZamotohinaMaria Apr 6, 2026
3c79b45
Update README.md
ZamotohinaMaria Apr 7, 2026
05231a3
Update README.md
ZamotohinaMaria Apr 7, 2026
ed9ba41
Пакет правок по ЛР 2 №1
ZamotohinaMaria Apr 8, 2026
b530971
Создан FileService
ZamotohinaMaria May 10, 2026
460d06a
Первый запуск, пусть не очень удачный...
ZamotohinaMaria May 10, 2026
1fdf2fe
Minio насроен и работает
ZamotohinaMaria May 10, 2026
8e9e390
Начало тестов
ZamotohinaMaria May 10, 2026
1626238
попытка прогнать тесты
ZamotohinaMaria May 10, 2026
b6a31a8
Тесты готовы
ZamotohinaMaria May 10, 2026
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
8 changes: 4 additions & 4 deletions Client.Wasm/Components/StudentCard.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
</CardHeader>
<CardBody>
<UnorderedList Unstyled>
<UnorderedListItem>Номер <Strong>№X "Название лабораторной"</Strong></UnorderedListItem>
<UnorderedListItem>Вариант <Strong>№Х "Название варианта"</Strong></UnorderedListItem>
<UnorderedListItem>Выполнена <Strong>Фамилией Именем 65ХХ</Strong> </UnorderedListItem>
<UnorderedListItem><Link To="https://puginarug.com/">Ссылка на форк</Link></UnorderedListItem>
<UnorderedListItem>Номер <Strong>№1 "Кэширование"</Strong></UnorderedListItem>
<UnorderedListItem>Вариант <Strong>№6 "Медицинский пациент"</Strong></UnorderedListItem>
<UnorderedListItem>Выполнена <Strong>Замотохиной Марией 6511</Strong> </UnorderedListItem>
<UnorderedListItem><Link To="https://github.com/ZamotohinaMaria/cloud-development">Ссылка на форк</Link></UnorderedListItem>
</UnorderedList>
</CardBody>
</Card>
4 changes: 2 additions & 2 deletions Client.Wasm/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchBrowser": false,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:7282;http://localhost:5127",
"environmentVariables": {
Expand All @@ -31,7 +31,7 @@
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchBrowser": false,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
Expand Down
2 changes: 1 addition & 1 deletion Client.Wasm/wwwroot/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
}
},
"AllowedHosts": "*",
"BaseAddress": ""
"BaseAddress": "http://localhost:5100/medicalpatient-generator"
}
41 changes: 40 additions & 1 deletion CloudDevelopment.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,22 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36811.4
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client.Wasm", "Client.Wasm\Client.Wasm.csproj", "{AE7EEA74-2FE0-136F-D797-854FD87E022A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client.Wasm", "Client.Wasm\Client.Wasm.csproj", "{AE7EEA74-2FE0-136F-D797-854FD87E022A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MedicalPatient.AppHost.AppHost", "MedicalPatient.AppHost\MedicalPatient.AppHost.AppHost\MedicalPatient.AppHost.AppHost.csproj", "{892597A3-DF97-470C-AA27-6398D1C68C9E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MedicalPatient.AppHost.ServiceDefaults", "MedicalPatient.AppHost\MedicalPatient.AppHost.ServiceDefaults\MedicalPatient.AppHost.ServiceDefaults.csproj", "{0E685E2F-3762-4FF1-AF4F-A3E204FDF791}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MedicalPatient.Generator", "MedicalPatient.Generator\MedicalPatient.Generator.csproj", "{B9054D03-6CF6-4B8C-8E6F-3D27D39983F5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MedicalPatient.ApiGateway", "MedicalPatient.ApiGateway\MedicalPatient.ApiGateway.csproj", "{30D90454-DACC-4B41-86DF-FD441AC7AB6D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MedicalPatient.FileService", "MedicalPatient.FileService\MedicalPatient.FileService.csproj", "{118FA956-E736-4284-830B-9CEB94F785B3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MedicalPatient.Tests", "MedicalPatient.Tests\MedicalPatient.Tests.csproj", "{E3A7A49F-D372-4E07-A882-907F486A7382}"
ProjectSection(ProjectDependencies) = postProject
{B9054D03-6CF6-4B8C-8E6F-3D27D39983F5} = {B9054D03-6CF6-4B8C-8E6F-3D27D39983F5}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -15,6 +30,30 @@ Global
{AE7EEA74-2FE0-136F-D797-854FD87E022A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AE7EEA74-2FE0-136F-D797-854FD87E022A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AE7EEA74-2FE0-136F-D797-854FD87E022A}.Release|Any CPU.Build.0 = Release|Any CPU
{892597A3-DF97-470C-AA27-6398D1C68C9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{892597A3-DF97-470C-AA27-6398D1C68C9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{892597A3-DF97-470C-AA27-6398D1C68C9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{892597A3-DF97-470C-AA27-6398D1C68C9E}.Release|Any CPU.Build.0 = Release|Any CPU
{0E685E2F-3762-4FF1-AF4F-A3E204FDF791}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0E685E2F-3762-4FF1-AF4F-A3E204FDF791}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E685E2F-3762-4FF1-AF4F-A3E204FDF791}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E685E2F-3762-4FF1-AF4F-A3E204FDF791}.Release|Any CPU.Build.0 = Release|Any CPU
{B9054D03-6CF6-4B8C-8E6F-3D27D39983F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B9054D03-6CF6-4B8C-8E6F-3D27D39983F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B9054D03-6CF6-4B8C-8E6F-3D27D39983F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B9054D03-6CF6-4B8C-8E6F-3D27D39983F5}.Release|Any CPU.Build.0 = Release|Any CPU
{30D90454-DACC-4B41-86DF-FD441AC7AB6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{30D90454-DACC-4B41-86DF-FD441AC7AB6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30D90454-DACC-4B41-86DF-FD441AC7AB6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{30D90454-DACC-4B41-86DF-FD441AC7AB6D}.Release|Any CPU.Build.0 = Release|Any CPU
{118FA956-E736-4284-830B-9CEB94F785B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{118FA956-E736-4284-830B-9CEB94F785B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{118FA956-E736-4284-830B-9CEB94F785B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{118FA956-E736-4284-830B-9CEB94F785B3}.Release|Any CPU.Build.0 = Release|Any CPU
{E3A7A49F-D372-4E07-A882-907F486A7382}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E3A7A49F-D372-4E07-A882-907F486A7382}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E3A7A49F-D372-4E07-A882-907F486A7382}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E3A7A49F-D372-4E07-A882-907F486A7382}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
65 changes: 65 additions & 0 deletions MedicalPatient.ApiGateway/Balancer/WeightedRoundRobin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Ocelot.LoadBalancer.Errors;
using Ocelot.LoadBalancer.Interfaces;
using Ocelot.Responses;
using Ocelot.ServiceDiscovery.Providers;
using Ocelot.Values;

namespace MedicalPatient.ApiGateway.Balancer;

public class WeightedRoundRobin(IServiceDiscoveryProvider serviceDiscovery, IReadOnlyList<int>? weights = null)
: ILoadBalancer
{
private readonly int[] _weights = (weights is { Count: > 0 } ? [.. weights] : []);
private int _cursor = -1;

private List<int>? _wheel;
private int _lastServicesCount = -1;

public string Type => nameof(WeightedRoundRobin);

public async Task<Response<ServiceHostAndPort>> LeaseAsync(HttpContext httpContext)
{
var services = await serviceDiscovery.GetAsync();

if (services is null)
return new ErrorResponse<ServiceHostAndPort>(
new ServicesAreNullError("Service discovery returned null"));

if (services.Count == 0)
return new ErrorResponse<ServiceHostAndPort>(
new ServicesAreNullError("No downstream services are available"));

if (_wheel == null || _lastServicesCount != services.Count)
{
_wheel = BuildWheel(services.Count);
_lastServicesCount = services.Count;
}

var next = (uint)Interlocked.Increment(ref _cursor);
var wheelIndex = (int)(next % (uint)_wheel.Count);
var serviceIndex = _wheel[wheelIndex];

return new OkResponse<ServiceHostAndPort>(services[serviceIndex].HostAndPort);
}

private List<int> BuildWheel(int servicesCount)
{
var wheel = new List<int>();

for (var i = 0; i < servicesCount; i++)
{
var weight = i < _weights.Length ? _weights[i] : 1;
if (weight < 1) weight = 1;

for (var j = 0; j < weight; j++)
wheel.Add(i);
}

if (wheel.Count == 0)
wheel.Add(0);

return wheel;
}

public void Release(ServiceHostAndPort hostAndPort) { }
}
17 changes: 17 additions & 0 deletions MedicalPatient.ApiGateway/MedicalPatient.ApiGateway.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Ocelot" Version="24.1.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MedicalPatient.AppHost\MedicalPatient.AppHost.ServiceDefaults\MedicalPatient.AppHost.ServiceDefaults.csproj" />
</ItemGroup>

</Project>
64 changes: 64 additions & 0 deletions MedicalPatient.ApiGateway/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using MedicalPatient.ApiGateway.Balancer;
using MedicalPatient.AppHost.ServiceDefaults;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;

var builder = WebApplication.CreateBuilder(args);

builder.AddServiceDefaults();

var allowedOrigins = builder.Configuration.GetSection("AllowedOrigins").Get<string[]>() ??
["https://localhost:7282", "http://localhost:5127"];

builder.Services.AddCors(options =>
{
options.AddPolicy("ClientCorsPolicy", policy =>
{
policy.WithOrigins(allowedOrigins)
.WithMethods("GET", "POST", "PUT", "DELETE")
.WithHeaders("Authorization", "Content-Type")
.AllowCredentials();
});
});

builder.Configuration
.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);

var generators = builder.Configuration.GetSection("Generators").Get<string[]>() ?? [];

var configuredWeights = builder.Configuration
.GetSection("Routes:0:DownstreamHostWeights")
.GetChildren()
.Select(x => x.GetValue("Weight", 1))
.Where(w => w > 0)
.ToArray();
var weights = configuredWeights.Length > 0 ? configuredWeights : [3, 2, 1];

var addressOverrides = new List<KeyValuePair<string, string?>>();

for (var i = 0; i < generators.Length; i++)
{
var name = generators[i];
var url = builder.Configuration[$"services:{name}:http:0"];

if (!string.IsNullOrEmpty(url) && Uri.TryCreate(url, UriKind.Absolute, out var uri))
{
addressOverrides.Add(new($"Routes:0:DownstreamHostAndPorts:{i}:Host", uri.Host));
addressOverrides.Add(new($"Routes:0:DownstreamHostAndPorts:{i}:Port", uri.Port.ToString()));
}
}

if (addressOverrides.Count > 0)
builder.Configuration.AddInMemoryCollection(addressOverrides);

builder.Services
.AddOcelot(builder.Configuration)
.AddCustomLoadBalancer<WeightedRoundRobin>((route, serviceDiscovery) =>
new WeightedRoundRobin(serviceDiscovery, weights));

var app = builder.Build();

app.UseCors("ClientCorsPolicy");

await app.UseOcelot();
await app.RunAsync();
23 changes: 23 additions & 0 deletions MedicalPatient.ApiGateway/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5100",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7293;http://localhost:5100",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
11 changes: 11 additions & 0 deletions MedicalPatient.ApiGateway/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"GlobalConfiguration": {
"BaseUrl": "http://localhost:5100"
}
}
14 changes: 14 additions & 0 deletions MedicalPatient.ApiGateway/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"AllowedOrigins": [
"https://localhost:7282",
"http://localhost:5127"
],
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Generators": [ "generator-1", "generator-2", "generator-3" ]
}
44 changes: 44 additions & 0 deletions MedicalPatient.ApiGateway/ocelot.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"Routes": [
{
"DownstreamPathTemplate": "/medicalpatient-generator",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5101
},
{
"Host": "localhost",
"Port": 5102
},
{
"Host": "localhost",
"Port": 5103
}
],
"UpstreamPathTemplate": "/medicalpatient-generator",
"UpstreamHttpMethod": [ "GET" ],
"LoadBalancerOptions": {
"Type": "WeightedRoundRobin"
},
"DownstreamHostWeights": [
{
"Host": "localhost",
"Port": 5101,
"Weight": 3
},
{
"Host": "localhost",
"Port": 5102,
"Weight": 2
},
{
"Host": "localhost",
"Port": 5103,
"Weight": 1
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<Sdk Name="Aspire.AppHost.Sdk" Version="9.5.2" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireHost>true</IsAspireHost>
<UserSecretsId>fe743bf2-08eb-41c7-817b-f144b739dce3</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting" Version="9.5.2" />
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.5.2" />
<PackageReference Include="Aspire.Hosting.Redis" Version="9.5.2" />
<PackageReference Include="CommunityToolkit.Aspire.Hosting.Minio" Version="9.9.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Client.Wasm\Client.Wasm.csproj" />
<ProjectReference Include="..\..\MedicalPatient.ApiGateway\MedicalPatient.ApiGateway.csproj" />
<ProjectReference Include="..\..\MedicalPatient.FileService\MedicalPatient.FileService.csproj" />
<ProjectReference Include="..\..\MedicalPatient.Generator\MedicalPatient.Generator.csproj" />
<ProjectReference Include="..\..\MedicalPatient.Tests\MedicalPatient.Tests.csproj" />
</ItemGroup>

</Project>
Loading
Loading