Skip to content

Commit d4b49cf

Browse files
authored
Merge pull request #1110 from bollhals/feature/connectionConfig
introduce Connection Config class
2 parents bb84da0 + 9e91ead commit d4b49cf

20 files changed

+299
-162
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
3+
namespace RabbitMQ
4+
{
5+
#nullable enable
6+
#if NETSTANDARD
7+
internal static class StringExtension
8+
{
9+
public static bool Contains(this string toSearch, string value, StringComparison comparisonType)
10+
{
11+
return toSearch.IndexOf(value, comparisonType) > 0;
12+
}
13+
}
14+
#endif
15+
}

projects/RabbitMQ.Client/RabbitMQ.Client.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
<Deterministic>true</Deterministic>
3737
</PropertyGroup>
3838

39+
<!-- disable nullable warnings for .NET Standard 2.0 -->
40+
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
41+
<NoWarn>$(NoWarn);nullable</NoWarn>
42+
</PropertyGroup>
43+
3944
<Target Name="SetVersionFromConcourseData" AfterTargets="MinVer" Condition="'$(CONCOURSE_PULL_REQUEST_NUMBER)' != ''">
4045
<PropertyGroup>
4146
<PackageVersion>$(MinVerMajor).$(MinVerMinor).$(MinVerPatch)-$(MinVerPreRelease)-pr.$(CONCOURSE_PULL_REQUEST_NUMBER)</PackageVersion>
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// This source code is dual-licensed under the Apache License, version
2+
// 2.0, and the Mozilla Public License, version 2.0.
3+
//
4+
// The APL v2.0:
5+
//
6+
//---------------------------------------------------------------------------
7+
// Copyright (c) 2007-2020 VMware, Inc.
8+
//
9+
// Licensed under the Apache License, Version 2.0 (the "License");
10+
// you may not use this file except in compliance with the License.
11+
// You may obtain a copy of the License at
12+
//
13+
// https://www.apache.org/licenses/LICENSE-2.0
14+
//
15+
// Unless required by applicable law or agreed to in writing, software
16+
// distributed under the License is distributed on an "AS IS" BASIS,
17+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
// See the License for the specific language governing permissions and
19+
// limitations under the License.
20+
//---------------------------------------------------------------------------
21+
//
22+
// The MPL v2.0:
23+
//
24+
//---------------------------------------------------------------------------
25+
// This Source Code Form is subject to the terms of the Mozilla Public
26+
// License, v. 2.0. If a copy of the MPL was not distributed with this
27+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
28+
//
29+
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
30+
//---------------------------------------------------------------------------
31+
32+
using System;
33+
using System.Collections.Generic;
34+
35+
using RabbitMQ.Client.Impl;
36+
37+
namespace RabbitMQ.Client
38+
{
39+
#nullable enable
40+
/// <summary>
41+
/// The configuration of a connection.
42+
/// </summary>
43+
public sealed class ConnectionConfig
44+
{
45+
/// <summary>
46+
/// Virtual host to access during this connection.
47+
/// </summary>
48+
public string VirtualHost { get; }
49+
50+
/// <summary>
51+
/// Username to use when authenticating to the server.
52+
/// </summary>
53+
public string UserName { get; }
54+
55+
/// <summary>
56+
/// Password to use when authenticating to the server.
57+
/// </summary>
58+
public string Password { get; internal set; }
59+
60+
/// <summary>
61+
/// SASL auth mechanisms to use.
62+
/// </summary>
63+
public IList<IAuthMechanismFactory> AuthMechanisms { get; }
64+
65+
/// <summary>
66+
/// Dictionary of client properties to be sent to the server.
67+
/// </summary>
68+
public IDictionary<string, object?> ClientProperties { get; }
69+
70+
/// <summary>
71+
/// Default client provided name to be used for connections.
72+
/// </summary>
73+
public string? ClientProvidedName { get; }
74+
75+
/// <summary>
76+
/// Maximum channel number to ask for.
77+
/// </summary>
78+
public ushort MaxChannelCount { get; }
79+
/// <summary>
80+
/// Frame-max parameter to ask for (in bytes).
81+
/// </summary>
82+
public uint MaxFrameSize { get; }
83+
84+
/// <summary>
85+
/// Set to false to make automatic connection recovery not recover topology (exchanges, queues, bindings, etc).
86+
/// </summary>
87+
public bool TopologyRecoveryEnabled { get; }
88+
89+
/// <summary>
90+
/// Amount of time client will wait for before re-trying to recover connection.
91+
/// </summary>
92+
public TimeSpan NetworkRecoveryInterval { get; }
93+
94+
/// <summary>
95+
/// Heartbeat timeout to use when negotiating with the server.
96+
/// </summary>
97+
public TimeSpan HeartbeatInterval { get; }
98+
99+
/// <summary>
100+
/// Amount of time protocol operations (e.g. <code>queue.declare</code>) are allowed to take before timing out.
101+
/// </summary>
102+
public TimeSpan ContinuationTimeout { get; }
103+
104+
/// <summary>
105+
/// Amount of time protocol handshake operations are allowed to take before timing out.
106+
/// </summary>
107+
108+
public TimeSpan HandshakeContinuationTimeout { get; }
109+
/// <summary>
110+
/// Timeout setting for connection attempts.
111+
/// </summary>
112+
public TimeSpan RequestedConnectionTimeout { get; }
113+
114+
/// <summary>
115+
/// Set to true will enable an asynchronous consumer dispatcher which is compatible with <see cref="IAsyncBasicConsumer"/>.
116+
/// </summary>
117+
public bool DispatchConsumersAsync { get; }
118+
119+
/// <summary>
120+
/// Set to a value greater than one to enable concurrent processing. For a concurrency greater than one <see cref="IBasicConsumer"/>
121+
/// will be offloaded to the worker thread pool so it is important to choose the value for the concurrency wisely to avoid thread pool overloading.
122+
/// <see cref="IAsyncBasicConsumer"/> can handle concurrency much more efficiently due to the non-blocking nature of the consumer.
123+
/// </summary>
124+
public int DispatchConsumerConcurrency { get; }
125+
126+
internal Func<AmqpTcpEndpoint, IFrameHandler> FrameHandlerFactory { get; }
127+
128+
internal ConnectionConfig(string virtualHost, string userName, string password, IList<IAuthMechanismFactory> authMechanisms,
129+
IDictionary<string, object?> clientProperties, string? clientProvidedName,
130+
ushort maxChannelCount, uint maxFrameSize, bool topologyRecoveryEnabled,
131+
TimeSpan networkRecoveryInterval, TimeSpan heartbeatInterval, TimeSpan continuationTimeout, TimeSpan handshakeContinuationTimeout, TimeSpan requestedConnectionTimeout,
132+
bool dispatchConsumersAsync, int dispatchConsumerConcurrency,
133+
Func<AmqpTcpEndpoint, IFrameHandler> frameHandlerFactory)
134+
{
135+
VirtualHost = virtualHost;
136+
UserName = userName;
137+
Password = password;
138+
AuthMechanisms = authMechanisms;
139+
ClientProperties = clientProperties;
140+
ClientProvidedName = clientProvidedName;
141+
MaxChannelCount = maxChannelCount;
142+
MaxFrameSize = maxFrameSize;
143+
TopologyRecoveryEnabled = topologyRecoveryEnabled;
144+
NetworkRecoveryInterval = networkRecoveryInterval;
145+
HeartbeatInterval = heartbeatInterval;
146+
ContinuationTimeout = continuationTimeout;
147+
HandshakeContinuationTimeout = handshakeContinuationTimeout;
148+
RequestedConnectionTimeout = requestedConnectionTimeout;
149+
DispatchConsumersAsync = dispatchConsumersAsync;
150+
DispatchConsumerConcurrency = dispatchConsumerConcurrency;
151+
FrameHandlerFactory = frameHandlerFactory;
152+
}
153+
}
154+
}

projects/RabbitMQ.Client/client/api/ConnectionFactory.cs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ public TimeSpan HandshakeContinuationTimeout
199199
}
200200

201201
/// <summary>
202-
/// Amount of time protocol operations (e.g. <code>queue.declare</code>) are allowed to take before
202+
/// Amount of time protocol operations (e.g. <code>queue.declare</code>) are allowed to take before
203203
/// timing out.
204204
/// </summary>
205205
public TimeSpan ContinuationTimeout
@@ -492,32 +492,47 @@ public IConnection CreateConnection(IList<AmqpTcpEndpoint> endpoints, string cli
492492
/// </exception>
493493
public IConnection CreateConnection(IEndpointResolver endpointResolver, string clientProvidedName)
494494
{
495-
IConnection conn;
495+
ConnectionConfig config = CreateConfig(clientProvidedName);
496496
try
497497
{
498498
if (AutomaticRecoveryEnabled)
499499
{
500-
var autorecoveringConnection = new AutorecoveringConnection(this, clientProvidedName);
501-
autorecoveringConnection.Init(endpointResolver);
502-
conn = autorecoveringConnection;
503-
}
504-
else
505-
{
506-
conn = ((ProtocolBase)Protocols.AMQP_0_9_1).CreateConnection(this, endpointResolver.SelectOne(CreateFrameHandler), clientProvidedName);
500+
return new AutorecoveringConnection(config, endpointResolver);
507501
}
502+
503+
return new Connection(config, endpointResolver.SelectOne(CreateFrameHandler));
508504
}
509505
catch (Exception e)
510506
{
511507
throw new BrokerUnreachableException(e);
512508
}
509+
}
513510

514-
return conn;
511+
private ConnectionConfig CreateConfig(string clientProvidedName)
512+
{
513+
return new ConnectionConfig(
514+
VirtualHost,
515+
UserName,
516+
Password,
517+
AuthMechanisms,
518+
ClientProperties,
519+
clientProvidedName,
520+
RequestedChannelMax,
521+
RequestedFrameMax,
522+
TopologyRecoveryEnabled,
523+
NetworkRecoveryInterval,
524+
RequestedHeartbeat,
525+
ContinuationTimeout,
526+
HandshakeContinuationTimeout,
527+
RequestedConnectionTimeout,
528+
DispatchConsumersAsync,
529+
ConsumerDispatchConcurrency,
530+
CreateFrameHandler);
515531
}
516532

517533
internal IFrameHandler CreateFrameHandler(AmqpTcpEndpoint endpoint)
518534
{
519-
IFrameHandler fh = Protocols.DefaultProtocol.CreateFrameHandler(endpoint, SocketFactory,
520-
RequestedConnectionTimeout, SocketReadTimeout, SocketWriteTimeout);
535+
IFrameHandler fh = new SocketFrameHandler(endpoint, SocketFactory, RequestedConnectionTimeout, SocketReadTimeout, SocketWriteTimeout);
521536
return ConfigureFrameHandler(fh);
522537
}
523538

projects/RabbitMQ.Client/client/api/ExternalMechanism.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class ExternalMechanism : IAuthMechanism
3838
/// <summary>
3939
/// Handle one round of challenge-response.
4040
/// </summary>
41-
public byte[] handleChallenge(byte[] challenge, IConnectionFactory factory)
41+
public byte[] handleChallenge(byte[] challenge, ConnectionConfig config)
4242
{
4343
return Array.Empty<byte>();
4444
}

projects/RabbitMQ.Client/client/api/IAuthMechanism.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,6 @@ public interface IAuthMechanism
3939
/// <summary>
4040
/// Handle one round of challenge-response.
4141
/// </summary>
42-
byte[] handleChallenge(byte[] challenge, IConnectionFactory factory);
42+
byte[] handleChallenge(byte[] challenge, ConnectionConfig config);
4343
}
4444
}

projects/RabbitMQ.Client/client/api/IProtocol.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
3030
//---------------------------------------------------------------------------
3131

32-
using RabbitMQ.Client.Impl;
33-
3432
namespace RabbitMQ.Client
3533
{
3634
/// <summary>

projects/RabbitMQ.Client/client/api/PlainMechanism.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ namespace RabbitMQ.Client
3535
{
3636
public class PlainMechanism : IAuthMechanism
3737
{
38-
public byte[] handleChallenge(byte[] challenge, IConnectionFactory factory)
38+
public byte[] handleChallenge(byte[] challenge, ConnectionConfig config)
3939
{
40-
return Encoding.UTF8.GetBytes($"\0{factory.UserName}\0{factory.Password}");
40+
return Encoding.UTF8.GetBytes($"\0{config.UserName}\0{config.Password}");
4141
}
4242
}
4343
}

projects/RabbitMQ.Client/client/framing/Model.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,14 @@
3131

3232
using System.Collections.Generic;
3333
using RabbitMQ.Client.client.framing;
34+
using RabbitMQ.Client.client.impl;
3435
using RabbitMQ.Client.Impl;
3536

3637
namespace RabbitMQ.Client.Framing.Impl
3738
{
3839
internal class Model: ModelBase
3940
{
40-
public Model(bool dispatchAsync, int concurrency, ISession session) : base(dispatchAsync, concurrency, session)
41+
public Model(ConnectionConfig config, ISession session) : base(config, session)
4142
{
4243
}
4344

projects/RabbitMQ.Client/client/impl/AutorecoveringConnection.Recording.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ internal void DeleteRecordedBinding(in RecordedBinding rb)
176176

177177
internal void RecordConsumer(in RecordedConsumer consumer)
178178
{
179-
if (!_factory.TopologyRecoveryEnabled)
179+
if (!_config.TopologyRecoveryEnabled)
180180
{
181181
return;
182182
}
@@ -189,7 +189,7 @@ internal void RecordConsumer(in RecordedConsumer consumer)
189189

190190
internal void DeleteRecordedConsumer(string consumerTag)
191191
{
192-
if (!_factory.TopologyRecoveryEnabled)
192+
if (!_config.TopologyRecoveryEnabled)
193193
{
194194
return;
195195
}

0 commit comments

Comments
 (0)