Implement Devices REST API
This commit is contained in:
commit
f48b76ce00
42
.gitignore
vendored
Normal file
42
.gitignore
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
*.swp
|
||||||
|
*.*~
|
||||||
|
project.lock.json
|
||||||
|
.DS_Store
|
||||||
|
*.pyc
|
||||||
|
nupkg/
|
||||||
|
|
||||||
|
# Visual Studio Code
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# Rider
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
build/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Oo]ut/
|
||||||
|
msbuild.log
|
||||||
|
msbuild.err
|
||||||
|
msbuild.wrn
|
||||||
|
|
||||||
|
# Visual Studio 2015
|
||||||
|
.vs/
|
||||||
|
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Configuration files
|
||||||
|
src/DevicesRestApi/appsettings.json
|
||||||
27
DevicesRestApi.sln
Normal file
27
DevicesRestApi.sln
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.0.31903.59
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4A5A8403-EDDE-4155-A3CF-1AF9567A0321}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevicesRestApi", "src\DevicesRestApi\DevicesRestApi.csproj", "{427E1A48-04F1-4C1D-B867-EE717FB2C139}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{427E1A48-04F1-4C1D-B867-EE717FB2C139}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{427E1A48-04F1-4C1D-B867-EE717FB2C139}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{427E1A48-04F1-4C1D-B867-EE717FB2C139}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{427E1A48-04F1-4C1D-B867-EE717FB2C139}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
{427E1A48-04F1-4C1D-B867-EE717FB2C139} = {4A5A8403-EDDE-4155-A3CF-1AF9567A0321}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
114
src/DevicesRestApi/Controllers/ClustersController.cs
Normal file
114
src/DevicesRestApi/Controllers/ClustersController.cs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
namespace DevicesRestApi.Controllers;
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using DevicesRestApi.Helpers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class ClustersController : ControllerBase
|
||||||
|
{
|
||||||
|
private ClusterConfigurationFile? _clusterConfigurationFile;
|
||||||
|
|
||||||
|
private readonly ILogger<ClustersController> _logger;
|
||||||
|
|
||||||
|
private readonly AppSettings _appSettings;
|
||||||
|
|
||||||
|
public ClustersController(
|
||||||
|
ILogger<ClustersController> logger,
|
||||||
|
IOptions<AppSettings> appSettings
|
||||||
|
) {
|
||||||
|
_logger = logger;
|
||||||
|
_appSettings = appSettings.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("~/clusters/{clusterName}/schedules")]
|
||||||
|
public IActionResult GetClusterSchedules(string clusterName)
|
||||||
|
{
|
||||||
|
_clusterConfigurationFile = null;
|
||||||
|
try {
|
||||||
|
_clusterConfigurationFile = new ClusterConfigurationFile(clusterName, _appSettings);
|
||||||
|
}
|
||||||
|
catch (ArgumentException e)
|
||||||
|
{
|
||||||
|
_logger.LogError($"Something went wrong: {e}");
|
||||||
|
return new BadRequest(e.Message);
|
||||||
|
}
|
||||||
|
if (!_clusterConfigurationFile.DirectoryExists())
|
||||||
|
{
|
||||||
|
_logger.LogError($"Cluster not found: {clusterName}");
|
||||||
|
return new NotFound("Cluster not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
var filePath = _clusterConfigurationFile.GetFilePath();
|
||||||
|
if (!_clusterConfigurationFile.FileExists())
|
||||||
|
{
|
||||||
|
_logger.LogError($"Configuration file not found: {filePath}");
|
||||||
|
return new NotFound("Configuration file not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
var schedule = new List<MeasuringEvent>();
|
||||||
|
|
||||||
|
using (StreamReader reader = new StreamReader(filePath))
|
||||||
|
{
|
||||||
|
string line;
|
||||||
|
while ((line = reader.ReadLine()) != null)
|
||||||
|
{
|
||||||
|
var s = line.Split(',');
|
||||||
|
schedule.Add(
|
||||||
|
new MeasuringEvent() {
|
||||||
|
Day = (MeasuringDay)int.Parse(s[0]),
|
||||||
|
Time = s[1]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Ok(
|
||||||
|
new{
|
||||||
|
name = clusterName,
|
||||||
|
schedule = schedule,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("~/clusters/{clusterName}/schedules")]
|
||||||
|
public IActionResult UpdateClusterSchedules(string clusterName, UpdateScheduleRequest request)
|
||||||
|
{
|
||||||
|
var message = "Cluster updated";
|
||||||
|
_clusterConfigurationFile = null;
|
||||||
|
try {
|
||||||
|
_clusterConfigurationFile = new ClusterConfigurationFile(clusterName, _appSettings);
|
||||||
|
}
|
||||||
|
catch (ArgumentException e)
|
||||||
|
{
|
||||||
|
_logger.LogError($"Something went wrong: {e}");
|
||||||
|
return new BadRequest(e.Message);
|
||||||
|
}
|
||||||
|
if (!_clusterConfigurationFile.FileExists())
|
||||||
|
{
|
||||||
|
_clusterConfigurationFile.Create();
|
||||||
|
message = "Cluster created";
|
||||||
|
}
|
||||||
|
if (request.Schedule?.Count > 0)
|
||||||
|
{
|
||||||
|
var filePath = _clusterConfigurationFile.GetFilePath();
|
||||||
|
using (StreamWriter writer = new StreamWriter(filePath))
|
||||||
|
{
|
||||||
|
foreach (
|
||||||
|
var e in request.Schedule.OrderBy(s => s.Day).ThenBy(
|
||||||
|
s => TimeSpan.Parse(s.Time)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
var time = TimeSpan.Parse(e.Time);
|
||||||
|
writer.WriteLine($"{(int)e.Day},{time.ToString(@"hh\:mm")}");
|
||||||
|
writer.Flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Ok(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/DevicesRestApi/DevicesRestApi.csproj
Normal file
19
src/DevicesRestApi/DevicesRestApi.csproj
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.20" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
<PackageReference Include="Serilog" Version="4.0.0" />
|
||||||
|
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
8
src/DevicesRestApi/Helpers/AppSettings.cs
Normal file
8
src/DevicesRestApi/Helpers/AppSettings.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace DevicesRestApi.Helpers;
|
||||||
|
|
||||||
|
public class AppSettings
|
||||||
|
{
|
||||||
|
public string ApiKey { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string ClustersRootPath { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
75
src/DevicesRestApi/Helpers/ClusterConfigurationFile.cs
Normal file
75
src/DevicesRestApi/Helpers/ClusterConfigurationFile.cs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
namespace DevicesRestApi.Helpers;
|
||||||
|
|
||||||
|
public class ClusterConfigurationFile
|
||||||
|
{
|
||||||
|
private readonly string _rootDirectory;
|
||||||
|
|
||||||
|
private readonly string _clusterName;
|
||||||
|
|
||||||
|
private const string RegularTimeFilename = "regular.time";
|
||||||
|
|
||||||
|
private readonly AppSettings _appSettings;
|
||||||
|
|
||||||
|
public ClusterConfigurationFile(
|
||||||
|
string clusterName,
|
||||||
|
AppSettings appSettings
|
||||||
|
) {
|
||||||
|
_clusterName = clusterName;
|
||||||
|
_appSettings = appSettings;
|
||||||
|
_rootDirectory = _appSettings.ClustersRootPath;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(_clusterName))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("The provided cluster name is null or empty.");
|
||||||
|
}
|
||||||
|
if (string.IsNullOrEmpty(_rootDirectory))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Clusters root directory is not configured.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetDirectoryPath()
|
||||||
|
{
|
||||||
|
return Path.Combine(_rootDirectory, _clusterName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetFilePath()
|
||||||
|
{
|
||||||
|
return Path.Combine(GetDirectoryPath(), RegularTimeFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool FileExists()
|
||||||
|
{
|
||||||
|
return File.Exists(GetFilePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DirectoryExists()
|
||||||
|
{
|
||||||
|
return Directory.Exists(GetDirectoryPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateDirectory()
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(GetDirectoryPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateFile()
|
||||||
|
{
|
||||||
|
using (FileStream fs = File.Create(GetFilePath()))
|
||||||
|
{
|
||||||
|
// The file is created and opened, we don't need to write anything to it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Create()
|
||||||
|
{
|
||||||
|
if (!DirectoryExists())
|
||||||
|
{
|
||||||
|
CreateDirectory();
|
||||||
|
}
|
||||||
|
if (!FileExists())
|
||||||
|
{
|
||||||
|
CreateFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/DevicesRestApi/Helpers/MeasuringDay.cs
Normal file
12
src/DevicesRestApi/Helpers/MeasuringDay.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace DevicesRestApi.Helpers;
|
||||||
|
|
||||||
|
public enum MeasuringDay
|
||||||
|
{
|
||||||
|
MONDAY = 1,
|
||||||
|
TUESDAY = 2,
|
||||||
|
WEDNESDAY = 3,
|
||||||
|
THURSDAY = 4,
|
||||||
|
FRIDAY = 5,
|
||||||
|
SATURDAY = 6,
|
||||||
|
SUNDAY = 7
|
||||||
|
}
|
||||||
7
src/DevicesRestApi/Helpers/MeasuringEvent.cs
Normal file
7
src/DevicesRestApi/Helpers/MeasuringEvent.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace DevicesRestApi.Helpers;
|
||||||
|
|
||||||
|
public class MeasuringEvent
|
||||||
|
{
|
||||||
|
public MeasuringDay Day { get; set; }
|
||||||
|
public string Time { get; set; }
|
||||||
|
}
|
||||||
6
src/DevicesRestApi/Helpers/UpdateScheduleRequest.cs
Normal file
6
src/DevicesRestApi/Helpers/UpdateScheduleRequest.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace DevicesRestApi.Helpers;
|
||||||
|
|
||||||
|
public class UpdateScheduleRequest
|
||||||
|
{
|
||||||
|
public List<MeasuringEvent>? Schedule { get; set; }
|
||||||
|
}
|
||||||
5
src/DevicesRestApi/Logs/.gitignore
vendored
Normal file
5
src/DevicesRestApi/Logs/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Ignore everything
|
||||||
|
*
|
||||||
|
|
||||||
|
# But not this file
|
||||||
|
!.gitignore
|
||||||
36
src/DevicesRestApi/Middlewares/ApiKeyMiddleware.cs
Normal file
36
src/DevicesRestApi/Middlewares/ApiKeyMiddleware.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
public class ApiKeyMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
private const string ApiKeyHeaderName = "X-Api-Key";
|
||||||
|
|
||||||
|
public ApiKeyMiddleware(RequestDelegate next)
|
||||||
|
{
|
||||||
|
_next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext context, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
if (!context.Request.Headers.TryGetValue(ApiKeyHeaderName, out var extractedApiKey))
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = 401;
|
||||||
|
await context.Response.WriteAsync("API key was not provided.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var appSettings = configuration.GetSection("AppSettings");
|
||||||
|
var apiKey = appSettings.GetValue<string>("ApiKey");
|
||||||
|
|
||||||
|
if (!extractedApiKey.Equals(apiKey))
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = 401;
|
||||||
|
await context.Response.WriteAsync("Unauthorized client.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _next(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
47
src/DevicesRestApi/Middlewares/ErrorHandlerMiddleware.cs
Normal file
47
src/DevicesRestApi/Middlewares/ErrorHandlerMiddleware.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
public class ErrorHandlerMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
private readonly ILogger<ErrorHandlerMiddleware> _logger;
|
||||||
|
|
||||||
|
public ErrorHandlerMiddleware(
|
||||||
|
RequestDelegate next,
|
||||||
|
ILogger<ErrorHandlerMiddleware> logger
|
||||||
|
) {
|
||||||
|
_next = next;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _next(httpContext);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError($"Something went wrong: {ex}");
|
||||||
|
await HandleExceptionAsync(httpContext, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task HandleExceptionAsync(HttpContext context, Exception exception)
|
||||||
|
{
|
||||||
|
context.Response.ContentType = "application/json";
|
||||||
|
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||||
|
|
||||||
|
var response = new
|
||||||
|
{
|
||||||
|
status = context.Response.StatusCode,
|
||||||
|
message = "Internal Server Error.",
|
||||||
|
detailed = exception.Message
|
||||||
|
};
|
||||||
|
|
||||||
|
return context.Response.WriteAsync(System.Text.Json.JsonSerializer.Serialize(response));
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/DevicesRestApi/Middlewares/NotFoundMiddleware.cs
Normal file
29
src/DevicesRestApi/Middlewares/NotFoundMiddleware.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
public class NotFoundMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
|
||||||
|
public NotFoundMiddleware(RequestDelegate next)
|
||||||
|
{
|
||||||
|
_next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext context)
|
||||||
|
{
|
||||||
|
await _next(context);
|
||||||
|
|
||||||
|
if (context.Response.StatusCode == 404 && !context.Response.HasStarted)
|
||||||
|
{
|
||||||
|
context.Response.ContentType = "application/json";
|
||||||
|
var errorResponse = new
|
||||||
|
{
|
||||||
|
status = 404,
|
||||||
|
message = "Not Found"
|
||||||
|
};
|
||||||
|
await context.Response.WriteAsync(JsonConvert.SerializeObject(errorResponse));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
74
src/DevicesRestApi/Program.cs
Normal file
74
src/DevicesRestApi/Program.cs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
|
using DevicesRestApi.Helpers;
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
builder.Services.AddControllers();
|
||||||
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
builder.Services.AddSwaggerGen();
|
||||||
|
|
||||||
|
builder.Services.Configure<AppSettings>(builder.Configuration.GetSection("AppSettings"));
|
||||||
|
|
||||||
|
var configuration = new ConfigurationBuilder()
|
||||||
|
.AddJsonFile("appsettings.json")
|
||||||
|
.AddJsonFile("serilog.json", optional: true, reloadOnChange: true)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Log.Logger = new LoggerConfiguration()
|
||||||
|
.ReadFrom.Configuration(configuration)
|
||||||
|
.Enrich.FromLogContext()
|
||||||
|
.WriteTo.Console()
|
||||||
|
.CreateLogger();
|
||||||
|
|
||||||
|
// Suppress the default logging providers to avoid duplicate messages
|
||||||
|
/*
|
||||||
|
builder.Host.UseSerilog((context, services, configuration) => configuration
|
||||||
|
.ReadFrom.Configuration(context.Configuration)
|
||||||
|
.ReadFrom.Services(services)
|
||||||
|
.Enrich.FromLogContext()
|
||||||
|
.WriteTo.Console());
|
||||||
|
*/
|
||||||
|
|
||||||
|
builder.Host.UseSerilog();
|
||||||
|
|
||||||
|
builder.Logging.ClearProviders();
|
||||||
|
builder.Logging.AddSerilog(Log.Logger);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Log.Information("Starting up");
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
|
app.UseMiddleware<ApiKeyMiddleware>();
|
||||||
|
app.UseMiddleware<ErrorHandlerMiddleware>();
|
||||||
|
app.UseMiddleware<NotFoundMiddleware>();
|
||||||
|
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
app.Run();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Fatal(e, "Application start-up failed");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Log.CloseAndFlush();
|
||||||
|
}
|
||||||
41
src/DevicesRestApi/Properties/launchSettings.json
Normal file
41
src/DevicesRestApi/Properties/launchSettings.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:53426",
|
||||||
|
"sslPort": 44360
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "http://localhost:5148",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "https://localhost:7113;http://localhost:5148",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/DevicesRestApi/Results/BadRequest.cs
Normal file
10
src/DevicesRestApi/Results/BadRequest.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
public class BadRequest : ObjectResult
|
||||||
|
{
|
||||||
|
public BadRequest(string message)
|
||||||
|
: base(new { status = 400, message = message })
|
||||||
|
{
|
||||||
|
StatusCode = StatusCodes.Status400BadRequest;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/DevicesRestApi/Results/NotFound.cs
Normal file
10
src/DevicesRestApi/Results/NotFound.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
public class NotFound : ObjectResult
|
||||||
|
{
|
||||||
|
public NotFound(string message)
|
||||||
|
: base(new { status = 404, message = message })
|
||||||
|
{
|
||||||
|
StatusCode = StatusCodes.Status404NotFound;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/DevicesRestApi/Results/Ok.cs
Normal file
16
src/DevicesRestApi/Results/Ok.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
public class Ok : ObjectResult
|
||||||
|
{
|
||||||
|
public Ok(string message = null)
|
||||||
|
: base(new { status = 200, message = message })
|
||||||
|
{
|
||||||
|
StatusCode = StatusCodes.Status200OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ok(object data = null)
|
||||||
|
: base(new { status = 200, data = data })
|
||||||
|
{
|
||||||
|
StatusCode = StatusCodes.Status200OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
40
src/DevicesRestApi/appsettings.example.json
Normal file
40
src/DevicesRestApi/appsettings.example.json
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"System": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AppSettings": {
|
||||||
|
"ApiKey": "api-key",
|
||||||
|
"ClustersRootPath": "/tmp/projects"
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*",
|
||||||
|
"Serilog": {
|
||||||
|
"MinimumLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Override": {
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"System": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"WriteTo": [
|
||||||
|
{
|
||||||
|
"Name": "File",
|
||||||
|
"Args": {
|
||||||
|
"path": "Logs/log-.txt",
|
||||||
|
"rollingInterval": "Day"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Enrich": [
|
||||||
|
"FromLogContext",
|
||||||
|
"WithMachineName",
|
||||||
|
"WithThreadId"
|
||||||
|
],
|
||||||
|
"Properties": {
|
||||||
|
"Application": "DevicesRestApi"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user