Added MQTT tester, added input service

This commit is contained in:
kunkliricsi 2020-11-08 18:51:19 +01:00
parent e1a596dae9
commit f102b89a21
16 changed files with 1956 additions and 17 deletions

View File

@ -10,7 +10,7 @@ using Microsoft.AspNetCore.Authorization;
namespace Birdmap.API.Controllers namespace Birdmap.API.Controllers
{ {
[Authorize] [Authorize(Roles = "Admin")]
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]")]
public class DevicesController : ControllerBase public class DevicesController : ControllerBase
@ -26,6 +26,7 @@ namespace Birdmap.API.Controllers
/// <summary>Get all device info</summary> /// <summary>Get all device info</summary>
/// <returns>Array of devices</returns> /// <returns>Array of devices</returns>
[Authorize(Roles = "User,Admin")]
[HttpGet] [HttpGet]
public async Task<ActionResult<List<Device>>> Getall() public async Task<ActionResult<List<Device>>> Getall()
{ {
@ -61,6 +62,7 @@ namespace Birdmap.API.Controllers
/// <summary>Get all device info</summary> /// <summary>Get all device info</summary>
/// <param name="deviceID">ID of device to query</param> /// <param name="deviceID">ID of device to query</param>
/// <returns>Information about a particular device</returns> /// <returns>Information about a particular device</returns>
[Authorize(Roles = "User,Admin")]
[HttpGet, Route("{deviceID}")] [HttpGet, Route("{deviceID}")]
public async Task<ActionResult<Device>> Getdevice([BindRequired] Guid deviceID) public async Task<ActionResult<Device>> Getdevice([BindRequired] Guid deviceID)
{ {
@ -99,6 +101,7 @@ namespace Birdmap.API.Controllers
/// <param name="deviceID">ID of device to query</param> /// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param> /// <param name="sensorID">ID of sensor to query</param>
/// <returns>Information about a sensor</returns> /// <returns>Information about a sensor</returns>
[Authorize(Roles = "User,Admin")]
[HttpGet, Route("{deviceID}/{sensorID}")] [HttpGet, Route("{deviceID}/{sensorID}")]
public async Task<ActionResult<Sensor>> Getsensor([BindRequired] Guid deviceID, [BindRequired] Guid sensorID) public async Task<ActionResult<Sensor>> Getsensor([BindRequired] Guid deviceID, [BindRequired] Guid sensorID)
{ {

View File

@ -14,7 +14,7 @@ using System.Threading.Tasks;
namespace Birdmap.API.Controllers namespace Birdmap.API.Controllers
{ {
[Authorize] [Authorize(Roles = "Admin")]
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]")]
public class ServicesController : ControllerBase public class ServicesController : ControllerBase
@ -30,6 +30,7 @@ namespace Birdmap.API.Controllers
_logger = logger; _logger = logger;
} }
[Authorize(Roles = "User,Admin")]
[HttpGet, ProducesResponseType(StatusCodes.Status200OK)] [HttpGet, ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<List<ServiceInfo>>> GetAsync() public async Task<ActionResult<List<ServiceInfo>>> GetAsync()
{ {

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Birdmap.BLL.Helpers
{
public static class IEnumerableExtensions
{
public static TSource RandomElementAt<TSource>(this IEnumerable<TSource> source, Random random = null)
{
random ??= new Random();
return source.ElementAt(random.Next(source.Count()));
}
}
}

View File

@ -0,0 +1,163 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Birdmap.BLL.Interfaces
{
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0))")]
public partial interface IInputService
{
/// <summary>Get input object by ID</summary>
/// <param name="tagID">ID of input object file</param>
/// <returns>input object</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task<InputSingeResponse> GetInputAsync(System.Guid tagID);
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Get input object by ID</summary>
/// <param name="tagID">ID of input object file</param>
/// <returns>input object</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task<InputSingeResponse> GetInputAsync(System.Guid tagID, System.Threading.CancellationToken cancellationToken);
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
public partial class InputSingeResponse
{
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
public string Status { get; set; }
[Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
public InputObject Message { get; set; } = new InputObject();
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
[Newtonsoft.Json.JsonExtensionData]
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
{
get { return _additionalProperties; }
set { _additionalProperties = value; }
}
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
public partial class InputResponse : System.Collections.ObjectModel.Collection<InputObject>
{
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
public partial class InputObject
{
[Newtonsoft.Json.JsonProperty("tag", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
public System.Guid Tag { get; set; }
[Newtonsoft.Json.JsonProperty("date", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
[Newtonsoft.Json.JsonConverter(typeof(DateFormatConverter))]
public System.DateTimeOffset Date { get; set; }
[Newtonsoft.Json.JsonProperty("device_id", Required = Newtonsoft.Json.Required.Always)]
public Guid Device_id { get; set; }
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
[Newtonsoft.Json.JsonExtensionData]
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
{
get { return _additionalProperties; }
set { _additionalProperties = value; }
}
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
public partial class ApiResponse
{
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
public string Status { get; set; }
[Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
public string Message { get; set; }
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
[Newtonsoft.Json.JsonExtensionData]
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
{
get { return _additionalProperties; }
set { _additionalProperties = value; }
}
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
public partial class Description
{
[Newtonsoft.Json.JsonProperty("deviceid", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string Deviceid { get; set; }
[Newtonsoft.Json.JsonProperty("date", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
[Newtonsoft.Json.JsonConverter(typeof(DateFormatConverter))]
public System.DateTimeOffset Date { get; set; }
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
[Newtonsoft.Json.JsonExtensionData]
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
{
get { return _additionalProperties; }
set { _additionalProperties = value; }
}
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
internal class DateFormatConverter : Newtonsoft.Json.Converters.IsoDateTimeConverter
{
public DateFormatConverter()
{
DateTimeFormat = "yyyy-MM-dd";
}
}
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0))")]
public partial class FileParameter
{
public FileParameter(System.IO.Stream data)
: this(data, null, null)
{
}
public FileParameter(System.IO.Stream data, string fileName)
: this(data, fileName, null)
{
}
public FileParameter(System.IO.Stream data, string fileName, string contentType)
{
Data = data;
FileName = fileName;
ContentType = contentType;
}
public System.IO.Stream Data { get; private set; }
public string FileName { get; private set; }
public string ContentType { get; private set; }
}
}

View File

@ -6,8 +6,12 @@ using System.Threading.Tasks;
namespace Birdmap.BLL.Services namespace Birdmap.BLL.Services
{ {
public abstract class DeviceServiceBase : IDeviceService public abstract class DeviceAndInputServiceBase : IDeviceService, IInputService
{ {
public virtual Task<InputSingeResponse> GetInputAsync(Guid tagID)
=> GetInputAsync(tagID, CancellationToken.None);
public abstract Task<InputSingeResponse> GetInputAsync(Guid tagID, CancellationToken cancellationToken);
public virtual Task<ICollection<Device>> GetallAsync() public virtual Task<ICollection<Device>> GetallAsync()
=> GetallAsync(CancellationToken.None); => GetallAsync(CancellationToken.None);
public abstract Task<ICollection<Device>> GetallAsync(CancellationToken cancellationToken); public abstract Task<ICollection<Device>> GetallAsync(CancellationToken cancellationToken);

View File

@ -1,4 +1,5 @@
using Birdmap.BLL.Interfaces; using Birdmap.BLL.Helpers;
using Birdmap.BLL.Interfaces;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -7,33 +8,40 @@ using System.Threading.Tasks;
namespace Birdmap.BLL.Services namespace Birdmap.BLL.Services
{ {
public class DummyDeviceService : DeviceServiceBase public class DummyDeviceAndInputService : DeviceAndInputServiceBase
{ {
private const int numberOfDevices = 15;
private const double centerLong = 21.469640; private const double centerLong = 21.469640;
private const double centerLat = 48.275939; private const double centerLat = 48.275939;
private const double radius = 0.000200; private const double radius = 0.000200;
private readonly Lazy<ICollection<Device>> _devices = new Lazy<ICollection<Device>>(GenerateDevices); private static readonly Random Rand = new Random();
private static readonly Lazy<ICollection<Device>> Devices = new Lazy<ICollection<Device>>(GenerateDevices);
private static readonly Dictionary<Guid, InputSingeResponse> TagToInput = new Dictionary<Guid, InputSingeResponse>();
private static readonly object InputLock = new object();
private static ListOfDevices GenerateDevices() private static ListOfDevices GenerateDevices()
{ {
var devices = new ListOfDevices(); var devices = new ListOfDevices();
var rand = new Random();
T GetRandomEnum<T>() T GetRandomEnum<T>()
{ {
var values = Enum.GetValues(typeof(T)); var values = Enum.GetValues(typeof(T));
return (T)values.GetValue(rand.Next(values.Length)); return (T)values.GetValue(Rand.Next(values.Length));
} }
double GetPlusMinus(double center, double radius) double GetPlusMinus(double center, double radius)
{ {
return center - radius + rand.NextDouble() * radius * 2; return center - radius + Rand.NextDouble() * radius * 2;
} }
for (int d = 0; d < 15; d++) for (int d = 0; d < numberOfDevices; d++)
{ {
var sensors = new ArrayofSensors(); var sensors = new ArrayofSensors();
for (int s = 0; s < rand.Next(1, 5); s++) for (int s = 0; s < Rand.Next(1, 6); s++)
{ {
sensors.Add(new Sensor sensors.Add(new Sensor
{ {
@ -61,17 +69,17 @@ namespace Birdmap.BLL.Services
public override Task<ICollection<Device>> GetallAsync(CancellationToken cancellationToken) public override Task<ICollection<Device>> GetallAsync(CancellationToken cancellationToken)
{ {
return Task.FromResult(_devices.Value); return Task.FromResult(Devices.Value);
} }
public override Task<Device> GetdeviceAsync(Guid deviceID, CancellationToken cancellationToken) public override Task<Device> GetdeviceAsync(Guid deviceID, CancellationToken cancellationToken)
{ {
return Task.FromResult(_devices.Value.SingleOrDefault(d => d.Id == deviceID)); return Task.FromResult(Devices.Value.SingleOrDefault(d => d.Id == deviceID));
} }
public override Task<Sensor> GetsensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken) public override Task<Sensor> GetsensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken)
{ {
return Task.FromResult(_devices.Value.SingleOrDefault(d => d.Id == deviceID)?.Sensors.SingleOrDefault(s => s.Id == sensorID)); return Task.FromResult(Devices.Value.SingleOrDefault(d => d.Id == deviceID)?.Sensors.SingleOrDefault(s => s.Id == sensorID));
} }
public override Task OfflineallAsync(CancellationToken cancellationToken) public override Task OfflineallAsync(CancellationToken cancellationToken)
@ -114,7 +122,7 @@ namespace Birdmap.BLL.Services
private void SetStatus(DeviceStatus deviceStatus, SensorStatus sensorStatus) private void SetStatus(DeviceStatus deviceStatus, SensorStatus sensorStatus)
{ {
foreach (var device in _devices.Value) foreach (var device in Devices.Value)
{ {
device.Status = deviceStatus; device.Status = deviceStatus;
foreach (var sensor in device.Sensors) foreach (var sensor in device.Sensors)
@ -135,5 +143,29 @@ namespace Birdmap.BLL.Services
var sensor = GetsensorAsync(deviceId, sensorID).Result; var sensor = GetsensorAsync(deviceId, sensorID).Result;
sensor.Status = status; sensor.Status = status;
} }
public override Task<InputSingeResponse> GetInputAsync(Guid tagID, CancellationToken cancellationToken)
{
lock (InputLock)
{
if (!TagToInput.TryGetValue(tagID, out var value))
{
value = new InputSingeResponse
{
Status = "Dummy_OK",
Message = new InputObject
{
Tag = tagID,
Date = DateTime.Now,
Device_id = Devices.Value.Where(d => d.Status == DeviceStatus.Online).RandomElementAt(Rand).Id,
}
};
TagToInput.TryAdd(tagID, value);
}
return Task.FromResult(value);
}
}
} }
} }

View File

@ -0,0 +1,477 @@
//----------------------
// <auto-generated>
// Generated using the NSwag toolchain v13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0)) (http://NSwag.org)
// </auto-generated>
//----------------------
#pragma warning disable 108 // Disable "CS0108 '{derivedDto}.ToJson()' hides inherited member '{dtoBase}.ToJson()'. Use the new keyword if hiding was intended."
#pragma warning disable 114 // Disable "CS0114 '{derivedDto}.RaisePropertyChanged(String)' hides inherited member 'dtoBase.RaisePropertyChanged(String)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword."
#pragma warning disable 472 // Disable "CS0472 The result of the expression is always 'false' since a value of type 'Int32' is never equal to 'null' of type 'Int32?'
#pragma warning disable 1573 // Disable "CS1573 Parameter '...' has no matching param tag in the XML comment for ...
#pragma warning disable 1591 // Disable "CS1591 Missing XML comment for publicly visible type or member ..."
namespace Birdmap.BLL.Services
{
using Birdmap.BLL.Interfaces;
using System = global::System;
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0))")]
public partial class LiveInputService : IInputService
{
private string _baseUrl = "https://birb.k8s.kmlabz.com";
private System.Net.Http.HttpClient _httpClient;
private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;
public LiveInputService(System.Net.Http.HttpClient httpClient)
{
_httpClient = httpClient;
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings);
}
private Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()
{
var settings = new Newtonsoft.Json.JsonSerializerSettings();
UpdateJsonSerializerSettings(settings);
return settings;
}
public string BaseUrl
{
get { return _baseUrl; }
set { _baseUrl = value; }
}
protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _settings.Value; } }
partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings);
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url);
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder);
partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
/// <summary>Get all stored input queries</summary>
/// <returns>Array of input objects</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task<System.Collections.Generic.ICollection<InputObject>> GetallAsync()
{
return GetallAsync(System.Threading.CancellationToken.None);
}
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Get all stored input queries</summary>
/// <returns>Array of input objects</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task<System.Collections.Generic.ICollection<InputObject>> GetallAsync(System.Threading.CancellationToken cancellationToken)
{
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/sample");
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Method = new System.Net.Http.HttpMethod("GET");
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
var objectResponse_ = await ReadObjectResponseAsync<System.Collections.Generic.ICollection<InputObject>>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
if (status_ == 404)
{
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
throw new ApiException<ApiResponse>("No object matching filter", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
/// <summary>uploads a sample into the system</summary>
/// <returns>successful operation</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task<ApiResponse> UploadFileAsync(Description description, FileParameter file)
{
return UploadFileAsync(description, file, System.Threading.CancellationToken.None);
}
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>uploads a sample into the system</summary>
/// <returns>successful operation</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task<ApiResponse> UploadFileAsync(Description description, FileParameter file, System.Threading.CancellationToken cancellationToken)
{
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/sample");
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
var boundary_ = System.Guid.NewGuid().ToString();
var content_ = new System.Net.Http.MultipartFormDataContent(boundary_);
content_.Headers.Remove("Content-Type");
content_.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=" + boundary_);
if (description == null)
throw new System.ArgumentNullException("description");
else
{
content_.Add(new System.Net.Http.StringContent(ConvertToString(description, System.Globalization.CultureInfo.InvariantCulture)), "description");
}
if (file == null)
throw new System.ArgumentNullException("file");
else
{
var content_file_ = new System.Net.Http.StreamContent(file.Data);
if (!string.IsNullOrEmpty(file.ContentType))
content_file_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse(file.ContentType);
content_.Add(content_file_, "file", file.FileName ?? "file");
}
request_.Content = content_;
request_.Method = new System.Net.Http.HttpMethod("POST");
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
if (status_ == 400)
{
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
throw new ApiException<ApiResponse>("JSON parse error", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
if (status_ == 415)
{
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
throw new ApiException<ApiResponse>("Media type error", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
if (status_ == 417)
{
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
throw new ApiException<ApiResponse>("JSON invalid schema", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
if (status_ == 469)
{
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
throw new ApiException<ApiResponse>("No file found", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
if (status_ == 470)
{
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
throw new ApiException<ApiResponse>("Description missing", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
/// <summary>Get input object by ID</summary>
/// <param name="tagID">ID of input object file</param>
/// <returns>input object</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task<InputSingeResponse> GetInputAsync(System.Guid tagID)
{
return GetInputAsync(tagID, System.Threading.CancellationToken.None);
}
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Get input object by ID</summary>
/// <param name="tagID">ID of input object file</param>
/// <returns>input object</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task<InputSingeResponse> GetInputAsync(System.Guid tagID, System.Threading.CancellationToken cancellationToken)
{
if (tagID == null)
throw new System.ArgumentNullException("tagID");
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/sample/{tagID}");
urlBuilder_.Replace("{tagID}", System.Uri.EscapeDataString(ConvertToString(tagID, System.Globalization.CultureInfo.InvariantCulture)));
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Method = new System.Net.Http.HttpMethod("GET");
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
var objectResponse_ = await ReadObjectResponseAsync<InputSingeResponse>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
if (status_ == 404)
{
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
throw new ApiException<ApiResponse>("Tag not found", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
protected struct ObjectResponseResult<T>
{
public ObjectResponseResult(T responseObject, string responseText)
{
this.Object = responseObject;
this.Text = responseText;
}
public T Object { get; }
public string Text { get; }
}
public bool ReadResponseAsString { get; set; }
protected virtual async System.Threading.Tasks.Task<ObjectResponseResult<T>> ReadObjectResponseAsync<T>(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers)
{
if (response == null || response.Content == null)
{
return new ObjectResponseResult<T>(default(T), string.Empty);
}
if (ReadResponseAsString)
{
var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
try
{
var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseText, JsonSerializerSettings);
return new ObjectResponseResult<T>(typedBody, responseText);
}
catch (Newtonsoft.Json.JsonException exception)
{
var message = "Could not deserialize the response body string as " + typeof(T).FullName + ".";
throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception);
}
}
else
{
try
{
using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
using (var streamReader = new System.IO.StreamReader(responseStream))
using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader))
{
var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings);
var typedBody = serializer.Deserialize<T>(jsonTextReader);
return new ObjectResponseResult<T>(typedBody, string.Empty);
}
}
catch (Newtonsoft.Json.JsonException exception)
{
var message = "Could not deserialize the response body stream as " + typeof(T).FullName + ".";
throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception);
}
}
}
private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value == null)
{
return null;
}
if (value is System.Enum)
{
var name = System.Enum.GetName(value.GetType(), value);
if (name != null)
{
var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name);
if (field != null)
{
var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute))
as System.Runtime.Serialization.EnumMemberAttribute;
if (attribute != null)
{
return attribute.Value != null ? attribute.Value : name;
}
}
return System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo));
}
}
else if (value is bool)
{
return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant();
}
else if (value is byte[])
{
return System.Convert.ToBase64String((byte[])value);
}
else if (value.GetType().IsArray)
{
var array = System.Linq.Enumerable.OfType<object>((System.Array)value);
return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo)));
}
var result = System.Convert.ToString(value, cultureInfo);
return (result is null) ? string.Empty : result;
}
}
}
#pragma warning restore 1591
#pragma warning restore 1573
#pragma warning restore 472
#pragma warning restore 114
#pragma warning restore 108

View File

@ -14,9 +14,15 @@ namespace Birdmap.BLL
services.AddTransient<IServiceService, ServiceService>(); services.AddTransient<IServiceService, ServiceService>();
if (configuration.GetValue<bool>("UseDummyServices")) if (configuration.GetValue<bool>("UseDummyServices"))
services.AddTransient<IDeviceService, DummyDeviceService>(); {
services.AddTransient<IInputService, DummyDeviceAndInputService>();
services.AddTransient<IDeviceService, DummyDeviceAndInputService>();
}
else else
{
services.AddTransient<IInputService, LiveInputService>();
services.AddTransient<IDeviceService, LiveDummyService>(); services.AddTransient<IDeviceService, LiveDummyService>();
}
return services; return services;
} }

View File

@ -9,7 +9,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Birdmap.BLL", "Birdmap.BLL\
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Birdmap.DAL", "Birdmap.DAL\Birdmap.DAL.csproj", "{543FAB06-B960-41A9-8865-1624A2ED2170}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Birdmap.DAL", "Birdmap.DAL\Birdmap.DAL.csproj", "{543FAB06-B960-41A9-8865-1624A2ED2170}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Birdmap.Common", "Birdmap.Common\Birdmap.Common.csproj", "{CE96BAFA-A0FD-4010-8EF2-700451091F71}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Birdmap.Common", "Birdmap.Common\Birdmap.Common.csproj", "{CE96BAFA-A0FD-4010-8EF2-700451091F71}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.TestApp.WinForm", "MQTTnet.TestApp.WinForm\MQTTnet.TestApp.WinForm.csproj", "{E1707FE7-4A65-42AC-B71C-6CC1A55FC42A}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -33,6 +35,10 @@ Global
{CE96BAFA-A0FD-4010-8EF2-700451091F71}.Debug|Any CPU.Build.0 = Debug|Any CPU {CE96BAFA-A0FD-4010-8EF2-700451091F71}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CE96BAFA-A0FD-4010-8EF2-700451091F71}.Release|Any CPU.ActiveCfg = Release|Any CPU {CE96BAFA-A0FD-4010-8EF2-700451091F71}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CE96BAFA-A0FD-4010-8EF2-700451091F71}.Release|Any CPU.Build.0 = Release|Any CPU {CE96BAFA-A0FD-4010-8EF2-700451091F71}.Release|Any CPU.Build.0 = Release|Any CPU
{E1707FE7-4A65-42AC-B71C-6CC1A55FC42A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E1707FE7-4A65-42AC-B71C-6CC1A55FC42A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1707FE7-4A65-42AC-B71C-6CC1A55FC42A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E1707FE7-4A65-42AC-B71C-6CC1A55FC42A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

394
MQTTnet.TestApp.WinForm/Form1.Designer.cs generated Normal file
View File

@ -0,0 +1,394 @@
namespace MQTTnet.TestApp.WinForm
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.TextBoxPort = new System.Windows.Forms.TextBox();
this.ButtonServerStart = new System.Windows.Forms.Button();
this.ButtonServerStop = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.maskedTextBox1 = new System.Windows.Forms.MaskedTextBox();
this.label3 = new System.Windows.Forms.Label();
this.TextBoxTopicPublished = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.ButtonPublisherStop = new System.Windows.Forms.Button();
this.ButtonPublisherStart = new System.Windows.Forms.Button();
this.TextBoxPublish = new System.Windows.Forms.TextBox();
this.ButtonPublish = new System.Windows.Forms.Button();
this.ButtonSubscriberStop = new System.Windows.Forms.Button();
this.ButtonSubscriberStart = new System.Windows.Forms.Button();
this.TextBoxSubscriber = new System.Windows.Forms.TextBox();
this.ButtonGeneratePublishedMessage = new System.Windows.Forms.Button();
this.label6 = new System.Windows.Forms.Label();
this.TextBoxTopicSubscribed = new System.Windows.Forms.TextBox();
this.ButtonSubscribe = new System.Windows.Forms.Button();
this.label7 = new System.Windows.Forms.Label();
this.trackBar1 = new System.Windows.Forms.TrackBar();
this.ButtonAutoPublisherStop = new System.Windows.Forms.Button();
this.ButtonAutoPublisherStart = new System.Windows.Forms.Button();
this.label8 = new System.Windows.Forms.Label();
this.checkBox1 = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(119, 24);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(32, 15);
this.label1.TabIndex = 0;
this.label1.Text = "Port:";
//
// TextBoxPort
//
this.TextBoxPort.Location = new System.Drawing.Point(172, 21);
this.TextBoxPort.Name = "TextBoxPort";
this.TextBoxPort.Size = new System.Drawing.Size(100, 23);
this.TextBoxPort.TabIndex = 1;
this.TextBoxPort.Text = "1883";
this.TextBoxPort.TextChanged += new System.EventHandler(this.TextBoxPortTextChanged);
//
// ButtonServerStart
//
this.ButtonServerStart.Location = new System.Drawing.Point(433, 21);
this.ButtonServerStart.Name = "ButtonServerStart";
this.ButtonServerStart.Size = new System.Drawing.Size(75, 23);
this.ButtonServerStart.TabIndex = 2;
this.ButtonServerStart.Text = "Start";
this.ButtonServerStart.UseVisualStyleBackColor = true;
this.ButtonServerStart.Click += new System.EventHandler(this.ButtonServerStartClick);
//
// ButtonServerStop
//
this.ButtonServerStop.Location = new System.Drawing.Point(514, 21);
this.ButtonServerStop.Name = "ButtonServerStop";
this.ButtonServerStop.Size = new System.Drawing.Size(75, 23);
this.ButtonServerStop.TabIndex = 3;
this.ButtonServerStop.Text = "Stop";
this.ButtonServerStop.UseVisualStyleBackColor = true;
this.ButtonServerStop.Click += new System.EventHandler(this.ButtonServerStopClick);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(33, 25);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(39, 15);
this.label2.TabIndex = 4;
this.label2.Text = "Server";
//
// maskedTextBox1
//
this.maskedTextBox1.Location = new System.Drawing.Point(0, 0);
this.maskedTextBox1.Name = "maskedTextBox1";
this.maskedTextBox1.Size = new System.Drawing.Size(100, 23);
this.maskedTextBox1.TabIndex = 5;
this.maskedTextBox1.Text = "maskedTextBox1";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(33, 79);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(90, 15);
this.label3.TabIndex = 5;
this.label3.Text = "Topic Published";
//
// TextBoxTopicPublished
//
this.TextBoxTopicPublished.Location = new System.Drawing.Point(164, 76);
this.TextBoxTopicPublished.Name = "TextBoxTopicPublished";
this.TextBoxTopicPublished.Size = new System.Drawing.Size(425, 23);
this.TextBoxTopicPublished.TabIndex = 1;
this.TextBoxTopicPublished.Text = "devices/output";
this.TextBoxTopicPublished.TextChanged += new System.EventHandler(this.TextBoxPortTextChanged);
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(33, 109);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(90, 15);
this.label4.TabIndex = 5;
this.label4.Text = "Client Publisher";
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(33, 224);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(96, 15);
this.label5.TabIndex = 5;
this.label5.Text = "Client Subscriber";
//
// ButtonPublisherStop
//
this.ButtonPublisherStop.Location = new System.Drawing.Point(514, 105);
this.ButtonPublisherStop.Name = "ButtonPublisherStop";
this.ButtonPublisherStop.Size = new System.Drawing.Size(75, 23);
this.ButtonPublisherStop.TabIndex = 3;
this.ButtonPublisherStop.Text = "Stop";
this.ButtonPublisherStop.UseVisualStyleBackColor = true;
this.ButtonPublisherStop.Click += new System.EventHandler(this.ButtonPublisherStopClick);
//
// ButtonPublisherStart
//
this.ButtonPublisherStart.Location = new System.Drawing.Point(433, 105);
this.ButtonPublisherStart.Name = "ButtonPublisherStart";
this.ButtonPublisherStart.Size = new System.Drawing.Size(75, 23);
this.ButtonPublisherStart.TabIndex = 2;
this.ButtonPublisherStart.Text = "Start";
this.ButtonPublisherStart.UseVisualStyleBackColor = true;
this.ButtonPublisherStart.Click += new System.EventHandler(this.ButtonPublisherStartClick);
//
// TextBoxPublish
//
this.TextBoxPublish.Location = new System.Drawing.Point(33, 134);
this.TextBoxPublish.Name = "TextBoxPublish";
this.TextBoxPublish.Size = new System.Drawing.Size(394, 23);
this.TextBoxPublish.TabIndex = 1;
this.TextBoxPublish.TextChanged += new System.EventHandler(this.TextBoxPortTextChanged);
//
// ButtonPublish
//
this.ButtonPublish.Location = new System.Drawing.Point(514, 134);
this.ButtonPublish.Name = "ButtonPublish";
this.ButtonPublish.Size = new System.Drawing.Size(75, 23);
this.ButtonPublish.TabIndex = 3;
this.ButtonPublish.Text = "Publish";
this.ButtonPublish.UseVisualStyleBackColor = true;
this.ButtonPublish.Click += new System.EventHandler(this.ButtonPublishClick);
//
// ButtonSubscriberStop
//
this.ButtonSubscriberStop.Location = new System.Drawing.Point(514, 220);
this.ButtonSubscriberStop.Name = "ButtonSubscriberStop";
this.ButtonSubscriberStop.Size = new System.Drawing.Size(75, 23);
this.ButtonSubscriberStop.TabIndex = 3;
this.ButtonSubscriberStop.Text = "Stop";
this.ButtonSubscriberStop.UseVisualStyleBackColor = true;
this.ButtonSubscriberStop.Click += new System.EventHandler(this.ButtonSubscriberStopClick);
//
// ButtonSubscriberStart
//
this.ButtonSubscriberStart.Location = new System.Drawing.Point(433, 220);
this.ButtonSubscriberStart.Name = "ButtonSubscriberStart";
this.ButtonSubscriberStart.Size = new System.Drawing.Size(75, 23);
this.ButtonSubscriberStart.TabIndex = 2;
this.ButtonSubscriberStart.Text = "Start";
this.ButtonSubscriberStart.UseVisualStyleBackColor = true;
this.ButtonSubscriberStart.Click += new System.EventHandler(this.ButtonSubscriberStartClick);
//
// TextBoxSubscriber
//
this.TextBoxSubscriber.Location = new System.Drawing.Point(33, 309);
this.TextBoxSubscriber.Multiline = true;
this.TextBoxSubscriber.Name = "TextBoxSubscriber";
this.TextBoxSubscriber.Size = new System.Drawing.Size(556, 182);
this.TextBoxSubscriber.TabIndex = 6;
//
// ButtonGeneratePublishedMessage
//
this.ButtonGeneratePublishedMessage.Location = new System.Drawing.Point(433, 133);
this.ButtonGeneratePublishedMessage.Name = "ButtonGeneratePublishedMessage";
this.ButtonGeneratePublishedMessage.Size = new System.Drawing.Size(75, 23);
this.ButtonGeneratePublishedMessage.TabIndex = 2;
this.ButtonGeneratePublishedMessage.Text = "Random";
this.ButtonGeneratePublishedMessage.UseVisualStyleBackColor = true;
this.ButtonGeneratePublishedMessage.Click += new System.EventHandler(this.ButtonGeneratePublishedMessageClick);
//
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(33, 252);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(96, 15);
this.label6.TabIndex = 5;
this.label6.Text = "Topic Subscribed";
//
// TextBoxTopicSubscribed
//
this.TextBoxTopicSubscribed.Location = new System.Drawing.Point(164, 249);
this.TextBoxTopicSubscribed.Name = "TextBoxTopicSubscribed";
this.TextBoxTopicSubscribed.Size = new System.Drawing.Size(344, 23);
this.TextBoxTopicSubscribed.TabIndex = 1;
this.TextBoxTopicSubscribed.Text = "devices/output";
this.TextBoxTopicSubscribed.TextChanged += new System.EventHandler(this.TextBoxPortTextChanged);
//
// ButtonSubscribe
//
this.ButtonSubscribe.Location = new System.Drawing.Point(514, 248);
this.ButtonSubscribe.Name = "ButtonSubscribe";
this.ButtonSubscribe.Size = new System.Drawing.Size(75, 23);
this.ButtonSubscribe.TabIndex = 3;
this.ButtonSubscribe.Text = "Subscribe";
this.ButtonSubscribe.UseVisualStyleBackColor = true;
this.ButtonSubscribe.Click += new System.EventHandler(this.ButtonSubscribeClick);
//
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(33, 167);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(141, 15);
this.label7.TabIndex = 5;
this.label7.Text = "Auto (Random) Publisher";
//
// trackBar1
//
this.trackBar1.LargeChange = 500;
this.trackBar1.Location = new System.Drawing.Point(180, 162);
this.trackBar1.Maximum = 5050;
this.trackBar1.Minimum = 50;
this.trackBar1.Name = "trackBar1";
this.trackBar1.Size = new System.Drawing.Size(247, 45);
this.trackBar1.SmallChange = 100;
this.trackBar1.TabIndex = 7;
this.trackBar1.TickFrequency = 500;
this.trackBar1.Value = 550;
this.trackBar1.Scroll += new System.EventHandler(this.trackBar1_Scroll);
//
// ButtonAutoPublisherStop
//
this.ButtonAutoPublisherStop.Location = new System.Drawing.Point(513, 162);
this.ButtonAutoPublisherStop.Name = "ButtonAutoPublisherStop";
this.ButtonAutoPublisherStop.Size = new System.Drawing.Size(75, 23);
this.ButtonAutoPublisherStop.TabIndex = 8;
this.ButtonAutoPublisherStop.Text = "Stop";
this.ButtonAutoPublisherStop.UseVisualStyleBackColor = true;
this.ButtonAutoPublisherStop.Click += new System.EventHandler(this.ButtonAutoPublisherStopClick);
//
// ButtonAutoPublisherStart
//
this.ButtonAutoPublisherStart.Location = new System.Drawing.Point(433, 162);
this.ButtonAutoPublisherStart.Name = "ButtonAutoPublisherStart";
this.ButtonAutoPublisherStart.Size = new System.Drawing.Size(75, 23);
this.ButtonAutoPublisherStart.TabIndex = 8;
this.ButtonAutoPublisherStart.Text = "Start";
this.ButtonAutoPublisherStart.UseVisualStyleBackColor = true;
this.ButtonAutoPublisherStart.Click += new System.EventHandler(this.ButtonAutoPublisherStartClick);
//
// label8
//
this.label8.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.label8.AutoSize = true;
this.label8.Location = new System.Drawing.Point(180, 191);
this.label8.Name = "label8";
this.label8.RightToLeft = System.Windows.Forms.RightToLeft.No;
this.label8.Size = new System.Drawing.Size(44, 15);
this.label8.TabIndex = 9;
this.label8.Text = "550 ms";
this.label8.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// checkBox1
//
this.checkBox1.AutoSize = true;
this.checkBox1.Checked = true;
this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBox1.Location = new System.Drawing.Point(433, 191);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(82, 19);
this.checkBox1.TabIndex = 10;
this.checkBox1.Text = "randomize";
this.checkBox1.UseVisualStyleBackColor = true;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(627, 530);
this.Controls.Add(this.checkBox1);
this.Controls.Add(this.label8);
this.Controls.Add(this.ButtonAutoPublisherStart);
this.Controls.Add(this.ButtonAutoPublisherStop);
this.Controls.Add(this.trackBar1);
this.Controls.Add(this.label7);
this.Controls.Add(this.TextBoxSubscriber);
this.Controls.Add(this.label5);
this.Controls.Add(this.label4);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.ButtonServerStop);
this.Controls.Add(this.ButtonServerStart);
this.Controls.Add(this.TextBoxPort);
this.Controls.Add(this.label1);
this.Controls.Add(this.TextBoxTopicPublished);
this.Controls.Add(this.ButtonPublisherStop);
this.Controls.Add(this.ButtonPublisherStart);
this.Controls.Add(this.TextBoxPublish);
this.Controls.Add(this.ButtonPublish);
this.Controls.Add(this.ButtonSubscriberStop);
this.Controls.Add(this.ButtonSubscriberStart);
this.Controls.Add(this.ButtonGeneratePublishedMessage);
this.Controls.Add(this.label6);
this.Controls.Add(this.TextBoxTopicSubscribed);
this.Controls.Add(this.ButtonSubscribe);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Name = "Form1";
this.Text = "MQTT Testing";
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox TextBoxPort;
private System.Windows.Forms.Button ButtonServerStart;
private System.Windows.Forms.Button ButtonServerStop;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.MaskedTextBox maskedTextBox1;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Button ButtonPublisherStop;
private System.Windows.Forms.Button ButtonPublisherStart;
private System.Windows.Forms.TextBox TextBoxPublish;
private System.Windows.Forms.Button ButtonPublish;
private System.Windows.Forms.Button ButtonSubscriberStop;
private System.Windows.Forms.Button ButtonSubscriberStart;
private System.Windows.Forms.TextBox TextBoxSubscriber;
private System.Windows.Forms.Button ButtonGeneratePublishedMessage;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.TextBox TextBoxTopicPublished;
private System.Windows.Forms.Button ButtonSubscribe;
private System.Windows.Forms.TextBox TextBoxTopicSubscribed;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.TrackBar trackBar1;
private System.Windows.Forms.Button ButtonAutoPublisherStop;
private System.Windows.Forms.Button ButtonAutoPublisherStart;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.CheckBox checkBox1;
}
}

View File

@ -0,0 +1,476 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Form1.cs" company="Haemmer Electronics">
// Copyright (c) 2020 All rights reserved.
// </copyright>
// <summary>
// The main form.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace MQTTnet.TestApp.WinForm
{
using System;
using System.Text;
using System.Timers;
using System.Windows.Forms;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using MQTTnet.Client.Receiving;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Formatter;
using MQTTnet.Protocol;
using MQTTnet.Server;
using Newtonsoft.Json;
using Timer = System.Timers.Timer;
/// <summary>
/// The main form.
/// </summary>
public partial class Form1 : Form
{
/// <summary>
/// The managed publisher client.
/// </summary>
private IManagedMqttClient managedMqttClientPublisher;
/// <summary>
/// The managed subscriber client.
/// </summary>
private IManagedMqttClient managedMqttClientSubscriber;
/// <summary>
/// The MQTT server.
/// </summary>
private IMqttServer mqttServer;
/// <summary>
/// The port.
/// </summary>
private string port = "1883";
private readonly Random random;
private readonly Timer randomPublisherTimer;
/// <summary>
/// Initializes a new instance of the <see cref="Form1"/> class.
/// </summary>
public Form1()
{
this.InitializeComponent();
var timer = new Timer
{
AutoReset = true, Enabled = true, Interval = 1000
};
timer.Elapsed += this.TimerElapsed;
random = new Random();
randomPublisherTimer = new Timer
{
AutoReset = true,
Enabled = false,
};
randomPublisherTimer.Elapsed += (_, __) => this.BeginInvoke((MethodInvoker)delegate
{
if (checkBox1.Checked)
ButtonGeneratePublishedMessageClick(ButtonGeneratePublishedMessage, EventArgs.Empty);
ButtonPublishClick(ButtonPublish, EventArgs.Empty);
});
}
/// <summary>
/// Handles the publisher connected event.
/// </summary>
/// <param name="x">The MQTT client connected event args.</param>
private void OnPublisherConnected(MqttClientConnectedEventArgs x)
{
var item = "Publisher Connected";
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
/// <summary>
/// Handles the publisher disconnected event.
/// </summary>
/// <param name="x">The MQTT client disconnected event args.</param>
private void OnPublisherDisconnected(MqttClientDisconnectedEventArgs x)
{
var item = "Publisher Disconnected";
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
/// <summary>
/// Handles the subscriber connected event.
/// </summary>
/// <param name="x">The MQTT client connected event args.</param>
private void OnSubscriberConnected(MqttClientConnectedEventArgs x)
{
var item = "Subscriber Connected";
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
/// <summary>
/// Handles the subscriber disconnected event.
/// </summary>
/// <param name="x">The MQTT client disconnected event args.</param>
private void OnSubscriberDisconnected(MqttClientDisconnectedEventArgs x)
{
var item = "Subscriber Disconnected";
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
/// <summary>
/// The method that handles the button click to generate a message.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private void ButtonGeneratePublishedMessageClick(object sender, EventArgs e)
{
var message = new
{
tag = Guid.NewGuid(),
probability = random.NextDouble(),
};
var json = JsonConvert.SerializeObject(message);
this.TextBoxPublish.Text = json;
}
/// <summary>
/// The method that handles the button click to publish a message.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonPublishClick(object sender, EventArgs e)
{
((Button)sender).Enabled = false;
try
{
var payload = Encoding.UTF8.GetBytes(this.TextBoxPublish.Text);
var message = new MqttApplicationMessageBuilder().WithTopic(this.TextBoxTopicPublished.Text.Trim()).WithPayload(payload).WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce).WithRetainFlag().Build();
if (this.managedMqttClientPublisher != null)
{
await this.managedMqttClientPublisher.PublishAsync(message);
}
}
catch (Exception ex)
{
var item = ex.Message;
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
((Button)sender).Enabled = true;
}
/// <summary>
/// The method that handles the button click to start the publisher.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonPublisherStartClick(object sender, EventArgs e)
{
var mqttFactory = new MqttFactory();
var tlsOptions = new MqttClientTlsOptions
{
UseTls = false, IgnoreCertificateChainErrors = true, IgnoreCertificateRevocationErrors = true, AllowUntrustedCertificates = true
};
var options = new MqttClientOptions
{
ClientId = "ClientPublisher",
ProtocolVersion = MqttProtocolVersion.V311,
ChannelOptions = new MqttClientTcpOptions
{
Server = "localhost", Port = int.Parse(this.TextBoxPort.Text.Trim()), TlsOptions = tlsOptions
}
};
if (options.ChannelOptions == null)
{
throw new InvalidOperationException();
}
options.Credentials = new MqttClientCredentials
{
Username = "username", Password = Encoding.UTF8.GetBytes("password")
};
options.CleanSession = true;
options.KeepAlivePeriod = TimeSpan.FromSeconds(5);
this.managedMqttClientPublisher = mqttFactory.CreateManagedMqttClient();
this.managedMqttClientPublisher.UseApplicationMessageReceivedHandler(this.HandleReceivedApplicationMessage);
this.managedMqttClientPublisher.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnPublisherConnected);
this.managedMqttClientPublisher.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnPublisherDisconnected);
await this.managedMqttClientPublisher.StartAsync(
new ManagedMqttClientOptions
{
ClientOptions = options
});
}
/// <summary>
/// The method that handles the button click to stop the publisher.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonPublisherStopClick(object sender, EventArgs e)
{
if (this.managedMqttClientPublisher == null)
{
return;
}
await this.managedMqttClientPublisher.StopAsync();
this.managedMqttClientPublisher = null;
}
/// <summary>
/// The method that handles the button click to start the server.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonServerStartClick(object sender, EventArgs e)
{
if (this.mqttServer != null)
{
return;
}
var storage = new JsonServerStorage();
storage.Clear();
this.mqttServer = new MqttFactory().CreateMqttServer();
var options = new MqttServerOptions();
options.DefaultEndpointOptions.Port = int.Parse(this.TextBoxPort.Text);
options.Storage = storage;
options.EnablePersistentSessions = true;
options.ConnectionValidator = new MqttServerConnectionValidatorDelegate(
c =>
{
if (c.ClientId.Length < 10)
{
c.ReasonCode = MqttConnectReasonCode.ClientIdentifierNotValid;
return;
}
if (c.Username != "username")
{
c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
return;
}
if (c.Password != "password")
{
c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
return;
}
c.ReasonCode = MqttConnectReasonCode.Success;
});
try
{
await this.mqttServer.StartAsync(options);
}
catch (Exception ex)
{
var item = ex.Message;
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
await this.mqttServer.StopAsync();
this.mqttServer = null;
}
}
/// <summary>
/// The method that handles the button click to stop the server.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonServerStopClick(object sender, EventArgs e)
{
if (this.mqttServer == null)
{
return;
}
await this.mqttServer.StopAsync();
this.mqttServer = null;
}
/// <summary>
/// The method that handles the button click to subscribe to a certain topic.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonSubscribeClick(object sender, EventArgs e)
{
var topicFilter = new MqttTopicFilter { Topic = this.TextBoxTopicSubscribed.Text.Trim() };
await this.managedMqttClientSubscriber.SubscribeAsync(topicFilter);
var item = "Topic " + this.TextBoxTopicSubscribed.Text.Trim() + " is subscribed";
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
/// <summary>
/// The method that handles the button click to start the subscriber.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonSubscriberStartClick(object sender, EventArgs e)
{
var mqttFactory = new MqttFactory();
var tlsOptions = new MqttClientTlsOptions
{
UseTls = false, IgnoreCertificateChainErrors = true, IgnoreCertificateRevocationErrors = true, AllowUntrustedCertificates = true
};
var options = new MqttClientOptions
{
ClientId = "ClientSubscriber",
ProtocolVersion = MqttProtocolVersion.V311,
ChannelOptions = new MqttClientTcpOptions
{
Server = "localhost", Port = int.Parse(this.TextBoxPort.Text.Trim()), TlsOptions = tlsOptions
}
};
if (options.ChannelOptions == null)
{
throw new InvalidOperationException();
}
options.Credentials = new MqttClientCredentials
{
Username = "username",
Password = Encoding.UTF8.GetBytes("password")
};
options.CleanSession = true;
options.KeepAlivePeriod = TimeSpan.FromSeconds(5);
this.managedMqttClientSubscriber = mqttFactory.CreateManagedMqttClient();
this.managedMqttClientSubscriber.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnSubscriberConnected);
this.managedMqttClientSubscriber.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnSubscriberDisconnected);
this.managedMqttClientSubscriber.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(this.OnSubscriberMessageReceived);
await this.managedMqttClientSubscriber.StartAsync(
new ManagedMqttClientOptions
{
ClientOptions = options
});
}
/// <summary>
/// The method that handles the button click to stop the subscriber.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonSubscriberStopClick(object sender, EventArgs e)
{
if (this.managedMqttClientSubscriber == null)
{
return;
}
await this.managedMqttClientSubscriber.StopAsync();
this.managedMqttClientSubscriber = null;
}
/// <summary>
/// Handles the received application message event.
/// </summary>
/// <param name="x">The MQTT application message received event args.</param>
private void HandleReceivedApplicationMessage(MqttApplicationMessageReceivedEventArgs x)
{
var item = $"Timestamp: {DateTime.Now:O} | Topic: {x.ApplicationMessage.Topic} | Payload: {x.ApplicationMessage.ConvertPayloadToString()} | QoS: {x.ApplicationMessage.QualityOfServiceLevel}";
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
/// <summary>
/// Handles the received subscriber message event.
/// </summary>
/// <param name="x">The MQTT application message received event args.</param>
private void OnSubscriberMessageReceived(MqttApplicationMessageReceivedEventArgs x)
{
var item = $"Timestamp: {DateTime.Now:O} | Topic: {x.ApplicationMessage.Topic} | Payload: {x.ApplicationMessage.ConvertPayloadToString()} | QoS: {x.ApplicationMessage.QualityOfServiceLevel}";
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
/// <summary>
/// The method that handles the text changes in the text box.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private void TextBoxPortTextChanged(object sender, EventArgs e)
{
// ReSharper disable once StyleCop.SA1126
if (int.TryParse(this.TextBoxPort.Text, out _))
{
this.port = this.TextBoxPort.Text.Trim();
}
else
{
this.TextBoxPort.Text = this.port;
this.TextBoxPort.SelectionStart = this.TextBoxPort.Text.Length;
this.TextBoxPort.SelectionLength = 0;
}
}
/// <summary>
/// The method that handles the timer events.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
this.BeginInvoke(
(MethodInvoker)delegate
{
// Server
this.TextBoxPort.Enabled = this.mqttServer == null;
this.ButtonServerStart.Enabled = this.mqttServer == null;
this.ButtonServerStop.Enabled = this.mqttServer != null;
// Publisher
this.ButtonPublisherStart.Enabled = this.managedMqttClientPublisher == null;
this.ButtonPublisherStop.Enabled = this.managedMqttClientPublisher != null;
// Auto Publisher
this.ButtonAutoPublisherStart.Enabled = !this.randomPublisherTimer.Enabled;
this.ButtonAutoPublisherStop.Enabled = this.randomPublisherTimer.Enabled;
// Subscriber
this.ButtonSubscriberStart.Enabled = this.managedMqttClientSubscriber == null;
this.ButtonSubscriberStop.Enabled = this.managedMqttClientSubscriber != null;
});
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
this.label8.Text = $"{this.trackBar1.Value:N0} ms";
this.randomPublisherTimer.Interval = this.trackBar1.Value;
}
private void ButtonAutoPublisherStartClick(object sender, EventArgs e)
{
((Button)sender).Enabled = false;
this.randomPublisherTimer.Start();
((Button)sender).Enabled = true;
}
private void ButtonAutoPublisherStopClick(object sender, EventArgs e)
{
((Button)sender).Enabled = false;
this.randomPublisherTimer.Stop();
((Button)sender).Enabled = true;
}
}
}

View File

@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,83 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="JsonServerStorage.cs" company="Haemmer Electronics">
// Copyright (c) 2020 All rights reserved.
// </copyright>
// <summary>
// The JSON server storage.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace MQTTnet.TestApp.WinForm
{
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using MQTTnet.Server;
using Newtonsoft.Json;
/// <inheritdoc cref="IMqttServerStorage"/>
/// <summary>
/// The JSON server storage.
/// </summary>
/// <seealso cref="IMqttServerStorage"/>
public class JsonServerStorage : IMqttServerStorage
{
/// <summary>
/// The file name.
/// </summary>
private readonly string filename = Path.Combine(Directory.GetCurrentDirectory(), "Retained.json");
/// <summary>
/// Clears the file.
/// </summary>
public void Clear()
{
if (File.Exists(this.filename))
{
File.Delete(this.filename);
}
}
/// <inheritdoc cref="IMqttServerStorage"/>
/// <summary>
/// Loads the retained messages.
/// </summary>
/// <returns>A <see cref="IList{T}"/> of <see cref="MqttApplicationMessage"/>.</returns>
/// <seealso cref="IMqttServerStorage"/>
public async Task<IList<MqttApplicationMessage>> LoadRetainedMessagesAsync()
{
await Task.CompletedTask;
if (!File.Exists(this.filename))
{
return new List<MqttApplicationMessage>();
}
try
{
var json = await File.ReadAllTextAsync(this.filename);
return JsonConvert.DeserializeObject<List<MqttApplicationMessage>>(json);
}
catch
{
return new List<MqttApplicationMessage>();
}
}
/// <inheritdoc cref="IMqttServerStorage"/>
/// <summary>
/// Saves the retained messages to a file.
/// </summary>
/// <param name="messages">The messages.</param>
/// <returns>A <see cref="Task"/> representing any asynchronous operation.</returns>
/// <seealso cref="IMqttServerStorage"/>
public async Task SaveRetainedMessagesAsync(IList<MqttApplicationMessage> messages)
{
await Task.CompletedTask;
var json = JsonConvert.SerializeObject(messages);
await File.WriteAllTextAsync(this.filename, json);
}
}
}

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GitVersionTask" Version="5.3.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="MQTTnet" Version="3.0.11" />
<PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="3.0.11" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,32 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Program.cs" company="Haemmer Electronics">
// Copyright (c) 2020 All rights reserved.
// </copyright>
// <summary>
// The main program.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace MQTTnet.TestApp.WinForm
{
using System;
using System.Windows.Forms;
/// <summary>
/// The main program.
/// </summary>
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static void Main()
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}

167
input.yml Normal file
View File

@ -0,0 +1,167 @@
openapi: 3.0.3
info:
title: Input Service
description: This is the input interface of the Birbnetes system.
contact:
email: tormakristof@tormakristof.eu
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
version: 1.1.3
servers:
- url: https://birb.k8s.kmlabz.com
tags:
- name: input
description: Input Service interaction
paths:
/sample:
get:
tags:
- input
summary: Get all stored input queries
operationId: getall
responses:
200:
description: Array of input objects
content:
application/json:
schema:
$ref: '#/components/schemas/InputResponse'
404:
description: No object matching filter
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
post:
tags:
- input
summary: uploads a sample into the system
operationId: uploadFile
requestBody:
content:
multipart/form-data:
schema:
required:
- description
- file
properties:
description:
type: object
description: Metadata json
properties:
deviceid:
type: string
date:
type: string
format: date
file:
type: string
description: Wave file to upload
format: binary
required: true
responses:
200:
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
400:
description: JSON parse error
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
415:
description: Media type error
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
417:
description: JSON invalid schema
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
469:
description: No file found
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
470:
description: Description missing
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
/sample/{tagID}:
get:
tags:
- input
summary: Get input object by ID
operationId: getInput
parameters:
- name: tagID
in: path
description: ID of input object file
required: true
schema:
type: string
format: uuid
responses:
200:
description: input object
content:
application/json:
schema:
$ref: '#/components/schemas/InputSingeResponse'
404:
description: Tag not found
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
components:
schemas:
InputSingeResponse:
required:
- message
- status
type: object
properties:
status:
type: string
message:
$ref: '#/components/schemas/InputObject'
InputResponse:
type: array
items:
$ref: '#/components/schemas/InputObject'
InputObject:
required:
- date
- device_id
- tag
type: object
properties:
tag:
type: string
format: uuid
date:
type: string
format: date
device_id:
type: integer
ApiResponse:
required:
- message
- status
type: object
properties:
status:
type: string
message:
type: string