Exemplo n.º 1
0
        /// <summary>
        /// Validates if the buffer has sufficient bytes for read or space for write.
        /// </summary>
        /// <param name="write">true if validation is for writing bytes.</param>
        /// <param name="dataSize">The requested size.</param>
        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));
            }
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
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)));
            }
        }
Exemplo n.º 5
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));
            }
        }
Exemplo n.º 6
0
        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));
        }
Exemplo n.º 7
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);
                        }
                    }
                }
Exemplo n.º 8
0
        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);
        }
Exemplo n.º 9
0
        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");
        }
Exemplo n.º 10
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);
        }
Exemplo n.º 11
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++;
        }
Exemplo n.º 12
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)
            {
                if (Fx.IsFatal(exception))
                {
                    throw;
                }

                AmqpTrace.Provider.AmqpLogError(this, "ProcessFrame", exception.Message);
                this.SafeClose(exception);
            }
        }
Exemplo n.º 13
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);
            }
Exemplo n.º 14
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);
            }
        }
Exemplo n.º 15
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);
        }
Exemplo n.º 16
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);
        }
Exemplo n.º 17
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));
        }
Exemplo n.º 18
0
            static bool HandleSection(AmqpBufferMessage thisPtr, int unused, Section section)
            {
                if (section.Flag == SectionFlag.Header)
                {
                    thisPtr.Header = (Header)section.Value;
                }
                else if (section.Flag == SectionFlag.DeliveryAnnotations)
                {
                    thisPtr.DeliveryAnnotations = (DeliveryAnnotations)section.Value;
                }
                else if (section.Flag == SectionFlag.MessageAnnotations)
                {
                    thisPtr.MessageAnnotations = (MessageAnnotations)section.Value;
                }
                else if (section.Flag == SectionFlag.Properties)
                {
                    thisPtr.Properties = (Properties)section.Value;
                }
                else if (section.Flag == SectionFlag.ApplicationProperties)
                {
                    thisPtr.ApplicationProperties = (ApplicationProperties)section.Value;
                }
                else if (section.Flag == SectionFlag.Data)
                {
                    if (thisPtr.dataList == null)
                    {
                        thisPtr.bodyOffset    = section.Offset;
                        thisPtr.dataList      = new List <Data>();
                        thisPtr.sectionFlags |= SectionFlag.Data;
                    }

                    thisPtr.bodyLength += section.Length;
                    thisPtr.dataList.Add((Data)section.Value);
                }
                else if (section.Flag == SectionFlag.AmqpSequence)
                {
                    if (thisPtr.sequenceList == null)
                    {
                        thisPtr.bodyOffset    = section.Offset;
                        thisPtr.sequenceList  = new List <AmqpSequence>();
                        thisPtr.sectionFlags |= SectionFlag.AmqpSequence;
                    }

                    thisPtr.bodyLength += section.Length;
                    thisPtr.sequenceList.Add((AmqpSequence)section.Value);
                }
                else if (section.Flag == SectionFlag.AmqpValue)
                {
                    thisPtr.bodyOffset    = section.Offset;
                    thisPtr.bodyLength    = section.Length;
                    thisPtr.amqpValue     = (AmqpValue)section.Value;
                    thisPtr.sectionFlags |= SectionFlag.AmqpValue;
                }
                else if (section.Flag == SectionFlag.Footer)
                {
                    thisPtr.Footer = (Footer)section.Value;
                }
                else
                {
                    throw new AmqpException(AmqpErrorCode.DecodeError,
                                            AmqpResources.GetString(Resources.AmqpInvalidMessageSectionCode, section.Flag));
                }

                return(true);
            }
Exemplo n.º 19
0
 protected virtual void CompleteOnTimer()
 {
     this.CompleteInternal(false, new TimeoutException(AmqpResources.GetString(AmqpResources.AmqpTimeout, this.timeout, this.Target)));
 }
Exemplo n.º 20
0
        void OnReceiveLinkFrame(Frame frame)
        {
            AmqpLink     link    = null;
            Performative command = frame.Command;

            if (command.DescriptorCode == Attach.Code)
            {
                Attach attach = (Attach)command;
                lock (this.ThisLock)
                {
                    this.links.TryGetValue(attach.LinkName, out link);
                }

                if (link == null)
                {
                    if (!this.TryCreateRemoteLink(attach, out link))
                    {
                        return;
                    }
                }
                else
                {
                    lock (this.ThisLock)
                    {
                        link.RemoteHandle = attach.Handle;
                        this.linksByRemoteHandle.Add(attach.Handle.Value, link);
                    }
                }
            }
            else
            {
                LinkPerformative linkBody = (LinkPerformative)command;
                if (!this.linksByRemoteHandle.TryGetObject(linkBody.Handle.Value, out link))
                {
                    if (this.Settings.IgnoreMissingLinks)
                    {
                        AmqpTrace.Provider.AmqpMissingHandle(this.connection, this, "link", linkBody.Handle.Value);
                        return;
                    }

                    if (linkBody.DescriptorCode != Detach.Code)
                    {
                        this.SafeClose(new AmqpException(AmqpErrorCode.UnattachedHandle, AmqpResources.GetString(AmqpResources.AmqpHandleNotFound, linkBody.Handle.Value, this)));
                    }

                    return;
                }
            }

            link.ProcessFrame(frame);
        }
Exemplo n.º 21
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)));
            }
Exemplo n.º 22
0
        /// <summary>
        /// Sends a security token for a resource for later access.
        /// </summary>
        /// <param name="tokenProvider">The provider for issuing security tokens.</param>
        /// <param name="namespaceAddress">The namespace (or tenant) name.</param>
        /// <param name="audience">The audience. In most cases it is the same as resource.</param>
        /// <param name="resource">The resource to access.</param>
        /// <param name="requiredClaims">The required claims to access the resource.</param>
        /// <param name="timeout">The operation timeout.</param>
        /// <returns></returns>
        public async Task <DateTime> SendTokenAsync(ICbsTokenProvider tokenProvider, Uri namespaceAddress, string audience, string resource, string[] requiredClaims, TimeSpan timeout)
        {
            if (this.connection.IsClosing())
            {
                throw new OperationCanceledException("Connection is closing or closed.");
            }

            CbsToken token = await tokenProvider.GetTokenAsync(namespaceAddress, resource, requiredClaims).ConfigureAwait(false);

            string tokenType = token.TokenType;

            if (tokenType == null)
            {
                throw new NotSupportedException(AmqpResources.AmqpUnsupportedTokenType);
            }

            RequestResponseAmqpLink requestResponseLink;

            if (!this.linkFactory.TryGetOpenedObject(out requestResponseLink))
            {
                requestResponseLink = await this.linkFactory.GetOrCreateAsync(timeout).ConfigureAwait(false);
            }

            AmqpValue value = new AmqpValue();

            value.Value = token.TokenValue;
            AmqpMessage putTokenRequest = AmqpMessage.Create(value);

            putTokenRequest.ApplicationProperties.Map[CbsConstants.Operation]           = CbsConstants.PutToken.OperationValue;
            putTokenRequest.ApplicationProperties.Map[CbsConstants.PutToken.Type]       = tokenType;
            putTokenRequest.ApplicationProperties.Map[CbsConstants.PutToken.Audience]   = audience;
            putTokenRequest.ApplicationProperties.Map[CbsConstants.PutToken.Expiration] = token.ExpiresAtUtc;

            AmqpMessage putTokenResponse = await requestResponseLink.RequestAsync(putTokenRequest, timeout).ConfigureAwait(false);

            int    statusCode        = (int)putTokenResponse.ApplicationProperties.Map[CbsConstants.PutToken.StatusCode];
            string statusDescription = (string)putTokenResponse.ApplicationProperties.Map[CbsConstants.PutToken.StatusDescription];

            if (statusCode == (int)AmqpResponseStatusCode.Accepted || statusCode == (int)AmqpResponseStatusCode.OK)
            {
                return(token.ExpiresAtUtc);
            }

            Exception exception;
            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;
            }

            throw exception;
        }
Exemplo n.º 23
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);
        }
Exemplo n.º 24
0
        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);
            }
        }
Exemplo n.º 25
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));
                    }
                }
Exemplo n.º 26
0
 public AmqpException(Error error)
     : base(error.Description ?? AmqpResources.GetString(AmqpResources.AmqpErrorOccurred, error.Condition.Value))
 {
     this.Error = error;
 }