Example #1
0
        private async Task PostOrDeleteSubscriber(IHttpResourceRequest request, IHttpResourceResponse response,
                                                  TopicName topic)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            if (response == null)
            {
                throw new ArgumentNullException(nameof(response));
            }

            var uri = request.QueryString["uri"];

            if (uri == null)
            {
                response.StatusCode        = 400;
                response.StatusDescription = "Subscriber URI is required";
                return;
            }

            var subscriber = new Uri(uri);

            if (!_topics.Contains(topic))
            {
                response.StatusCode        = 404;
                response.StatusDescription = "Topic not found";
                return;
            }

            var authorized = _authorizationService == null ||
                             await _authorizationService.IsAuthorizedToSubscribe(request.Principal, topic);

            if (!authorized)
            {
                response.StatusCode        = 401;
                response.StatusDescription = "Unauthorized";
                return;
            }

            if ("delete".Equals(request.HttpMethod, StringComparison.OrdinalIgnoreCase))
            {
                // TODO: Verify that the subscriber is the one deleting the subscription
                // Ideas: Issue another HTTP request back to the subscriber to verify?
                //        Require the subscriber to specify a subscription ID (GUID?)
                //        when subscribing and then supply the same ID when unsubscribing?
                await _subscriptionTrackingService.RemoveSubscription(topic, subscriber);
            }
            else
            {
                var ttlStr = request.QueryString["ttl"];
                var ttl    = string.IsNullOrWhiteSpace(ttlStr)
                    ? default(TimeSpan)
                    : TimeSpan.FromSeconds(int.Parse(ttlStr));

                await _subscriptionTrackingService.AddSubscription(topic, subscriber, ttl);
            }
            response.StatusCode = 200;
        }
        private async Task HandleReceiveResult(UdpReceiveResult result)
        {
            try
            {
                var datagram = SubscriptionTrackingDatagram.Decode(result.Buffer);
                if (datagram.NodeId == _nodeId)
                {
                    return;
                }

                switch (datagram.Action)
                {
                case SubscriptionTrackingDatagram.ActionType.Add:
                    await _inner.AddSubscription(datagram.Topic, datagram.SubscriberUri, datagram.TTL);

                    return;

                case SubscriptionTrackingDatagram.ActionType.Remove:
                    await _inner.RemoveSubscription(datagram.Topic, datagram.SubscriberUri);

                    return;

                default:
                    await _diagnosticService.EmitAsync(new MulticastEventBuilder(this, MulticastEventType.MalformedDatagram)
                    {
                        Detail = "Unknown or unsupported subscription tracking action: " + datagram.Action,
                        Node   = _nodeId.ToString(),
                        Host   = result.RemoteEndPoint.Address.ToString(),
                        Port   = result.RemoteEndPoint.Port
                    }.Build());

                    break;
                }
            }
            catch (Exception e)
            {
                _diagnosticService.Emit(new MulticastEventBuilder(this, MulticastEventType.MalformedDatagram)
                {
                    Detail    = "Error unmarshaling datagram",
                    Node      = _nodeId.ToString(),
                    Host      = result.RemoteEndPoint.Address.ToString(),
                    Port      = result.RemoteEndPoint.Port,
                    Exception = e
                }.Build());
            }
        }