public void Init(Uri uri, DelayOptions options) { if (uri == null) { throw new ArgumentNullException(nameof(uri)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } _options = options; var ordered = options.QueueOptions.GroupBy(x => x.Ttl).OrderBy(x => x.Key).Select(x => x.First()).ToArray(); _delays = new Dictionary <TimeSpan, RabbitDelayInfo>(ordered.Length); RabbitDelayInfo next = null; for (int i = ordered.Length - 1; i >= 0; i--) { var delay = ordered[i]; var info = new RabbitDelayInfo { Option = delay, Next = next, QueueName = QueueNameExtensions.GetQueue(uri, delay.Uri) }; _delays.Add(delay.Ttl, info); next = info; } _first = next; }
public RabbitServerCommunication( ILogger <RabbitServerCommunication> log, IRabbitmqConnection connection, RabbitServerOptions option, IRabbitDelayConfig delayConfig) { _log = log; _connection = connection; _option = option ?? throw new ArgumentNullException(nameof(option), "RabbitMQ settings not set."); _delayConfig = delayConfig; _queue = _option.Queue.Uri.Host; _errorQueue = _option.ErrorQueue == null ? null : QueueNameExtensions.GetQueue(_option.Queue.Uri, _option.ErrorQueue.Uri); _delayQueue = _option.DefaultDelayQueue == null ? null : QueueNameExtensions.GetQueue(_option.Queue.Uri, _option.DefaultDelayQueue.Uri); }
public Task <QueueContext> Parse(BasicDeliverEventArgs args, IFeatureCollection features) { try { _log.LogTrace("Validate request"); _validator.Validate(args); var props = args.BasicProperties; var headers = args.BasicProperties.Headers.ToDictionary(x => x.Key.ToLower(CultureInfo.InvariantCulture), pair => pair.Value); _log.LogTrace("Parsing standart headers method, accept, uri, content-type e.t.c"); var method = headers.GetOrDefaultString(QueueHeaders.Method, HttpMethods.Get); var accept = headers.GetOrDefaultString(HeaderNames.Accept.ToLowerInvariant(), QueueConsts.DefaultContentType); var uriHeader = headers.GetOrDefaultString(QueueHeaders.Uri); if (!Uri.TryCreate(uriHeader, UriKind.RelativeOrAbsolute, out var uri)) { throw new ArgumentException($"Header {QueueHeaders.Uri} must be valid uri absolute or relative"); } var relativeUri = uri.IsAbsoluteUri ? QueueNameExtensions.GetQueue(uri) : uriHeader; if (relativeUri[0] != '/') { relativeUri = "/" + relativeUri; } var contentType = headers.GetOrDefaultString(HeaderNames.ContentType.ToLowerInvariant(), QueueConsts.DefaultContentType); _log.LogTrace("Parse query parameters"); var startIndex = uriHeader.IndexOf('?'); var queryString = new QueryString(startIndex == -1 ? string.Empty : uriHeader.Substring(startIndex)); var query = HttpUtility.ParseQueryString(queryString.Value ?? string.Empty); var host = headers.GetOrDefaultString(HeaderNames.Host.ToLowerInvariant(), _options.Queue.Uri.Host); var emptyBody = method == HttpMethods.Get || method == HttpMethods.Delete; if (emptyBody && args.Body.Length != 0) { _log.LogWarning($"{args.ConsumerTag}, uri: {relativeUri} method not available body. But body is set"); } MemoryMarshal.TryGetArray(args.Body, out ArraySegment <byte> array); var request = new QueueRequest { Body = !emptyBody ? new MemoryStream(array.Array, 0, array.Count, false) : Stream.Null, ContentLength = array.Count, ContentType = contentType, IsHttps = false, Method = method, Protocol = props.ProtocolClassName, QueryString = queryString, Query = new QueryCollection(query.AllKeys.ToDictionary(x => x, x => new StringValues(query[x]))), Path = relativeUri, Host = host != null ? new HostString(host) : new HostString(string.Empty), Scheme = RabbitConsts.Schema, PathBase = PathString.Empty, }; _log.LogTrace("Filling in the request headers"); foreach (var header in headers) { if (header.Value is List <object> list) { } else { request.Headers.TryAdd(header.Key, Encoding.UTF8.GetString((byte[])header.Value)); } } _log.LogTrace($"Create default response"); var response = new QueueResponse { ContentType = accept, StatusCode = StatusCodes.Status200OK, Body = !_options.ForceResponseStream && args.BasicProperties.ReplyTo == null ? Stream.Null : new MemoryStream() }; _log.LogTrace($"Create queue context"); var context = new QueueContext(features, response, request); return(Task.FromResult(context)); } catch (Exception e) { _log.LogError(e, "Error create Context"); return(Task.FromResult(default(QueueContext))); } }