示例#1
0
        private static async void OnSubscriptionNotify(string server, ServiceEventMessage message)
        {
#if DEBUG
            Console.WriteLine("Consumed OnSubscriptionNotify message");
            Console.WriteLine("Server: " + server);
            Console.WriteLine("Message: " + message.ToString());
#endif
            string url      = (string)message.Parameters["Url"];
            string clientID = (string)message.Parameters["ClientID"];

            Model.WebhookNotification notification = new Model.WebhookNotification();
            MemoryStream stream = new MemoryStream(16384);
            new ServiceModels.WebhookNotification(notification, message).Serialise(stream);
            string payload = new StreamReader(stream).ReadToEnd();

            bool retry        = message.Parameters.ContainsKey("RequeueCount");
            long requeueCount = retry ? (long)message.Parameters["RequeueCount"] : 0;
            bool dropMessage  = false;

#if DEBUG
            Console.WriteLine($"Sending payload to {url}: \n" + payload);
#endif

            try
            {
                RESTClient.RESTResponse response = await RESTClient.PostAsync(url, ACCEPT_TYPE, null, notification.AcceptContentType, payload);

                switch ((HttpStatusCode)response.StatusCode)
                {
                case HttpStatusCode.OK:
                case HttpStatusCode.Created:
                    ApplicationEventLog.Write(LogLevel.Information, $"Webhook post notification from client {clientID} to {url} successful.");
                    break;

                case HttpStatusCode.BadRequest:
                case HttpStatusCode.Unauthorized:
                case HttpStatusCode.NotFound:
                case HttpStatusCode.MethodNotAllowed:
                    // No retry for these failures
                    ApplicationEventLog.Write(LogLevel.Warning, $"Non-recoverable HTTP Status code from{url}:{response.StatusCode}, discarding message.");
                    dropMessage = true;
                    break;

                default:
                    ApplicationEventLog.Write(LogLevel.Warning, $"Unexpected HTTP Status code from{url}:{response.StatusCode}");
                    break;
                }
            }
            catch (Exception ex)
            {
                ApplicationEventLog.Write(LogLevel.Error, "Failed to post webhook", ex);
            }

            if ((MAX_POST_ATTEMPTS <= 0 || requeueCount < MAX_POST_ATTEMPTS) && !dropMessage)
            {
                BusinessLogicFactory.ServiceMessages.NackMessage(message);
            }
        }
示例#2
0
        private void ProcessUpdateRequest(Exchange exchange)
        {
            Request  request = exchange.Request;
            Guid     clientID;
            Response response;

            if (StringUtils.GuidTryDecode(request.UriPath.Substring(4), out clientID))
            {
                LWM2MClient client = BusinessLogicFactory.Clients.GetClient(clientID);
                if (client == null)
                {
                    response = Response.CreateResponse(request, StatusCode.NotFound);
                }
                else
                {
                    client.Parse(request.UriQueries);
                    BusinessLogicFactory.Clients.UpdateClientActivity(client);
                    client.Address  = request.Source;
                    client.EndPoint = exchange.EndPoint;
                    bool updatedLifeTime = false;
                    if ((request.ContentType == (int)MediaType.ApplicationLinkFormat) || (request.ContentType == -1))
                    {
                        if (request.PayloadSize > 0)
                        {
                            ObjectTypes objectTypes = new ObjectTypes();
                            objectTypes.Parse(request.PayloadString);
                            if (ObjectTypes.Compare(client.SupportedTypes, objectTypes) != 0)
                            {
                                client.SupportedTypes = objectTypes;
                                if (client.ClientID != Guid.Empty)
                                {
                                    DataAccessFactory.Clients.SaveClient(client, TObjectState.Add);
                                    updatedLifeTime = true;
                                }
                                BusinessLogicFactory.Clients.ClientChangedSupportedTypes(client);
                            }
                        }
                    }
                    if (!updatedLifeTime)
                    {
                        BusinessLogicFactory.Clients.UpdateClientLifetime(client.ClientID, client.Lifetime);
                    }
                    response = Response.CreateResponse(request, StatusCode.Changed);

                    ApplicationEventLog.Write(LogLevel.Information, string.Concat("Client update ", client.Name, " address ", client.Address.ToString()));
                }
            }
            else
            {
                ApplicationEventLog.WriteEntry(string.Concat("Invalid update location", request.UriPath));
                response = Response.CreateResponse(request, StatusCode.BadRequest);
            }
            exchange.SendResponse(response);
        }
示例#3
0
        private static void Observe(Subscription subscription)
        {
            Client client = DataAccessFactory.Clients.GetClient(subscription.ClientID);

            if (client != null)
            {
                if (subscription.PropertyDefinitionID != Guid.Empty)
                {
                    if (subscription.NotificationParameters != null)
                    {
                        if (DataAccessFactory.Servers.SetNotificationParameters(client, subscription.ObjectDefinitionID, subscription.ObjectID, subscription.PropertyDefinitionID, subscription.NotificationParameters))
                        {
                            ApplicationEventLog.Write(LogLevel.Information, $"Updated notification parameters for resource /{subscription.ObjectDefinitionID}/{subscription.ObjectID}/{subscription.PropertyDefinitionID}");
                        }
                        else
                        {
                            ApplicationEventLog.Write(LogLevel.Warning, $"Failed to update notification parameters for resource /{subscription.ObjectDefinitionID}/{subscription.ObjectID}/{subscription.PropertyDefinitionID}");
                        }
                    }
                    DataAccessFactory.Servers.ObserveResource(client, subscription.ObjectDefinitionID, subscription.ObjectID, subscription.PropertyDefinitionID);
#if DEBUG
                    ApplicationEventLog.Write(LogLevel.Information, $"Observing resource /{subscription.ObjectDefinitionID}/{subscription.ObjectID}/{subscription.PropertyDefinitionID}");
#endif
                }
                else if (subscription.ObjectID != null)
                {
                    DataAccessFactory.Servers.ObserveObject(client, subscription.ObjectDefinitionID, subscription.ObjectID);
#if DEBUG
                    ApplicationEventLog.Write(LogLevel.Information, $"Observing object /{subscription.ObjectDefinitionID}/{subscription.ObjectID}");
#endif
                }
                else if (subscription.ObjectDefinitionID != Guid.Empty)
                {
                    DataAccessFactory.Servers.ObserveObjects(client, subscription.ObjectDefinitionID);
#if DEBUG
                    ApplicationEventLog.Write(LogLevel.Information, $"Observing objects /{subscription.ObjectDefinitionID}");
#endif
                }
                else
                {
                    ApplicationEventLog.Write(LogLevel.Warning, $"Subscription {subscription.SubscriptionID} has no definition ID");
                }
            }
            else
            {
                ApplicationEventLog.Write(LogLevel.Warning, $"No client exists for {subscription.ClientID} in subscription {subscription.SubscriptionID}");
            }
        }
示例#4
0
        public WebhookNotification(Model.WebhookNotification webhookNotification, ServiceEventMessage message)
        {
            _WebhookNotification = webhookNotification;
            _WebhookNotification.AcceptContentType = (string)message.Parameters["AcceptContentType"];
            _WebhookNotification.SubscriptionID    = (string)message.Parameters["SubscriptionID"];
            _WebhookNotification.ClientID          = (string)message.Parameters["ClientID"];
            _WebhookNotification.SubscriptionType  = (string)message.Parameters["SubscriptionType"];
            _WebhookNotification.TimeTriggered     = (DateTime)message.Parameters["TimeTriggered"];
            if (message.Parameters.ContainsKey("Object"))
            {
                _WebhookNotification.ChangedObject = (Model.Object)message.Parameters["Object"];

                _WebhookNotification.ObjectDefinition = DataAccessFactory.ObjectDefinitions.GetLookups().GetObjectDefinition(_WebhookNotification.ChangedObject.ObjectDefinitionID);
                if (_WebhookNotification.ObjectDefinition == null)
                {
                    ApplicationEventLog.Write(LogLevel.Warning, $"Could not lookup object definition {_WebhookNotification.ChangedObject.ObjectDefinitionID}");
                }
            }
        }
示例#5
0
        private static void OnDeleteSubscription(string server, ServiceEventMessage message)
        {
#if DEBUG
            Console.WriteLine("Consumed delete subscription message");
            Console.WriteLine("Server: " + server);
            Console.WriteLine("Message: " + message.ToString());
#endif
            Subscription subscription = GetSubscriptionFromMessage(message);
            if (subscription != null)
            {
                if (subscription.SubscriptionType == TSubscriptionType.Observation)
                {
                    CancelObservation(subscription);
                }
                DataAccessFactory.Subscriptions.SaveSubscription(subscription, TObjectState.Delete);
            }
            else
            {
                ApplicationEventLog.Write(LogLevel.Warning, $"Failed to lookup subscription: {message.Parameters["SubscriptionID"]}");
            }
        }
示例#6
0
        private static void OnUpdateSubscription(string server, ServiceEventMessage message)
        {
#if DEBUG
            Console.WriteLine("Consumed update subscription message");
            Console.WriteLine("Server: " + server);
            Console.WriteLine("Message: " + message.ToString());
#endif
            Subscription subscription = GetSubscriptionFromMessage(message);
            if (subscription != null)
            {
                if (subscription.SubscriptionType == TSubscriptionType.Observation)
                {
                    if (subscription.NotificationParameters != null && subscription.PropertyDefinitionID != Guid.Empty)
                    {
                        Client client = DataAccessFactory.Clients.GetClient(subscription.ClientID);
                        if (client != null)
                        {
                            if (DataAccessFactory.Servers.SetNotificationParameters(client, subscription.ObjectDefinitionID, subscription.ObjectID, subscription.PropertyDefinitionID, subscription.NotificationParameters))
                            {
                                ApplicationEventLog.Write(LogLevel.Information, $"Updated notification parameters for resource /{subscription.ObjectDefinitionID}/{subscription.ObjectID}/{subscription.PropertyDefinitionID}");
                            }
                            else
                            {
                                ApplicationEventLog.Write(LogLevel.Warning, $"Failed to update notification parameters for resource /{subscription.ObjectDefinitionID}/{subscription.ObjectID}/{subscription.PropertyDefinitionID}");
                            }
                        }
                        else
                        {
                            ApplicationEventLog.Write(LogLevel.Warning, $"No client exists for {subscription.ClientID} in subscription {subscription.SubscriptionID}");
                        }
                    }
                }
                DataAccessFactory.Subscriptions.SaveSubscription(subscription, TObjectState.Update);
            }
            else
            {
                ApplicationEventLog.Write(LogLevel.Warning, $"Failed to lookup subscription: {message.Parameters["SubscriptionID"]}");
            }
        }
示例#7
0
        private void _CheckDeadClientsTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            List <LWM2MClient> clientsToRemove = new List <LWM2MClient>();

            try
            {
                ICollection <LWM2MClient> clients = _Clients.Values;
                foreach (LWM2MClient client in clients)
                {
                    if (client.Lifetime < DateTime.UtcNow)
                    {
                        clientsToRemove.Add(client);
                    }
                }
            }
            catch
            {
            }

            try
            {
                foreach (LWM2MClient item in clientsToRemove)
                {
                    ApplicationEventLog.Write(LogLevel.Information, string.Concat("Client connection expired: ", item.Name, " address ", item.Address.ToString()));
                    BusinessLogicFactory.Events.ClientConnectionExpired(item);
                    LWM2MClient client;
                    item.Cancel();
                    _Clients.TryRemove(item.ClientID, out client);
                    if (item.ClientID != Guid.Empty)
                    {
                        _ClientByDeviceID.TryRemove(item.ClientID, out client);
                    }
                }
            }
            catch
            {
            }
        }
示例#8
0
        private void ProcessDeregisterRequest(Exchange exchange)
        {
            Request     request  = exchange.Request;
            Guid        clientID = StringUtils.GuidDecode(request.UriPath.Substring(4));
            LWM2MClient client   = BusinessLogicFactory.Clients.GetClient(clientID);
            Response    response;

            if (client == null)
            {
                response = Response.CreateResponse(request, StatusCode.NotFound);
            }
            else
            {
                client.Lifetime = DateTime.UtcNow;
                BusinessLogicFactory.Clients.UpdateClientLifetime(client.ClientID, DateTime.UtcNow);
                BusinessLogicFactory.Clients.UpdateClientActivity(client.ClientID, DateTime.UtcNow);
                BusinessLogicFactory.Clients.DeleteClient(clientID);
                response = Response.CreateResponse(request, StatusCode.Deleted);

                ApplicationEventLog.Write(LogLevel.Information, string.Concat("Client deregister ", client.Name, " address ", client.Address.ToString()));
            }
            exchange.SendResponse(response);
        }
示例#9
0
        private static void CancelObservation(Subscription subscription)
        {
            Client client = DataAccessFactory.Clients.GetClient(subscription.ClientID);

            if (client != null)
            {
                if (subscription.PropertyDefinitionID != Guid.Empty)
                {
                    DataAccessFactory.Servers.CancelObserveResource(client, subscription.ObjectDefinitionID, subscription.ObjectID, subscription.PropertyDefinitionID, false);
#if DEBUG
                    ApplicationEventLog.Write(LogLevel.Information, $"Cancelled observing resource /{subscription.ObjectDefinitionID}/{subscription.ObjectID}/{subscription.PropertyDefinitionID}");
#endif
                }
                else if (subscription.ObjectID != null)
                {
                    DataAccessFactory.Servers.CancelObserveObject(client, subscription.ObjectDefinitionID, subscription.ObjectID, false);
#if DEBUG
                    ApplicationEventLog.Write(LogLevel.Information, $"Cancelled observing object /{subscription.ObjectDefinitionID}/{subscription.ObjectID}");
#endif
                }
                else if (subscription.ObjectDefinitionID != Guid.Empty)
                {
                    DataAccessFactory.Servers.CancelObserveObjects(client, subscription.ObjectDefinitionID, false);
#if DEBUG
                    ApplicationEventLog.Write(LogLevel.Information, $"Cancelled observing objects /{subscription.ObjectDefinitionID}");
#endif
                }
                else
                {
                    ApplicationEventLog.Write(LogLevel.Warning, $"Subscription {subscription.SubscriptionID} has no definition ID");
                }
            }
            else
            {
                ApplicationEventLog.Write(LogLevel.Warning, $"No client exists for {subscription.ClientID} in subscription {subscription.SubscriptionID}");
            }
        }
示例#10
0
        private static void OnCreateSubscription(string server, ServiceEventMessage message)
        {
#if DEBUG
            Console.WriteLine("Consumed create subscription message");
            Console.WriteLine("Server: " + server);
            Console.WriteLine("Message: " + message.ToString());
#endif
            Subscription subscription = GetSubscriptionFromMessage(message);
            if (subscription != null)
            {
                if (subscription.SubscriptionType == TSubscriptionType.Observation)
                {
                    Observe(subscription);
                }
                else
                {
                    // for server event types, we are already subscribed to RabbitMQ service messages.
                }
            }
            else
            {
                ApplicationEventLog.Write(LogLevel.Warning, $"Failed to lookup subscription: {message.Parameters["SubscriptionID"]}");
            }
        }
示例#11
0
        private void ProcessRegisterRequest(Exchange exchange)
        {
            Request     request = exchange.Request;
            LWM2MClient client  = new LWM2MClient();

            client.Server  = _ServerEndPoint;
            client.Address = request.Source;
            client.Parse(request.UriQueries);
            ObjectTypes objectTypes = new ObjectTypes();

            objectTypes.Parse(request.PayloadString);
            client.SupportedTypes = objectTypes;
            client.EndPoint       = exchange.EndPoint;
            if (_SecureChannel != null)
            {
                CertificateInfo certificateInfo = _SecureChannel.GetClientCertificateInfo(client.Address);
                if (certificateInfo == null)
                {
                    string pskIdentity = _SecureChannel.GetClientPSKIdentity(client.Address);
                    if (!string.IsNullOrEmpty(pskIdentity))
                    {
                        Guid        clientID;
                        PSKIdentity identity = DataAccessFactory.Identities.GetPSKIdentity(pskIdentity);
                        if (identity != null)
                        {
                            if (StringUtils.GuidTryDecode(pskIdentity, out clientID))
                            {
                                client.ClientID = clientID;
                            }
                            client.OrganisationID = identity.OrganisationID;
                        }
                    }
                }
                else
                {
                    Console.WriteLine(certificateInfo.Subject.CommonName);
                    Console.WriteLine(certificateInfo.Subject.Organistion);
                    Guid clientID;
                    if (Guid.TryParse(certificateInfo.Subject.CommonName, out clientID))
                    {
                        client.ClientID = clientID;
                    }
                    int organisationID;
                    if (int.TryParse(certificateInfo.Subject.Organistion, out organisationID))
                    {
                        client.OrganisationID = organisationID;
                    }
                }
            }
            if (client.ClientID != Guid.Empty && (client.OrganisationID > 0 || !SecureOnly) && !DataAccessFactory.Clients.IsBlacklisted(client.ClientID))
            {
                BusinessLogicFactory.Clients.AddClient(client);
            }

            Response response = Response.CreateResponse(request, StatusCode.Created);

            //response.AddOption(Option.Create(OptionType.LocationPath, string.Concat("rd/",StringUtils.GuidEncode(client.ClientID))));
            response.AddOption(Option.Create(OptionType.LocationPath, "rd"));
            response.AddOption(Option.Create(OptionType.LocationPath, StringUtils.GuidEncode(client.ClientID)));

            exchange.SendResponse(response);

            ApplicationEventLog.Write(LogLevel.Information, string.Concat("Client registered ", client.Name, " address ", client.Address.ToString()));
        }
示例#12
0
        public void SaveObjectProperty(Guid clientID, Guid objectDefinitionID, string instanceID, Property property, TObjectState state)
        {
            LWM2MClient client = BusinessLogicFactory.Clients.GetClient(clientID);

            if (client == null)
            {
                ApplicationEventLog.Write(LogLevel.Warning, string.Concat("SaveObject - Client not found ", clientID.ToString()));
                throw new NoLongerAvailableException("Device not connected");
            }
            else
            {
                ObjectDefinitionLookups lookups          = BusinessLogicFactory.Clients.GetLookups();
                ObjectDefinition        objectDefinition = lookups.GetObjectDefinition(objectDefinitionID);
                if (objectDefinition != null)
                {
                    int objectID;
                    if (int.TryParse(objectDefinition.ObjectID, out objectID))
                    {
                        Model.ObjectType objectType = client.SupportedTypes.GetObjectType(objectID);
                        if (objectType != null)
                        {
                            PropertyDefinition propertyDefinition = objectDefinition.GetProperty(property.PropertyDefinitionID);
                            if (propertyDefinition != null)
                            {
                                byte[] payload     = null;
                                int    contentType = TlvConstant.CONTENT_TYPE_TLV;
                                if (state != TObjectState.Delete)
                                {
                                    if ((property.Value != null) || (property.Values != null))
                                    {
                                        if ((property.Value != null) && (LWM2MClient.DataFormat == MediaType.TextPlain))
                                        {
                                            contentType = LWM2MClient.DataFormat;
                                            //contentType = TlvConstant.CONTENT_TYPE_PLAIN;
                                            string text = SerialiseProperty(propertyDefinition, property);
                                            if (text != null)
                                            {
                                                payload = Encoding.UTF8.GetBytes(text);
                                            }
                                        }
                                        else
                                        {
                                            Model.Object lwm2mObject = new Model.Object();
                                            lwm2mObject.Properties.Add(property);
                                            payload = SerialiseObject(objectDefinition, lwm2mObject);
                                        }
                                    }
                                }
                                Request request = null;
                                switch (state)
                                {
                                case TObjectState.NotChanged:
                                    break;

                                case TObjectState.Add:
                                    request = client.NewPostRequest(objectType, instanceID, propertyDefinition.PropertyID, contentType, payload);
                                    break;

                                case TObjectState.Update:
                                    request = client.NewPutRequest(objectType, instanceID, propertyDefinition.PropertyID, contentType, payload);
                                    break;

                                case TObjectState.Delete:
                                    request = client.NewDeleteRequest(objectType, instanceID, propertyDefinition.PropertyID);
                                    break;

                                default:
                                    break;
                                }
                                Response response = client.SendRequest(request).WaitForResponse(LWM2MClient.REQUEST_TIMEOUT);
                                if (response == null)
                                {
                                    throw new TimeoutException();
                                }
                                else
                                {
                                    BusinessLogicFactory.Clients.UpdateClientActivity(client);
                                    if (response.StatusCode != StatusCode.Changed)
                                    {
                                        throw new BadRequestException();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
示例#13
0
        public string SaveObject(Guid clientID, Model.Object item, TObjectState state)
        {
            string      result = null;
            LWM2MClient client = BusinessLogicFactory.Clients.GetClient(clientID);

            if (client == null)
            {
                ApplicationEventLog.Write(LogLevel.Warning, string.Concat("SaveObject - Client not found ", clientID.ToString()));
                throw new NoLongerAvailableException("Device not connected");
            }
            else
            {
                ObjectDefinitionLookups lookups          = BusinessLogicFactory.Clients.GetLookups();
                ObjectDefinition        objectDefinition = lookups.GetObjectDefinition(item.ObjectDefinitionID);
                if (objectDefinition == null)
                {
                    ApplicationEventLog.Write(LogLevel.Warning, string.Concat("SaveObject - Metadata not found ", item.ObjectDefinitionID.ToString(), " client ", client.Address.ToString()));
                }
                else
                {
                    int objectID;
                    if (int.TryParse(objectDefinition.ObjectID, out objectID))
                    {
                        Model.ObjectType objectType = client.SupportedTypes.GetObjectType(objectID);
                        if (objectType != null)
                        {
                            Request request = null;
                            switch (state)
                            {
                            case TObjectState.NotChanged:
                                break;

                            case TObjectState.Add:
                                ushort instanceID;
                                if (ushort.TryParse(item.InstanceID, out instanceID))
                                {
                                    request = client.NewPostRequest(objectType, null, null, TlvConstant.CONTENT_TYPE_TLV, SerialiseObject(objectDefinition, item, instanceID));
                                }
                                else
                                {
                                    request = client.NewPostRequest(objectType, null, null, TlvConstant.CONTENT_TYPE_TLV, SerialiseObject(objectDefinition, item));
                                }
                                break;

                            case TObjectState.Update:
                                request = client.NewPostRequest(objectType, item.InstanceID, null, TlvConstant.CONTENT_TYPE_TLV, SerialiseObject(objectDefinition, item));
                                break;

                            case TObjectState.Delete:
                                request = client.NewDeleteRequest(objectType, item.InstanceID, null);
                                break;

                            default:
                                break;
                            }
                            ApplicationEventLog.Write(LogLevel.Information, string.Concat("SaveObject - Send request ", string.Concat(objectType.Path, "/", item.InstanceID), " client ", client.Address.ToString()));

                            Response response = client.SendRequest(request).WaitForResponse(LWM2MClient.REQUEST_TIMEOUT);
                            if (response == null)
                            {
                                throw new TimeoutException();
                            }
                            else
                            {
                                BusinessLogicFactory.Clients.UpdateClientActivity(client);
                                if (response.StatusCode == StatusCode.Created)
                                {
                                    if (!string.IsNullOrEmpty(response.LocationPath) && (response.LocationPath.StartsWith(request.UriPath)))
                                    {
                                        int startIndex = request.UriPath.Length + 1;
                                        if (startIndex < response.LocationPath.Length)
                                        {
                                            result = response.LocationPath.Substring(startIndex);
                                        }
                                    }
                                }
                                else if (response.StatusCode == StatusCode.Changed)
                                {
                                }
                                else if ((response.StatusCode == StatusCode.NotFound) && (state == TObjectState.Delete))
                                {
                                }
                                else
                                {
                                    throw new BadRequestException();
                                }
                            }
                        }
                    }
                }
            }
            return(result);
        }