async Task SendTokenAsync()

in src/Cbs/AmqpCbsLink.cs [98:165]


        async Task<DateTime> SendTokenAsync(ICbsTokenProvider tokenProvider, Uri namespaceAddress, string audience,
            string resource, string[] requiredClaims, TimeSpan timeout, CancellationToken cancellationToken)
        {
            ThrowIfNull(tokenProvider, nameof(tokenProvider));
            ThrowIfNull(namespaceAddress, nameof(namespaceAddress));
            ThrowIfNull(audience, nameof(audience));
            ThrowIfNull(resource, nameof(resource));
            ThrowIfNull(requiredClaims, nameof(requiredClaims));
            if (this.connection.IsClosing())
            {
                throw new OperationCanceledException("Connection is closing or closed.");
            }

            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
            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(timeoutHelper.RemainingTime(), cancellationToken).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, AmqpConstants.NullBinary,
                timeoutHelper.RemainingTime(), cancellationToken).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;
        }