[skip appveyor] Added support for ClientProperties (manual and in the AppSettings)
Added support for managementport in the ConnectionStringParser Added documentation on setting the connection parameters
This commit is contained in:
parent
7075baeb80
commit
84ee6f090d
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using ExampleLib;
|
||||
using SimpleInjector;
|
||||
@ -42,7 +43,13 @@ namespace _01_PublishSubscribe
|
||||
{
|
||||
HostName = "localhost",
|
||||
Username = "guest",
|
||||
Password = "guest"
|
||||
Password = "guest",
|
||||
|
||||
// These properties allow you to identify the connection in the RabbitMQ Management interface
|
||||
ClientProperties = new Dictionary<string, string>
|
||||
{
|
||||
{ "example", "01 - Publish Subscribe" }
|
||||
}
|
||||
}
|
||||
})
|
||||
{
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
@ -481,6 +482,16 @@ namespace Tapeti.Connection
|
||||
RequestedHeartbeat = 30
|
||||
};
|
||||
|
||||
if (connectionParams.ClientProperties != null)
|
||||
foreach (var pair in connectionParams.ClientProperties)
|
||||
{
|
||||
if (connectionFactory.ClientProperties.ContainsKey(pair.Key))
|
||||
connectionFactory.ClientProperties[pair.Key] = Encoding.UTF8.GetBytes(pair.Value);
|
||||
else
|
||||
connectionFactory.ClientProperties.Add(pair.Key, Encoding.UTF8.GetBytes(pair.Value));
|
||||
}
|
||||
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
|
@ -123,6 +123,7 @@ namespace Tapeti.Helpers
|
||||
case "username": result.Username = value; break;
|
||||
case "password": result.Password = value; break;
|
||||
case "prefetchcount": result.PrefetchCount = ushort.Parse(value); break;
|
||||
case "managementport": result.ManagementPort = int.Parse(value); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
|
||||
namespace Tapeti
|
||||
@ -19,6 +18,7 @@ namespace Tapeti
|
||||
/// <item><description>rabbitmq:password</description></item>
|
||||
/// <item><description>rabbitmq:prefetchcount</description></item>
|
||||
/// <item><description>rabbitmq:managementport</description></item>
|
||||
/// <item><description>rabbitmq:clientproperty:*</description></item>
|
||||
/// </list>
|
||||
public class TapetiAppSettingsConnectionParams : TapetiConnectionParams
|
||||
{
|
||||
@ -30,6 +30,20 @@ namespace Tapeti
|
||||
private const string KeyPassword = "password";
|
||||
private const string KeyPrefetchCount = "prefetchcount";
|
||||
private const string KeyManagementPort = "managementport";
|
||||
private const string KeyClientProperty = "clientproperty:";
|
||||
|
||||
|
||||
private struct AppSettingsKey
|
||||
{
|
||||
public readonly string Entry;
|
||||
public readonly string Parameter;
|
||||
|
||||
public AppSettingsKey(string entry, string parameter)
|
||||
{
|
||||
Entry = entry;
|
||||
Parameter = parameter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -37,21 +51,35 @@ namespace Tapeti
|
||||
/// <param name="prefix">The prefix to apply to the keys. Defaults to "rabbitmq:"</param>
|
||||
public TapetiAppSettingsConnectionParams(string prefix = DefaultPrefix)
|
||||
{
|
||||
var keys = ConfigurationManager.AppSettings.AllKeys;
|
||||
var keys = !string.IsNullOrEmpty(prefix)
|
||||
? ConfigurationManager.AppSettings.AllKeys.Where(k => k.StartsWith(prefix)).Select(k => new AppSettingsKey(k, k.Substring(prefix.Length)))
|
||||
: ConfigurationManager.AppSettings.AllKeys.Select(k => new AppSettingsKey(k, k));
|
||||
|
||||
void GetAppSetting(string key, Action<string> setValue)
|
||||
|
||||
|
||||
foreach (var key in keys)
|
||||
{
|
||||
if (keys.Contains(prefix + key)) setValue(ConfigurationManager.AppSettings[prefix + key]);
|
||||
}
|
||||
var value = ConfigurationManager.AppSettings[key.Entry];
|
||||
|
||||
|
||||
GetAppSetting(KeyHostname, value => HostName = value);
|
||||
GetAppSetting(KeyPort, value => Port = int.Parse(value));
|
||||
GetAppSetting(KeyVirtualHost, value => VirtualHost = value);
|
||||
GetAppSetting(KeyUsername, value => Username = value);
|
||||
GetAppSetting(KeyPassword, value => Password = value);
|
||||
GetAppSetting(KeyPrefetchCount, value => PrefetchCount = ushort.Parse(value));
|
||||
GetAppSetting(KeyManagementPort, value => ManagementPort = int.Parse(value));
|
||||
if (key.Parameter.StartsWith(KeyClientProperty))
|
||||
{
|
||||
ClientProperties.Add(key.Parameter.Substring(KeyClientProperty.Length), value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ReSharper disable once SwitchStatementMissingSomeCases - don't fail if we encounter an unknown value
|
||||
switch (key.Parameter)
|
||||
{
|
||||
case KeyHostname: HostName = value; break;
|
||||
case KeyPort: Port = int.Parse(value); break;
|
||||
case KeyVirtualHost: VirtualHost = value; break;
|
||||
case KeyUsername: Username = value; break;
|
||||
case KeyPassword: Password = value; break;
|
||||
case KeyPrefetchCount: PrefetchCount = ushort.Parse(value); break;
|
||||
case KeyManagementPort: ManagementPort = int.Parse(value); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
// ReSharper disable UnusedMember.Global
|
||||
|
||||
namespace Tapeti
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// Defines the connection parameters.
|
||||
/// </summary>
|
||||
public class TapetiConnectionParams
|
||||
{
|
||||
private IDictionary<string, string> clientProperties;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The hostname to connect to. Defaults to localhost.
|
||||
/// </summary>
|
||||
@ -46,6 +50,20 @@ namespace Tapeti
|
||||
/// </summary>
|
||||
public int ManagementPort { get; set; } = 15672;
|
||||
|
||||
/// <summary>
|
||||
/// Key-value pair of properties that are set on the connection. These will be visible in the RabbitMQ Management interface.
|
||||
/// Note that you can either set a new dictionary entirely, to allow for inline declaration, or use this property directly
|
||||
/// and use the auto-created dictionary.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If any of the default keys used by the RabbitMQ Client library (product, version) are specified their value
|
||||
/// will be overwritten. See DefaultClientProperties in Connection.cs in the RabbitMQ .NET client source for the default values.
|
||||
/// </remarks>
|
||||
public IDictionary<string, string> ClientProperties {
|
||||
get => clientProperties ?? (clientProperties = new Dictionary<string, string>());
|
||||
set => clientProperties = value;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public TapetiConnectionParams()
|
||||
|
@ -149,3 +149,72 @@ To send a message, get a reference to IPublisher using dependency injection and
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Connection parameters
|
||||
---------------------
|
||||
If you don't want to use the default connection parameters, which is probably a good idea in a production environment, you can manually specify the properties for TapetiConnectionParams or get them from your configuration of choice. Tapeti provides with two helpers.
|
||||
|
||||
App.config / Web.config
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
The TapetiAppSettingsConnectionParams class can be used to load the connection parameters from the AppSettings:
|
||||
|
||||
::
|
||||
|
||||
using (var connection = new TapetiConnection(config)
|
||||
{
|
||||
Params = new TapetiAppSettingsConnectionParams()
|
||||
})
|
||||
|
||||
The constructor accepts a prefix parameter, which defaults to "rabbitmq:". You can then specify the values in the appSettings block of your App.config or Web.config. Any omitted parameters will use the default value.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="rabbitmq:hostname" value="localhost" />
|
||||
<add key="rabbitmq:port" value="5672" />
|
||||
<add key="rabbitmq:virtualhost" value="/" />
|
||||
<add key="rabbitmq:username" value="guest" />
|
||||
<add key="rabbitmq:password" value="guest" />
|
||||
<add key="rabbitmq:prefetchcount" value="50" />
|
||||
<add key="rabbitmq:managementport" value="15672" />
|
||||
<add key="rabbitmq:clientproperty:application" value="Example" />
|
||||
</appSettings>
|
||||
</configuration>
|
||||
|
||||
|
||||
The last entry is special: any setting which starts with "clientproperty:", after the configured prefix, will be added to the ClientProperties set. These properties are visible in the RabbitMQ Management interface and can be used to identify the connection.
|
||||
|
||||
ConnectionString
|
||||
^^^^^^^^^^^^^^^^
|
||||
Tapeti also includes a helper which can parse a connection string style value which is mainly for compatibility with `EasyNetQ <http://easynetq.com/>`_. It made porting our applications slightly easier. EasyNetQ is a very capable library which includes high- and low-level wrappers for the RabbitMQ Client as well as a Management API client, and is worth checking out if you have a use case that is not suited to Tapeti.
|
||||
|
||||
To parse a connection string, use the ConnectionStringParser.Parse method. You can of course still load the value from the AppSettings easily:
|
||||
|
||||
::
|
||||
|
||||
using (var connection = new TapetiConnection(config)
|
||||
{
|
||||
Params = Tapeti.Helpers.ConnectionStringParser.Parse(
|
||||
ConfigurationManager.AppSettings["RabbitMQ.ConnectionString"])
|
||||
})
|
||||
|
||||
An example connection string:
|
||||
|
||||
::
|
||||
|
||||
host=localhost;username=guest;password=prefetchcount=5
|
||||
|
||||
Supported keys are:
|
||||
|
||||
- hostname
|
||||
- port
|
||||
- virtualhost
|
||||
- username
|
||||
- password
|
||||
- prefetchcount
|
||||
- managementport
|
||||
|
||||
Any keys in the connection string which are not supported will be silently ignored.
|
@ -22,3 +22,5 @@ Key features
|
||||
What it is not
|
||||
--------------
|
||||
Tapeti is not a general purpose RabbitMQ client. Although some behaviour can be overridden by implementing various interfaces, it enforces it's style of messaging and assumes everyone on the bus speaks the same language.
|
||||
|
||||
There is no support for TLS connections, nor are there any plans to support it. The author is of the opinion the message bus should be considered an internal, highly available, service and recommends self-hosted REST API's behind an SSL proxy for communicating over public interfaces.
|
Loading…
Reference in New Issue
Block a user