| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System; |
| | | 5 | | using System.Linq; |
| | | 6 | | using RabbitMQ.Client; |
| | | 7 | | |
| | | 8 | | namespace CoreWCF.ServiceModel.Channels |
| | | 9 | | { |
| | | 10 | | public class RabbitMqConnectionSettings |
| | | 11 | | { |
| | | 12 | | private const string TempQueuePrefix = "corewcf-temp-"; |
| | | 13 | | private const string AMQPScheme = "amqp"; |
| | | 14 | | private const string SecureAMQPScheme = "amqps"; |
| | | 15 | | private const string DefaultVirtualHost = "/"; |
| | | 16 | | |
| | 3 | 17 | | public Uri BaseAddress { get; set; } |
| | 6 | 18 | | public string Host { get; set; } |
| | 6 | 19 | | public int Port { get; set; } |
| | 9 | 20 | | public string Exchange { get; set; } = string.Empty; |
| | 3 | 21 | | public string QueueName { get; set; } |
| | 9 | 22 | | public string VirtualHost { get; set; } = DefaultVirtualHost; |
| | 6 | 23 | | public virtual string RoutingKey { get; set; } |
| | 9 | 24 | | public string UserName { get; set; } = ConnectionFactory.DefaultUser; |
| | 9 | 25 | | public string Password { get; set; } = ConnectionFactory.DefaultPass; |
| | 6 | 26 | | public SslOption SslOption { get; set; } |
| | 3 | 27 | | public bool AutomaticRecoveryEnabled => true; |
| | | 28 | | |
| | | 29 | | public static RabbitMqConnectionSettings FromUri( |
| | | 30 | | Uri uri, |
| | | 31 | | string userName, |
| | | 32 | | string password, |
| | | 33 | | SslOption sslOption = null, |
| | | 34 | | string virtualHost = DefaultVirtualHost) |
| | | 35 | | { |
| | 3 | 36 | | if (uri == null) |
| | | 37 | | { |
| | 0 | 38 | | throw new ArgumentException($"Parameter {nameof(uri)} cannot be null."); |
| | | 39 | | } |
| | | 40 | | |
| | 3 | 41 | | sslOption = ConfigureSslOption(sslOption, uri); |
| | 3 | 42 | | var queueName = GetQueueNameFromUri(uri); |
| | 3 | 43 | | var exchange = GetExchangeFromUri(uri); |
| | 3 | 44 | | var routingKey = GetRoutingKeyFromUri(uri, queueName); |
| | | 45 | | |
| | 3 | 46 | | return new RabbitMqConnectionSettings |
| | 3 | 47 | | { |
| | 3 | 48 | | BaseAddress = uri, |
| | 3 | 49 | | Host = uri.Host, |
| | 3 | 50 | | Port = uri.Port, |
| | 3 | 51 | | Exchange = exchange, |
| | 3 | 52 | | RoutingKey = routingKey, |
| | 3 | 53 | | QueueName = queueName, |
| | 3 | 54 | | VirtualHost = virtualHost, |
| | 3 | 55 | | UserName = userName, |
| | 3 | 56 | | Password = password, |
| | 3 | 57 | | SslOption = sslOption |
| | 3 | 58 | | }; |
| | | 59 | | } |
| | | 60 | | |
| | | 61 | | public ConnectionFactory GetConnectionFactory(string userName = null, string password = null) |
| | | 62 | | { |
| | 3 | 63 | | return new ConnectionFactory |
| | 3 | 64 | | { |
| | 3 | 65 | | HostName = Host, |
| | 3 | 66 | | Port = Port, |
| | 3 | 67 | | VirtualHost = VirtualHost, |
| | 3 | 68 | | UserName = userName ?? UserName, |
| | 3 | 69 | | Password = password ?? Password, |
| | 3 | 70 | | Ssl = SslOption, |
| | 3 | 71 | | AutomaticRecoveryEnabled = AutomaticRecoveryEnabled |
| | 3 | 72 | | }; |
| | | 73 | | } |
| | | 74 | | |
| | | 75 | | private static string GetQueueNameFromUri(Uri uri) |
| | | 76 | | { |
| | 3 | 77 | | if (uri.Segments.Length < 2) |
| | | 78 | | { |
| | 0 | 79 | | throw new ArgumentException(SR.Format(SR.InvalidRabbitMqUri, uri)); |
| | | 80 | | } |
| | | 81 | | |
| | 3 | 82 | | var lastSegment = uri.Segments.LastOrDefault(); |
| | 3 | 83 | | if (lastSegment.EndsWith("/")) |
| | | 84 | | { |
| | | 85 | | // Exchange found but no queueName, so create unique queueName |
| | 0 | 86 | | return $"{TempQueuePrefix}{new Guid()}"; |
| | | 87 | | } |
| | | 88 | | |
| | 3 | 89 | | return lastSegment.Replace("/", string.Empty); |
| | | 90 | | } |
| | | 91 | | |
| | | 92 | | private static string GetExchangeFromUri(Uri uri) |
| | | 93 | | { |
| | 3 | 94 | | if (uri.Segments.Length < 2) |
| | | 95 | | { |
| | 0 | 96 | | throw new ArgumentException(SR.Format(SR.InvalidRabbitMqUri, uri)); |
| | | 97 | | } |
| | | 98 | | |
| | 3 | 99 | | var secondSegment = uri.Segments[1]; |
| | 3 | 100 | | if (secondSegment.EndsWith("/")) |
| | | 101 | | { |
| | | 102 | | // Exchange name was found |
| | 3 | 103 | | return secondSegment.Replace("/", string.Empty); |
| | | 104 | | } |
| | | 105 | | |
| | | 106 | | // Exchange name was not found |
| | 0 | 107 | | return string.Empty; |
| | | 108 | | } |
| | | 109 | | |
| | | 110 | | private static string GetRoutingKeyFromUri(Uri uri, string queueName) |
| | | 111 | | { |
| | 3 | 112 | | if (string.IsNullOrEmpty(uri.Fragment)) |
| | | 113 | | { |
| | 0 | 114 | | return queueName; |
| | | 115 | | } |
| | | 116 | | |
| | 3 | 117 | | return uri.Fragment.Replace("#", string.Empty); |
| | | 118 | | } |
| | | 119 | | |
| | | 120 | | |
| | | 121 | | private static SslOption ConfigureSslOption(SslOption sslOption, Uri uri) |
| | | 122 | | { |
| | 3 | 123 | | if (sslOption != null) |
| | | 124 | | { |
| | 3 | 125 | | return sslOption; |
| | | 126 | | } |
| | | 127 | | |
| | 0 | 128 | | if (uri.Scheme.Contains(SecureAMQPScheme)) |
| | | 129 | | { |
| | 0 | 130 | | return new SslOption { ServerName = uri.Host, Enabled = true }; |
| | | 131 | | } |
| | | 132 | | |
| | 0 | 133 | | return new SslOption(); |
| | | 134 | | } |
| | | 135 | | } |
| | | 136 | | } |