diff options
Diffstat (limited to 'qpid/dotnet/Qpid.Client/qms')
-rw-r--r-- | qpid/dotnet/Qpid.Client/qms/BrokerInfo.cs | 55 | ||||
-rw-r--r-- | qpid/dotnet/Qpid.Client/qms/ConnectionInfo.cs | 63 | ||||
-rw-r--r-- | qpid/dotnet/Qpid.Client/qms/FailoverPolicy.cs | 315 | ||||
-rw-r--r-- | qpid/dotnet/Qpid.Client/qms/UrlSyntaxException.cs | 134 | ||||
-rw-r--r-- | qpid/dotnet/Qpid.Client/qms/failover/FailoverMethod.cs | 78 | ||||
-rw-r--r-- | qpid/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs | 255 | ||||
-rw-r--r-- | qpid/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs | 147 |
7 files changed, 1047 insertions, 0 deletions
diff --git a/qpid/dotnet/Qpid.Client/qms/BrokerInfo.cs b/qpid/dotnet/Qpid.Client/qms/BrokerInfo.cs new file mode 100644 index 0000000000..93c00af6e0 --- /dev/null +++ b/qpid/dotnet/Qpid.Client/qms/BrokerInfo.cs @@ -0,0 +1,55 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +using System; + +namespace Apache.Qpid.Client.Qms +{ + /// <summary> + /// Know URL option names. + /// <seealso cref="IConnectionInfo"/> + /// </summary> + public class BrokerInfoConstants + { + public const String OPTIONS_RETRY = "retries"; + public const String OPTIONS_SSL = ConnectionUrlConstants.OPTIONS_SSL; + public const String OPTIONS_CONNECT_TIMEOUT = "connecttimeout"; + public const int DEFAULT_PORT = 5672; + public const String DEFAULT_TRANSPORT = "tcp"; + + public readonly string URL_FORMAT_EXAMPLE = + "<transport>://<hostname>[:<port Default=\"" + DEFAULT_PORT + "\">][?<option>='<value>'[,<option>='<value>']]"; + + public const long DEFAULT_CONNECT_TIMEOUT = 30000L; + } + + public interface IBrokerInfo + { + string Host { get; set; } + int Port { get; set; } + string Transport { get; set; } + bool UseSSL { get; set; } + long Timeout { get; set; } + SslOptions SslOptions { get; } + + String GetOption(string key); + void SetOption(string key, string value); + } +} diff --git a/qpid/dotnet/Qpid.Client/qms/ConnectionInfo.cs b/qpid/dotnet/Qpid.Client/qms/ConnectionInfo.cs new file mode 100644 index 0000000000..4d3f7698b5 --- /dev/null +++ b/qpid/dotnet/Qpid.Client/qms/ConnectionInfo.cs @@ -0,0 +1,63 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +using System.Collections; + +namespace Apache.Qpid.Client.Qms +{ + class ConnectionUrlConstants + { + public const string AMQ_PROTOCOL = "amqp"; + public const string OPTIONS_BROKERLIST = "brokerlist"; + public const string OPTIONS_FAILOVER = "failover"; + public const string OPTIONS_FAILOVER_CYCLE = "cyclecount"; + public const string OPTIONS_SSL = "ssl"; + } + + /// <summary> + /// Connection URL format + /// amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\'&option=\'value\';vm://:3/virtualpath?option=\'value\''&failover='method?option=\'value\'&option='value''" + /// Options are of course optional except for requiring a single broker in the broker list. + /// The option seperator is defined to be either '&' or ',' + /// </summary> + public interface IConnectionInfo + { + string AsUrl(); + + string FailoverMethod { get; set; } + string ClientName { get; set; } + string Username { get; set; } + string Password { get; set; } + string VirtualHost { get; set; } + string GetFailoverOption(string key); + + int BrokerCount { get; } + + IBrokerInfo GetBrokerInfo(int index); + + void AddBrokerInfo(IBrokerInfo broker); + + IList GetAllBrokerInfos(); + + string GetOption(string key); + + void SetOption(string key, string value); + } +} diff --git a/qpid/dotnet/Qpid.Client/qms/FailoverPolicy.cs b/qpid/dotnet/Qpid.Client/qms/FailoverPolicy.cs new file mode 100644 index 0000000000..179a695bf9 --- /dev/null +++ b/qpid/dotnet/Qpid.Client/qms/FailoverPolicy.cs @@ -0,0 +1,315 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +using System; +using System.Text; +using log4net; +using Apache.Qpid.Client.Qms.Failover; + +namespace Apache.Qpid.Client.Qms +{ + public class FailoverPolicy + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(FailoverPolicy)); + + private const long MINUTE = 60000L; + + private const long DEFAULT_METHOD_TIMEOUT = 1 * MINUTE; + private const long DEFAULT_FAILOVER_TIMEOUT = 4 * MINUTE; + + private IFailoverMethod[] _methods = new IFailoverMethod[1]; + + private int _currentMethod; + + private int _methodsRetries; + + private int _currentRetry; + + private bool _timing; + + private long _lastMethodTime; + private long _lastFailTime; + + public FailoverPolicy(IConnectionInfo connectionInfo) + { + IFailoverMethod method; + + //todo This should be integrated in to the connection url when it supports + // multiple strategies. + + _methodsRetries = 0; + + if (connectionInfo.FailoverMethod == null) + { + if (connectionInfo.BrokerCount > 1) + { + method = new FailoverRoundRobin(connectionInfo); + } + else + { + method = new FailoverSingleServer(connectionInfo); + } + } + else + { + string failoverMethod = connectionInfo.FailoverMethod; + + /* + if (failoverMethod.equals(FailoverMethod.RANDOM)) + { + //todo write a random connection Failover + } + */ + if (failoverMethod.Equals(FailoverMethodConstants.ROUND_ROBIN)) + { + method = new FailoverRoundRobin(connectionInfo); + } + else + { + throw new NotImplementedException("Dynamic loading of FailoverMethods not yet implemented."); +// try +// { +// Type[] constructorSpec = {ConnectionInfo.class}; +// Object [] params = {connectionInfo}; +// +// method = (FailoverMethod) ClassLoader.getSystemClassLoader(). +// loadClass(failoverMethod). +// getConstructor(constructorSpec).newInstance(params); +// } +// catch (Exception cnfe) +// { +// throw new IllegalArgumentException("Unknown failover method:" + failoverMethod); +// } + } + } + + if (method == null) + { + throw new ArgumentException("Unknown failover method specified."); + } + + reset(); + + _methods[_currentMethod] = method; + } + + public FailoverPolicy(IFailoverMethod method) : this(method, 0) + { + } + + public FailoverPolicy(IFailoverMethod method, int retries) + { + _methodsRetries = retries; + + reset(); + + _methods[_currentMethod] = method; + } + + private void reset() + { + _currentMethod = 0; + _currentRetry = 0; + _timing = false; + + } + + public bool FailoverAllowed() + { + bool failoverAllowed; + + if (_timing) + { + long now = CurrentTimeMilliseconds(); + + if ((now - _lastMethodTime) >= DEFAULT_METHOD_TIMEOUT) + { + _logger.Info("Failover method timeout"); + _lastMethodTime = now; + + if (!nextMethod()) + { + return false; + } + + + } + else if ((now - _lastFailTime) >= DEFAULT_FAILOVER_TIMEOUT) + { + _logger.Info("Failover timeout"); + return false; + } + else + { + _lastMethodTime = now; + } + } + else + { + _timing = true; + _lastMethodTime = CurrentTimeMilliseconds(); + _lastFailTime = _lastMethodTime; + } + + + if (_methods[_currentMethod].FailoverAllowed()) + { + failoverAllowed = true; + } + else + { + if (_currentMethod < (_methods.Length - 1)) + { + nextMethod(); + _logger.Info("Changing method to " + _methods[_currentMethod].MethodName); + return FailoverAllowed(); + } + else + { + return cycleMethods(); + } + } + + return failoverAllowed; + } + + private static long CurrentTimeMilliseconds() + { + return DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; + } + + private bool nextMethod() + { + if (_currentMethod < (_methods.Length - 1)) + { + _currentMethod++; + _methods[_currentMethod].Reset(); + return true; + } + else + { + return cycleMethods(); + } + } + + private bool cycleMethods() + { + if (_currentRetry < _methodsRetries) + { + _currentRetry++; + + _currentMethod = 0; + + _logger.Info("Retrying methods starting with " + _methods[_currentMethod].MethodName); + _methods[_currentMethod].Reset(); + return FailoverAllowed(); + } + else + { + _logger.Debug("All failover methods exhausted"); + return false; + } + } + + /** + * Notification that connection was successful. + */ + public void attainedConnection() + { + _currentRetry = 0; + + _methods[_currentMethod].AttainedConnection(); + + _timing = false; + } + + public IBrokerInfo GetCurrentBrokerInfo() + { + return _methods[_currentMethod].GetCurrentBrokerInfo(); + } + + public IBrokerInfo GetNextBrokerInfo() + { + return _methods[_currentMethod].GetNextBrokerDetails(); + } + + public void setBroker(IBrokerInfo broker) + { + _methods[_currentMethod].SetBroker(broker); + } + + public void addMethod(IFailoverMethod method) + { + int len = _methods.Length + 1; + IFailoverMethod[] newMethods = new IFailoverMethod[len]; + _methods.CopyTo(newMethods, 0); +// System.arraycopy(_methods, 0, newMethods, 0, _methods.length); + int index = len - 1; + newMethods[index] = method; + _methods = newMethods; + } + + public void setMethodRetries(int retries) + { + _methodsRetries = retries; + } + + public IFailoverMethod getCurrentMethod() + { + if (_currentMethod >= 0 && _currentMethod < (_methods.Length - 1)) + { + return _methods[_currentMethod]; + } + else + { + return null; + } + } + + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.Append("Failover Policy:\n"); + + if (FailoverAllowed()) + { + sb.Append("Failover allowed\n"); + } + else + { + sb.Append("Failover not allowed\n"); + } + + sb.Append("Failover policy methods\n"); + for (int i = 0; i < _methods.Length; i++) + { + + if (i == _currentMethod) + { + sb.Append(">"); + } + sb.Append(_methods[i].ToString()); + } + + return sb.ToString(); + } + } +} diff --git a/qpid/dotnet/Qpid.Client/qms/UrlSyntaxException.cs b/qpid/dotnet/Qpid.Client/qms/UrlSyntaxException.cs new file mode 100644 index 0000000000..ab3de325d4 --- /dev/null +++ b/qpid/dotnet/Qpid.Client/qms/UrlSyntaxException.cs @@ -0,0 +1,134 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +using System; +using System.Runtime.Serialization; +using System.Text; + +namespace Apache.Qpid.Client.Qms +{ + [Serializable] + public class UrlSyntaxException : UriFormatException + { + private string _url; + private int _index; + private int _length; + + public int GetIndex() + { + return _index; + } + + public UrlSyntaxException(String input, String reason) + : this(input, reason, -1) + { + } + + private UrlSyntaxException(string input, string reason, int index) + : + this(input, reason, index, input.Length) + { + } + + public UrlSyntaxException(String url, String error, int index, int length) + : base(error) + { + _url = url; + _index = index; + _length = length; + } + + protected UrlSyntaxException(SerializationInfo info, StreamingContext ctxt) + : base(info, ctxt) + { + _url = info.GetString("Url"); + _index = info.GetInt32("Index"); + _length = info.GetInt32("Length"); + } + + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + info.AddValue("Url", _url); + info.AddValue("Index", _index); + info.AddValue("Length", _length); + } + + private static String getPositionString(int index, int length) + { + StringBuilder sb = new StringBuilder(index + 1); + + for (int i = 0; i < index; i++) + { + sb.Append(" "); + } + + if (length > -1) + { + for (int i = 0; i < length; i++) + { + sb.Append('^'); + } + } + + return sb.ToString(); + } + + + public String toString() + { + StringBuilder sb = new StringBuilder(); + +// sb.Append(getReason()); + + if (_index > -1) + { + if (_length != -1) + { + sb.Append(" between indicies "); + sb.Append(_index); + sb.Append(" and "); + sb.Append(_length); + } + else + { + sb.Append(" at index "); + sb.Append(_index); + } + } + + sb.Append(" "); + if (_index != -1) + { + sb.Append("\n"); + } + + sb.Append(_url); + + if (_index != -1) + { + sb.Append("\n"); + sb.Append(getPositionString(_index, _length)); + } + + return sb.ToString(); + } + } +} diff --git a/qpid/dotnet/Qpid.Client/qms/failover/FailoverMethod.cs b/qpid/dotnet/Qpid.Client/qms/failover/FailoverMethod.cs new file mode 100644 index 0000000000..f32b275e84 --- /dev/null +++ b/qpid/dotnet/Qpid.Client/qms/failover/FailoverMethod.cs @@ -0,0 +1,78 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +using System; + +namespace Apache.Qpid.Client.Qms.Failover +{ + public class FailoverMethodConstants + { + public const String ROUND_ROBIN = "roundrobin"; + public const String RANDOM = "random"; + } + + public interface IFailoverMethod + { + /// <summary> + /// The name of this method for display purposes. + /// </summary> + String MethodName { get; } + + /// <summary> + /// Reset the Failover to initial conditions + /// </summary> + void Reset(); + + /// <summary> + /// Check if failover is possible for this method + /// </summary> + /// <returns>true if failover is allowed</returns> + bool FailoverAllowed(); + + /// <summary> + /// Notification to the Failover method that a connection has been attained. + /// </summary> + void AttainedConnection(); + + /// <summary> + /// If there is no current BrokerInfo the null will be returned. + /// </summary> + /// <returns>The current BrokerDetail value to use</returns> + IBrokerInfo GetCurrentBrokerInfo(); + + /// <summary> + /// Move to the next BrokerInfo if one is available. + /// </summary> + /// <returns>the next BrokerDetail or null if there is none.</returns> + IBrokerInfo GetNextBrokerDetails(); + + /// <summary> + /// Set the currently active broker to be the new value. + /// </summary> + /// <param name="broker">The new BrokerDetail value</param> + void SetBroker(IBrokerInfo broker); + + /// <summary> + /// Set the retries for this method + /// </summary> + /// <param name="maxRetries">the maximum number of time to retry this Method</param> + void SetRetries(int maxRetries); + } +} diff --git a/qpid/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs b/qpid/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs new file mode 100644 index 0000000000..8103940fb4 --- /dev/null +++ b/qpid/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs @@ -0,0 +1,255 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +using System; +using System.Text; +using log4net; + +namespace Apache.Qpid.Client.Qms.Failover +{ + public class FailoverRoundRobin : IFailoverMethod + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(FailoverRoundRobin)); + + /** The default number of times to cycle through all servers */ + public const int DEFAULT_CYCLE_RETRIES = 0; + /** The default number of times to retry each server */ + public const int DEFAULT_SERVER_RETRIES = 0; + + /** + * The index into the hostDetails array of the broker to which we are connected + */ + private int _currentBrokerIndex = -1; + + /** + * The number of times to retry connecting for each server + */ + private int _serverRetries; + + /** + * The current number of retry attempts made + */ + private int _currentServerRetry; + + /** + * The number of times to cycle through the servers + */ + private int _cycleRetries; + + /** + * The current number of cycles performed. + */ + private int _currentCycleRetries; + + /** + * Array of BrokerDetail used to make connections. + */ + private IConnectionInfo _connectionDetails; + + public FailoverRoundRobin(IConnectionInfo connectionDetails) + { + if (!(connectionDetails.BrokerCount > 0)) + { + throw new ArgumentException("At least one broker details must be specified."); + } + + _connectionDetails = connectionDetails; + + //There is no current broker at startup so set it to -1. + _currentBrokerIndex = -1; + + String cycleRetries = _connectionDetails.GetFailoverOption(ConnectionUrlConstants.OPTIONS_FAILOVER_CYCLE); + + if (cycleRetries != null) + { + try + { + _cycleRetries = int.Parse(cycleRetries); + } + catch (FormatException) + { + _cycleRetries = DEFAULT_CYCLE_RETRIES; + } + } + + _currentCycleRetries = 0; + + _serverRetries = 0; + _currentServerRetry = -1; + } + + public void Reset() + { + _currentBrokerIndex = 0; + _currentCycleRetries = 0; + _currentServerRetry = -1; + } + + public bool FailoverAllowed() + { + return ((_currentCycleRetries < _cycleRetries) + || (_currentServerRetry < _serverRetries) + || (_currentBrokerIndex < (_connectionDetails.BrokerCount - 1))); + } + + public void AttainedConnection() + { + _currentCycleRetries = 0; + _currentServerRetry = -1; + } + + public IBrokerInfo GetCurrentBrokerInfo() + { + if (_currentBrokerIndex == -1) + { + return null; + } + + return _connectionDetails.GetBrokerInfo(_currentBrokerIndex); + } + + public IBrokerInfo GetNextBrokerDetails() + { + if (_currentBrokerIndex == (_connectionDetails.BrokerCount - 1)) + { + if (_currentServerRetry < _serverRetries) + { + if (_currentBrokerIndex == -1) + { + _currentBrokerIndex = 0; + + SetBroker(_connectionDetails.GetBrokerInfo(_currentBrokerIndex )); + + _logger.Info("First Run using " + _connectionDetails.GetBrokerInfo(_currentBrokerIndex)); + } + else + { + _logger.Info("Retrying " + _connectionDetails.GetBrokerInfo(_currentBrokerIndex)); + } + + _currentServerRetry++; + } + else + { + _currentCycleRetries++; + //failed to connect to first broker + _currentBrokerIndex = 0; + + SetBroker(_connectionDetails.GetBrokerInfo(_currentBrokerIndex )); + + // This is zero rather than -1 as we are already retrieving the details. + _currentServerRetry = 0; + } + //else - should force client to stop as max retries has been reached. + } + else + { + if (_currentServerRetry < _serverRetries) + { + if (_currentBrokerIndex == -1) + { + _currentBrokerIndex = 0; + + SetBroker(_connectionDetails.GetBrokerInfo(_currentBrokerIndex )); + + _logger.Info("First Run using " + _connectionDetails.GetBrokerInfo(_currentBrokerIndex)); + } + else + { + _logger.Info("Retrying " + _connectionDetails.GetBrokerInfo(_currentBrokerIndex)); + } + _currentServerRetry++; + } + else + { + _currentBrokerIndex++; + + SetBroker(_connectionDetails.GetBrokerInfo(_currentBrokerIndex )); + // This is zero rather than -1 as we are already retrieving the details. + _currentServerRetry = 0; + } + } + + return _connectionDetails.GetBrokerInfo(_currentBrokerIndex); + } + + public void SetBroker(IBrokerInfo broker) + { + _connectionDetails.AddBrokerInfo(broker); + + int index = _connectionDetails.GetAllBrokerInfos().IndexOf(broker); + + String serverRetries = broker.GetOption(BrokerInfoConstants.OPTIONS_RETRY); + + if (serverRetries != null) + { + try + { + _serverRetries = int.Parse(serverRetries); + } + catch (FormatException) + { + _serverRetries = DEFAULT_SERVER_RETRIES; + } + } + + _currentServerRetry = -1; + _currentBrokerIndex = index; + } + + public void SetRetries(int maxRetries) + { + _cycleRetries = maxRetries; + } + + public String MethodName + { + get { return "Cycle Servers"; } + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + + sb.Append(GetType().Name).Append("\n"); + + sb.Append("Broker count: ").Append(_connectionDetails.BrokerCount); + sb.Append("\ncurrent broker index: ").Append(_currentBrokerIndex); + + sb.Append("\nCycle Retries: ").Append(_cycleRetries); + sb.Append("\nCurrent Cycle:").Append(_currentCycleRetries); + sb.Append("\nServer Retries:").Append(_serverRetries); + sb.Append("\nCurrent Retry:").Append(_currentServerRetry); + sb.Append("\n"); + + for(int i=0; i < _connectionDetails.BrokerCount ; i++) + { + if (i == _currentBrokerIndex) + { + sb.Append(">"); + } + sb.Append(_connectionDetails.GetBrokerInfo(i)); + sb.Append("\n"); + } + + return sb.ToString(); + } + } +} diff --git a/qpid/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs b/qpid/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs new file mode 100644 index 0000000000..5e502b897e --- /dev/null +++ b/qpid/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs @@ -0,0 +1,147 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +using System; + +namespace Apache.Qpid.Client.Qms.Failover +{ + public class FailoverSingleServer : IFailoverMethod + { + /** The default number of times to rety a conection to this server */ + public const int DEFAULT_SERVER_RETRIES = 1; + + /** + * The details of the Single Server + */ + private IBrokerInfo _brokerDetail; + + /** + * The number of times to retry connecting to the sever + */ + private int _retries; + + /** + * The current number of attempts made to the server + */ + private int _currentRetries; + + + public FailoverSingleServer(IConnectionInfo connectionDetails) + { + if (connectionDetails.BrokerCount > 0) + { + SetBroker(connectionDetails.GetBrokerInfo(0)); + } + else + { + throw new ArgumentException("BrokerInfo details required for connection."); + } + } + + public FailoverSingleServer(IBrokerInfo brokerDetail) + { + SetBroker(brokerDetail); + } + + public void Reset() + { + _currentRetries = -1; + } + + public bool FailoverAllowed() + { + return _currentRetries < _retries; + } + + public void AttainedConnection() + { + Reset(); + } + + public IBrokerInfo GetCurrentBrokerInfo() + { + return _brokerDetail; + } + + public IBrokerInfo GetNextBrokerDetails() + { + if (_currentRetries == _retries) + { + return null; + } + else + { + if (_currentRetries < _retries) + { + _currentRetries ++; + } + + return _brokerDetail; + } + } + + public void SetBroker(IBrokerInfo broker) + { + if (broker == null) + { + throw new ArgumentException("BrokerInfo details cannot be null"); + } + _brokerDetail = broker; + + String retries = broker.GetOption(BrokerInfoConstants.OPTIONS_RETRY); + if (retries != null) + { + try + { + _retries = int.Parse(retries); + } + catch (FormatException) + { + _retries = DEFAULT_SERVER_RETRIES; + } + } + else + { + _retries = DEFAULT_SERVER_RETRIES; + } + + Reset(); + } + + public void SetRetries(int retries) + { + _retries = retries; + } + + public String MethodName + { + get { return "Single Server"; } + } + + public String toString() + { + return "SingleServer:\n"+ + "Max Retries:"+_retries+ + "\nCurrent Retry:"+_currentRetries+ + "\n"+_brokerDetail+"\n"; + } + + } +} |