Skip to content
Closed
Show file tree
Hide file tree
Changes from 6 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
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>№14 "Медицинский пациeнт"</Strong></UnorderedListItem>
<UnorderedListItem>Выполнена <Strong>Степановым Дмитрием 6511</Strong> </UnorderedListItem>
<UnorderedListItem><Link To="https://github.com/negniy/cloud-development.git">Ссылка на форк</Link></UnorderedListItem>
</UnorderedList>
</CardBody>
</Card>
12 changes: 6 additions & 6 deletions Client.Wasm/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,30 @@
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchBrowser": false,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "http://localhost:5127",
"applicationUrl": "http://localhost:5128",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"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",
"applicationUrl": "https://localhost:7283;http://localhost:5128",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchBrowser": false,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
}
4 changes: 2 additions & 2 deletions 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:5171/patient"
}
20 changes: 19 additions & 1 deletion CloudDevelopment.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ 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("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PatientApp.Generator", "GeneratorService\PatientApp.Generator.csproj", "{DB627DDE-E411-4B5B-9FE3-15F9A8EC1491}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PatientApp.AppHost", "Patient\Patient.AppHost\PatientApp.AppHost.csproj", "{03605D0F-0E69-461D-9417-32DD06B53E23}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PatientApp.ServiceDefaults", "Patient\Patient.ServiceDefaults\PatientApp.ServiceDefaults.csproj", "{DA24CCA7-7B4A-871C-985C-DBE0FA1F7524}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -15,6 +21,18 @@ 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
{DB627DDE-E411-4B5B-9FE3-15F9A8EC1491}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DB627DDE-E411-4B5B-9FE3-15F9A8EC1491}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB627DDE-E411-4B5B-9FE3-15F9A8EC1491}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB627DDE-E411-4B5B-9FE3-15F9A8EC1491}.Release|Any CPU.Build.0 = Release|Any CPU
{03605D0F-0E69-461D-9417-32DD06B53E23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{03605D0F-0E69-461D-9417-32DD06B53E23}.Debug|Any CPU.Build.0 = Debug|Any CPU
{03605D0F-0E69-461D-9417-32DD06B53E23}.Release|Any CPU.ActiveCfg = Release|Any CPU
{03605D0F-0E69-461D-9417-32DD06B53E23}.Release|Any CPU.Build.0 = Release|Any CPU
{DA24CCA7-7B4A-871C-985C-DBE0FA1F7524}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DA24CCA7-7B4A-871C-985C-DBE0FA1F7524}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA24CCA7-7B4A-871C-985C-DBE0FA1F7524}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA24CCA7-7B4A-871C-985C-DBE0FA1F7524}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
6 changes: 6 additions & 0 deletions GeneratorService/GeneratorService.http
Comment thread
negniy marked this conversation as resolved.
Outdated
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@GeneratorService_HostAddress = http://localhost:5104

GET {{GeneratorService_HostAddress}}/weatherforecast/
Accept: application/json

###
21 changes: 21 additions & 0 deletions GeneratorService/Models/Patient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace PatientApp.Generator.Models;

public class Patient
{
public int Id { get; set; }
public string FullName { get; set; }
public DateOnly Birthday { get; set; }
public string Address { get; set; }

public double Height { get; set; }
public double Weight { get; set; }

public int BloodType { get; set; }

public bool Resus { get; set; }

public DateOnly LastVisit { get; set; }

public bool Vactination { get; set; }
Comment thread
negniy marked this conversation as resolved.

}
22 changes: 22 additions & 0 deletions GeneratorService/PatientApp.Generator.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

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

<ItemGroup>
<PackageReference Include="Aspire.StackExchange.Redis.DistributedCaching" Version="13.1.2" />
<PackageReference Include="Bogus" Version="35.6.5" />
<PackageReference Include="Serilog" Version="4.3.2-dev-02419" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
<PackageReference Include="StackExchange.Redis" Version="2.12.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Patient\Patient.ServiceDefaults\PatientApp.ServiceDefaults.csproj" />
</ItemGroup>

</Project>
58 changes: 58 additions & 0 deletions GeneratorService/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using PatientApp.Generator.Services;
using PatientApp.ServiceDefaults;
using Serilog;

var builder = WebApplication.CreateBuilder(args);

builder.AddServiceDefaults();

builder.AddRedisDistributedCache("redis");

builder.Services.AddSingleton<PatientGenerator>();
builder.Services.AddScoped<PatientService>();

builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
Comment thread
negniy marked this conversation as resolved.

var app = builder.Build();

app.UseCors();
app.UseSerilogRequestLogging();

app.MapDefaultEndpoints();

app.MapGet("/patient", async (
int id,
PatientService service,
ILogger<Program> logger,
CancellationToken cancellationToken) =>
{
logger.LogInformation($"Received request for patient with ID: {id}");

if (id <= 0)
{
logger.LogWarning($"Received invalid ID: {id}");
return Results.BadRequest(new { error = "ID must be a positive number" });
}

try
{
var application = await service.GetByIdAsync(id, cancellationToken);
return Results.Ok(application);
}
catch (Exception ex)
{
logger.LogError(ex, $"Error while getting patient {id}");
return Results.Problem("An error occurred while processing the request");
}
})
.WithName("GetPatient");

app.Run();
23 changes: 23 additions & 0 deletions GeneratorService/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": false,
"applicationUrl": "http://localhost:5171",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7171;http://localhost:5171",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
37 changes: 37 additions & 0 deletions GeneratorService/Services/Generator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Bogus;
using Bogus.DataSets;
using static System.Math;
using PatientApp.Generator.Models;

namespace PatientApp.Generator.Services;

public class PatientGenerator(ILogger<PatientGenerator> logger)
{
private readonly Faker<Patient> _faker = new Faker<Patient>("ru")
.RuleFor(x => x.FullName, GeneratePatientFullName)
.RuleFor(x => x.Birthday, f => f.Date.PastDateOnly())
Comment thread
negniy marked this conversation as resolved.
Outdated
.RuleFor(x => x.Address, f => f.Address.FullAddress())
.RuleFor(x => x.Weight, f => Round(f.Random.Double(5, 120), 2))
.RuleFor(x => x.Height, f => Round(f.Random.Double(50, 200), 2))
Comment thread
negniy marked this conversation as resolved.
Outdated
.RuleFor(x => x.BloodType, f => f.Random.Int(1, 4))
.RuleFor(x => x.Resus, f => f.Random.Bool())
.RuleFor(x => x.Vactination, f => f.Random.Bool())
.RuleFor(x => x.LastVisit, (f, patient) => f.Date.BetweenDateOnly(patient.Birthday, DateOnly.FromDateTime(DateTime.UtcNow))
);

public Patient Generate(int id)
{
logger.LogInformation($"Generating Patient with ID: {id}");
Comment thread
negniy marked this conversation as resolved.
Outdated
return _faker.UseSeed(id).RuleFor(x => x.Id, _ => id).Generate();
}

private static string GeneratePatientFullName(Faker faker)
{
var gender = faker.Person.Gender;
var firstName = faker.Name.FirstName(gender);
var lastName = faker.Name.LastName(gender);
var patronymic = faker.Name.FirstName(Name.Gender.Male) + (gender == Name.Gender.Male ? "еевич" : "еевна");

return string.Join(' ', firstName, lastName, patronymic);
}
}
47 changes: 47 additions & 0 deletions GeneratorService/Services/PatientService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Microsoft.Extensions.Caching.Distributed;
using System.Text.Json;
using PatientApp.Generator.Services;
using PatientApp.Generator.Models;

public class PatientService(
Comment on lines +4 to +6
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь не хватает пространства имен

PatientGenerator generator,
IDistributedCache cache,
ILogger<PatientService> logger,
IConfiguration config
)
{
private readonly TimeSpan _cacheExpiration = TimeSpan.FromMinutes(config.GetSection("CacheSetting").GetValue("CacheExpirationMinutes", 5));
private const string CacheKeyPrefix = "patient:";

public async Task<Patient> GetByIdAsync(int id, CancellationToken cancellationToken = default)
{
var cacheKey = $"{CacheKeyPrefix}{id}";

logger.LogInformation($"Patient with Id: {id} was requested");

var cachedData = await cache.GetStringAsync(cacheKey, cancellationToken);

if (!string.IsNullOrEmpty(cachedData))
{
logger.LogInformation($"Patient with {id} was found in cache");
var cachedPatient = JsonSerializer.Deserialize<Patient>(cachedData);
if (cachedPatient != null) return cachedPatient;
}

logger.LogInformation($"Patient with {id} was found in cache, start generating");

var patient = generator.Generate(id);

var serializedData = JsonSerializer.Serialize(patient);
var cacheOptions = new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = _cacheExpiration
};

await cache.SetStringAsync(cacheKey, serializedData, cacheOptions, cancellationToken);

logger.LogInformation($"Patint with Id: {id} was saved to cache with TTL {_cacheExpiration.TotalMinutes} minutes");

return patient;
}
}
8 changes: 8 additions & 0 deletions GeneratorService/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
9 changes: 9 additions & 0 deletions GeneratorService/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
13 changes: 13 additions & 0 deletions Patient/Patient.AppHost/AppHost.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
var builder = DistributedApplication.CreateBuilder(args);

var redis = builder.AddRedis("redis")
.WithRedisCommander();

var generator = builder.AddProject<Projects.PatientApp_Generator>("generator")
Comment thread
negniy marked this conversation as resolved.
.WithReference(redis)
.WithExternalHttpEndpoints();

builder.AddProject<Projects.Client_Wasm>("client")
.WithReference(generator);
Comment thread
negniy marked this conversation as resolved.
Outdated

builder.Build().Run();
25 changes: 25 additions & 0 deletions Patient/Patient.AppHost/PatientApp.AppHost.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<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>
<UserSecretsId>9850a275-b1ed-4763-b4e3-9c0fbc45d25f</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" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Client.Wasm\Client.Wasm.csproj" />
<ProjectReference Include="..\..\GeneratorService\PatientApp.Generator.csproj" />
<ProjectReference Include="..\Patient.ServiceDefaults\PatientApp.ServiceDefaults.csproj" />
</ItemGroup>

</Project>
Loading
Loading