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