/// <summary>
        /// Notifies the connected digital shelf/shelves when a shopping cart has been manipulated in the It-System.
        /// </summary>
        /// <param name="shoppingCart">The shopping cart that has been manipulated.</param>
        /// <returns><c>true</c> if the shopping cart update message was sent successfully, <c>false</c> otherwise.</returns>
        public bool UpdateShoppingCart(IShoppingCart shoppingCart)
        {
            if (shoppingCart == null)
            {
                throw new ArgumentException("No shopping cart specified.");
            }

            if (!this.Connected)
            {
                throw new InvalidOperationException("The digital shelf is currently not connected.");
            }

            var message = new ShoppingCartUpdateMessageEnvelope()
            {
                ShoppingCartUpdateMessage = new ShoppingCartUpdateMessage()
                {
                    Id           = MessageId.Next,
                    Destination  = _destinationId,
                    Source       = SubscriberID,
                    ShoppingCart = (ShoppingCart)shoppingCart
                }
            };

            if (!_messageObjectStream.Write(message))
            {
                throw new ApplicationException("Sending 'ShoppingCartUpdateMessage' to digital shelf failed.");
            }

            return(true);
        }
Esempio n. 2
0
        /// <summary>
        /// Sends the specified message envelope and waits for the response in form of the specified message type.
        /// </summary>
        /// <param name="messageEnvelope">The message envelope to send.</param>
        /// <param name="messageId">The message identifier to use while waiting for the response.</param>
        /// <param name="responseType">The type of the response message to wait for.</param>
        /// <param name="waitTimeoutMilliseconds">The wait timeout milliseconds.</param>
        /// <returns>
        /// Requested response message if it was received; null otherwise.
        /// </returns>
        public MessageBase SendAndWaitForResponse(object messageEnvelope,
                                                  string messageId,
                                                  Type responseType,
                                                  int waitTimeoutMilliseconds = 0)
        {
            if (messageEnvelope == null)
            {
                throw new ArgumentException("Invalid messageEnvelope specified.");
            }

            if (responseType == null)
            {
                throw new ArgumentException("Invalid responseType specified.");
            }

            MessageInterceptor interceptor = null;

            try
            {
                lock (_syncLock)
                {
                    if (_messageObjectStream == null)
                    {
                        return(null);
                    }

                    interceptor = new MessageInterceptor(messageId, responseType);
                    AddInterceptor(interceptor);

                    if (_messageObjectStream.Write(messageEnvelope) == false)
                    {
                        throw new ApplicationException(string.Format("Sending '{0}' to storage system failed.", messageEnvelope.GetType().Name));
                    }
                }

                if (waitTimeoutMilliseconds == 0)
                {
                    interceptor.Wait();
                    return(interceptor.Message);
                }
                else
                {
                    if (interceptor.Wait(waitTimeoutMilliseconds))
                    {
                        return(interceptor.Message);
                    }

                    return(null);
                }
            }
            finally
            {
                if (interceptor != null)
                {
                    RemoveInterceptor(interceptor);
                    interceptor.Dispose();
                }
            }
        }
        /// <summary>
        /// Sends the specified message envelope and waits for the response in form of the specified message type.
        /// </summary>
        /// <param name="messageEnvelope">The message envelope to send.</param>
        /// <param name="messageId">The message identifier to use while waiting for the response.</param>
        /// <param name="responseType">The type of the response message to wait for.</param>
        /// <param name="waitTimeoutMilliseconds">The wait timeout milliseconds.</param>
        /// <returns>
        /// Requested response message if it was received; null otherwise.
        /// </returns>
        public MessageBase SendAndWaitForResponse(object messageEnvelope,
                                                  string messageId,
                                                  Type responseType,
                                                  int waitTimeoutMilliseconds = 0)
        {
            if (messageEnvelope == null)
            {
                throw new ArgumentException("Invalid messageEnvelope specified.");
            }

            if (responseType == null)
            {
                throw new ArgumentException("Invalid responseType specified.");
            }

            MessageInterceptor interceptor = null;

            try
            {
                lock (_syncLock)
                {
                    if (_messageObjectStream == null)
                    {
                        return(null);
                    }

                    this.Trace("Initialize a new Message Interceptor and add it to the internal interceptor list.");
                    interceptor = new MessageInterceptor(messageId, responseType);
                    AddInterceptor(interceptor);

                    this.Trace($"Start sending {messageEnvelope.GetType().Name} to Storage System.");
                    if (_messageObjectStream.Write(messageEnvelope) == false)
                    {
                        throw new ApplicationException(string.Format("Sending '{0}' to storage system failed.", messageEnvelope.GetType().Name));
                    }
                }

                this.Trace("Waiting for the message interception notification and return the intercepted message.");
                if (waitTimeoutMilliseconds == 0)
                {
                    interceptor.Wait();
                    return(interceptor.Message);
                }
                else
                {
                    if (interceptor.Wait(waitTimeoutMilliseconds))
                    {
                        return(interceptor.Message);
                    }

                    return(null);
                }
            }
            finally
            {
                if (interceptor != null)
                {
                    RemoveInterceptor(interceptor);
                    interceptor.Dispose();
                }
            }
        }
        /// <summary>
        /// Reads the next Mosaic message from the underlying connection and returns it. This method will block until a new Mosaic message
        /// has been read, the converter stream has been cancelled or an error occurred.
        /// </summary>
        /// <returns>
        /// Read Mosaic message if successful; <c>null</c> otherwise.
        /// </returns>
        public MosaicMessage Read()
        {
            while (true)
            {
                IMessageConversion message = null;

                while (message == null)
                {
                    object readMessage = _objectStream.Read();

                    if (readMessage == null)
                    {
                        return(null);
                    }

                    if (readMessage.GetType() == typeof(KeepAliveRequestEnvelope))
                    {
                        var request  = (KeepAliveRequestEnvelope)readMessage;
                        var response = new KeepAliveResponseEnvelope()
                        {
                            KeepAliveResponse = new KeepAliveResponse()
                            {
                                Id          = request.KeepAliveRequest.Id,
                                Source      = _configuration.SubscriberID,
                                Destination = request.KeepAliveRequest.Source
                            }
                        };

                        if (_objectStream.Write(response) == false)
                        {
                            this.Error("Sending keep alive response with ID '{0}' failed.", request.KeepAliveRequest.Id);
                            return(null);
                        }

                        continue;
                    }

                    if (readMessage.GetType() == typeof(KeepAliveResponseEnvelope))
                    {
                        var response = (KeepAliveResponseEnvelope)readMessage;

                        if (TypeConverter.ConvertInt(response.KeepAliveResponse.Id) == _keepAliveID)
                        {
                            System.Threading.Interlocked.Exchange(ref _lastKeepAlive, 0);
                            continue;
                        }

                        this.Error("Received orphan keep alive response with ID '{0}' but expected ID '{1}'.",
                                   response.KeepAliveResponse.Id, _keepAliveID);
                        return(null);
                    }

                    message = readMessage as IMessageConversion;

                    if (message == null)
                    {
                        this.Error("Ignored unsupported message of type '{0}'.", readMessage.GetType().FullName);
                        continue;
                    }
                }

                var mosaicMessage = message.ToMosaicMessage(this);

                if (mosaicMessage != null)
                {
                    mosaicMessage.TenantID = _tenantID;
                }

                return(mosaicMessage);
            }
        }