public override async Task <MqttMessage> ProcessAsync() { if (!Session.IsConnected) { Session.Disconnect(Message); return(null); } Session.IncrementKeepAlive(); List <QualityOfServiceLevelType> list = new List <QualityOfServiceLevelType>(); SubscribeMessage msg = Message as SubscribeMessage; List <string> validSubs = Session.Subscribe(Message); IEnumerator <KeyValuePair <string, QualityOfServiceLevelType> > en = msg.Topics.GetEnumerator(); while (en.MoveNext()) { MqttUri uri = new MqttUri(en.Current.Key); QualityOfServiceLevelType qos = validSubs.Contains(uri.ToString()) ? en.Current.Value : QualityOfServiceLevelType.Failure; list.Add(qos); Session.AddQosLevel(uri.Resource, qos); } return(await Task.FromResult <MqttMessage>(new SubscriptionAckMessage(Message.MessageId, list))); }
public static byte[] ConvertToCoap(CoapSession session, EventMessage message, byte[] observableToken = null) { CoapMessage coapMessage = null; CoapToken token = CoapToken.Create(); ushort id = observableToken == null?session.CoapSender.NewId(token.TokenBytes) : session.CoapSender.NewId(observableToken); string uriString = CoapUri.Create(session.Config.Authority, message.ResourceUri, IsEncryptedChannel); if (message.Protocol == ProtocolType.MQTT) { MqttMessage msg = MqttMessage.DecodeMessage(message.Message); PublishMessage pub = msg as PublishMessage; MqttUri uri = new MqttUri(pub.Topic); if (observableToken == null) { RequestMessageType messageType = msg.QualityOfService == QualityOfServiceLevelType.AtMostOnce ? RequestMessageType.NonConfirmable : RequestMessageType.Confirmable; //request coapMessage = new CoapRequest(id, messageType, MethodType.POST, new Uri(uriString), MediaTypeConverter.ConvertToMediaType(message.ContentType)); } else { //response coapMessage = new CoapResponse(id, ResponseMessageType.NonConfirmable, ResponseCodeType.Content, observableToken, MediaTypeConverter.ConvertToMediaType(uri.ContentType), msg.Payload); } } else if (message.Protocol == ProtocolType.COAP) { CoapMessage msg = CoapMessage.DecodeMessage(message.Message); if (observableToken == null) { //request coapMessage = new CoapRequest(id, msg.MessageType == CoapMessageType.Confirmable ? RequestMessageType.Confirmable : RequestMessageType.NonConfirmable, MethodType.POST, new Uri(uriString), MediaTypeConverter.ConvertToMediaType(message.ContentType), msg.Payload); } else { //response coapMessage = new CoapResponse(id, ResponseMessageType.NonConfirmable, ResponseCodeType.Content, observableToken, MediaTypeConverter.ConvertToMediaType(message.ContentType), msg.Payload); } } else { if (observableToken == null) { //request coapMessage = new CoapRequest(id, RequestMessageType.NonConfirmable, MethodType.POST, new Uri(uriString), MediaTypeConverter.ConvertToMediaType(message.ContentType), message.Message); } else { //response coapMessage = new CoapResponse(id, ResponseMessageType.NonConfirmable, ResponseCodeType.Content, observableToken, MediaTypeConverter.ConvertToMediaType(message.ContentType), message.Message); } } return(coapMessage.Encode()); }
private async Task PublishAsync(PublishMessage message) { MessageAuditRecord record = null; EventMetadata metadata = null; try { MqttUri mqttUri = new MqttUri(message.Topic); metadata = await graphManager.GetPiSystemMetadataAsync(mqttUri.Resource); if (EventValidator.Validate(true, metadata, Channel, graphManager, context).Validated) { EventMessage msg = new EventMessage(mqttUri.ContentType, mqttUri.Resource, ProtocolType.MQTT, message.Encode(), DateTime.UtcNow, metadata.Audit); if (!string.IsNullOrEmpty(mqttUri.CacheKey)) { msg.CacheKey = mqttUri.CacheKey; } if (mqttUri.Indexes != null) { List <KeyValuePair <string, string> > list = GetIndexes(mqttUri); await adapter.PublishAsync(msg, list); } else { await adapter.PublishAsync(msg); } } else { if (metadata.Audit) { record = new MessageAuditRecord("XXXXXXXXXXXX", session.Identity, Channel.TypeId, "MQTT", message.Payload.Length, MessageDirectionType.In, false, DateTime.UtcNow, "Not authorized, missing resource metadata, or channel encryption requirements"); } throw new SecurityException(string.Format("'{0}' not authorized to publish to '{1}'", session.Identity, metadata.ResourceUriString)); } } catch (Exception ex) { await logger?.LogErrorAsync(ex, $"MQTT adapter PublishAsync error on channel '{Channel.Id}'."); OnError?.Invoke(this, new ProtocolAdapterErrorEventArgs(Channel.Id, ex)); } finally { if (metadata != null && metadata.Audit && record != null) { await messageAuditor?.WriteAuditRecordAsync(record); } } }
private void Dispatch(PublishMessage msg) { MqttUri uri = new MqttUri(msg.Topic); if (Dispatcher != null) { Dispatcher.Dispatch(uri.Resource, uri.ContentType, msg.Payload); } else { Session.Publish(msg); } }
//private Task<bool> CanSubscribe(string resourceUriString) //{ // TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>(); // Task t = Task.Factory.StartNew(async () => // { // try // { // bool r = await adapter.CanSubscribeAsync(resourceUriString, Channel.IsEncrypted); // tcs.SetResult(r); // } // catch (Exception ex) // { // await logger?.LogErrorAsync(ex, $"MQTT adapter CanSubscribe error on channel '{Channel.Id}'."); // tcs.SetException(ex); // } // }); // return tcs.Task; //} private void Session_OnPublish(object sender, MqttMessageEventArgs args) { try { PublishMessage message = args.Message as PublishMessage; MqttUri muri = new MqttUri(message.Topic); PublishAsync(message).GetAwaiter(); } catch (Exception ex) { logger?.LogErrorAsync(ex, $"MQTT adapter Session_OnPublish error on channel '{Channel.Id}'.").GetAwaiter(); OnError?.Invoke(this, new ProtocolAdapterErrorEventArgs(Channel.Id, ex)); } }
private static byte[] MqttConversion(MqttSession session, byte[] message, string contentType = null) { PublishMessage msg = MqttMessage.DecodeMessage(message) as PublishMessage; MqttUri uri = new MqttUri(msg.Topic); QualityOfServiceLevelType?qos = session.GetQoS(uri.Resource); PublishMessage pm = new PublishMessage(false, qos.HasValue ? qos.Value : QualityOfServiceLevelType.AtMostOnce, false, session.NewId(), uri.Resource, msg.Payload); if (pm.QualityOfService != QualityOfServiceLevelType.AtMostOnce) { session.Quarantine(pm, SkunkLab.Protocols.Mqtt.Handlers.DirectionType.Out); } return(pm.Encode()); }
private static byte[] MqttConversion(MqttSession session, byte[] message) { PublishMessage msg = MqttMessage.DecodeMessage(message) as PublishMessage; MqttUri uri = new MqttUri(msg.Topic); QualityOfServiceLevelType?qos = session.GetQoS(uri.Resource); PublishMessage pm = new PublishMessage(false, qos ?? QualityOfServiceLevelType.AtMostOnce, false, session.NewId(), uri.Resource, msg.Payload); if (pm.QualityOfService != QualityOfServiceLevelType.AtMostOnce) { session.Quarantine(pm, DirectionType.Out); } return(pm.Encode()); }
private List <KeyValuePair <string, string> > GetIndexes(MqttUri mqttUri) { List <KeyValuePair <string, string> > list = new List <KeyValuePair <string, string> >(mqttUri.Indexes); if (mqttUri.Indexes.Contains(new KeyValuePair <string, string>("~", "~"))) { list.Remove(new KeyValuePair <string, string>("~", "~")); var query = config.GetClientIndexes().Where((ck) => ck.Key == session.Config.IdentityClaimType); if (query.Count() == 1) { query.GetEnumerator().MoveNext(); list.Add(new KeyValuePair <string, string>(query.GetEnumerator().Current.Value, "~" + session.Identity)); } } return(list.Count > 0 ? list : null); }
private void Session_OnUnsubscribe(object sender, MqttMessageEventArgs args) { try { UnsubscribeMessage msg = (UnsubscribeMessage)args.Message; foreach (var item in msg.Topics) { MqttUri uri = new MqttUri(item.ToLowerInvariant()); if (adapter.CanSubscribeAsync(uri.Resource, Channel.IsEncrypted).GetAwaiter().GetResult()) { adapter.UnsubscribeAsync(uri.Resource).GetAwaiter(); } } } catch (Exception ex) { logger.LogError(ex, $"MQTT adapter Session_OnUnsubscribe error on channel '{Channel.Id}'."); OnError?.Invoke(this, new ProtocolAdapterErrorEventArgs(Channel.Id, ex)); } }
public override async Task <MqttMessage> ProcessAsync() { Session.IncrementKeepAlive(); MqttMessage message = Session.GetHeldMessage(Message.MessageId); if (message != null) { PublishMessage msg = message as PublishMessage; MqttUri uri = new MqttUri(msg.Topic); if (Dispatcher != null) { Dispatcher.Dispatch(uri.Resource, uri.ContentType, msg.Payload); } else { Session.Publish(msg, true); } } return(await Task.FromResult <MqttMessage>(new PublishAckMessage(PublishAckType.PUBCOMP, Message.MessageId))); }
private List <string> Session_OnSubscribe(object sender, MqttMessageEventArgs args) { List <string> list = new List <string>(); try { SubscribeMessage message = args.Message as SubscribeMessage; SubscriptionMetadata metadata = new SubscriptionMetadata() { Identity = session.Identity, Indexes = session.Indexes, IsEphemeral = true }; foreach (var item in message.Topics) { MqttUri uri = new MqttUri(item.Key); string resourceUriString = uri.Resource; Task <bool> t = CanSubscribe(resourceUriString); bool subscribe = t.Result; if (subscribe) { Task <string> subTask = Subscribe(resourceUriString, metadata); string subscriptionUriString = subTask.Result; list.Add(resourceUriString); } } } catch (Exception ex) { logger.LogError(ex, $"MQTT adapter Session_OnSubscribe error on channel '{Channel.Id}'."); OnError?.Invoke(this, new ProtocolAdapterErrorEventArgs(Channel.Id, ex)); } return(list); }
private void Session_OnUnsubscribe(object sender, MqttMessageEventArgs args) { try { UnsubscribeMessage msg = (UnsubscribeMessage)args.Message; foreach (var item in msg.Topics) { MqttUri uri = new MqttUri(item.ToLowerInvariant()); if (EventValidator.Validate(false, uri.Resource, Channel, graphManager, context).Validated) { adapter.UnsubscribeAsync(uri.Resource).GetAwaiter(); logger?.LogInformationAsync($"MQTT adapter unsubscribed {uri.ToString()}"); } } } catch (Exception ex) { logger?.LogErrorAsync(ex, $"MQTT adapter Session_OnUnsubscribe error on channel '{Channel.Id}'.").GetAwaiter(); OnError?.Invoke(this, new ProtocolAdapterErrorEventArgs(Channel.Id, ex)); } }
private List <string> Session_OnSubscribe(object sender, MqttMessageEventArgs args) { List <string> list = new List <string>(); try { SubscribeMessage message = args.Message as SubscribeMessage; SubscriptionMetadata metadata = new SubscriptionMetadata { Identity = session.Identity, Indexes = session.Indexes, IsEphemeral = true }; foreach (var item in message.Topics) { MqttUri uri = new MqttUri(item.Key); string resourceUriString = uri.Resource; if (EventValidator.Validate(false, resourceUriString, Channel, graphManager, context).Validated) { Task <string> subTask = Subscribe(resourceUriString, metadata); string subscriptionUriString = subTask.Result; list.Add(resourceUriString); } } } catch (Exception ex) { logger?.LogErrorAsync(ex, $"MQTT adapter Session_OnSubscribe error on channel '{Channel.Id}'.") .GetAwaiter(); OnError?.Invoke(this, new ProtocolAdapterErrorEventArgs(Channel.Id, ex)); } return(list); }