Example #1
0
        public char ReadChar()
        {
            InitializeReading();

            try
            {
                long startingPos = this.byteBuffer.Position;
                try
                {
                    int type = this.dataIn.ReadByte();

                    if (type == PrimitiveMap.CHAR_TYPE)
                    {
                        return(this.dataIn.ReadChar());
                    }
                    else if (type == PrimitiveMap.NULL)
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new NMSException("Cannot convert Null type to a char");
                    }
                    else
                    {
                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                        throw new MessageFormatException("Value is not a Char type.");
                    }
                }
                catch (FormatException e)
                {
                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                    throw NMSExceptionSupport.CreateMessageFormatException(e);
                }
            }
            catch (EndOfStreamException e)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(e);
            }
            catch (IOException e)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
        }
        public object ReadObject()
        {
            FailIfWriteOnlyMsgBody();
            FailIfBytesInBuffer();
            object result = null;
            object value  = null;

            try
            {
                value = cloak.Peek();
                if (value == null)
                {
                    result = null;
                }
                else if (value is byte[])
                {
                    byte[] buffer = value as byte[];
                    result = new byte[buffer.Length];
                    Array.Copy(buffer, 0, result as byte[], 0, buffer.Length);
                }
                else if (ConversionSupport.IsNMSType(value))
                {
                    result = value;
                }
            }
            catch (EndOfStreamException eos)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(eos);
            }
            catch (IOException ioe)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(ioe);
            }
            catch (Exception e)
            {
                Tracer.InfoFormat("Unexpected exception caught reading Object stream. Exception = {0}", e);
                throw NMSExceptionSupport.Create("Unexpected exception caught reading Object stream.", e);
            }
            cloak.Pop();
            return(result);
        }
Example #3
0
 public void WriteString(string value)
 {
     InitializeWriting();
     try
     {
         if (value.Length > 8192)
         {
             this.dataOut.Write(PrimitiveMap.BIG_STRING_TYPE);
             this.dataOut.WriteString32(value);
         }
         else
         {
             this.dataOut.Write(PrimitiveMap.STRING_TYPE);
             this.dataOut.WriteString16(value);
         }
     }
     catch (IOException e)
     {
         NMSExceptionSupport.Create(e);
     }
 }
Example #4
0
        internal void OnAsyncException(Exception error)
        {
            if (!this.closed.Value && !this.closing.Value)
            {
                if (this.ExceptionListener != null)
                {
                    if (!(error is NMSException))
                    {
                        error = NMSExceptionSupport.Create(error);
                    }
                    NMSException e = (NMSException)error;

                    // Called in another thread so that processing can continue
                    // here, ensures no lock contention.
                    executor.QueueUserWorkItem(AsyncCallExceptionListener, e);
                }
                else
                {
                    Tracer.Debug("Async exception with no exception listener: " + error);
                }
            }
        }
Example #5
0
        /// <summary>
        /// Used to get an enqueued message from the unconsumedMessages list. The
        /// amount of time this method blocks is based on the timeout value.  if
        /// timeout == Timeout.Infinite then it blocks until a message is received.
        /// if timeout == 0 then it it tries to not block at all, it returns a
        /// message if it is available if timeout > 0 then it blocks up to timeout
        /// amount of time.  Expired messages will consumed by this method.
        /// </summary>
        /// <param name="timeout">
        /// A <see cref="System.TimeSpan"/>
        /// </param>
        /// <returns>
        /// A <see cref="MessageDispatch"/>
        /// </returns>
        private MessageDispatch Dequeue(TimeSpan timeout)
        {
            DateTime deadline = DateTime.Now;

            if (timeout > TimeSpan.Zero)
            {
                deadline += timeout;
            }

            while (true)
            {
                MessageDispatch dispatch = this.unconsumedMessages.Dequeue(timeout);

                // Grab a single date/time for calculations to avoid timing errors.
                DateTime dispatchTime = DateTime.Now;

                if (dispatch == null)
                {
                    if (timeout > TimeSpan.Zero && !this.unconsumedMessages.Closed)
                    {
                        if (dispatchTime > deadline)
                        {
                            // Out of time.
                            timeout = TimeSpan.Zero;
                        }
                        else
                        {
                            // Adjust the timeout to the remaining time.
                            timeout = deadline - dispatchTime;
                        }
                    }
                    else
                    {
                        // Informs the caller of an error in the event that an async exception
                        // took down the parent connection.
                        if (this.failureError != null)
                        {
                            throw NMSExceptionSupport.Create(this.failureError);
                        }

                        return(null);
                    }
                }
                else if (dispatch.Message == null)
                {
                    return(null);
                }
                else if (!IgnoreExpiration && dispatch.Message.IsExpired())
                {
                    Tracer.DebugFormat("{0} received expired message: {1}", info.ConsumerId, dispatch.Message.MessageId);

                    BeforeMessageIsConsumed(dispatch);
                    AfterMessageIsConsumed(dispatch, true);
                    // Refresh the dispatch time
                    dispatchTime = DateTime.Now;

                    if (timeout > TimeSpan.Zero && !this.unconsumedMessages.Closed)
                    {
                        if (dispatchTime > deadline)
                        {
                            // Out of time.
                            timeout = TimeSpan.Zero;
                        }
                        else
                        {
                            // Adjust the timeout to the remaining time.
                            timeout = deadline - dispatchTime;
                        }
                    }
                }
                else
                {
                    return(dispatch);
                }
            }
        }
Example #6
0
        public Object ReadObject()
        {
            InitializeReading();

            long startingPos = this.byteBuffer.Position;

            try
            {
                int type = this.dataIn.ReadByte();

                if (type == PrimitiveMap.BIG_STRING_TYPE)
                {
                    return(this.dataIn.ReadString32());
                }
                else if (type == PrimitiveMap.STRING_TYPE)
                {
                    return(this.dataIn.ReadString16());
                }
                else if (type == PrimitiveMap.LONG_TYPE)
                {
                    return(this.dataIn.ReadInt64());
                }
                else if (type == PrimitiveMap.INTEGER_TYPE)
                {
                    return(this.dataIn.ReadInt32());
                }
                else if (type == PrimitiveMap.SHORT_TYPE)
                {
                    return(this.dataIn.ReadInt16());
                }
                else if (type == PrimitiveMap.FLOAT_TYPE)
                {
                    return(this.dataIn.ReadSingle());
                }
                else if (type == PrimitiveMap.DOUBLE_TYPE)
                {
                    return(this.dataIn.ReadDouble());
                }
                else if (type == PrimitiveMap.CHAR_TYPE)
                {
                    return(this.dataIn.ReadChar());
                }
                else if (type == PrimitiveMap.BYTE_TYPE)
                {
                    return(this.dataIn.ReadByte());
                }
                else if (type == PrimitiveMap.BOOLEAN_TYPE)
                {
                    return(this.dataIn.ReadBoolean());
                }
                else if (type == PrimitiveMap.BYTE_ARRAY_TYPE)
                {
                    int    length = this.dataIn.ReadInt32();
                    byte[] data   = new byte[length];
                    this.dataIn.Read(data, 0, length);
                    return(data);
                }
                else if (type == PrimitiveMap.NULL)
                {
                    return(null);
                }
                else
                {
                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                    throw new MessageFormatException("Value is not a known type.");
                }
            }
            catch (FormatException e)
            {
                this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
            catch (EndOfStreamException e)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(e);
            }
            catch (IOException e)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
        }
        public string ReadString()
        {
            InitializeReading();

            long startingPos = this.byteBuffer.Position;

            try
            {
                int type = this.dataIn.ReadByte();

                switch (type)
                {
                case PrimitiveMap.BIG_STRING_TYPE:
                    return(this.dataIn.ReadString32());

                case PrimitiveMap.STRING_TYPE:
                    return(this.dataIn.ReadString16());

                case PrimitiveMap.LONG_TYPE:
                    return(this.dataIn.ReadInt64().ToString());

                case PrimitiveMap.INTEGER_TYPE:
                    return(this.dataIn.ReadInt32().ToString());

                case PrimitiveMap.SHORT_TYPE:
                    return(this.dataIn.ReadInt16().ToString());

                case PrimitiveMap.FLOAT_TYPE:
                    return(this.dataIn.ReadSingle().ToString());

                case PrimitiveMap.DOUBLE_TYPE:
                    return(this.dataIn.ReadDouble().ToString());

                case PrimitiveMap.CHAR_TYPE:
                    return(this.dataIn.ReadChar().ToString());

                case PrimitiveMap.BYTE_TYPE:
                    return(this.dataIn.ReadByte().ToString());

                case PrimitiveMap.BOOLEAN_TYPE:
                    return(this.dataIn.ReadBoolean().ToString());

                case PrimitiveMap.NULL:
                    return(null);

                default:
                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                    throw new MessageFormatException("Value is not a known type.");
                }
            }
            catch (FormatException e)
            {
                this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
            catch (EndOfStreamException e)
            {
                throw NMSExceptionSupport.CreateMessageEOFException(e);
            }
            catch (IOException e)
            {
                throw NMSExceptionSupport.CreateMessageFormatException(e);
            }
        }
        /// <summary>
        /// Sets the public properties of a target object using a string map.
        /// This method uses .Net reflection to access public properties of
        /// the target object matching the keys from the passed map.
        /// </summary>
        /// <param name="target">The object whose properties will be set.</param>
        /// <param name="valueMap">Map of key/value pairs.</param>
        /// <param name="nameMap">Map of key/property name pairs.</param>
        public static void SetProperties(object target,
                                         StringDictionary valueMap,
                                         StringDictionary nameMap)
        {
            Tracer.DebugFormat("SetProperties called with target: {0}",
                               target.GetType().Name);

            // Application of specified values is recursive. If a key does not
            // correspond to a member of the current target object, it is
            // supposed to refer to a sub-member of such a member. Since member
            // keys can contain dot characters, an attempt is made to find the
            // "longest" key corresponding to a member of the current object
            // (this identifies the "sub-target"), and extract the remaining
            // key characters as a sub-key to sub-members.
            // The following dictionary indexes keys to "sub-targets", and
            // "sub-key"/value pairs to assign to "sub-targets".
            Dictionary <string, StringDictionary> subTargetMap = null;

            foreach (string key in valueMap.Keys)
            {
                if (nameMap.ContainsKey(key))
                {
                    // Key refers to a member of the current target
                    string     memberName = nameMap[key];
                    MemberInfo member     = FindMemberInfo(target, memberName);
                    if (member == null)
                    {
                        // Should not happen if the nameMap was indeed created
                        // for the current target object...
                        throw new NMSException(string.Format(
                                                   "No such property or field: {0} on class: {1}",
                                                   memberName, target.GetType().Name));
                    }

                    // Set value
                    try
                    {
                        if (member.MemberType == MemberTypes.Property)
                        {
                            PropertyInfo property = (PropertyInfo)member;
                            object       value    = ConvertValue(valueMap[key],
                                                                 property.PropertyType);
                            property.SetValue(target, value, null);
                        }
                        else
                        {
                            FieldInfo field = (FieldInfo)member;
                            object    value = ConvertValue(valueMap[key],
                                                           field.FieldType);
                            field.SetValue(target, value);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw NMSExceptionSupport.Create(
                                  "Error while attempting to apply option.", ex);
                    }
                }
                else
                {
                    // Key does NOT refers to a member of the current target
                    // Extract maximal member key + subkeys
                    string memberKey   = key;
                    int    dotPos      = memberKey.LastIndexOf('.');
                    bool   memberFound = false;
                    while (!memberFound && dotPos > 0)
                    {
                        memberKey = memberKey.Substring(0, dotPos);
                        if (nameMap.ContainsKey(memberKey))
                        {
                            memberKey   = nameMap[memberKey];
                            memberFound = true;
                        }
                        else
                        {
                            dotPos = memberKey.LastIndexOf('.');
                        }
                    }

                    if (!memberFound)
                    {
                        throw new NMSException(string.Format(
                                                   "Unknown property or field: {0} on class: {1}",
                                                   key, target.GetType().Name));
                    }

                    // Register memberKey, subKey and value for further processing
                    string           subKey = key.Substring(dotPos + 1);
                    StringDictionary subValueMap;

                    if (subTargetMap == null)
                    {
                        subTargetMap = new Dictionary <string, StringDictionary>();
                    }

                    if (!subTargetMap.TryGetValue(memberKey, out subValueMap))
                    {
                        subValueMap = new StringDictionary();
                        subTargetMap.Add(memberKey, subValueMap);
                    }

                    // In theory, we can't have the same subkey twice, since
                    // they were unique subkeys from another dictionary.
                    // Therefore, no need to check for subValueMap.ContainsKey.
                    subValueMap.Add(subKey, valueMap[key]);
                }
            }

            // Now process any compound assignments.
            if (subTargetMap != null)
            {
                foreach (string subTargetKey in subTargetMap.Keys)
                {
                    MemberInfo member    = FindMemberInfo(target, subTargetKey);
                    object     subTarget = GetUnderlyingObject(member, target);
                    SetProperties(subTarget, subTargetMap[subTargetKey]);
                }
            }
        }
        private IMessage ReceiveInternal(int timeout)
        {
            try
            {
                long deadline = 0;
                if (timeout > 0)
                {
                    deadline = GetDeadline(timeout);
                }

                while (true)
                {
                    InboundMessageDispatch envelope = messageQueue.Dequeue(timeout);

                    if (failureCause != null)
                    {
                        throw NMSExceptionSupport.Create(failureCause);
                    }

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

                    if (IsMessageExpired(envelope))
                    {
                        if (Tracer.IsDebugEnabled)
                        {
                            Tracer.Debug($"{Info.Id} filtered expired message: {envelope.Message.NMSMessageId}");
                        }

                        DoAckExpired(envelope);

                        if (timeout > 0)
                        {
                            timeout = (int)Math.Max(deadline - DateTime.UtcNow.Ticks / 10_000L, 0);
                        }
                    }
                    else if (IsRedeliveryExceeded(envelope))
                    {
                        if (Tracer.IsDebugEnabled)
                        {
                            Tracer.Debug($"{Info.Id} filtered message with excessive redelivery count: {envelope.RedeliveryCount}");
                        }

                        // TODO: Apply redelivery policy
                        DoAckExpired(envelope);
                    }
                    else
                    {
                        if (Tracer.IsDebugEnabled)
                        {
                            Tracer.Debug($"{Info.Id}  received message {envelope.Message.NMSMessageId}.");
                        }

                        AckFromReceive(envelope);
                        return(envelope.Message.Copy());
                    }
                }
            }
            catch (NMSException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw ExceptionSupport.Wrap(ex, "Receive failed");
            }
        }
Example #10
0
        /// <summary>
        /// Sets the public properties of a target object using a string map.
        /// This method uses .Net reflection to identify public properties of
        /// the target object matching the keys from the passed map.
        /// </summary>
        /// <param name="target">The object whose properties will be set.</param>
        /// <param name="map">Map of key/value pairs.</param>
        /// <param name="prefix">Key value prefix.  This is prepended to the property name
        /// before searching for a matching key value.</param>
        public static void SetProperties(object target, StringDictionary map, string prefix)
        {
            Tracer.DebugFormat("SetProperties called with target: {0}, and prefix: {1}",
                               target.GetType().Name, prefix);

            foreach (string key in map.Keys)
            {
                if (key.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
                {
                    string propertyName = key.Substring(prefix.Length);

                    // Process all member assignments at this level before processing
                    // any deeper member assignments.
                    if (!propertyName.Contains("."))
                    {
                        MemberInfo member = FindPropertyInfo(target, propertyName);

                        if (member == null)
                        {
                            throw new NMSException(string.Format("No such property or field: {0} on class: {1}", propertyName, target.GetType().Name));
                        }

                        try
                        {
                            if (member.MemberType == MemberTypes.Property)
                            {
                                PropertyInfo property = member as PropertyInfo;
                                property.SetValue(target, Convert.ChangeType(map[key], property.PropertyType, CultureInfo.InvariantCulture), null);
                            }
                            else
                            {
                                FieldInfo field = member as FieldInfo;
                                field.SetValue(target, Convert.ChangeType(map[key], field.FieldType, CultureInfo.InvariantCulture));
                            }
                        }
                        catch (Exception ex)
                        {
                            throw NMSExceptionSupport.Create("Error while attempting to apply option.", ex);
                        }
                    }
                }
            }

            IList <string> propertiesSet = new List <string>();

            // Now process any compound assignments, ensuring that once we recurse into an
            // object we don't do it again as there could be multiple compunds element assignments
            // and they'd have already been processed recursively.
            foreach (string key in map.Keys)
            {
                if (key.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
                {
                    string propertyName = key.Substring(prefix.Length);

                    if (propertyName.Contains("."))
                    {
                        string newTargetName = propertyName.Substring(0, propertyName.IndexOf('.'));
                        string newPrefix     = prefix + newTargetName + ".";

                        if (!propertiesSet.Contains(newPrefix))
                        {
                            MemberInfo member    = FindPropertyInfo(target, newTargetName);
                            object     newTarget = GetUnderlyingObject(member, target);
                            SetProperties(newTarget, map, newPrefix);
                            propertiesSet.Add(newPrefix);
                        }
                    }
                }
            }
        }
Example #11
0
        public void Close()
        {
            if (!this.closed.Value && !transportFailed.Value)
            {
                this.Stop();
            }

            lock (connectedLock)
            {
                if (this.closed.Value)
                {
                    return;
                }

                try
                {
                    Tracer.InfoFormat("Connection[{0}]: Closing Connection Now.", this.ClientId);
                    this.closing.Value = true;

                    Scheduler scheduler = this.scheduler;
                    if (scheduler != null)
                    {
                        try
                        {
                            scheduler.Stop();
                        }
                        catch (Exception e)
                        {
                            throw NMSExceptionSupport.Create(e);
                        }
                    }

                    lock (sessions.SyncRoot)
                    {
                        foreach (Session session in sessions)
                        {
                            session.Shutdown();
                        }
                    }
                    sessions.Clear();

                    // Connected is true only when we've successfully sent our CONNECT
                    // to the broker, so if we haven't announced ourselves there's no need to
                    // inform the broker of a remove, and if the transport is failed, why bother.
                    if (connected.Value && !transportFailed.Value)
                    {
                        DISCONNECT disconnect = new DISCONNECT();
                        transport.Oneway(disconnect);
                    }

                    executor.Shutdown();
                    if (!executor.AwaitTermination(TimeSpan.FromMinutes(1)))
                    {
                        Tracer.DebugFormat("Connection[{0}]: Failed to properly shutdown its executor", this.ClientId);
                    }

                    Tracer.DebugFormat("Connection[{0}]: Disposing of the Transport.", this.ClientId);
                    transport.Stop();
                    transport.Dispose();
                }
                catch (Exception ex)
                {
                    Tracer.ErrorFormat("Connection[{0}]: Error during connection close: {1}", ClientId, ex);
                }
                finally
                {
                    if (executor != null)
                    {
                        executor.Shutdown();
                    }

                    this.transport       = null;
                    this.closed.Value    = true;
                    this.connected.Value = false;
                    this.closing.Value   = false;
                }
            }
        }