コード例 #1
0
        /// <summary>
        /// Receives a flow from the session.
        /// </summary>
        /// <param name="flow">The received flow.</param>
        protected virtual void OnReceiveFlow(Flow flow)
        {
            this.outgoingChannel.OnFlow(flow);
            this.incomingChannel.OnFlow(flow);

            if (flow.Handle.HasValue)
            {
                AmqpLink link = null;
                if (!this.linksByRemoteHandle.TryGetObject(flow.Handle.Value, out link))
                {
                    if (this.Settings.IgnoreMissingLinks)
                    {
                        AmqpTrace.Provider.AmqpMissingHandle(this.connection, this, "link", flow.Handle.Value);
                        return;
                    }

                    this.SafeClose(new AmqpException(AmqpErrorCode.UnattachedHandle, AmqpResources.GetString(AmqpResources.AmqpHandleNotFound, flow.Handle.Value, this)));
                    return;
                }

                link.OnFlow(flow);
            }
            else if (flow.Echo())
            {
                this.SendFlow();
            }
        }
コード例 #2
0
        protected override void OnProcessTransfer(Delivery delivery, Transfer transfer, Frame frame)
        {
            Fx.Assert(delivery == null || delivery == this.currentMessage, "The delivery must be null or must be the same as the current message.");
            if (this.Settings.MaxMessageSize.HasValue && this.Settings.MaxMessageSize.Value > 0)
            {
                ulong size = (ulong)(this.currentMessage.BytesTransfered + frame.Payload.Count);
                if (size > this.Settings.MaxMessageSize.Value)
                {
                    if (this.IsClosing())
                    {
                        // The closing sequence has been started, so any
                        // transfer is meaningless, so we can treat them as no-op
                        return;
                    }

                    throw new AmqpException(AmqpErrorCode.MessageSizeExceeded,
                                            AmqpResources.GetString(AmqpResources.AmqpMessageSizeExceeded, this.currentMessage.DeliveryId.Value, size, this.Settings.MaxMessageSize.Value));
                }
            }

            Fx.Assert(this.currentMessage != null, "Current message must have been created!");
            ArraySegment <byte> payload = frame.Payload;

            frame.RawByteBuffer.AdjustPosition(payload.Offset, payload.Count);
            frame.RawByteBuffer.Clone();    // Message also owns the buffer from now on
            this.currentMessage.AddPayload(frame.RawByteBuffer, !transfer.More());
            if (!transfer.More())
            {
                AmqpMessage message = this.currentMessage;
                this.currentMessage = null;

                AmqpTrace.Provider.AmqpReceiveMessage(this, message.DeliveryId.Value, message.RawByteBuffers.Count);
                this.OnReceiveMessage(message);
            }
        }
コード例 #3
0
        public void ProcessFrame(Frame frame)
        {
            Performative command = frame.Command;

            try
            {
                if (command.DescriptorCode == Attach.Code)
                {
                    this.OnReceiveAttach((Attach)command);
                }
                else if (command.DescriptorCode == Detach.Code)
                {
                    this.OnReceiveDetach((Detach)command);
                }
                else if (command.DescriptorCode == Transfer.Code)
                {
                    this.OnReceiveTransfer((Transfer)command, frame);
                }
                else if (command.DescriptorCode == Flow.Code)
                {
                    this.OnReceiveFlow((Flow)command);
                }
                else
                {
                    throw new AmqpException(AmqpErrorCode.InvalidField, AmqpResources.GetString(AmqpResources.AmqpInvalidPerformativeCode, command.DescriptorCode));
                }
            }
            catch (Exception exception) when(!Fx.IsFatal(exception))
            {
                AmqpTrace.Provider.AmqpLogError(this, nameof(ProcessFrame), exception.Message);
                this.SafeClose(exception);
            }
        }
コード例 #4
0
ファイル: AmqpObject.cs プロジェクト: baulig/azure-amqp
        public void Open(TimeSpan timeout)
        {
            bool syncOpen = false;

            lock (this.thisLock)
            {
                if (this.openCalled)
                {
                    throw new InvalidOperationException(AmqpResources.GetString(AmqpResources.AmqpInvalidReOpenOperation, this, this.State));
                }

                this.openCalled = true;
                if (this.State == AmqpObjectState.OpenReceived)
                {
                    syncOpen = true;
                }
            }

            if (syncOpen)
            {
                this.OpenInternal();
                this.NotifyOpened();
            }
            else
            {
                this.OnOpen(timeout);
            }
        }
コード例 #5
0
ファイル: AmqpObject.cs プロジェクト: myagley/azure-amqp
        public void Open(TimeSpan timeout)
        {
            bool syncOpen = false;

            lock (this.thisLock)
            {
                if (this.openCalled)
                {
                    var exception = new InvalidOperationException(AmqpResources.GetString(AmqpResources.AmqpInvalidReOpenOperation, this, this.State));
                    AmqpTrace.Provider.AmqpThrowingExceptionWarning(ExceptionTrace.GetDetailsForThrownException(exception));
                    throw Fx.Exception.AsWarning(exception);
                }

                this.openCalled = true;
                if (this.State == AmqpObjectState.OpenReceived)
                {
                    syncOpen = true;
                }
            }

            if (syncOpen)
            {
                this.OpenInternal();
                this.NotifyOpened();
            }
            else
            {
                this.OnOpen(timeout);
            }
        }
コード例 #6
0
ファイル: AmqpObject.cs プロジェクト: myagley/azure-amqp
        protected StateTransition TransitState(string operation, StateTransition[] states)
        {
            StateTransition state = null;

            lock (this.ThisLock)
            {
                foreach (StateTransition st in states)
                {
                    if (st.From == this.State)
                    {
                        this.State = st.To;
                        state      = st;
                        break;
                    }
                }
            }

            if (state == null)
            {
                throw new AmqpException(AmqpErrorCode.IllegalState, AmqpResources.GetString(AmqpResources.AmqpIllegalOperationState, operation, this.State));
            }

            AmqpTrace.Provider.AmqpStateTransition(this, operation, state.From, state.To);

            return(state);
        }
コード例 #7
0
        public uint Add(T value)
        {
            if (this.count > this.maxHandle)
            {
                throw new AmqpException(AmqpErrorCode.ResourceLimitExceeded, AmqpResources.GetString(AmqpResources.AmqpHandleExceeded, this.maxHandle));
            }
            else if (this.count >= this.handleArray.Length)
            {
                this.GrowHandleArray(this.handleArray.Length * 2);

                int index = this.count;
                this.handleArray[index] = value;
                this.count++;
                return((uint)index);
            }
            else
            {
                for (int i = 0; i < this.handleArray.Length; i++)
                {
                    if (this.handleArray[i] == null)
                    {
                        this.handleArray[i] = value;
                        this.count++;
                        return((uint)i);
                    }
                }

                // count and actual handles go out of sync. there must be a bug
                throw new AmqpException(AmqpErrorCode.InternalError, null);
            }
        }
コード例 #8
0
        protected virtual void CompleteOnTimer()
        {
            if (this.timer != null)
            {
                this.timer.Dispose();
            }

            this.CompleteInternal(false, new TimeoutException(AmqpResources.GetString(AmqpResources.AmqpTimeout, this.timeout, this.Target)));
        }
コード例 #9
0
        void OnReceiveSessionFrame(Frame frame)
        {
            AmqpSession  session = null;
            Performative command = frame.Command;
            ushort       channel = frame.Channel;

            if (command.DescriptorCode == Begin.Code)
            {
                Begin begin = (Begin)command;
                if (begin.RemoteChannel.HasValue)
                {
                    // reply to begin
                    lock (this.ThisLock)
                    {
                        if (!this.sessionsByLocalHandle.TryGetObject(begin.RemoteChannel.Value, out session))
                        {
                            throw new AmqpException(AmqpErrorCode.NotFound, AmqpResources.GetString(AmqpResources.AmqpChannelNotFound, begin.RemoteChannel.Value, this));
                        }

                        session.RemoteChannel = channel;
                        this.sessionsByRemoteHandle.Add(channel, session);
                    }
                }
                else
                {
                    // new begin request
                    AmqpSessionSettings settings = AmqpSessionSettings.Create(begin);
                    settings.RemoteChannel = channel;
                    session = this.SessionFactory.CreateSession(this, settings);
                    this.AddSession(session, channel);
                }
            }
            else
            {
                if (!this.sessionsByRemoteHandle.TryGetObject((uint)channel, out session))
                {
                    if (command.DescriptorCode == End.Code ||
                        command.DescriptorCode == Detach.Code ||
                        this.Settings.IgnoreMissingSessions)
                    {
                        // The session close may timed out already
                        AmqpTrace.Provider.AmqpMissingHandle(this, "session", channel);
                        return;
                    }

                    throw new AmqpException(AmqpErrorCode.NotFound, AmqpResources.GetString(AmqpResources.AmqpChannelNotFound, channel, this));
                }
                else if (command.DescriptorCode == End.Code)
                {
                    this.sessionsByRemoteHandle.Remove((uint)channel);
                    session.RemoteChannel = null;
                }
            }

            session.ProcessFrame(frame);
        }
コード例 #10
0
        static Error AdvanceBuffer(ByteBuffer buffer, uint size)
        {
            if (size > buffer.Length)
            {
                return(GetDecodeError(AmqpResources.GetString(Resources.AmqpInsufficientBufferSize, size, buffer.Length)));
            }

            buffer.Complete((int)size);
            return(null);
        }
コード例 #11
0
        public void Validate(bool write, int dataSize)
        {
            bool valid = false;

            if (write)
            {
                if (this.Size < dataSize && this.autoGrow)
                {
                    if (this.references != 1)
                    {
                        throw new InvalidOperationException("Cannot grow the current buffer because it has more than one references");
                    }

                    int           newSize = Math.Max(this.Capacity * 2, this.Capacity + dataSize);
                    ManagedBuffer newBuffer;
                    if (this.bufferManager != null)
                    {
                        newBuffer = ByteBuffer.AllocateBuffer(newSize, this.bufferManager);
                    }
                    else
                    {
                        newBuffer = new ManagedBuffer(new byte[newSize], null);
                    }

                    System.Buffer.BlockCopy(this.buffer, this.start, newBuffer.Buffer, 0, this.Capacity);

                    int consumed = this.read - this.start;
                    int written  = this.write - this.start;

                    this.start = 0;
                    this.read  = consumed;
                    this.write = written;
                    this.end   = newSize;

                    if (this.bufferManager != null)
                    {
                        this.bufferManager.ReturnBuffer(this.buffer);
                    }
                    this.buffer        = newBuffer.Buffer;
                    this.bufferManager = newBuffer.BufferManager;
                }

                valid = this.Size >= dataSize;
            }
            else
            {
                valid = this.Length >= dataSize;
            }

            if (!valid)
            {
                throw new AmqpException(AmqpErrorCode.DecodeError, AmqpResources.GetString(AmqpResources.AmqpInsufficientBufferSize, dataSize, write ? this.Size : this.Length));
            }
        }
コード例 #12
0
        protected void ProcessTransfer(Transfer transfer, Frame rawFrame, Delivery delivery, bool newDelivery)
        {
            if (newDelivery)
            {
                if (this.linkCredit < uint.MaxValue)
                {
                    bool creditAvailable = true;
                    lock (this.syncRoot)
                    {
                        // Updating new total credit is delayed to avoid flooding
                        // the network with flows when there are many links that are
                        // frequently opened/closed
                        if (this.tempTotalCredit != null &&
                            this.ApplyTempTotalLinkCredit())
                        {
                            this.SendFlow(false, false, properties: null);
                        }

                        if (this.linkCredit == 0 && this.bufferedCredit == 0)
                        {
                            creditAvailable = false;
                        }
                        else
                        {
                            this.deliveryCount.Increment();
                            if (this.bufferedCredit > 0)
                            {
                                --this.bufferedCredit;
                            }
                            else if (this.linkCredit < uint.MaxValue)
                            {
                                --this.linkCredit;
                            }
                        }
                    }

                    if (!creditAvailable)
                    {
                        throw new AmqpException(AmqpErrorCode.TransferLimitExceeded,
                                                AmqpResources.GetString(AmqpResources.AmqpTransferLimitExceeded, delivery.DeliveryId.Value));
                    }
                }

                if (!delivery.Settled)
                {
                    lock (this.syncRoot)
                    {
                        this.unsettledMap.Add(delivery.DeliveryTag, delivery);
                    }
                }
            }

            this.OnProcessTransfer(delivery, transfer, rawFrame);
        }
コード例 #13
0
        /// <summary>
        /// Compares two integers as sequence numbers.
        /// </summary>
        /// <param name="x">The first number.</param>
        /// <param name="y">The second number.</param>
        /// <returns>A negative integer, 0, or a possitive number if the first is
        /// less than, equal or greater than the second respectively.</returns>
        public static int Compare(int x, int y)
        {
            int delta = x - y;

            if (delta == int.MinValue)
            {
                // Behavior of comparing 0u-2147483648u, 1u-2147483649u, ...
                // is undefined, so we do not allow it.
                throw new InvalidOperationException(AmqpResources.GetString(AmqpResources.AmqpInvalidSequenceNumberComparison, x, y));
            }

            return(delta);
        }
コード例 #14
0
        static Error ScanDataSection(byte formatCode, ByteBuffer buffer)
        {
            switch (formatCode)
            {
            case FormatCode.Binary8:
                return(AdvanceBuffer(buffer, AmqpBitConverter.ReadUByte(buffer)));

            case FormatCode.Binary32:
                return(AdvanceBuffer(buffer, AmqpBitConverter.ReadUInt(buffer)));

            default:
                return(GetDecodeError(AmqpResources.GetString(Resources.AmqpInvalidFormatCode, formatCode, buffer.Offset)));
            }
        }
コード例 #15
0
        void EnsureBodyType(SectionFlag expected)
        {
            if (this.sectionFlags == 0 && this.buffer != null)
            {
                this.Initialize(SectionFlag.All);
            }

            SectionFlag actual = this.sectionFlags & SectionFlag.Body;

            if (actual > 0 && actual != expected)
            {
                throw new InvalidOperationException(AmqpResources.GetString(Resources.AmqpInvalidMessageBodyType, actual, expected));
            }
        }
コード例 #16
0
ファイル: AmqpObject.cs プロジェクト: baulig/azure-amqp
        public IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
        {
            lock (this.thisLock)
            {
                if (this.openCalled)
                {
                    throw new InvalidOperationException(AmqpResources.GetString(AmqpResources.AmqpInvalidReOpenOperation, this, this.State));
                }

                this.openCalled = true;
            }

            AmqpTrace.Provider.AmqpLogOperationVerbose(this, TraceOperation.Execute, "BeginOpen");
            return(new OpenAsyncResult(this, timeout, callback, state));
        }
コード例 #17
0
                static void OnHeartBeatTimer(object state)
                {
                    TimedHeartBeat thisPtr = (TimedHeartBeat)state;

                    if (thisPtr.connection.IsClosing())
                    {
                        return;
                    }

                    DateTime now = DateTime.UtcNow;

                    try
                    {
                        if (thisPtr.localInterval < uint.MaxValue &&
                            now.Subtract(thisPtr.lastReceiveTime).TotalMilliseconds > thisPtr.localInterval)
                        {
                            string message = AmqpResources.GetString(AmqpResources.AmqpConnectionInactive,
                                                                     thisPtr.localInterval, thisPtr.connection.Settings.ContainerId);
                            AmqpTrace.Provider.AmqpLogError(thisPtr.connection, "OnHeartBeatTimer", message);

                            thisPtr.connection.SafeClose(new AmqpException(AmqpErrorCode.ConnectionForced, message));

                            return;
                        }

                        if (thisPtr.remoteInterval < uint.MaxValue &&
                            now.Subtract(thisPtr.lastSendTime).TotalMilliseconds >= thisPtr.remoteInterval)
                        {
                            thisPtr.connection.SendCommand(null, 0, null);
                        }

                        thisPtr.SetTimer(now);
                    }
                    catch (Exception exception)
                    {
                        if (Fx.IsFatal(exception))
                        {
                            throw;
                        }

                        if (!thisPtr.connection.IsClosing())
                        {
                            AmqpTrace.Provider.AmqpLogError(thisPtr.connection, "OnHeartBeatTimer", exception.Message);
                            thisPtr.connection.SafeClose(exception);
                        }
                    }
                }
コード例 #18
0
ファイル: AmqpCbsLink.cs プロジェクト: xinchen10/azure-amqp
        async Task <RequestResponseAmqpLink> CreateCbsLinkAsync(TimeSpan timeout)
        {
            string                  address       = CbsConstants.CbsAddress;
            TimeoutHelper           timeoutHelper = new TimeoutHelper(timeout);
            AmqpSession             session       = null;
            RequestResponseAmqpLink link          = null;
            Exception               lastException = null;

            while (timeoutHelper.RemainingTime() > TimeSpan.Zero)
            {
                try
                {
                    AmqpSessionSettings sessionSettings = new AmqpSessionSettings()
                    {
                        Properties = new Fields()
                    };
                    session = this.connection.CreateSession(sessionSettings);
                    await session.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                    Fields properties = new Fields();
                    properties.Add(CbsConstants.TimeoutName, (uint)timeoutHelper.RemainingTime().TotalMilliseconds);
                    link = new RequestResponseAmqpLink("cbs", session, address, properties);
                    await link.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                    AmqpTrace.Provider.AmqpOpenEntitySucceeded(this, link.Name, address);
                    return(link);
                }
                catch (Exception exception)
                {
                    if (this.connection.IsClosing())
                    {
                        throw new OperationCanceledException("Connection is closing or closed.", exception);
                    }

                    lastException = exception;
                    AmqpTrace.Provider.AmqpOpenEntityFailed(this, this.GetType().Name, address, exception);
                }

                await Task.Delay(1000).ConfigureAwait(false);
            }

            link?.Abort();
            session?.SafeClose();

            throw new TimeoutException(AmqpResources.GetString(AmqpResources.AmqpTimeout, timeout, address), lastException);
        }
コード例 #19
0
ファイル: AmqpSession.cs プロジェクト: myagley/azure-amqp
        public void AttachLink(AmqpLink link)
        {
            Fx.Assert(link.Session == this, "The link is not owned by this session.");
            link.Closed += onLinkClosed;

            lock (this.ThisLock)
            {
                if (this.links.ContainsKey(link.Name))
                {
                    throw new AmqpException(AmqpErrorCode.ResourceLocked, AmqpResources.GetString(AmqpResources.AmqpLinkNameInUse, link.Name, this.LocalChannel));
                }

                this.links.Add(link.Name, link);
                link.LocalHandle = this.linksByLocalHandle.Add(link);
            }

            AmqpTrace.Provider.AmqpAttachLink(this.connection, this, link, link.LocalHandle.Value, link.RemoteHandle ?? 0u, link.Name, link.IsReceiver ? "receiver" : "sender");
        }
コード例 #20
0
        void OnReceiveOpen(Open open)
        {
            StateTransition stateTransition = this.TransitState("R:OPEN", StateTransition.ReceiveOpen);

            uint peerIdleTimeout = open.IdleTimeOut();

            if (peerIdleTimeout < this.Settings.MinIdleTimeout)
            {
                this.CompleteOpen(false,
                                  new AmqpException(AmqpErrorCode.NotAllowed, AmqpResources.GetString(AmqpResources.AmqpIdleTimeoutNotSupported, peerIdleTimeout, this.Settings.MinIdleTimeout)));
                return;
            }

            this.Negotiate(open);
            this.NotifyOpening(open);

            if (stateTransition.To == AmqpObjectState.OpenReceived)
            {
                this.SendOpen();
            }

            if (this.isInitiator)
            {
                // check if open returned an error right away
                Error openError = null;
                if (open.Properties != null && open.Properties.TryGetValue <Error>(AmqpConstants.OpenErrorName, out openError))
                {
                    this.CompleteOpen(stateTransition.From == AmqpObjectState.Start, new AmqpException(openError));
                    return;
                }
            }

            uint myIdleTimeout = this.Settings.IdleTimeOut();

            peerIdleTimeout = open.IdleTimeOut();
            if (peerIdleTimeout != uint.MaxValue || myIdleTimeout != uint.MaxValue)
            {
                this.heartBeat = HeartBeat.Initialize(this, myIdleTimeout, peerIdleTimeout);
            }

            this.CompleteOpen(stateTransition.From == AmqpObjectState.Start, null);
        }
コード例 #21
0
        public void Add(uint handle, T value)
        {
            if (handle > this.maxHandle)
            {
                throw new AmqpException(AmqpErrorCode.ResourceLimitExceeded, AmqpResources.GetString(AmqpResources.AmqpHandleExceeded, this.maxHandle));
            }

            int index = (int)handle;

            if (index >= this.handleArray.Length)
            {
                int capacity = UpperPowerOfTwo(this.handleArray.Length, index);
                this.GrowHandleArray(capacity);
            }
            else if (this.handleArray[index] != null)
            {
                throw new AmqpException(AmqpErrorCode.HandleInUse, AmqpResources.GetString(AmqpResources.AmqpHandleInUse, handle, this.handleArray[index]));
            }

            this.handleArray[(int)handle] = value;
            this.count++;
        }
コード例 #22
0
        internal static AmqpDescribed CreateAmqpDescribed(
            ByteBuffer buffer,
            Dictionary <string, Func <AmqpDescribed> > byName,
            Dictionary <ulong, Func <AmqpDescribed> > byCode)
        {
            FormatCode formatCode = AmqpEncoding.ReadFormatCode(buffer);

            if (formatCode == FormatCode.Null)
            {
                return(null);
            }

            EncodingBase.VerifyFormatCode(formatCode, buffer.Offset, FormatCode.Described);

            Func <AmqpDescribed> knownTypeCtor = null;

            formatCode = AmqpEncoding.ReadFormatCode(buffer);
            if (formatCode == FormatCode.Symbol8 || formatCode == FormatCode.Symbol32)
            {
                AmqpSymbol name = SymbolEncoding.Decode(buffer, formatCode);
                byName.TryGetValue(name.Value, out knownTypeCtor);
            }
            else if (formatCode == FormatCode.ULong0 || formatCode == FormatCode.ULong || formatCode == FormatCode.SmallULong)
            {
                ulong code = ULongEncoding.Decode(buffer, formatCode).Value;
                byCode.TryGetValue(code, out knownTypeCtor);
            }

            if (knownTypeCtor == null)
            {
                throw AmqpEncoding.GetEncodingException(AmqpResources.GetString(AmqpResources.AmqpInvalidFormatCode, formatCode, buffer.Offset));
            }

            AmqpDescribed value = knownTypeCtor();

            return(value);
        }
コード例 #23
0
        protected override void OnProtocolHeader(ProtocolHeader header)
        {
#if DEBUG
            header.Trace(false);
            AmqpTrace.Provider.AmqpLogOperationVerbose(this, TraceOperation.Receive, header);
#endif
            this.heartBeat.OnReceive();
            if (this.UsageMeter != null)
            {
                this.UsageMeter.OnRead(this, 0, header.EncodeSize);
            }

            this.TransitState("R:HDR", StateTransition.ReceiveHeader);
            Exception exception = null;

            if (this.isInitiator)
            {
                if (!this.initialHeader.Equals(header))
                {
                    exception = new AmqpException(AmqpErrorCode.NotImplemented, AmqpResources.GetString(AmqpResources.AmqpProtocolVersionNotSupported, this.initialHeader.ToString(), header.ToString()));
                }
            }
            else
            {
                ProtocolHeader supportedHeader = this.amqpSettings.GetSupportedHeader(header);
                this.SendProtocolHeader(supportedHeader);
                if (!supportedHeader.Equals(header))
                {
                    exception = new AmqpException(AmqpErrorCode.NotImplemented, AmqpResources.GetString(AmqpResources.AmqpProtocolVersionNotSupported, this.initialHeader.ToString(), header.ToString()));
                }
            }

            if (exception != null)
            {
                this.CompleteOpen(false, exception);
            }
        }
コード例 #24
0
            static Exception ConvertToException(int statusCode, string statusDescription)
            {
                Exception exception;

                if (Enum.IsDefined(typeof(AmqpResponseStatusCode), statusCode))
                {
                    AmqpResponseStatusCode amqpResponseStatusCode = (AmqpResponseStatusCode)statusCode;
                    switch (amqpResponseStatusCode)
                    {
                    case AmqpResponseStatusCode.BadRequest:
                        exception = new AmqpException(AmqpErrorCode.InvalidField, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription));
                        break;

                    case AmqpResponseStatusCode.NotFound:
                        exception = new AmqpException(AmqpErrorCode.NotFound, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription));
                        break;

                    case AmqpResponseStatusCode.Forbidden:
                        exception = new AmqpException(AmqpErrorCode.TransferLimitExceeded, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription));
                        break;

                    case AmqpResponseStatusCode.Unauthorized:
                        exception = new AmqpException(AmqpErrorCode.UnauthorizedAccess, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription));
                        break;

                    default:
                        exception = new AmqpException(AmqpErrorCode.InvalidField, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription));
                        break;
                    }
                }
                else
                {
                    exception = new AmqpException(AmqpErrorCode.InvalidField, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription));
                }

                return(exception);
            }
コード例 #25
0
        static Error ScanValueSection(byte formatCode, ByteBuffer buffer, int depth = 0)
        {
            if (formatCode == FormatCode.Described)
            {
                if (depth > 10)
                {
                    // protection for stack overflow
                    return(GetDecodeError(AmqpResources.GetString(Resources.AmqpInvalidFormatCode, formatCode, buffer.Offset)));
                }

                Error error = ScanValueSection(AmqpEncoding.ReadFormatCode(buffer), buffer, depth + 1);
                if (error != null)
                {
                    return(error);
                }

                formatCode = AmqpEncoding.ReadFormatCode(buffer);
            }

            uint size;

            if (formatCode >= FormatCode.Binary8)
            {
                // variable width
                size = (formatCode & 0x10) == 0 ?
                       AmqpBitConverter.ReadUByte(buffer) :
                       AmqpBitConverter.ReadUInt(buffer);
            }
            else
            {
                // fixed width
                size = (uint)((1 << ((formatCode >> 4) - 4)) >> 1);
            }

            return(AdvanceBuffer(buffer, size));
        }
コード例 #26
0
        /// <summary>
        /// Attaches a link to the session. The link is assigned a local handle on success.
        /// </summary>
        /// <param name="link">The link to attach.</param>
        public void AttachLink(AmqpLink link)
        {
            Fx.Assert(link.Session == this, "The link is not owned by this session.");

            lock (this.ThisLock)
            {
                if (this.IsClosing())
                {
                    throw new InvalidOperationException(AmqpResources.GetString(AmqpResources.AmqpIllegalOperationState, "attach", this.State));
                }

                if (this.links.ContainsKey(link.Name))
                {
                    throw new AmqpException(AmqpErrorCode.ResourceLocked, AmqpResources.GetString(AmqpResources.AmqpLinkNameInUse, link.Name, this.LocalChannel));
                }

                link.Closed += onLinkClosed;
                this.links.Add(link.Name, link);
                link.LocalHandle = this.linksByLocalHandle.Add(link);
            }

            AmqpTrace.Provider.AmqpAttachLink(this, link, link.LocalHandle.Value,
                                              link.RemoteHandle ?? 0u, link.Name, link.IsReceiver ? "receiver" : "sender", link.Settings.Source, link.Settings.Target);
        }
コード例 #27
0
ファイル: AmqpObject.cs プロジェクト: myagley/azure-amqp
        void NotifyClosed()
        {
            // Make sure no pending async result is leaked
            if (this.pendingOpen != null)
            {
                this.CompleteOpen(false, this.TerminalException ?? new OperationCanceledException(AmqpResources.GetString(AmqpResources.AmqpObjectAborted, this.name)));
            }

            if (this.pendingClose != null)
            {
                this.CompleteClose(false, this.TerminalException ?? new OperationCanceledException(AmqpResources.GetString(AmqpResources.AmqpObjectAborted, this.name)));
            }

            EventHandler closed = null;

            lock (this.thisLock)
            {
                if (!this.closedHandlerInvoked)
                {
                    closed = this.Closed;
                    this.closedHandlerInvoked = true;
                }
            }

            if (closed != null)
            {
                closed(this, EventArgs.Empty);
            }
        }
コード例 #28
0
        static bool TryReadSectionInfo(ByteBuffer buffer, out SectionInfo info, out Error error)
        {
            info = default(SectionInfo);

            FormatCode formatCode = AmqpEncoding.ReadFormatCode(buffer);

            if (formatCode != FormatCode.Described)
            {
                error = GetDecodeError(AmqpResources.GetString(Resources.AmqpInvalidFormatCode, formatCode, buffer.Offset - FixedWidth.FormatCode));
                return(false);
            }

            ulong code = ulong.MaxValue;

            formatCode = AmqpEncoding.ReadFormatCode(buffer);
            switch (formatCode)
            {
            case FormatCode.SmallULong:
                code = AmqpBitConverter.ReadUByte(buffer);
                break;

            case FormatCode.ULong:
                code = AmqpBitConverter.ReadULong(buffer);
                break;

            case FormatCode.Symbol32:
            case FormatCode.Symbol8:
                // symbol name should be seldom used so do not optimize for it
                AmqpSymbol name = SymbolEncoding.Decode(buffer, formatCode);
                for (int i = 0; i < MessageSections.Length; i++)
                {
                    if (MessageSections[i].Name.Equals(name.Value))
                    {
                        code = MessageSections[i].Code;
                        break;
                    }
                }
                if (code == ulong.MaxValue)
                {
                    error = GetDecodeError(AmqpResources.GetString(Resources.AmqpInvalidMessageSectionCode, name));
                    return(false);
                }
                break;

            default:
                error = GetDecodeError(AmqpResources.GetString(Resources.AmqpInvalidFormatCode, formatCode, buffer.Offset - FixedWidth.FormatCode));
                return(false);
            }

            int index = (int)(code - MessageSections[0].Code);

            if (index < 0 || index >= MessageSections.Length)
            {
                error = GetDecodeError(AmqpResources.GetString(Resources.AmqpInvalidMessageSectionCode, code));
                return(false);
            }

            info  = MessageSections[index];
            error = null;

            return(true);
        }
コード例 #29
0
                static void OnHeartBeatTimer(object state)
                {
                    TimedHeartBeat thisPtr = (TimedHeartBeat)state;

                    if (thisPtr.connection.IsClosing())
                    {
                        return;
                    }

                    bool     wasActive          = false;
                    DateTime capturedLastActive = thisPtr.lastSendTime;
                    DateTime now = DateTime.UtcNow;
                    DateTime scheduleAfterTime = now;

                    if (now.Subtract(capturedLastActive) < TimeSpan.FromMilliseconds(thisPtr.heartBeatInterval))
                    {
                        wasActive         = true;
                        scheduleAfterTime = capturedLastActive;
                    }

                    try
                    {
                        if (!wasActive)
                        {
                            thisPtr.connection.SendCommand(null, 0, null);
                        }

                        thisPtr.heartBeatTimer.Change(scheduleAfterTime.AddMilliseconds(thisPtr.heartBeatInterval).Subtract(now), Timeout.InfiniteTimeSpan);
                    }
                    catch (Exception exception)
                    {
                        if (Fx.IsFatal(exception))
                        {
                            throw;
                        }

                        AmqpTrace.Provider.AmqpLogError(thisPtr.connection, "OnHeartBeatTimer", exception.Message);
                    }

                    // idle timeout can be different for the peers. but instead of creating another timer,
                    // we use the sending timer to also check if we have received anything just in case
                    uint thisIdletimeout = thisPtr.connection.Settings.IdleTimeOut();

                    if (thisIdletimeout < uint.MaxValue &&
                        now > thisPtr.lastReceiveTime.AddMilliseconds((int)thisIdletimeout))
                    {
                        AmqpTrace.Provider.AmqpLogError(thisPtr.connection, "OnHeartBeatTimer", AmqpResources.GetString(AmqpResources.AmqpTimeout, thisIdletimeout, thisPtr.connection));

                        thisPtr.connection.SafeClose(new AmqpException(AmqpErrorCode.ConnectionForced, AmqpResources.AmqpConnectionInactive));
                    }
                }
コード例 #30
0
            protected override IEnumerator <AsyncStep> GetAsyncSteps()
            {
                string address = CbsConstants.CbsAddress;

                while (this.RemainingTime() > TimeSpan.Zero)
                {
                    try
                    {
                        AmqpSessionSettings sessionSettings = new AmqpSessionSettings()
                        {
                            Properties = new Fields()
                        };
                        this.session = new AmqpSession(this.connection, sessionSettings, this);
                        connection.AddSession(session, null);
                    }
                    catch (InvalidOperationException exception)
                    {
                        this.Complete(exception);
                        yield break;
                    }

                    yield return(this.CallAsync(
                                     (thisPtr, t, c, s) => thisPtr.session.BeginOpen(t, c, s),
                                     (thisPtr, r) => thisPtr.session.EndOpen(r),
                                     ExceptionPolicy.Continue));

                    Exception lastException = this.LastAsyncStepException;
                    if (lastException != null)
                    {
                        AmqpTrace.Provider.AmqpOpenEntityFailed(this.connection, this.session, string.Empty, address, lastException.Message);
                        this.session.Abort();
                        this.Complete(lastException);
                        yield break;
                    }

                    Fields properties = new Fields();
                    properties.Add(CbsConstants.TimeoutName, (uint)this.RemainingTime().TotalMilliseconds);
                    this.Link = new RequestResponseAmqpLink("cbs", this.session, address, properties);
                    yield return(this.CallAsync(
                                     (thisPtr, t, c, s) => thisPtr.Link.BeginOpen(t, c, s),
                                     (thisPtr, r) => thisPtr.Link.EndOpen(r),
                                     ExceptionPolicy.Continue));

                    lastException = this.LastAsyncStepException;
                    if (lastException != null)
                    {
                        AmqpTrace.Provider.AmqpOpenEntityFailed(this.connection, this.Link, this.Link.Name, address, lastException.Message);
                        this.session.SafeClose();
                        this.Link = null;
                        this.Complete(lastException);
                        yield break;
                    }

                    AmqpTrace.Provider.AmqpOpenEntitySucceeded(this.connection, this.Link, this.Link.Name, address);
                    yield break;
                }

                if (this.session != null)
                {
                    this.session.SafeClose();
                }

                this.Complete(new TimeoutException(AmqpResources.GetString(AmqpResources.AmqpTimeout, this.OriginalTimeout, address)));
            }