public async Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context) { context.AcceptPublish = true; if (context.ApplicationMessage == null) { return; } var payload = context.ApplicationMessage.Payload == null ? null : Encoding.UTF8.GetString(context.ApplicationMessage?.Payload); if (context.ApplicationMessage.Retain) { if (context.ApplicationMessage.Topic.StartsWith("mcu/")) { return; } var msg = _repo.AddMessage(new MqttMessage { Created = DateTime.Now, Message = payload, Topic = context.ApplicationMessage.Topic, ContentType = context.ApplicationMessage.ContentType }); await _repo.SaveChangesAsync(); } // _logger.LogInformation( // $"Message: ClientId = {context.ClientId}, Topic = {context.ApplicationMessage?.Topic}," // + $" Payload = {payload}, QoS = {context.ApplicationMessage?.QualityOfServiceLevel}," // + $" Retain-Flag = {context.ApplicationMessage?.Retain}"); }
public static void Intercept(MqttApplicationMessageInterceptorContext context) { if (context.ApplicationMessage.Payload == null || context.ApplicationMessage.Payload.Length == 0) { return; } try { var content = Encoding.UTF8.GetString(context.ApplicationMessage.Payload); if (!content.StartsWith("{") || !content.EndsWith("}")) { return; } var json = JObject.Parse(content); var timestampProperty = json.Property("timestamp"); if (timestampProperty != null && timestampProperty.Value.Type == JTokenType.Null) { timestampProperty.Value = DateTime.Now.ToString("O"); context.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(json.ToString(Formatting.None)); } } catch (Exception e) { } }
public void notifyObservers(MqttApplicationMessageInterceptorContext Log) { foreach (var value in _observers) { value.update(Log); } }
public void Intercept(MqttApplicationMessageInterceptorContext context) { if (context.ApplicationMessage.Topic == "hha-server") { SaveMessage(context); } }
// Extend the timestamp for all messages from clients. public async void HandleMessage(MqttApplicationMessageInterceptorContext context) { Console.WriteLine("Broker: New message"); //if(clientManagers[context.ClientId] == null) if (context.ClientId.EndsWith("_fake")) { return; } Console.WriteLine("### BROKER: RECEIVED APPLICATION MESSAGE ###"); Console.WriteLine($"+ Topic = {context.ApplicationMessage.Topic}"); Console.WriteLine($"+ Payload = {Encoding.UTF8.GetString(context.ApplicationMessage.Payload)}"); Console.WriteLine($"+ QoS = {context.ApplicationMessage.QualityOfServiceLevel}"); Console.WriteLine($"+ Retain = {context.ApplicationMessage.Retain}"); Console.WriteLine(); context.AcceptPublish = false; //If intercept on save msg if (clientManagers[context.ClientId].intercept) { MQTTProxyMessage tmp = new MQTTProxyMessage(context.ApplicationMessage, context.ClientId, MessageState.Intercepted); db.messageList.Add(tmp); wss.SendMessage(tmp); } //if intercept off forward else { ForwardMessage(context); } }
public Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context) { try { var pythonContext = new PythonDictionary { { "accept_publish", context.AcceptPublish }, { "close_connection", context.CloseConnection }, { "client_id", context.ClientId }, { "topic", context.ApplicationMessage.Topic }, { "qos", (int)context.ApplicationMessage.QualityOfServiceLevel }, { "retain", context.ApplicationMessage.Retain } }; _pythonScriptHostService.InvokeOptionalFunction("on_intercept_application_message", pythonContext); context.AcceptPublish = (bool)pythonContext.get("accept_publish", context.AcceptPublish); context.CloseConnection = (bool)pythonContext.get("close_connection", context.CloseConnection); context.ApplicationMessage.Topic = (string)pythonContext.get("topic", context.ApplicationMessage.Topic); context.ApplicationMessage.QualityOfServiceLevel = (MqttQualityOfServiceLevel)(int)pythonContext.get("qos", (int)context.ApplicationMessage.QualityOfServiceLevel); } catch (Exception exception) { _logger.LogError(exception, "Error while intercepting application message."); } return(Task.CompletedTask); }
/// <summary> /// Fired when a messages was received /// </summary> /// <param name="context">MqttApplicationMessageInterceptorContext</param> /// <returns>Task</returns> public Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context) { // White-Listing of Topics if (!(context.ApplicationMessage.Topic.StartsWith("metrics") || context.ApplicationMessage.Topic.StartsWith("status"))) { context.AcceptPublish = false; Helper.Log(new LogMessage(LogSeverity.Warning, nameof(MqttService), $"Denied publish by {context.ClientId} with topic {context.ApplicationMessage.Topic}")); return(Task.CompletedTask); } // If its a node message, cache the category of the client and send the status if its not set yet var match = nodeRegex.Match(context.ApplicationMessage.Topic); if (match.Success) { var category = match.Groups[1].Value; if (nodeStates.TryGetValue(context.ClientId, out var previousState) && previousState == null) { var state = new NodeState { IsActive = true, Category = category, Location = Helper.GetLocation(client, mqtt, context.ClientId) }; Helper.SendClientStatus(mqtt, context.ClientId, state).GetAwaiter().GetResult(); nodeStates[context.ClientId] = state; Helper.SendConnectedClients(mqtt, nodeStates).GetAwaiter().GetResult(); } } context.AcceptPublish = true; return(Task.CompletedTask); }
public Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context) { // we do not process messages from ourselves if (string.IsNullOrEmpty(context.ClientId)) { return(Task.CompletedTask); } try { string payload = (context.ApplicationMessage.Payload.Length > 0) ? Encoding.UTF8.GetString(context.ApplicationMessage.Payload) : ""; if (!string.IsNullOrEmpty(payload)) { var messageElements = JsonConvert.DeserializeObject <Dictionary <string, string> >(payload); if (!messageElements.TryGetValue("client_id", out var value)) { string clientId = context.ClientId; messageElements.Add("mqtt_client_id", clientId); string json = JsonConvert.SerializeObject(messageElements); context.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(json); } } return(Task.CompletedTask); } catch { return(Task.CompletedTask); } }
public async Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context) { if (context.ClientId == null) { return; } string rawTopic = context.ApplicationMessage.Topic; byte[] payload = context.ApplicationMessage.Payload; LockTopic(rawTopic, payload); try { context.AcceptPublish = await HandleMessage(rawTopic, payload); } catch (Exception e) { context.AcceptPublish = false; System.Diagnostics.Debug.WriteLine(e.ToString()); await PublishDebug(e); } UnlockTopic(rawTopic); }
public Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context) { try { // This might be not set when a message was published by the server instead of a client. context.SessionItems.TryGetValue(MqttServerConnectionValidator.WrappedSessionItemsKey, out var sessionItems); var pythonContext = new PythonDictionary { { "client_id", context.ClientId }, { "session_items", sessionItems }, { "retain", context.ApplicationMessage.Retain }, { "accept_publish", context.AcceptPublish }, { "close_connection", context.CloseConnection }, { "topic", context.ApplicationMessage.Topic }, { "qos", (int)context.ApplicationMessage.QualityOfServiceLevel } }; _pythonScriptHostService.InvokeOptionalFunction("on_intercept_application_message", pythonContext); context.AcceptPublish = (bool)pythonContext.get("accept_publish", context.AcceptPublish); context.CloseConnection = (bool)pythonContext.get("close_connection", context.CloseConnection); context.ApplicationMessage.Topic = (string)pythonContext.get("topic", context.ApplicationMessage.Topic); context.ApplicationMessage.QualityOfServiceLevel = (MqttQualityOfServiceLevel)(int)pythonContext.get("qos", (int)context.ApplicationMessage.QualityOfServiceLevel); } catch (Exception exception) { _logger.LogError(exception, "Error while intercepting application message."); } return(Task.CompletedTask); }
async Task <MqttApplicationMessageInterceptorContext> InterceptApplicationMessageAsync( IMqttServerApplicationMessageInterceptor interceptor, MqttClientConnection clientConnection, MqttApplicationMessage applicationMessage) { string senderClientId; IDictionary <object, object> sessionItems; var messageIsFromServer = clientConnection == null; if (messageIsFromServer) { senderClientId = _options.ClientId; sessionItems = _serverSessionItems; } else { senderClientId = clientConnection.ClientId; sessionItems = clientConnection.Session.Items; } var interceptorContext = new MqttApplicationMessageInterceptorContext { ClientId = senderClientId, SessionItems = sessionItems, AcceptPublish = true, ApplicationMessage = applicationMessage, CloseConnection = false }; await interceptor.InterceptApplicationMessagePublishAsync(interceptorContext).ConfigureAwait(false); return(interceptorContext); }
private MqttApplicationMessageInterceptorContext CreateMqttContext(string clientId, string topic, Dictionary <string, object> payload) { var logger = A.Fake <IMqttNetScopedLogger>(); var context = new MqttApplicationMessageInterceptorContext(clientId, null, logger); var payloadAsBytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(payload)); var applicationMessage = new MqttApplicationMessage() { ContentType = "", CorrelationData = new byte[0], Dup = false, MessageExpiryInterval = 0, Payload = payloadAsBytes, PayloadFormatIndicator = MQTTnet.Protocol.MqttPayloadFormatIndicator.Unspecified, QualityOfServiceLevel = 0, ResponseTopic = "", Retain = false, SubscriptionIdentifiers = null, Topic = topic, TopicAlias = null, UserProperties = null }; context.ApplicationMessage = applicationMessage; return(context); }
/// <summary> /// Logs the message from the MQTT message interceptor context. /// </summary> /// <param name="context">The MQTT message interceptor context.</param> private static void LogMessage(MqttApplicationMessageInterceptorContext context) { Log.Information( $"Message: ClientId = {context.ClientId}, Topic = {context.ApplicationMessage.Topic}," + $" Payload = {Encoding.UTF8.GetString(context.ApplicationMessage.Payload)}, QoS = {context.ApplicationMessage.QualityOfServiceLevel}," + $" Retain-Flag = {context.ApplicationMessage.Retain}"); }
public void MqttMessageInterceptor(MqttApplicationMessageInterceptorContext message_context) { Log.Debug(TAG, "MqttMessageInterceptor"); string PayloadTest = Encoding.UTF8.GetString(message_context.ApplicationMessage.Payload); logsDB.AddLogRow(LogStatusesEnum.Info, $"MqttMessageInterceptor - ClientId={message_context.ClientId} Topic={message_context.ApplicationMessage.Topic} Payload={PayloadTest}", TAG); }
/// <summary> /// Publishes a message to a remote broker that hasn't initially sent the message to the cluster. /// </summary> /// <param name="context">The context.</param> /// <param name="brokerConnectionSettings">The broker connection settings.</param> /// <returns>A <see cref="Task" /> representing asynchronous operation.</returns> private static async Task PublishMessageToBroker(MqttApplicationMessageInterceptorContext context, IBrokerConnectionSettings brokerConnectionSettings) { if (context.ApplicationMessage == null) { return; } // Create a new MQTT client var factory = new MqttFactory(); var mqttClient = factory.CreateMqttClient(); var optionsBuilder = new MqttClientOptionsBuilder().WithClientId(brokerConnectionSettings.ClientId).WithTcpServer(brokerConnectionSettings.HostName, brokerConnectionSettings.Port) .WithCredentials(brokerConnectionSettings.UserName, brokerConnectionSettings.Password).WithCleanSession(brokerConnectionSettings.UseCleanSession); if (brokerConnectionSettings.UseTls) { optionsBuilder.WithTls(); } var options = optionsBuilder.Build(); // Deserialize payload var payloadString = context.ApplicationMessage?.Payload == null ? string.Empty : Encoding.UTF8.GetString(context.ApplicationMessage.Payload); // Connect the MQTT client await mqttClient.ConnectAsync(options, CancellationToken.None); // Send the message var message = new MqttApplicationMessageBuilder().WithTopic(context.ApplicationMessage.Topic).WithPayload(payloadString).WithQualityOfServiceLevel(context.ApplicationMessage.QualityOfServiceLevel) .WithRetainFlag(context.ApplicationMessage.Retain).Build(); await mqttClient.PublishAsync(message, CancellationToken.None); await mqttClient.DisconnectAsync(null, CancellationToken.None); }
public async Task ExecuteSystemCommandAsync(MqttApplicationMessageInterceptorContext context) { if (context.ApplicationMessage.Topic == commandTopics.GetConnectedClients) { await ServeConnectedClientsAsync(); } else if (context.ApplicationMessage.Topic == commandTopics.GetConnectedClientsCount) { await ServeConnectedClientsCountAsync(); } else if (context.ApplicationMessage.Topic == commandTopics.PatchDisconnectClient) { string clientId = GetClientIdFromPayload(context.ApplicationMessage); await DisconnectClientAsync(clientId); } else if (context.ApplicationMessage.Topic == commandTopics.GetClientIP) { string clientId = GetClientIdFromPayload(context.ApplicationMessage); await ServeClientIPAsync(clientId); } else if (context.ApplicationMessage.Topic == commandTopics.GetClientConnectedTime) { string clientId = GetClientIdFromPayload(context.ApplicationMessage); await ServeClientConnectedTimeAsync(clientId); } }
/// <summary> /// Publishes a message to all remote brokers that haven't initially sent the message to the cluster. /// </summary> /// <param name="context">The context.</param> /// <param name="brokerId">The broker identifier.</param> /// <returns>A <see cref="Task" /> representing asynchronous operation.</returns> private async Task PublishMessageToBrokers(MqttApplicationMessageInterceptorContext context, Guid brokerId) { var tasks = this.brokers .Where(kvp => kvp.Key != brokerId) .Select(b => PublishMessageToBroker(context, b.Value)); await Task.WhenAll(tasks); }
private void OnNewMessage(MqttApplicationMessageInterceptorContext context) { string message = context.ApplicationMessage.ConvertPayloadToString(); string topic = context.ApplicationMessage.Topic; string log = "Topic: " + topic + "Message: " + message; switch (topic) { case "/topic/log": AppendLog(log); break; case "/topic/remove": if (message == "REMOVED") { AppendLog(log); } else if (message == "NO DEVICES") { AppendLog(log); ClearTokenBox(); } break; case "/topic/add": if (message.StartsWith("ADDED DEVICE")) { AppendLog(log); } else { AppendLog(log); } break; case "/topic/list": if (message == "NO DEVICES") { AppendLog(log); ClearTokenBox(); } else { string parsedMessage = System.Text.RegularExpressions.Regex.Replace(message, "[^0-9]", "").Trim(); AppendTokenBox(parsedMessage); AppendLog("Sync device from ESP: " + parsedMessage); } break; } //var payload = context.ApplicationMessage?.Payload == null ? null : Encoding.UTF8.GetString(context.ApplicationMessage?.Payload); }
void MessageReceived(MqttApplicationMessageInterceptorContext context) { var messageAsString = Encoding.UTF8.GetString(context.ApplicationMessage.Payload); Console.WriteLine($"{DateTime.UtcNow} - MQTT Message received ({context.ApplicationMessage.Topic}) - {messageAsString}"); var message = new Message(context.ApplicationMessage.Payload); _deviceClient.SendEventAsync(context.ApplicationMessage.Topic, message); }
public Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context) { try { context.AcceptPublish = true; // Avoid loops by not mirroring messages that have been forwarded by other brokers. if (context.ApplicationMessage.CorrelationData != null && context.ApplicationMessage.CorrelationData.SequenceEqual(ForwardedSignature)) { _logger.LogTrace($"Detected already forwarded message. Remote Client ID: {context.ClientId}, Topic {context.ApplicationMessage.Topic}"); return(Task.CompletedTask); } foreach (var broker in _service.RemoteBrokers) { var brokerName = ""; if (broker.IsConnected) { // Find topic filters for this connection. Default to match all topics var topicFilters = new List <string> { "#" }; foreach (var remoteBroker in _service.Settings.RemoteBrokers) { // Remote brokers prefix their client id with [broker_name] if (broker.Options.ClientId.EndsWith(remoteBroker.ClientId)) { topicFilters = remoteBroker.TopicFilters; brokerName = remoteBroker.Name; } } // Publish only matching topics foreach (var filter in topicFilters) { if (MqttTopicFilterComparer.IsMatch(context.ApplicationMessage.Topic, filter)) { _logger.LogTrace($"Forwarded message with topic: '{context.ApplicationMessage.Topic}' to remote broker: {brokerName}"); // Include forwarding signature to flag message as forwarded context.ApplicationMessage.CorrelationData = ForwardedSignature; broker.PublishAsync(context.ApplicationMessage); // Should only send once even if topic matches multiple topic filters break; } } } } } catch (Exception exception) { _logger.LogError(exception, "Error while intercepting application message."); } return(Task.CompletedTask); }
public async Task TestValidatePublish() { var dataLimitCacheMonth = new MemoryCache(new MemoryCacheOptions()); // Add users to users dictionary to simulate that the connection was established successfully: var users = new Dictionary <string, User> { { "Test", new User { Id = User1Id, UserName = "******", ValidateClientId = false } } }; // Test user var mqttApplicationMessage = new MqttApplicationMessage { Retain = false, Payload = Encoding.UTF8.GetBytes("asdf"), Topic = "a/b", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce }; var mqttConnectionValidatorContext = new MqttApplicationMessageInterceptorContext("Test", new Dictionary <object, object>(), mqttApplicationMessage); var result = await this.mqttValidator.ValidatePublish( mqttConnectionValidatorContext, this.userRepository, users, dataLimitCacheMonth); Assert.IsTrue(result); mqttApplicationMessage = new MqttApplicationMessage { Retain = false, Payload = Encoding.UTF8.GetBytes("asdf"), Topic = "a/d", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce }; mqttConnectionValidatorContext = new MqttApplicationMessageInterceptorContext("Test", new Dictionary <object, object>(), mqttApplicationMessage); result = await this.mqttValidator.ValidatePublish( mqttConnectionValidatorContext, this.userRepository, users, dataLimitCacheMonth); Assert.IsTrue(result); }
/// <summary> /// Logs the message from the MQTT message interceptor context. /// </summary> /// <param name="context">The MQTT message interceptor context.</param> private void LogMessage(MqttApplicationMessageInterceptorContext context) { var payload = context.ApplicationMessage?.Payload == null ? null : Encoding.UTF8.GetString(context.ApplicationMessage.Payload); this.logger.Information( "Message: ClientId = {ClientId}, Topic = {Topic}, Payload = {Payload}, QoS = {Qos}, Retain-Flag = {RetainFlag}", context.ClientId, context.ApplicationMessage?.Topic, payload, context.ApplicationMessage?.QualityOfServiceLevel, context.ApplicationMessage?.Retain); }
/// <summary> /// Validates the message publication. /// </summary> /// <param name="context">The context.</param> private void ValidatePublish(MqttApplicationMessageInterceptorContext context) { if (this.cancellationToken.IsCancellationRequested) { return; } var repositoryGrain = this.clusterClient.GetGrain <IMqttRepositoryGrain>(0); var publishValid = repositoryGrain.ProceedPublish(context, this.brokerId).Result; context.AcceptPublish = publishValid; }
public MqttApplicationMessageInterceptorContext GetMessageInterceptorValue(MqttApplicationMessageInterceptorContext context) { if (!context.ApplicationMessage.Topic.StartsWith("test")) { context.AcceptPublish = false; } if (context.ApplicationMessage.Payload == null) { context.AcceptPublish = false; } return(context); }
/// <inheritdoc cref="IMqttClientGrain" /> /// <summary> /// Proceeds the published message for one client identifier. /// </summary> /// <param name="context">The context.</param> /// <returns>A value indicating whether the published message is accepted or not.</returns> /// <seealso cref="IMqttClientGrain" /> public async Task <bool> ProceedPublish(MqttApplicationMessageInterceptorContext context) { try { return(await this.mqttValidator.ValidatePublish(context, this.userRepository, this.users, DataLimitCacheMonth)); } catch (Exception ex) { this.logger.Error("An error occured: {ex}.", ex); return(false); } }
/// <summary> /// Publishes a message to all remote brokers that haven't initially sent the message to the cluster. /// </summary> /// <param name="context">The context.</param> /// <param name="brokerId">The broker identifier.</param> /// <returns>A <see cref="Task" /> representing asynchronous operation.</returns> private async Task PublishMessageToBrokers(MqttApplicationMessageInterceptorContext context, Guid brokerId) { foreach (var(key, settings) in this.brokers) { if (key == brokerId) { continue; } await PublishMessageToBroker(context, settings); } }
public Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context) { if (!context.ApplicationMessage.Topic.StartsWith(FedNetConstante.CLIENT_TO_SERVER + FedNetConstante.DEFAULT_TOPIC_SEPARATOR + context.ClientId) && context.ClientId != _theGameServer.Options.ClientId) { context.AcceptPublish = false; /*context.CloseConnection = true;*/ _logSystem.Warn(context.ClientId + " try to publish " + context.ApplicationMessage.Payload.Length + " bytes on topic : " + context.ApplicationMessage.Topic); return(Task.Delay(1)); } context.AcceptPublish = true; return(Task.Delay(1)); }
/// <inheritdoc cref="IMqttClientGrain" /> /// <summary> /// Proceeds the published message for one client identifier. /// </summary> /// <param name="context">The context.</param> /// <returns>A value indicating whether the published message is accepted or not.</returns> /// <seealso cref="IMqttClientGrain" /> public Task <bool> ProceedPublish(MqttApplicationMessageInterceptorContext context) { try { var result = this.mqttValidator.ValidatePublish(context, this.userData.PublishBlacklist, this.userData.PublishWhitelist, this.user, DataLimitCacheMonth, this.userData.ClientIdPrefixes); return(Task.FromResult(result)); } catch (Exception ex) { this.logger.Error("An error occurred: {@ex}.", ex); return(Task.FromResult(false)); } }
/// <summary> /// Validates the MQTT application messages. /// </summary> /// <param name="context">The context.</param> public Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context) { try { context.AcceptPublish = true; this.LogMessage(context); return(Task.CompletedTask); } catch (Exception ex) { this.logger.Error("An error occurred: {Exception}.", ex); return(Task.FromException(ex)); } }
/// <summary> /// Logs the message from the MQTT message interceptor context. /// </summary> /// <param name="context">The MQTT message interceptor context.</param> private static void LogMessage(MqttApplicationMessageInterceptorContext context) { if (context == null) { return; } var payload = context.ApplicationMessage?.Payload == null ? null : Encoding.UTF8.GetString(context.ApplicationMessage?.Payload); Log.Information( $"Message: ClientId = {context.ClientId}, Topic = {context.ApplicationMessage?.Topic}," + $" Payload = {payload}, QoS = {context.ApplicationMessage?.QualityOfServiceLevel}," + $" Retain-Flag = {context.ApplicationMessage?.Retain}"); }