brokerService #6
25
.dockerignore
Normal file
25
.dockerignore
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
**/.classpath
|
||||||
|
**/.dockerignore
|
||||||
|
**/.env
|
||||||
|
**/.git
|
||||||
|
**/.gitignore
|
||||||
|
**/.project
|
||||||
|
**/.settings
|
||||||
|
**/.toolstarget
|
||||||
|
**/.vs
|
||||||
|
**/.vscode
|
||||||
|
**/*.*proj.user
|
||||||
|
**/*.dbmdl
|
||||||
|
**/*.jfm
|
||||||
|
**/bin
|
||||||
|
**/charts
|
||||||
|
**/docker-compose*
|
||||||
|
**/compose*
|
||||||
|
**/Dockerfile*
|
||||||
|
**/node_modules
|
||||||
|
**/npm-debug.log
|
||||||
|
**/obj
|
||||||
|
**/secrets.dev.yaml
|
||||||
|
**/values.dev.yaml
|
||||||
|
LICENSE
|
||||||
|
README.md
|
35
.vscode/launch.json
vendored
Normal file
35
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
// Use IntelliSense to find out which attributes exist for C# debugging
|
||||||
|
// Use hover for the description of the existing attributes
|
||||||
|
// For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md.
|
||||||
|
"name": ".NET Core Launch (web)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "build",
|
||||||
|
// If you have changed target frameworks, make sure to update the program path.
|
||||||
|
"program": "${workspaceFolder}/Cloud/bin/Debug/net6.0/Cloud.dll",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}/Cloud",
|
||||||
|
"stopAtEntry": false,
|
||||||
|
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
|
||||||
|
"serverReadyAction": {
|
||||||
|
"action": "openExternally",
|
||||||
|
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"sourceFileMap": {
|
||||||
|
"/Views": "${workspaceFolder}/Views"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": ".NET Core Attach",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "attach"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
41
.vscode/tasks.json
vendored
Normal file
41
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "build",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"${workspaceFolder}/Cloud.sln",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "publish",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"publish",
|
||||||
|
"${workspaceFolder}/Cloud.sln",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "watch",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"watch",
|
||||||
|
"run",
|
||||||
|
"--project",
|
||||||
|
"${workspaceFolder}/Cloud.sln"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -6,123 +6,123 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
namespace Cloud.Controllers
|
namespace Cloud.Controllers
|
||||||
{
|
{
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/user")]
|
[Route("api/user")]
|
||||||
public class FarmController : ControllerBase
|
public class FarmController : ControllerBase
|
||||||
{
|
{
|
||||||
private IConfiguration _config;
|
private IConfiguration _config;
|
||||||
private ApplicationContext _context;
|
private ApplicationContext _context;
|
||||||
|
|
||||||
public FarmController(IConfiguration config, ApplicationContext context)
|
public FarmController(IConfiguration config, ApplicationContext context)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
_context = context;
|
_context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{userId}/farm")]
|
[HttpGet("{userId}/farm")]
|
||||||
public async Task<ActionResult<List<Farm>>> Index (int userId)
|
public async Task<ActionResult<List<Farm>>> Index(int userId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<Farm> farms = await
|
List<Farm> farms = await
|
||||||
_context.Farms.Where(x => x.UserId == userId).AsNoTracking().ToListAsync();
|
_context.Farms.Where(x => x.UserId == userId).AsNoTracking().ToListAsync();
|
||||||
if (!farms.Any())
|
if (!farms.Any())
|
||||||
return NotFound("Farms is not found");
|
return NotFound("Farms is not found");
|
||||||
|
|
||||||
return Ok(farms);
|
return Ok(farms);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return BadRequest(ex.Message);
|
return BadRequest(ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{userId}/farm/{farmId}")]
|
[HttpGet("{userId}/farm/{farmId}")]
|
||||||
public async Task<ActionResult<Farm>> Show(int userId, int farmId)
|
public async Task<ActionResult<Farm>> Show(int userId, int farmId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Farm? farm = await
|
Farm? farm = await
|
||||||
_context.Farms.FirstOrDefaultAsync(x => x.UserId == userId && x.Id == farmId);
|
_context.Farms.FirstOrDefaultAsync(x => x.UserId == userId && x.Id == farmId);
|
||||||
|
|
||||||
if (farm == null)
|
if (farm == null)
|
||||||
return NotFound("Farm is not found");
|
return NotFound("Farm is not found");
|
||||||
|
|
||||||
return Ok(farm);
|
return Ok(farm);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return BadRequest(ex.Message);
|
return BadRequest(ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("{userId}/farm")]
|
[HttpPost("{userId}/farm")]
|
||||||
public async Task<ActionResult<Farm>> Create([FromBody] FarmRequest farmRequest, int userId)
|
public async Task<ActionResult<Farm>> Create([FromBody] FarmRequest farmRequest, int userId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var farm = new Farm {
|
var farm = new Farm
|
||||||
Name = farmRequest.Name,
|
{
|
||||||
UserId = userId,
|
Name = farmRequest.Name,
|
||||||
RaspberryMacAddr = farmRequest.RaspberryMacAddr,
|
UserId = userId,
|
||||||
};
|
RaspberryIP = farmRequest.RaspberryIP,
|
||||||
|
};
|
||||||
|
|
||||||
Farm? farmCreated = _context.Farms.Add(farm).Entity;
|
Farm? farmCreated = _context.Farms.Add(farm).Entity;
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
return Ok(farmCreated);
|
return Ok(farmCreated);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return BadRequest(ex.Message);
|
return BadRequest(ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut("{userId}/farm/{farmId}")]
|
[HttpPut("{userId}/farm/{farmId}")]
|
||||||
public async Task<ActionResult<Farm>> Update([FromBody] FarmRequest farmRequest, int userId, int farmId)
|
public async Task<ActionResult<Farm>> Update([FromBody] FarmRequest farmRequest, int userId, int farmId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Farm? farm = await _context.Farms.FirstOrDefaultAsync(x => x.Id == farmId && x.UserId == userId);
|
Farm? farm = await _context.Farms.FirstOrDefaultAsync(x => x.Id == farmId && x.UserId == userId);
|
||||||
|
|
||||||
if (farm == null)
|
if (farm == null)
|
||||||
return NotFound("Farm is not found");
|
return NotFound("Farm is not found");
|
||||||
|
|
||||||
farm.Name = farmRequest.Name;
|
farm.Name = farmRequest.Name;
|
||||||
farm.RaspberryMacAddr = farmRequest.RaspberryMacAddr;
|
farm.RaspberryIP = farmRequest.RaspberryIP;
|
||||||
|
|
||||||
_context.Farms.Update(farm);
|
_context.Farms.Update(farm);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
return Ok(farm);
|
return Ok(farm);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return BadRequest(ex.Message);
|
return BadRequest(ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete("{userId}/farm/{farmId}")]
|
[HttpDelete("{userId}/farm/{farmId}")]
|
||||||
public async Task<ActionResult> Delete(int userId, int farmId)
|
public async Task<ActionResult> Delete(int userId, int farmId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Farm? farm = await _context.Farms.FirstOrDefaultAsync(x => x.Id == farmId && x.UserId == userId);
|
Farm? farm = await _context.Farms.FirstOrDefaultAsync(x => x.Id == farmId && x.UserId == userId);
|
||||||
|
|
||||||
if (farm == null)
|
if (farm == null)
|
||||||
return NotFound("Farm is not found");
|
return NotFound("Farm is not found");
|
||||||
|
|
||||||
_context.Farms.Remove(farm);
|
_context.Farms.Remove(farm);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
return Ok("Farm deleted successfully");
|
return Ok("Farm deleted successfully");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return BadRequest(ex.Message);
|
return BadRequest(ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace Cloud.Controllers;
|
|
||||||
|
|
||||||
[ApiController]
|
|
||||||
[Route("[controller]")]
|
|
||||||
public class WeatherForecastController : ControllerBase
|
|
||||||
{
|
|
||||||
private static readonly string[] Summaries = new[]
|
|
||||||
{
|
|
||||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
|
||||||
};
|
|
||||||
|
|
||||||
private readonly ILogger<WeatherForecastController> _logger;
|
|
||||||
|
|
||||||
public WeatherForecastController(ILogger<WeatherForecastController> logger)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet(Name = "GetWeatherForecast")]
|
|
||||||
public IEnumerable<WeatherForecast> Get()
|
|
||||||
{
|
|
||||||
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
|
||||||
{
|
|
||||||
Date = DateTime.Now.AddDays(index),
|
|
||||||
TemperatureC = Random.Shared.Next(-20, 55),
|
|
||||||
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
|
|
||||||
})
|
|
||||||
.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
29
Cloud/Dockerfile
Normal file
29
Cloud/Dockerfile
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
|
||||||
|
WORKDIR /app
|
||||||
|
EXPOSE 5124
|
||||||
|
|
||||||
|
ENV ASPNETCORE_URLS=http://+:5124
|
||||||
|
|
||||||
|
# Creates a non-root user with an explicit UID and adds permission to access the /app folder
|
||||||
|
# For more info, please refer to https://aka.ms/vscode-docker-dotnet-configure-containers
|
||||||
|
RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /app
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
||||||
|
ARG configuration=Release
|
||||||
|
WORKDIR /src
|
||||||
|
COPY ["Cloud.csproj", "."]
|
||||||
|
RUN dotnet restore "./Cloud.csproj"
|
||||||
|
COPY . .
|
||||||
|
WORKDIR "/src/."
|
||||||
|
RUN dotnet build "./Cloud.csproj" -c $configuration -o /app/build
|
||||||
|
|
||||||
|
FROM build AS publish
|
||||||
|
ARG configuration=Release
|
||||||
|
RUN dotnet publish "./Cloud.csproj" -c $configuration -o /app/publish /p:UseAppHost=false
|
||||||
|
|
||||||
|
FROM base AS final
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=publish /app/publish .
|
||||||
|
ENTRYPOINT ["dotnet", "Cloud.dll"]
|
||||||
|
|
@ -1,12 +1,11 @@
|
|||||||
namespace Cloud.Models
|
namespace Cloud.Models
|
||||||
{
|
{
|
||||||
public class Farm
|
public class Farm
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public int UserId { get; set; }
|
public int UserId { get; set; }
|
||||||
public User? User { get; set; }
|
public User? User { get; set; }
|
||||||
public string RaspberryMacAddr { get; set; }
|
public string RaspberryIP { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
@ -1,8 +1,8 @@
|
|||||||
namespace Cloud.Requests
|
namespace Cloud.Requests
|
||||||
{
|
{
|
||||||
public class FarmRequest
|
public class FarmRequest
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string RaspberryMacAddr { get; set; }
|
public string RaspberryIP { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,16 +3,16 @@ using FluentValidation;
|
|||||||
|
|
||||||
namespace Cloud.Validation
|
namespace Cloud.Validation
|
||||||
{
|
{
|
||||||
public class FarmValidator : AbstractValidator<FarmRequest>
|
public class FarmValidator : AbstractValidator<FarmRequest>
|
||||||
{
|
{
|
||||||
public FarmValidator()
|
public FarmValidator()
|
||||||
{
|
{
|
||||||
RuleFor(request => request.RaspberryMacAddr)
|
RuleFor(request => request.RaspberryIP)
|
||||||
.NotEmpty().WithMessage("MAC address can't be empty")
|
.NotEmpty().WithMessage("IP address can't be empty")
|
||||||
.Matches("^([0-9A-Fa-f]{2}[:-]?){5}([0-9A-Fa-f]{2})$").WithMessage("MAC address is not valid");
|
.Matches(@"^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$").WithMessage("IP address is not valid");
|
||||||
|
|
||||||
RuleFor(request => request.Name)
|
RuleFor(request => request.Name)
|
||||||
.NotEmpty().WithMessage("Name can't be empty");
|
.NotEmpty().WithMessage("Name can't be empty");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,12 +0,0 @@
|
|||||||
namespace Cloud;
|
|
||||||
|
|
||||||
public class WeatherForecast
|
|
||||||
{
|
|
||||||
public DateTime Date { get; set; }
|
|
||||||
|
|
||||||
public int TemperatureC { get; set; }
|
|
||||||
|
|
||||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
|
||||||
|
|
||||||
public string? Summary { get; set; }
|
|
||||||
}
|
|
@ -1,16 +1,22 @@
|
|||||||
services:
|
services:
|
||||||
|
cloud:
|
||||||
|
build: ./Cloud/
|
||||||
|
ports:
|
||||||
|
- "5124:5124"
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
- redis
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:14
|
image: postgres:14
|
||||||
container_name: cucumber_database
|
container_name: cucumber_database
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: postgres
|
POSTGRES_USER: postgres
|
||||||
POSTGRES_PASSWORD: 12345
|
POSTGRES_PASSWORD: 12345
|
||||||
POSTGRES_DB: main_database
|
POSTGRES_DB: main_database
|
||||||
ports:
|
ports:
|
||||||
- "5438:5432"
|
- "5438:5432"
|
||||||
volumes:
|
volumes:
|
||||||
- postgres_data:/var/lib/postgresql/data
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: 'redis:latest'
|
image: 'redis:latest'
|
||||||
ports:
|
ports:
|
||||||
@ -28,4 +34,4 @@ volumes:
|
|||||||
postgres_data:
|
postgres_data:
|
||||||
driver: local
|
driver: local
|
||||||
cloud-redis:
|
cloud-redis:
|
||||||
driver: local
|
driver: local
|
||||||
|
Loading…
Reference in New Issue
Block a user