private ActionResult ModifyState(ClientSubscription clientSubscription, ClientSubscriptionState state)
        {
            if (ModelState.IsValid)
            {
                DateTime           time         = clientSubscription.Timestamp;
                ClientSubscription subscription = db.ClientSubscriptions.Find(clientSubscription.ClientSubscriptionId);
                long clientAccountId            = subscription.ClientAccountId;
                subscription.State     = state;
                subscription.Timestamp = DateTime.Now;
                subscription.Notes     = clientSubscription.Notes;

                db.Entry(subscription).State = EntityState.Modified;

                var clientSubscriptionHistory = new ClientSubscriptionHistory()
                {
                    UnitPrice            = subscription.UnitPrice,
                    State                = state,
                    Quantity             = subscription.CurrentQuantity,
                    Notes                = subscription.Notes,
                    VesselName           = subscription.VesselName,
                    ClientSubscriptionId = subscription.ClientSubscriptionId,
                    Timestamp            = time
                };

                db.ClientSubscriptionHistories.Add(clientSubscriptionHistory);

                db.SaveChanges();
                return(RedirectToAction("Index", new { accountId = clientAccountId }));
            }

            return(View("Invalid state."));
        }
        public async Task ClientSubscription_FromQueryData_GeneralPropertyCheck()
        {
            var testServer = new TestServerBuilder()
                             .AddGraphController <ClientSubscriptionTestController>()
                             .AddSubscriptionServer()
                             .Build();

            var schema    = testServer.Schema;
            var subServer = testServer.RetrieveSubscriptionServer();
            var queryPlan = await testServer.CreateQueryPlan("subscription { watchObjects { property1 property2  }} ");

            Assert.AreEqual(1, queryPlan.Operations.Count);
            Assert.AreEqual(0, queryPlan.Messages.Count);

            var field = queryPlan.Operations.Values.First().FieldContexts[0].Field;
            var name  = field.GetType().FullName;

            (var socketClient, var testClient) = await testServer.CreateSubscriptionClient();

            var queryData = new GraphQueryData();

            var sub = new ClientSubscription <GraphSchema>(
                testClient,
                queryData,
                queryPlan,
                queryPlan.Operations.First().Value,
                "abc123");

            Assert.IsTrue(sub.IsValid);
            Assert.AreEqual("[subscription]/WatchObjects", sub.Route.Path);
            Assert.AreEqual("abc123", sub.Id);
            Assert.AreEqual(field, sub.Field);
            Assert.AreEqual(testClient, sub.Client);
            Assert.AreEqual(queryData, sub.QueryData);
        }
        public ActionResult Deliver(long?id)
        {
            if (id == null)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }
            ClientSubscription clientSubscription = db.ClientSubscriptions.Find(id);

            if (clientSubscription == null)
            {
                return(HttpNotFound());
            }

            ClientSubscriptionDeliverViewModel model = new ClientSubscriptionDeliverViewModel()
            {
                ClientAccountId      = clientSubscription.ClientAccountId,
                ClientSubscriptionId = clientSubscription.ClientSubscriptionId,
                ClientAccountName    = clientSubscription.Client.ClientAccountName,
                VesselName           = clientSubscription.VesselName,
                StationAccountName   = clientSubscription.Station.StationName,
                Quantity             = clientSubscription.CurrentQuantity
            };

            return(View(model));
        }
        // GET: ClientSubscriptions/Pay/5
        public ActionResult Pay(long?id)
        {
            if (id == null)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }
            ClientSubscription clientSubscription = db.ClientSubscriptions.Find(id);

            if (clientSubscription == null)
            {
                return(HttpNotFound());
            }

            var client = db.ClientAccounts.Find(clientSubscription.ClientAccountId);

            if (client == null)
            {
                return(HttpNotFound());
            }

            if (client.Balance < clientSubscription.UnitPrice * clientSubscription.StartQuantity)
            {
                return(View("The balance is not enough to pay the subscription."));
            }

            return(View(clientSubscription));
        }
        public IHttpActionResult Subscribe([FromBody] ClientSubscription subscription)
        {
            // save this subscription into the database
            if (ModelState.IsValid)
            {
                var pushSub = new PushSubscription
                {
                    Username = "******",
                    Url      = subscription.Endpoint,
                    P256dh   = subscription.Keys.P256dh,
                    Auth     = subscription.Keys.Auth
                };

                db.PushSubscriptions.Add(pushSub);
                db.SaveChanges();

                var data = new { data = new { success = true } };

                return(Ok(data));
            }
            else
            {
                return(BadRequest(ModelState));
            }
        }
        public async Task ClientSubscription_NoFieldContextFound_ReturnsError()
        {
            var testServer = new TestServerBuilder()
                             .AddGraphController <ClientSubscriptionTestController>()
                             .AddSubscriptionServer()
                             .Build();

            var fakePlan         = new Mock <IGraphQueryPlan>();
            var fakeOp           = new Mock <IGraphFieldExecutableOperation>();
            var fakeFieldContext = new Mock <IGraphFieldInvocationContext>();

            fakeFieldContext.Setup(x => x.Field).Returns(null as IGraphField);

            var fakeFieldContexts = new Mock <IFieldInvocationContextCollection>();

            fakeFieldContexts.Setup(x => x[It.IsAny <int>()]).Returns(fakeFieldContext.Object);

            fakeOp.Setup(x => x.OperationType).Returns(GraphCollection.Subscription);
            fakeOp.Setup(x => x.FieldContexts).Returns(fakeFieldContexts.Object);

            (var socketClient, var testClient) = await testServer.CreateSubscriptionClient();

            var sub = new ClientSubscription <GraphSchema>(
                testClient,
                GraphQueryData.Empty,
                fakePlan.Object,
                fakeOp.Object,
                "abc123");

            Assert.IsFalse(sub.IsValid);
            Assert.AreEqual(1, sub.Messages.Count);
            Assert.AreEqual(Constants.ErrorCodes.BAD_REQUEST, sub.Messages[0].Code);
            Assert.IsTrue(sub.Messages.Severity.IsCritical());
        }
Example #7
0
        public async Task ExecuteAsync(string clientId, IPacket input, IMqttChannel <IPacket> channel)
        {
            if (input.Type != MqttPacketType.Unsubscribe)
            {
                return;
            }

            Unsubscribe   unsubscribe = input as Unsubscribe;
            ClientSession session     = _sessionRepository.Read(clientId);

            if (session == null)
            {
                throw new MqttException(ServerProperties.SessionRepository_ClientSessionNotFound(clientId));
            }

            foreach (string topic in unsubscribe.Topics)
            {
                ClientSubscription subscription = session.GetSubscriptions().FirstOrDefault(s => s.TopicFilter == topic);

                if (subscription != null)
                {
                    session.RemoveSubscription(subscription);
                }
            }

            _sessionRepository.Update(session);

            await channel.SendAsync(new UnsubscribeAck( unsubscribe.PacketId ));
        }
Example #8
0
        public async Task <Func <Task> > Subscribe <TEventArgs>(string eventName, EventHandler <TEventArgs> eventHandler, Dictionary <string, string> eventFilter = null)
            where TEventArgs : EventArgs
        {
            // match event name with the argument type
            MessageTypeProvider.Register(eventName, typeof(TEventArgs));

            // prepare subscription metadata
            var subscription = new ClientSubscription <TEventArgs>
            {
                SubscriptionId = GenerateMessageId(),
                EventName      = eventName,
                EventFilter    = eventFilter,
                EventHandler   = eventHandler,
            };

            // notify the server about the new subscription
            var subscrMessage = subscription.CreateSubscriptionMessage();

            await Call(subscrMessage);

            // register subscription in the subscription manager
            var unsubscribe  = SubscriptionManager.Add(subscription);
            var unsubMessage = subscription.CreateUnsubscriptionMessage();

            // return unsubscription action
            return(async() =>
            {
                unsubscribe();
                await Call(unsubMessage);
            });
        }
        public ActionResult DeleteConfirmed(long id)
        {
            ClientSubscription clientSubscription = db.ClientSubscriptions.Find(id);
            long clientAccountId = clientSubscription.ClientAccountId;

            db.ClientSubscriptions.Remove(clientSubscription);
            db.SaveChanges();
            return(RedirectToAction("Index", new { accountId = clientAccountId }));
        }
Example #10
0
        public async Task <IActionResult> Unsubscribe([FromBody] ClientSubscription sub)
        {
            //var user = await _userManager.GetUserAsync(User);
            var user = await db.Users.FirstOrDefaultAsync();

            var subscription = await db.Subscriptions.FirstOrDefaultAsync(s => s.UserId == user.UserId && s.auth == sub.keys.auth);

            db.Subscriptions.Remove(subscription);
            await db.SaveChangesAsync();

            return(Ok());
        }
        public ActionResult PayConfirmed([Bind(Include = "ClientSubscriptionId, Notes, Timestamp")] ClientSubscription subscription)
        {
            if (ModelState.IsValid)
            {
                DateTime time = subscription.Timestamp;

                ClientSubscription clientSubscription = db.ClientSubscriptions.Find(subscription.ClientSubscriptionId);
                long          clientAccountId         = clientSubscription.ClientAccountId;
                ClientAccount client = db.ClientAccounts.Find(clientAccountId);

                if (client.Balance >= clientSubscription.UnitPrice * clientSubscription.StartQuantity)
                {
                    clientSubscription.State           = ClientSubscriptionState.Paid;
                    db.Entry(clientSubscription).State = EntityState.Modified;
                    client.Balance -= clientSubscription.UnitPrice * clientSubscription.StartQuantity;
                    clientSubscription.Timestamp = time;
                    db.Entry(client).State       = EntityState.Modified;

                    var clientSubscriptionHistory = new ClientSubscriptionHistory()
                    {
                        UnitPrice            = clientSubscription.UnitPrice,
                        State                = ClientSubscriptionState.Paid,
                        Quantity             = clientSubscription.StartQuantity,
                        VesselName           = subscription.VesselName,
                        Notes                = clientSubscription.Notes,
                        ClientSubscriptionId = clientSubscription.ClientSubscriptionId,
                        Timestamp            = time
                    };

                    db.ClientSubscriptionHistories.Add(clientSubscriptionHistory);

                    var clientBalanceHistory = new ClientBalanceHistory()
                    {
                        Amount          = clientSubscription.UnitPrice * clientSubscription.StartQuantity * -1,
                        BalanceType     = BalanceChangeType.Pay,
                        ClientAccountId = clientAccountId,
                        Description     = string.Format("Pay for Subscription: {0}.", subscription.ClientSubscriptionId),
                        Timestamp       = time
                    };

                    db.ClientBalanceHistories.Add(clientBalanceHistory);

                    db.SaveChanges();
                    return(RedirectToAction("Index", new { accountId = clientAccountId }));
                }

                return(View("The balance is not enough to pay the subscription."));
            }

            return(View("The state is not valid."));
        }
        /// <summary>
        /// Client Manager Class Initaliser
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="EndpointURL"></param>
        /// <param name="OPCItems"></param>
        /// <param name="AutoAccept"></param>
        public ClientController(string ApplicationName, string EndpointURL, List <DataItem> OPCItems, bool AutoAccept)
        {
            opcItems        = OPCItems;
            applicationName = ApplicationName;
            endpointURL     = EndpointURL;
            autoAccept      = AutoAccept;

            opcSession = new ClientSession(applicationName, endpointURL, autoAccept).Execute();

            ClientSubscription clientSubscription = new ClientSubscription(opcSession);

            clientSubscription.OnNotificationEventHandler += (sender, e) => OnClientSubscriptionNotificationEventHandler(sender, e);
            clientSubscription.Execute(opcItems);
        }
        // GET: ClientSubscriptions/Details/5
        public ActionResult Details(long?id)
        {
            if (id == null)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }
            ClientSubscription clientSubscription = db.ClientSubscriptions.Find(id);

            if (clientSubscription == null)
            {
                return(HttpNotFound());
            }
            return(View(clientSubscription));
        }
        private ActionResult GetSnapshot(long?id)
        {
            if (id == null)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }
            ClientSubscription clientSubscription = db.ClientSubscriptions.Find(id);

            if (clientSubscription == null)
            {
                return(HttpNotFound());
            }
            return(View(clientSubscription));
        }
Example #15
0
        async Task DispatchAsync(Publish publish, ClientSubscription subscription, bool isWill = false)
        {
            MqttQualityOfService requestedQos = isWill ? publish.QualityOfService : subscription.MaximumQualityOfService;
            MqttQualityOfService supportedQos = configuration.GetSupportedQos(requestedQos);
            bool    retain              = isWill ? publish.Retain : false;
            ushort? packetId            = supportedQos == MqttQualityOfService.AtMostOnce ? null : (ushort?)_packetIdProvider.GetPacketId();
            Publish subscriptionPublish = new Publish(publish.Topic, supportedQos, retain, duplicated: false, packetId: packetId)
            {
                Payload = publish.Payload
            };
            IMqttChannel <IPacket> clientChannel = _connectionProvider.GetConnection(subscription.ClientId);

            await _senderFlow.SendPublishAsync(subscription.ClientId, subscriptionPublish, clientChannel);
        }
Example #16
0
        async Task DispatchAsync(Publish publish, ClientSubscription subscription, bool isWill = false)
        {
            var    requestedQos        = isWill ? publish.QualityOfService : subscription.MaximumQualityOfService;
            var    supportedQos        = configuration.GetSupportedQos(requestedQos);
            var    retain              = isWill ? publish.Retain : false;
            ushort?packetId            = supportedQos == MqttQualityOfService.AtMostOnce ? null : (ushort?)packetIdProvider.GetPacketId();
            var    subscriptionPublish = new Publish(publish.Topic, supportedQos, retain, duplicated: false, packetId: packetId)
            {
                Payload = publish.Payload
            };
            var clientChannel = connectionProvider.GetConnection(subscription.ClientId);

            await senderFlow.SendPublishAsync(subscription.ClientId, subscriptionPublish, clientChannel)
            .ConfigureAwait(continueOnCapturedContext: false);
        }
Example #17
0
        public async Task <IActionResult> Subscribe([FromBody] ClientSubscription sub)
        {
            //var user = await _userManager.GetUserAsync(User);
            var user = await db.Users.FirstOrDefaultAsync();

            var subscription = new Subscription
            {
                UserId   = user.UserId,
                p256dh   = sub.keys.p256dh,
                auth     = sub.keys.auth,
                endpoint = sub.endpoint
            };

            db.Subscriptions.Add(subscription);
            await db.SaveChangesAsync();

            return(Ok(subscription));
        }
        public ActionResult Create([Bind(Include = "ClientAccountId,StationAccountId, VesselName, Quantity,UnitPrice,Notes,Timestamp")] ClientSubscriptionViewModel clientSubscriptionViewModel)
        {
            if (ModelState.IsValid)
            {
                DateTime time = clientSubscriptionViewModel.Timestamp;

                var clientSubscription = new ClientSubscription()
                {
                    UnitPrice        = clientSubscriptionViewModel.UnitPrice,
                    State            = ClientSubscriptionState.Created,
                    StartQuantity    = clientSubscriptionViewModel.Quantity,
                    CurrentQuantity  = clientSubscriptionViewModel.Quantity,
                    ClientAccountId  = clientSubscriptionViewModel.ClientAccountId,
                    Notes            = clientSubscriptionViewModel.Notes,
                    VesselName       = clientSubscriptionViewModel.VesselName,
                    StationAccountId = int.Parse(clientSubscriptionViewModel.StationAccountId),
                    Timestamp        = time
                };

                db.ClientSubscriptions.Add(clientSubscription);



                db.SaveChanges();

                var clientSubscriptionHistory = new ClientSubscriptionHistory()
                {
                    UnitPrice            = clientSubscriptionViewModel.UnitPrice,
                    State                = ClientSubscriptionState.Created,
                    Quantity             = clientSubscriptionViewModel.Quantity,
                    Notes                = clientSubscriptionViewModel.Notes,
                    VesselName           = clientSubscriptionViewModel.VesselName,
                    ClientSubscriptionId = clientSubscription.ClientSubscriptionId,
                    Timestamp            = time
                };

                db.ClientSubscriptionHistories.Add(clientSubscriptionHistory);
                db.SaveChanges();

                return(RedirectToAction("Index", new { accountId = clientSubscriptionViewModel.ClientAccountId }));
            }

            return(View(clientSubscriptionViewModel));
        }
        public ActionResult DeliverConfirmed([Bind(Include = "ClientSubscriptionId, Quantity, Notes")] ClientSubscriptionDeliverViewModel model)
        {
            if (ModelState.IsValid)
            {
                DateTime           time         = DateTime.Now;
                ClientSubscription subscription = db.ClientSubscriptions.Find(model.ClientSubscriptionId);
                long clientAccountId            = subscription.ClientAccountId;

                float leftQuantity = subscription.CurrentQuantity - model.Quantity;

                if (leftQuantity == 0)
                {
                    subscription.State = ClientSubscriptionState.Delivered;
                }
                else
                {
                    subscription.State = ClientSubscriptionState.PartialDelivered;
                }

                subscription.CurrentQuantity = leftQuantity;
                subscription.Timestamp       = time;
                subscription.Notes           = model.Notes;

                db.Entry(subscription).State = EntityState.Modified;

                var clientSubscriptionHistory = new ClientSubscriptionHistory()
                {
                    UnitPrice            = subscription.UnitPrice,
                    State                = subscription.State,
                    Quantity             = model.Quantity,
                    Notes                = model.Notes,
                    VesselName           = subscription.VesselName,
                    ClientSubscriptionId = subscription.ClientSubscriptionId,
                    Timestamp            = time
                };

                db.ClientSubscriptionHistories.Add(clientSubscriptionHistory);

                db.SaveChanges();
                return(RedirectToAction("Index", new { accountId = clientAccountId }));
            }

            return(View("Invalid state."));
        }
Example #20
0
        async Task SendRetainedMessagesAsync(ClientSubscription subscription, IMqttChannel <IPacket> channel)
        {
            var retainedMessages = retainedRepository.GetAll()
                                   .Where(r => topicEvaluator.Matches(r.Topic, subscription.TopicFilter));

            if (retainedMessages != null)
            {
                foreach (var retainedMessage in retainedMessages)
                {
                    ushort?packetId = subscription.MaximumQualityOfService == MqttQualityOfService.AtMostOnce ?
                                      null : (ushort?)packetIdProvider.GetPacketId();
                    var publish = new Publish(retainedMessage.Topic, subscription.MaximumQualityOfService,
                                              retain: true, duplicated: false, packetId: packetId)
                    {
                        Payload = retainedMessage.Payload
                    };

                    await senderFlow.SendPublishAsync(subscription.ClientId, publish, channel)
                    .ConfigureAwait(continueOnCapturedContext: false);
                }
            }
        }
Example #21
0
        public void SubscribeAndUnsubscribeClientSubscription()
        {
            var firedCounter = 0;
            var cancel       = false;

            void handler(object s, CancelEventArgs e)
            {
                firedCounter++;
                cancel = e.Cancel;
            }

            var subscription = new ClientSubscription <CancelEventArgs>
            {
                SubscriptionId = "1",
                EventHandler   = handler,
                EventName      = EventName,
            };

            var unsubscribe = SubscriptionManager.Add(subscription);

            Assert.AreEqual(0, firedCounter);
            Assert.IsFalse(cancel);

            SubscriptionManager.Broadcast(EventName, new CancelEventArgs(true));
            Assert.AreEqual(1, firedCounter);
            Assert.IsTrue(cancel);

            SubscriptionManager.Broadcast(EventName, new CancelEventArgs(false));
            Assert.AreEqual(2, firedCounter);
            Assert.IsFalse(cancel);

            unsubscribe();
            SubscriptionManager.Broadcast(EventName, new CancelEventArgs(true));

            // event wasn't fired
            Assert.AreEqual(2, firedCounter);
            Assert.IsFalse(cancel);
        }
Example #22
0
        async Task SendRetainedMessagesAsync(ClientSubscription subscription, IMqttChannel <IPacket> channel)
        {
            IEnumerable <RetainedMessage> retainedMessages = _retainedRepository
                                                             .ReadAll()
                                                             .Where(r => _topicEvaluator.Matches(topicName: r.Id, topicFilter: subscription.TopicFilter));

            if (retainedMessages != null)
            {
                foreach (RetainedMessage retainedMessage in retainedMessages)
                {
                    ushort?packetId = subscription.MaximumQualityOfService == MqttQualityOfService.AtMostOnce ?
                                      null : (ushort?)_packetIdProvider.GetPacketId();
                    Publish publish = new Publish(topic: retainedMessage.Id,
                                                  qualityOfService: subscription.MaximumQualityOfService,
                                                  retain: true, duplicated: false, packetId: packetId)
                    {
                        Payload = retainedMessage.Payload
                    };

                    await _senderFlow.SendPublishAsync(subscription.ClientId, publish, channel);
                }
            }
        }
Example #23
0
        public async Task ExecuteAsync(string clientId, IPacket input, IMqttChannel <IPacket> channel)
        {
            if (input.Type != MqttPacketType.Subscribe)
            {
                return;
            }

            Subscribe     subscribe = input as Subscribe;
            ClientSession session   = _sessionRepository.Read(clientId);

            if (session == null)
            {
                throw new MqttException(ServerProperties.SessionRepository_ClientSessionNotFound(clientId));
            }

            List <SubscribeReturnCode> returnCodes = new List <SubscribeReturnCode>();

            foreach (Subscription subscription in subscribe.Subscriptions)
            {
                try
                {
                    if (!_topicEvaluator.IsValidTopicFilter(subscription.TopicFilter))
                    {
                        _tracer.Error(ServerProperties.ServerSubscribeFlow_InvalidTopicSubscription(subscription.TopicFilter, clientId));

                        returnCodes.Add(SubscribeReturnCode.Failure);
                        continue;
                    }

                    ClientSubscription clientSubscription = session
                                                            .GetSubscriptions()
                                                            .FirstOrDefault(s => s.TopicFilter == subscription.TopicFilter);

                    if (clientSubscription != null)
                    {
                        clientSubscription.MaximumQualityOfService = subscription.MaximumQualityOfService;
                    }
                    else
                    {
                        clientSubscription = new ClientSubscription
                        {
                            ClientId                = clientId,
                            TopicFilter             = subscription.TopicFilter,
                            MaximumQualityOfService = subscription.MaximumQualityOfService
                        };

                        session.AddSubscription(clientSubscription);
                    }

                    await SendRetainedMessagesAsync(clientSubscription, channel);

                    MqttQualityOfService supportedQos = _configuration.GetSupportedQos(subscription.MaximumQualityOfService);
                    SubscribeReturnCode  returnCode   = supportedQos.ToReturnCode();

                    returnCodes.Add(returnCode);
                }
                catch (RepositoryException repoEx)
                {
                    _tracer.Error(repoEx, ServerProperties.ServerSubscribeFlow_ErrorOnSubscription(clientId, subscription.TopicFilter));

                    returnCodes.Add(SubscribeReturnCode.Failure);
                }
            }

            _sessionRepository.Update(session);

            await channel.SendAsync(new SubscribeAck( subscribe.PacketId, returnCodes.ToArray()));
        }
Example #24
0
        public async Task ExecuteAsync(string clientId, IPacket input, IMqttChannel <IPacket> channel)
        {
            if (input.Type != MqttPacketType.Subscribe)
            {
                return;
            }

            var subscribe = input as Subscribe;
            var session   = sessionRepository.Read(clientId);

            if (session == null)
            {
                throw new MqttException(string.Format(Properties.Resources.SessionRepository_ClientSessionNotFound, clientId));
            }

            var returnCodes = new List <SubscribeReturnCode> ();

            foreach (var subscription in subscribe.Subscriptions)
            {
                try {
                    if (!topicEvaluator.IsValidTopicFilter(subscription.TopicFilter))
                    {
                        tracer.Error(Server.Properties.Resources.ServerSubscribeFlow_InvalidTopicSubscription, subscription.TopicFilter, clientId);

                        returnCodes.Add(SubscribeReturnCode.Failure);
                        continue;
                    }

                    var clientSubscription = session
                                             .GetSubscriptions()
                                             .FirstOrDefault(s => s.TopicFilter == subscription.TopicFilter);

                    if (clientSubscription != null)
                    {
                        clientSubscription.MaximumQualityOfService = subscription.MaximumQualityOfService;
                    }
                    else
                    {
                        Console.WriteLine("Client just connected: " + clientId + " " + subscription.TopicFilter);
                        clientSubscription = new ClientSubscription {
                            ClientId                = clientId,
                            TopicFilter             = subscription.TopicFilter,
                            MaximumQualityOfService = subscription.MaximumQualityOfService
                        };

                        session.AddSubscription(clientSubscription);
                    }

                    await SendRetainedMessagesAsync(clientSubscription, channel)
                    .ConfigureAwait(continueOnCapturedContext: false);

                    var supportedQos = configuration.GetSupportedQos(subscription.MaximumQualityOfService);
                    var returnCode   = supportedQos.ToReturnCode();

                    returnCodes.Add(returnCode);
                } catch (RepositoryException repoEx) {
                    tracer.Error(repoEx, Server.Properties.Resources.ServerSubscribeFlow_ErrorOnSubscription, clientId, subscription.TopicFilter);

                    returnCodes.Add(SubscribeReturnCode.Failure);
                }
            }

            sessionRepository.Update(session);

            await channel.SendAsync(new SubscribeAck (subscribe.PacketId, returnCodes.ToArray()))
            .ConfigureAwait(continueOnCapturedContext: false);
        }
        public ActionResult DeliverConfirmed([Bind(Include = "SubscriptionId, Quantity,ClientSubscriptionId, Notes, Timestamp")] SubscriptionDeliverViewModel model)
        {
            if (ModelState.IsValid)
            {
                DateTime           time         = model.Timestamp;
                Subscription       subscription = db.Subscriptions.Find(model.SubscriptionId);
                ClientSubscription cs           = db.ClientSubscriptions.Find(model.ClientSubscriptionId);
                long csId = cs.ClientSubscriptionId;

                if (cs.State != ClientSubscriptionState.Paid)
                {
                    if (cs.State != ClientSubscriptionState.PartialDelivered)
                    {
                        throw new Exception("The client subscription state must be 'paid'.");
                    }
                }

                if (cs.StationAccountId != subscription.StationAccountId)
                {
                    throw new Exception("The station does not match.");
                }

                string clientAccountName = cs.Client.ClientAccountName;
                string vesselName        = cs.VesselName;


                long accountId = subscription.StationAccountId;

                float leftQuantity = subscription.CurrentQuantity - model.Quantity;

                if (leftQuantity == 0)
                {
                    subscription.State = SubscriptionState.Delivered;
                }
                else
                {
                    subscription.State = SubscriptionState.PartialDelivered;
                }

                subscription.CurrentQuantity = leftQuantity;
                subscription.Timestamp       = time;
                subscription.Notes           = model.Notes;

                db.Entry(subscription).State = EntityState.Modified;

                var subscriptionHistory = new SubscriptionHistory()
                {
                    UnitPrice            = subscription.UnitPrice,
                    State                = subscription.State,
                    Quantity             = model.Quantity,
                    Notes                = model.Notes,
                    ClientSubscriptionId = model.ClientSubscriptionId,
                    ClientAccountName    = clientAccountName,
                    VesselName           = vesselName,
                    SubscriptionId       = subscription.SubscriptionId,
                    Timestamp            = time
                };

                db.SubscriptionHistories.Add(subscriptionHistory);

                float csLeftQuantity = cs.CurrentQuantity - model.Quantity;

                if (csLeftQuantity == 0)
                {
                    cs.State = ClientSubscriptionState.Delivered;
                }
                else
                {
                    cs.State = ClientSubscriptionState.PartialDelivered;
                }

                cs.CurrentQuantity = csLeftQuantity;
                cs.Timestamp       = time;
                cs.Notes           = model.Notes;

                db.Entry(cs).State = EntityState.Modified;

                var clientSubscriptionHistory = new ClientSubscriptionHistory()
                {
                    UnitPrice            = subscription.UnitPrice,
                    State                = cs.State,
                    Quantity             = model.Quantity,
                    Notes                = model.Notes,
                    VesselName           = vesselName,
                    ClientSubscriptionId = cs.ClientSubscriptionId,
                    Timestamp            = time
                };

                db.ClientSubscriptionHistories.Add(clientSubscriptionHistory);

                db.SaveChanges();
                return(RedirectToAction("Index", new { accountId = accountId }));
            }

            return(View("Invalid state."));
        }
 public ActionResult CloseConfirmed([Bind(Include = "ClientSubscriptionId, Notes, Timestamp")] ClientSubscription clientSubscription)
 {
     return(ModifyState(clientSubscription, ClientSubscriptionState.Closed));
 }