Browse Source

Add API controllers for MQTTnet.Server.

release/3.x.x
Christian Kratky 5 years ago
parent
commit
e6cf23aebd
8 changed files with 284 additions and 45 deletions
  1. +61
    -0
      Source/MQTTnet.Server/Controllers/ClientsController.cs
  2. +62
    -0
      Source/MQTTnet.Server/Controllers/RetainedApplicationMessagesController.cs
  3. +11
    -0
      Source/MQTTnet.Server/Controllers/ScriptsController.cs
  4. +77
    -0
      Source/MQTTnet.Server/Controllers/SessionsController.cs
  5. +0
    -42
      Source/MQTTnet.Server/Controllers/ValuesController.cs
  6. +2
    -2
      Source/MQTTnet.Server/MQTTnet.Server.csproj
  7. +29
    -0
      Source/MQTTnet.Server/Mqtt/MqttServerService.cs
  8. +42
    -1
      Source/MQTTnet.Server/Startup.cs

+ 61
- 0
Source/MQTTnet.Server/Controllers/ClientsController.cs View File

@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNetCore.Mvc;
using MQTTnet.Server.Mqtt;
using MQTTnet.Server.Status;

namespace MQTTnet.Server.Controllers
{
[ApiController]
public class ClientsController : ControllerBase
{
private readonly MqttServerService _mqttServerService;

public ClientsController(MqttServerService mqttServerService)
{
_mqttServerService = mqttServerService ?? throw new ArgumentNullException(nameof(mqttServerService));
}

[Route("api/v1/clients")]
[HttpGet]
public async Task<ActionResult<IList<IMqttClientStatus>>> GetClients()
{
return new ObjectResult(await _mqttServerService.GetClientStatusAsync());
}

[Route("api/v1/clients/{clientId}")]
[HttpGet]
public async Task<ActionResult<IMqttClientStatus>> GetClient(string clientId)
{
clientId = HttpUtility.UrlDecode(clientId);

var client = (await _mqttServerService.GetClientStatusAsync()).FirstOrDefault(c => c.ClientId == clientId);
if (client == null)
{
return new StatusCodeResult((int)HttpStatusCode.NotFound);
}

return new ObjectResult(client);
}

[Route("api/v1/clients/{clientId}")]
[HttpDelete]
public async Task<ActionResult> DeleteClient(string clientId)
{
clientId = HttpUtility.UrlDecode(clientId);

var client = (await _mqttServerService.GetClientStatusAsync()).FirstOrDefault(c => c.ClientId == clientId);
if (client == null)
{
return new StatusCodeResult((int)HttpStatusCode.NotFound);
}

await client.DisconnectAsync();
return StatusCode((int)HttpStatusCode.NoContent);
}
}
}

+ 62
- 0
Source/MQTTnet.Server/Controllers/RetainedApplicationMessagesController.cs View File

@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNetCore.Mvc;
using MQTTnet.Server.Mqtt;

namespace MQTTnet.Server.Controllers
{
[ApiController]
public class RetainedApplicationMessagesController : ControllerBase
{
private readonly MqttServerService _mqttServerService;

public RetainedApplicationMessagesController(MqttServerService mqttServerService)
{
_mqttServerService = mqttServerService ?? throw new ArgumentNullException(nameof(mqttServerService));
}

[Route("api/v1/retainedApplicationMessages")]
[HttpGet]
public async Task<ActionResult<IList<MqttApplicationMessage>>> GetRetainedApplicationMessages()
{
return new ObjectResult(await _mqttServerService.GetRetainedApplicationMessagesAsync());
}

[Route("api/v1/retainedApplicationMessages/{topic}")]
[HttpGet]
public async Task<ActionResult<MqttApplicationMessage>> GetRetainedApplicationMessage(string topic)
{
topic = HttpUtility.UrlDecode(topic);

var applicationMessage = (await _mqttServerService.GetRetainedApplicationMessagesAsync()).FirstOrDefault(c => c.Topic == topic);
if (applicationMessage == null)
{
return new StatusCodeResult((int)HttpStatusCode.NotFound);
}

return new ObjectResult(applicationMessage);
}

[Route("api/v1/retainedApplicationMessages")]
[HttpDelete]
public async Task<ActionResult> DeleteRetainedApplicationMessages()
{
await _mqttServerService.ClearRetainedApplicationMessagesAsync();
return StatusCode((int)HttpStatusCode.NoContent);
}

[Route("api/v1/retainedApplicationMessages/{topic}")]
[HttpDelete]
public async Task<ActionResult> DeleteRetainedApplicationMessage(string topic)
{
topic = HttpUtility.UrlDecode(topic);

await _mqttServerService.PublishAsync(new MqttApplicationMessageBuilder().WithTopic(topic).WithRetainFlag().Build());
return StatusCode((int)HttpStatusCode.NoContent);
}
}
}

+ 11
- 0
Source/MQTTnet.Server/Controllers/ScriptsController.cs View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MQTTnet.Server.Controllers
{
public class ScriptsController
{
}
}

+ 77
- 0
Source/MQTTnet.Server/Controllers/SessionsController.cs View File

@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNetCore.Mvc;
using MQTTnet.Server.Mqtt;
using MQTTnet.Server.Status;

namespace MQTTnet.Server.Controllers
{
[ApiController]
public class SessionsController : ControllerBase
{
private readonly MqttServerService _mqttServerService;

public SessionsController(MqttServerService mqttServerService)
{
_mqttServerService = mqttServerService ?? throw new ArgumentNullException(nameof(mqttServerService));
}

[Route("api/v1/sessions")]
[HttpGet]
public async Task<ActionResult<IList<IMqttSessionStatus>>> GetSessions()
{
return new ObjectResult(await _mqttServerService.GetSessionStatusAsync());
}

[Route("api/v1/sessions/{clientId}")]
[HttpGet]
public async Task<ActionResult<IMqttClientStatus>> GetSession(string clientId)
{
clientId = HttpUtility.UrlDecode(clientId);

var session = (await _mqttServerService.GetSessionStatusAsync()).FirstOrDefault(c => c.ClientId == clientId);
if (session == null)
{
return new StatusCodeResult((int)HttpStatusCode.NotFound);
}

return new ObjectResult(session);
}

[Route("api/v1/sessions/{clientId}")]
[HttpDelete]
public async Task<ActionResult> DeleteSession(string clientId)
{
clientId = HttpUtility.UrlDecode(clientId);

var session = (await _mqttServerService.GetSessionStatusAsync()).FirstOrDefault(c => c.ClientId == clientId);
if (session == null)
{
return new StatusCodeResult((int)HttpStatusCode.NotFound);
}

await session.DeleteAsync();
return StatusCode((int)HttpStatusCode.NoContent);
}

[Route("api/v1/sessions/{clientId}/pendingApplicationMessages")]
[HttpDelete]
public async Task<ActionResult> DeletePendingApplicationMessages(string clientId)
{
clientId = HttpUtility.UrlDecode(clientId);

var session = (await _mqttServerService.GetSessionStatusAsync()).FirstOrDefault(c => c.ClientId == clientId);
if (session == null)
{
return new StatusCodeResult((int)HttpStatusCode.NotFound);
}

await session.ClearPendingApplicationMessagesAsync();
return StatusCode((int)HttpStatusCode.NoContent);
}
}
}

+ 0
- 42
Source/MQTTnet.Server/Controllers/ValuesController.cs View File

@@ -1,42 +0,0 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;

namespace MQTTnet.Server.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}

// GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "value";
}

// POST api/values
[HttpPost]
public void Post([FromBody] string value)
{
}

// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}

// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}

+ 2
- 2
Source/MQTTnet.Server/MQTTnet.Server.csproj View File

@@ -40,8 +40,8 @@
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="2.2.1" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="4.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="4.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.0.0-rc2" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="5.0.0-rc2" />
</ItemGroup>

<ItemGroup>


+ 29
- 0
Source/MQTTnet.Server/Mqtt/MqttServerService.cs View File

@@ -10,10 +10,12 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using MQTTnet.Adapter;
using MQTTnet.AspNetCore;
using MQTTnet.Client.Publishing;
using MQTTnet.Implementations;
using MQTTnet.Protocol;
using MQTTnet.Server.Configuration;
using MQTTnet.Server.Scripting;
using MQTTnet.Server.Status;

namespace MQTTnet.Server.Mqtt
{
@@ -92,6 +94,33 @@ namespace MQTTnet.Server.Mqtt
return _webSocketServerAdapter.RunWebSocketConnectionAsync(webSocket, httpContext);
}

public Task<IList<IMqttClientStatus>> GetClientStatusAsync()
{
return _mqttServer.GetClientStatusAsync();
}

public Task<IList<IMqttSessionStatus>> GetSessionStatusAsync()
{
return _mqttServer.GetSessionStatusAsync();
}

public Task ClearRetainedApplicationMessagesAsync()
{
return _mqttServer.ClearRetainedApplicationMessagesAsync();
}

public Task<IList<MqttApplicationMessage>> GetRetainedApplicationMessagesAsync()
{
return _mqttServer.GetRetainedApplicationMessagesAsync();
}

public Task<MqttClientPublishResult> PublishAsync(MqttApplicationMessage applicationMessage)
{
if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));

return _mqttServer.PublishAsync(applicationMessage);
}

private void Publish(PythonDictionary parameters)
{
try


+ 42
- 1
Source/MQTTnet.Server/Startup.cs View File

@@ -5,12 +5,14 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Microsoft.Scripting.Utils;
using MQTTnet.Server.Configuration;
using MQTTnet.Server.Logging;
using MQTTnet.Server.Mqtt;
using MQTTnet.Server.Scripting;
using MQTTnet.Server.Scripting.DataSharing;
using Swashbuckle.AspNetCore.SwaggerUI;

namespace MQTTnet.Server
{
@@ -55,11 +57,28 @@ namespace MQTTnet.Server
pythonScriptHostService.Configure();

mqttServerService.Configure();

application.UseSwagger(o => o.RouteTemplate = "/api/{documentName}/swagger.json");

application.UseSwaggerUI(o =>
{
o.RoutePrefix = "api";
o.DocumentTitle = "MQTTnet.Server API";
o.SwaggerEndpoint("/api/v1/swagger.json", "MQTTnet.Server API v1");
o.DisplayRequestDuration();
o.DocExpansion(DocExpansion.List);
o.DefaultModelRendering(ModelRendering.Model);
});
}

public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(options =>
{
options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
});

services.AddSingleton(ReadSettings());

@@ -79,6 +98,28 @@ namespace MQTTnet.Server
services.AddSingleton<MqttConnectionValidator>();
services.AddSingleton<MqttSubscriptionInterceptor>();
services.AddSingleton<MqttApplicationMessageInterceptor>();
services.AddSwaggerGen(c =>
{
c.DescribeAllEnumsAsStrings();
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "MQTTnet.Server API",
Version = "v1",
Description = "The public API for the MQTT broker MQTTnet.Server.",
License = new OpenApiLicense
{
Name = "MIT",
Url = new Uri("https://github.com/chkr1011/MQTTnet/blob/master/README.md")
},
Contact = new OpenApiContact
{
Name = "MQTTnet.Server",
Email = string.Empty,
Url = new Uri("https://github.com/chkr1011/MQTTnet")
},
});
});
}

private SettingsModel ReadSettings()


Loading…
Cancel
Save