public MessageArrivedState(MessageArrivedEventHandler handler, ServiceEventMessage message,MessageQueue queue, AckMessageInfo ackMessageInfo) { AckMessageInfo = ackMessageInfo; Handler = handler; Message = message; Queue = queue; }
public void Publish(string routingKey, ServiceEventMessage message, TMessagePublishMode publishMode) { CheckRabbitMQ(); if (Security.CurrentOrganisation != null && !message.Parameters.ContainsKey("OrganisationID")) message.Parameters.Add("OrganisationID", Security.CurrentOrganisation.OrganisationID); _DALRabbitMQ.Publish(routingKey, message, publishMode); }
public void NackMessage(ServiceEventMessage message, TimeSpan? delayQueueingFor = null) { CheckRabbitMQ(); if (delayQueueingFor.HasValue) _DALRabbitMQ.NackMessage(message, delayQueueingFor.Value); else _DALRabbitMQ.NackMessage(message); }
public void ClientConnectionExpired(LWM2MClient client) { if (client.OrganisationID != 0) { ServiceEventMessage message = new ServiceEventMessage(); FillDeviceParameters(client, message); BusinessLogicFactory.ServiceMessages.Publish(RouteKeys.CLIENT_CONNECTION_EXPIRED, message, TMessagePublishMode.Confirms); } }
public void ClientUpdate(LWM2MClient client) { if (client.OrganisationID != 0) { ServiceEventMessage message = new ServiceEventMessage(); FillDeviceParameters(client, message); BusinessLogicFactory.ServiceMessages.Publish(RouteKeys.CLIENT_UPDATE, message, TMessagePublishMode.Confirms); } }
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); } }
private void OnUpdateMetrics(string server, ServiceEventMessage message) { Guid clientID = StringUtils.GuidDecode((string)message.Parameters["ClientID"]); int organisationID = (int)((long)message.Parameters["OrganisationID"]); List <ClientMetric> metrics = (List<ClientMetric>)message.Parameters["Metrics"]; foreach (ClientMetric parameter in metrics) { string metricName = parameter.Name; long oldValue = 0; long newValue = parameter.Value; ClientMetric clientMetric = DataAccessFactory.Metrics.GetMetric(clientID, metricName); if (clientMetric == null) { clientMetric = new ClientMetric(); clientMetric.Name = metricName; clientMetric.Value = newValue; clientMetric.ClientID = clientID; clientMetric.Incremental = parameter.Incremental; DataAccessFactory.Metrics.SaveMetric(clientMetric, TObjectState.Add); } else { oldValue = clientMetric.Value; if (clientMetric.Incremental) { clientMetric.Value += newValue; newValue = clientMetric.Value; } else { clientMetric.Value = newValue; } DataAccessFactory.Metrics.SaveMetric(clientMetric, TObjectState.Update); } long change = newValue - oldValue; OrganisationMetric organisationMetric = DataAccessFactory.Metrics.GetMetric(organisationID, metricName); if (organisationMetric == null) { organisationMetric = new OrganisationMetric(); organisationMetric.Name = metricName; organisationMetric.Value = change; organisationMetric.OrganisationID = organisationID; DataAccessFactory.Metrics.SaveMetric(organisationMetric, TObjectState.Add); } else { organisationMetric.Value += change; DataAccessFactory.Metrics.SaveMetric(organisationMetric, TObjectState.Update); } } }
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}"); } } }
public void SaveSubscription(Subscription subscription, TObjectState state) { ServiceEventMessage message = new ServiceEventMessage(); message.AddParameter("SubscriptionID", StringUtils.GuidEncode(subscription.SubscriptionID)); switch (state) { case TObjectState.Add: DataAccessFactory.Subscriptions.SaveSubscription(subscription, state); BusinessLogicFactory.ServiceMessages.Publish(RouteKeys.SUBSCRIPTION_CREATE, message, TMessagePublishMode.Confirms); break; case TObjectState.Update: DataAccessFactory.Subscriptions.SaveSubscription(subscription, state); BusinessLogicFactory.ServiceMessages.Publish(RouteKeys.SUBSCRIPTION_UPDATE, message, TMessagePublishMode.Confirms); break; case TObjectState.Delete: BusinessLogicFactory.ServiceMessages.Publish(RouteKeys.SUBSCRIPTION_DELETE, message, TMessagePublishMode.Confirms); break; default: DataAccessFactory.Subscriptions.SaveSubscription(subscription, state); break; } }
public void Publish(string routingKey, ServiceEventMessage message, TMessagePublishMode publishMode) { if (message.MessageID == Guid.Empty) message.MessageID = Guid.NewGuid(); if (message.TimeStamp == 0) message.TimeStamp = DateTime.UtcNow.Ticks; message.MessagePublishMode = publishMode; if (publishMode == TMessagePublishMode.FireAndForget && (!_Terminate)) { StartFireAndForgetThread(); lock (_FireAndForgetMessages) { _FireAndForgetMessages.Enqueue(new QueuedMessage() { RoutingKey = routingKey, Message = message}); } _TriggerPublishFireAndForgetMessages.Set(); } else if (publishMode == TMessagePublishMode.Confirms && (!_Terminate)) { StartConfirmsThread(); WriteMessageToDisk(routingKey, message, _ConfirmsMessagePath); _TriggerPublishConfirmMessages.Set(); } else { StartTransactionalThread(); WriteMessageToDisk(routingKey,message,_TransactionalMessagePath); _TriggerPublishTransactionalMessages.Set(); } }
public void NackMessage(ServiceEventMessage message, TimeSpan delayQueueingFor) { message.QueueAfterTime = DateTime.UtcNow.Add(delayQueueingFor); NackMessage(message); }
public void NackMessage(ServiceEventMessage message) { if (!message.QueueAfterTime.HasValue) message.QueueAfterTime = DateTime.UtcNow.AddSeconds(1.0); for (int index = 0; index < _ServerCount; index++) { _Subscriptions[index].NackMessage(message); } }
private static void NotifySubscriber(Guid clientID, Subscription subscription, Model.Object changedObject) { #if DEBUG Console.WriteLine("Publishing Subscription.Webhook message for subscription " + subscription.SubscriptionID); #endif ServiceEventMessage message = new ServiceEventMessage(); message.AddParameter("AcceptContentType", subscription.AcceptContentType); message.AddParameter("SubscriptionID", StringUtils.GuidEncode(subscription.SubscriptionID)); message.AddParameter("SubscriptionType", subscription.SubscriptionType.ToString()); message.AddParameter("ClientID", StringUtils.GuidEncode(clientID)); message.AddParameter("Url", subscription.Url); message.AddParameter("TimeTriggered", DateTime.Now); if (changedObject != null) message.AddParameter("Object", changedObject); BusinessLogicFactory.ServiceMessages.Publish(RouteKeys.SUBSCRIPTION_NOTIFICATION, message, TMessagePublishMode.Confirms); }
public void Serialise(Stream stream, ServiceEventMessage message) { JsonTextWriter jsonTextWriter = new JsonTextWriter(new StreamWriter(stream)); _Serialiser.Serialize(jsonTextWriter, message); jsonTextWriter.Flush(); jsonTextWriter.Close(); }
private void OnLWM2MServerStart(string server, ServiceEventMessage message) { LWM2MServer lwm2mServer = (LWM2MServer)message.Parameters["Server"]; DataAccessFactory.Servers.SaveLWM2MServer(lwm2mServer, TObjectState.Add); BusinessLogicFactory.ServiceMessages.AckMessage(message); }
private void WriteMessageToDisk(string routingKey, ServiceEventMessage message, string path) { string filename = Path.Combine(path, string.Concat(routingKey, "_", message.MessageID, ".lck")); lock (this) { string messageFilename = Path.ChangeExtension(filename, ".msg"); if (!File.Exists(messageFilename)) { using (FileStream stream = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, FileOptions.None)) { MessageFormatter messageFormatter = new MessageFormatter(stream); messageFormatter.Serialise(message); stream.Flush(); stream.Close(); } File.Move(filename, messageFilename); } } }
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"]}"); } }
private static void RestartObservations(ServiceEventMessage message) { Guid clientID = StringUtils.GuidDecode((string)message.Parameters["ClientID"]); #if DEBUG Console.WriteLine($"Restarting observations for client {clientID}"); #endif List<Subscription> subscriptions = DataAccessFactory.Subscriptions.GetSubscriptions(clientID); foreach (Subscription subscription in subscriptions) { if (subscription.SubscriptionType == TSubscriptionType.Observation) { Observe(subscription); } } }
public static void Main(string[] args) { try { int workerThreads; int completionPortThreads; System.Threading.ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads); if (workerThreads < 16) { workerThreads = 16; System.Threading.ThreadPool.SetMinThreads(workerThreads, completionPortThreads); } IConfigurationBuilder builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables() .AddCommandLine(args); IConfigurationRoot configuration = builder.Build(); ServiceConfiguration.LoadConfig(configuration.GetSection("ServiceConfiguration")); int port = 15683; bool secureOnly = true; IConfigurationSection sectionBootstrap = configuration.GetSection("LWM2MBootstrap"); if (sectionBootstrap != null) { IConfigurationSection sectionPort = sectionBootstrap.GetSection("Port"); if (sectionPort != null) { if (!int.TryParse(sectionPort.Value, out port)) port = 15683; } IConfigurationSection sectionSecure = sectionBootstrap.GetSection("SecureOnly"); if (sectionSecure != null) { if (!bool.TryParse(sectionSecure.Value, out secureOnly)) secureOnly = true; } } Version version = Assembly.GetExecutingAssembly().GetName().Version; Console.Write("LWM2M Bootstrap ("); Console.Write(version.ToString()); Console.WriteLine(")"); if (ServiceConfiguration.ExternalUri == null) { ServiceConfiguration.ExternalUri = new Uri(string.Concat("coaps://", ServiceConfiguration.Hostname, ":", (port+1).ToString())); } ServiceConfiguration.DisplayConfig(); BusinessLogicFactory.Initialise(); BootstrapServer bootstrapServer = new BootstrapServer(); //bootstrapServer.PSKIdentities.LoadFromFile("PSKIdentities.xml"); bootstrapServer.Port = port; bootstrapServer.SecureOnly = secureOnly; bootstrapServer.Start(); ServiceEventMessage message = new ServiceEventMessage(); Imagination.Model.BootstrapServer bootstrap = new Imagination.Model.BootstrapServer(); bootstrap.Url = ServiceConfiguration.ExternalUri.ToString(); //PSKIdentity pskIdentity = new PSKIdentity(); //pskIdentity.Identity = "Test1"; //pskIdentity.Secret = "TestSecret"; //bootstrap.AddServerIdentity(pskIdentity); message.AddParameter("BootstrapServer", bootstrap); BusinessLogicFactory.ServiceMessages.Publish("Bootstrap.Start", message, TMessagePublishMode.Confirms); _ShutdownEvent = new ManualResetEvent(false); Console.CancelKeyPress += delegate (object sender, ConsoleCancelEventArgs e) { _ShutdownEvent.Set(); e.Cancel = true; }; Console.Write("Listening on port "); Console.WriteLine(port.ToString()); Console.WriteLine("Press Ctrl+C to stop the server."); _ShutdownEvent.WaitOne(); Console.WriteLine("Exiting."); bootstrapServer.Stop(); BusinessLogicFactory.ServiceMessages.Stop(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } }
private void OnBootstrapStart(string server, ServiceEventMessage message) { BootstrapServer bootstrap = (BootstrapServer)message.Parameters["BootstrapServer"]; DataAccessFactory.Configuration.SaveBootstrapServer(bootstrap, TObjectState.Add); BusinessLogicFactory.ServiceMessages.AckMessage(message); }
private static void NotifySubscribers(ServiceEventMessage message, TSubscriptionType subscriptionType) { Guid clientID = StringUtils.GuidDecode((string)message.Parameters["ClientID"]); int organisationID = (int)((long)message.Parameters["OrganisationID"]); Model.Object changedObject = null; List<Subscription> subscriptions = null; if (subscriptionType == TSubscriptionType.Observation) { changedObject = (Model.Object)message.Parameters["Object"]; subscriptions = DataAccessFactory.Subscriptions.GetSubscriptions(clientID); } else subscriptions = DataAccessFactory.Subscriptions.GetSubscriptions(organisationID); foreach (Subscription subscription in subscriptions) { if (subscription.SubscriptionType == subscriptionType) { if (subscriptionType == TSubscriptionType.Observation) { if (subscription.ObjectDefinitionID == changedObject.ObjectDefinitionID) { if (subscription.ObjectID == null || subscription.ObjectID == changedObject.InstanceID) { if (subscription.PropertyDefinitionID == Guid.Empty || changedObject.ContainsPropertyWithDefinitionID(subscription.PropertyDefinitionID)) { NotifySubscriber(clientID, subscription, changedObject); } } } } else NotifySubscriber(clientID, subscription, changedObject); } } }
internal void Reject(ServiceEventMessage message) { WriteMessageToDisk(message.Queue, message, _RejectedMessagePath); }
public void FillDeviceParameters(Client client, ServiceEventMessage message) { message.Parameters.Add("ClientID", StringUtils.GuidEncode(client.ClientID)); message.Parameters.Add("OrganisationID", client.OrganisationID); }
internal void Requeue(ServiceEventMessage message) { if (message.MessagePublishMode == TMessagePublishMode.FireAndForget && (!_Terminate)) { StartFireAndForgetThread(); lock (_FireAndForgetMessages) { _FireAndForgetMessages.Enqueue(new QueuedMessage() { RoutingKey = message.Queue, Message = message, Requeued = true }); } _TriggerPublishFireAndForgetMessages.Set(); } else if (message.MessagePublishMode == TMessagePublishMode.Confirms && (!_Terminate)) { StartConfirmsThread(); WriteMessageToDisk(message.Queue, message, _ConfirmsRequeueMessagePath); _TriggerPublishConfirmMessages.Set(); } else { StartTransactionalThread(); WriteMessageToDisk(message.Queue, message, _TransactionalRequeueMessagePath); _TriggerPublishTransactionalMessages.Set(); } }
public void MetricsUpdate(LWM2MClient client) { if (client.OrganisationID != 0) { ServiceEventMessage message = new ServiceEventMessage(); FillDeviceParameters(client, message); client.Metrics.FillParameters(message); BusinessLogicFactory.ServiceMessages.Publish(RouteKeys.CLIENT_METRICS, message, TMessagePublishMode.Confirms); client.Metrics.ResetIncrementalMetrics(); } }
public void FillParameters(ServiceEventMessage message) { Dictionary <string, long> metrics = new Dictionary <string, long>(); message.Parameters.Add("Metrics", _Metrics); }
public void ObservationNotify(LWM2MClient client, Model.Object lwm2mObject) { if (client.OrganisationID != 0) { ServiceEventMessage message = new ServiceEventMessage(); FillDeviceParameters(client, message); message.Parameters.Add("Object", lwm2mObject); BusinessLogicFactory.ServiceMessages.Publish(RouteKeys.OBSERVATION_NOTIFICATION, message, TMessagePublishMode.Confirms); } }
public void Serialise(ServiceEventMessage message) { _Serialiser.Serialize(_JsonWriter, message); _JsonWriter.Flush(); }
public void AckMessage(ServiceEventMessage message) { for (int index = 0; index < _ServerCount; index++) { _Subscriptions[index].AckMessage(message); } }
public void Start() { CoAP.Log.LogManager.Level = CoAP.Log.LogLevel.Error; int port; string apiPort = System.Configuration.ConfigurationManager.AppSettings["APIPort"]; if (!int.TryParse(apiPort, out port)) port = 14080; _ProcessRequestsThread = new Thread(new ThreadStart(ProcessRequests)); if (_ProcessRequestsThread.Name == null) _ProcessRequestsThread.Name = "ProcessRequestsThread"; _ProcessRequestsThread.IsBackground = true; _ProcessRequestsThread.Start(); if (_CoapServer == null) { _CoapServer = new CoapServer(); _CoapServer.MessageDeliverer = this; if (!SecureOnly) _CoapServer.AddEndPoint(new CoAPEndPoint(new FlowChannel(Port), CoapConfig.Default)); _SecureChannel = new FlowSecureChannel(Port + 1); if (System.IO.File.Exists("LWM2MServer.pem")) { _SecureChannel.CertificateFile = "LWM2MServer.pem"; } _SecureChannel.PSKIdentities = _PSKIdentities; _SecureChannel.SupportedCipherSuites.Add(TCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8); _SecureChannel.SupportedCipherSuites.Add(TCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256); _SecureChannel.SupportedCipherSuites.Add(TCipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256); _SecureChannel.SupportedCipherSuites.Add(TCipherSuite.TLS_PSK_WITH_AES_128_CCM_8); _SecureChannel.SupportedCipherSuites.Add(TCipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256); _SecureChannel.ValidatePSK += new EventHandler<ValidatePSKEventArgs>(ValidatePSK); _CoapServer.AddEndPoint(new CoAPEndPoint(_SecureChannel, CoapConfig.Default)); } _CoapServer.Start(); ServiceEventMessage message = new ServiceEventMessage(); Imagination.Model.LWM2MServer lwm2mServer = new Imagination.Model.LWM2MServer(); lwm2mServer.Url = ServiceConfiguration.ExternalUri.ToString(); message.AddParameter("Server", lwm2mServer); BusinessLogicFactory.ServiceMessages.Publish("LWM2MServer.Start", message, TMessagePublishMode.Confirms); _ServerEndPoint = string.Concat("net.tcp://", ServiceConfiguration.Hostname, ":", port.ToString(), "/LWM2MServerService"); if (_NativeServerAPI == null) _NativeServerAPI = new NativeIPCServer(AddressFamily.InterNetwork,port); _NativeServerAPI.Start(); if (_NativeServerAPIv6 == null) _NativeServerAPIv6 = new NativeIPCServer(AddressFamily.InterNetworkV6, port); _NativeServerAPIv6.Start(); //if (_ServiceHost != null) // _ServiceHost.Close(); //_ServiceHost = new ServiceHost(typeof(Imagination.Service.ServerAPI)); //ServiceThrottlingBehavior throttle = _ServiceHost.Description.Behaviors.Find<ServiceThrottlingBehavior>(); //if (throttle == null) //{ // throttle = new ServiceThrottlingBehavior // { // MaxConcurrentCalls = 100, // MaxConcurrentSessions = 100, // MaxConcurrentInstances = int.MaxValue // }; // _ServiceHost.Description.Behaviors.Add(throttle); //} //else //{ // throttle.MaxConcurrentCalls = 100; // throttle.MaxConcurrentSessions = 100; // throttle.MaxConcurrentInstances = int.MaxValue; //} //NetTcpBinding netTcpBinding = new NetTcpBinding(); //_ServiceHost.AddServiceEndpoint(typeof(Imagination.Service.ILWM2MServerService), netTcpBinding, _ServerEndPoint); ////int newLimit = _ServiceHost.IncrementManualFlowControlLimit(100); //_ServiceHost.Open(); }
private static Subscription GetSubscriptionFromMessage(ServiceEventMessage message) { return DataAccessFactory.Subscriptions.GetSubscription(StringUtils.GuidDecode((string)message.Parameters["SubscriptionID"])); }