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