Author: jgomes
Date: Fri Sep 25 23:18:10 2015
New Revision: 1705382

URL: http://svn.apache.org/viewvc?rev=1705382&view=rev
Log:
Add calls to TIBCO API to turn on failover mode.
Add support for URL parameters:
   connection.ExceptionOnFTEvents
   connection.ExceptionOnFTSwitch
   connection.ConnAttemptCount
   connection.ConnAttemptDelay
   connection.ConnAttemptTimeout
   connection.ReconnAttemptCount
   connection.ReconnAttemptDelay
   connection.ReconnAttemptTimeout

Fixes [AMQNET-511]. (See https://issues.apache.org/jira/browse/AMQNET-511)

Added:
    
activemq/activemq-dotnet/Apache.NMS.EMS/trunk/src/main/csharp/IntrospectionSupport.cs
Modified:
    
activemq/activemq-dotnet/Apache.NMS.EMS/trunk/src/main/csharp/ConnectionFactory.cs
    activemq/activemq-dotnet/Apache.NMS.EMS/trunk/vs2008-ems.csproj

Modified: 
activemq/activemq-dotnet/Apache.NMS.EMS/trunk/src/main/csharp/ConnectionFactory.cs
URL: 
http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.EMS/trunk/src/main/csharp/ConnectionFactory.cs?rev=1705382&r1=1705381&r2=1705382&view=diff
==============================================================================
--- 
activemq/activemq-dotnet/Apache.NMS.EMS/trunk/src/main/csharp/ConnectionFactory.cs
 (original)
+++ 
activemq/activemq-dotnet/Apache.NMS.EMS/trunk/src/main/csharp/ConnectionFactory.cs
 Fri Sep 25 23:18:10 2015
@@ -17,7 +17,10 @@
 
 using System;
 using System.Collections;
+using System.Collections.Specialized;
+using Apache.NMS.EMS.Util;
 using Apache.NMS.Policies;
+using Apache.NMS.Util;
 
 namespace Apache.NMS.EMS
 {
@@ -30,6 +33,14 @@ namespace Apache.NMS.EMS
                private Uri brokerUri;
                private string clientId;
                private Hashtable properties;
+               private bool exceptionOnFTEvents = true;
+               private bool exceptionOnFTSwitch = true;
+               private int connAttemptCount = Int32.MaxValue;   // Infinite
+               private int connAttemptDelay = 30000;            // 30 seconds
+               private int connAttemptTimeout = 5000;           // 5 seconds
+               private int reconnAttemptCount = Int32.MaxValue; // Infinite
+               private int reconnAttemptDelay = 30000;          // 30 seconds
+               private int reconnAttemptTimeout = 5000;         // 5 seconds
 
                private IRedeliveryPolicy redeliveryPolicy = new 
RedeliveryPolicy();
 
@@ -38,6 +49,7 @@ namespace Apache.NMS.EMS
                        try
                        {
                                this.tibcoConnectionFactory = new 
TIBCO.EMS.ConnectionFactory();
+                               ConfigureConnectionFactory();
                        }
                        catch(Exception ex)
                        {
@@ -77,10 +89,11 @@ namespace Apache.NMS.EMS
                {
                        try
                        {
-                               this.tibcoConnectionFactory = new 
TIBCO.EMS.ConnectionFactory(serverUrl.AbsolutePath, clientId, properties);
-                               this.brokerUri = serverUrl;
+                               this.brokerUri = ParseUriProperties(serverUrl);
+                               this.tibcoConnectionFactory = new 
TIBCO.EMS.ConnectionFactory(TrimParens(this.brokerUri.AbsolutePath), clientId, 
properties);
                                this.clientId = clientId;
                                this.properties = properties;
+                               ConfigureConnectionFactory();
                        }
                        catch(Exception ex)
                        {
@@ -91,6 +104,22 @@ namespace Apache.NMS.EMS
                        VerifyConnectionFactory();
                }
 
+               private void ConfigureConnectionFactory()
+               {
+                       
TIBCO.EMS.Tibems.SetExceptionOnFTEvents(this.ExceptionOnFTEvents);
+                       
TIBCO.EMS.Tibems.SetExceptionOnFTSwitch(this.ExceptionOnFTSwitch);
+
+                       // Set the initial connection retry settings.
+                       
this.tibcoConnectionFactory.SetConnAttemptCount(this.ConnAttemptCount);
+                       
this.tibcoConnectionFactory.SetConnAttemptDelay(this.ConnAttemptDelay);
+                       
this.tibcoConnectionFactory.SetConnAttemptTimeout(this.ConnAttemptTimeout);
+
+                       // Set the failover reconnect retry settings
+                       
this.tibcoConnectionFactory.SetReconnAttemptCount(this.ReconnAttemptCount);
+                       
this.tibcoConnectionFactory.SetReconnAttemptDelay(this.ReconnAttemptDelay);
+                       
this.tibcoConnectionFactory.SetReconnAttemptTimeout(this.ReconnAttemptTimeout);
+               }
+
                private void VerifyConnectionFactory()
                {
                        if(null == this.tibcoConnectionFactory)
@@ -99,6 +128,58 @@ namespace Apache.NMS.EMS
                        }
                }
 
+               #region Connection Factory Properties (configure via URL 
parameters)
+
+               public bool ExceptionOnFTEvents
+               {
+                       get { return this.exceptionOnFTEvents; }
+                       set { this.exceptionOnFTEvents = value; }
+               }
+
+               public bool ExceptionOnFTSwitch
+               {
+                       get { return this.exceptionOnFTSwitch; }
+                       set { this.exceptionOnFTSwitch = value; }
+               }
+
+               public int ConnAttemptCount
+               {
+                       get { return this.connAttemptCount; }
+                       set { this.connAttemptCount = value; }
+               }
+
+               public int ConnAttemptDelay
+               {
+                       get { return this.connAttemptDelay; }
+                       set { this.connAttemptDelay = value; }
+               }
+
+               public int ConnAttemptTimeout
+               {
+                       get { return this.connAttemptTimeout; }
+                       set { this.connAttemptTimeout = value; }
+               }
+
+               public int ReconnAttemptCount
+               {
+                       get { return this.reconnAttemptCount; }
+                       set { this.reconnAttemptCount = value; }
+               }
+
+               public int ReconnAttemptDelay
+               {
+                       get { return this.reconnAttemptDelay; }
+                       set { this.reconnAttemptDelay = value; }
+               }
+
+               public int ReconnAttemptTimeout
+               {
+                       get { return this.reconnAttemptTimeout; }
+                       set { this.reconnAttemptTimeout = value; }
+               }
+
+               #endregion
+
                #region IConnectionFactory Members
 
                /// <summary>
@@ -162,33 +243,32 @@ namespace Apache.NMS.EMS
                        {
                                try
                                {
-                                       if(null == this.brokerUri || 
!this.brokerUri.Equals(value))
+                                       // Create or Re-create the TIBCO 
connection factory.
+                                       this.brokerUri = 
ParseUriProperties(value);
+                                       if(null == this.brokerUri)
                                        {
-                                               // Re-create the TIBCO 
connection factory.
-                                               this.brokerUri = value;
-                                               if(null == this.brokerUri)
+                                               this.tibcoConnectionFactory = 
new TIBCO.EMS.ConnectionFactory();
+                                       }
+                                       else
+                                       {
+                                               if(null == this.clientId)
                                                {
-                                                       
this.tibcoConnectionFactory = new TIBCO.EMS.ConnectionFactory();
+                                                       
this.tibcoConnectionFactory = new 
TIBCO.EMS.ConnectionFactory(TrimParens(this.brokerUri.AbsolutePath));
                                                }
                                                else
                                                {
-                                                       if(null == 
this.clientId)
+                                                       if(null == 
this.properties)
                                                        {
-                                                               
this.tibcoConnectionFactory = new 
TIBCO.EMS.ConnectionFactory(this.brokerUri.OriginalString);
+                                                               
this.tibcoConnectionFactory = new 
TIBCO.EMS.ConnectionFactory(TrimParens(this.brokerUri.AbsolutePath), 
this.clientId);
                                                        }
                                                        else
                                                        {
-                                                               if(null == 
this.properties)
-                                                               {
-                                                                       
this.tibcoConnectionFactory = new 
TIBCO.EMS.ConnectionFactory(this.brokerUri.OriginalString, this.clientId);
-                                                               }
-                                                               else
-                                                               {
-                                                                       
this.tibcoConnectionFactory = new 
TIBCO.EMS.ConnectionFactory(this.brokerUri.OriginalString, this.clientId, 
this.properties);
-                                                               }
+                                                               
this.tibcoConnectionFactory = new 
TIBCO.EMS.ConnectionFactory(TrimParens(this.brokerUri.AbsolutePath), 
this.clientId, this.properties);
                                                        }
                                                }
                                        }
+
+                                       ConfigureConnectionFactory();
                                }
                                catch(Exception ex)
                                {
@@ -197,6 +277,37 @@ namespace Apache.NMS.EMS
                        }
                }
 
+               private Uri ParseUriProperties(Uri rawUri)
+               {
+                       Tracer.InfoFormat("BrokerUri set = {0}", 
rawUri.OriginalString);
+                       Uri parsedUri = rawUri;
+
+                       if(!String.IsNullOrEmpty(rawUri.Query) && 
!rawUri.OriginalString.EndsWith(")"))
+                       {
+                               parsedUri = new Uri(rawUri.OriginalString);
+                               // Since the Uri class will return the end of a 
Query string found in a Composite
+                               // URI we must ensure that we trim that off 
before we proceed.
+                               string query = 
parsedUri.Query.Substring(parsedUri.Query.LastIndexOf(")") + 1);
+
+                               StringDictionary properties = 
URISupport.ParseQuery(query);
+
+                               StringDictionary connection = 
URISupport.ExtractProperties(properties, "connection.");
+                               StringDictionary nms = 
URISupport.ExtractProperties(properties, "nms.");
+
+                               IntrospectionSupport.SetProperties(this, 
connection, "connection.");
+                               IntrospectionSupport.SetProperties(this, nms, 
"nms.");
+
+                               parsedUri = 
URISupport.CreateRemainingUri(parsedUri, properties);
+                       }
+
+                       return parsedUri;
+               }
+
+               private string TrimParens(string stringWithParens)
+               {
+                       return stringWithParens.TrimStart('(').TrimEnd(')');
+               }
+
                /// <summary>
                /// Get/or set the redelivery policy that new IConnection 
objects are
                /// assigned upon creation.

Added: 
activemq/activemq-dotnet/Apache.NMS.EMS/trunk/src/main/csharp/IntrospectionSupport.cs
URL: 
http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.EMS/trunk/src/main/csharp/IntrospectionSupport.cs?rev=1705382&view=auto
==============================================================================
--- 
activemq/activemq-dotnet/Apache.NMS.EMS/trunk/src/main/csharp/IntrospectionSupport.cs
 (added)
+++ 
activemq/activemq-dotnet/Apache.NMS.EMS/trunk/src/main/csharp/IntrospectionSupport.cs
 Fri Sep 25 23:18:10 2015
@@ -0,0 +1,182 @@
+/*
+ * 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.Reflection;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using Apache.NMS;
+using Apache.NMS.Util;
+
+namespace Apache.NMS.EMS.Util
+{
+    /// <summary>
+    /// Utility class used to provide conveince methods that apply named 
property
+    /// settings to objects.
+    /// </summary>
+    public class IntrospectionSupport
+    {
+        /// <summary>
+        /// Sets the public properties of a target object using a string map.
+        /// This method uses .Net reflection to identify public properties of
+        /// the target object matching the keys from the passed map.
+        /// </summary>
+        /// <param name="target">The object whose properties will be 
set.</param>
+        /// <param name="map">Map of key/value pairs.</param>
+        public static void SetProperties(object target, StringDictionary map)
+        {
+            SetProperties(target, map, "");
+        }
+
+        /// <summary>
+        /// Sets the public properties of a target object using a string map.
+        /// This method uses .Net reflection to identify public properties of
+        /// the target object matching the keys from the passed map.
+        /// </summary>
+        /// <param name="target">The object whose properties will be 
set.</param>
+        /// <param name="map">Map of key/value pairs.</param>
+        /// <param name="prefix">Key value prefix.  This is prepended to the 
property name
+        /// before searching for a matching key value.</param>
+        public static void SetProperties(object target, StringDictionary map, 
string prefix)
+        {
+            Tracer.DebugFormat("SetProperties called with target: {0}, and 
prefix: {1}",
+                               target.GetType().Name, prefix);
+
+            foreach(string key in map.Keys)
+            {
+                if(key.StartsWith(prefix, 
StringComparison.InvariantCultureIgnoreCase))
+                {
+                    string propertyName = key.Substring(prefix.Length);
+
+                    // Process all member assignments at this level before 
processing
+                    // any deeper member assignments.
+                    if(!propertyName.Contains("."))
+                    {
+                        MemberInfo member = FindPropertyInfo(target, 
propertyName);
+
+                        if(member == null)
+                        {
+                            throw new NMSException(string.Format("No such 
property or field: {0} on class: {1}", propertyName, target.GetType().Name));
+                        }
+
+                        try
+                        {
+                            if(member.MemberType == MemberTypes.Property)
+                            {
+                                PropertyInfo property = member as PropertyInfo;
+                                property.SetValue(target, 
Convert.ChangeType(map[key], property.PropertyType, 
CultureInfo.InvariantCulture), null);
+                            }
+                            else
+                            {
+                                FieldInfo field = member as FieldInfo;
+                                field.SetValue(target, 
Convert.ChangeType(map[key], field.FieldType, CultureInfo.InvariantCulture));
+                            }
+                        }
+                        catch(Exception ex)
+                        {
+                            throw NMSExceptionSupport.Create("Error while 
attempting to apply option.", ex);
+                        }
+                    }
+                }
+            }
+
+            IList<string> propertiesSet = new List<string>();
+
+            // Now process any compound assignments, ensuring that once we 
recurse into an
+            // object we don't do it again as there could be multiple compunds 
element assignments
+            // and they'd have already been processed recursively.
+            foreach(string key in map.Keys)
+            {
+                if(key.StartsWith(prefix, 
StringComparison.InvariantCultureIgnoreCase))
+                {
+                    string propertyName = key.Substring(prefix.Length);
+
+                    if(propertyName.Contains("."))
+                    {
+                        string newTargetName = propertyName.Substring(0, 
propertyName.IndexOf('.'));
+                        string newPrefix = prefix + newTargetName + ".";
+
+                        if(!propertiesSet.Contains(newPrefix))
+                        {
+                            MemberInfo member = FindPropertyInfo(target, 
newTargetName);
+                            object newTarget = GetUnderlyingObject(member, 
target);
+                            SetProperties(newTarget, map, newPrefix);
+                            propertiesSet.Add(newPrefix);
+                        }
+                    }
+                }
+            }
+        }
+
+        private static object GetUnderlyingObject(MemberInfo member, object 
target)
+        {
+            object result = null;
+
+            if(member.MemberType == MemberTypes.Field)
+            {
+                FieldInfo field = member as FieldInfo;
+
+                if(field.FieldType.IsPrimitive)
+                {
+                    throw new NMSException("The field given is a priomitive 
type: " + member.Name);
+                }
+
+                result = field.GetValue(target);
+            }
+            else
+            {
+                PropertyInfo property = member as PropertyInfo;
+                MethodInfo getter = property.GetGetMethod();
+
+                if(getter == null)
+                {
+                    throw new NMSException("Cannot access member: " + 
member.Name);
+                }
+
+                result = getter.Invoke(target, null);
+            }
+
+            if(result == null)
+            {
+                throw new NMSException(String.Format("Could not retrieve the 
value of member {0}."), member.Name);
+            }
+
+            return result;
+        }
+
+        private static MemberInfo FindPropertyInfo(object target, string name)
+        {
+            BindingFlags flags = BindingFlags.FlattenHierarchy
+                               | BindingFlags.Public
+                               | BindingFlags.Instance
+                               | BindingFlags.IgnoreCase;
+
+            Type type = target.GetType();
+
+            MemberInfo member = type.GetProperty(name, flags);
+
+            if(member == null)
+            {
+                member = type.GetField(name, flags);
+            }
+
+            return member;
+        }
+
+    }
+}

Modified: activemq/activemq-dotnet/Apache.NMS.EMS/trunk/vs2008-ems.csproj
URL: 
http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.EMS/trunk/vs2008-ems.csproj?rev=1705382&r1=1705381&r2=1705382&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.EMS/trunk/vs2008-ems.csproj (original)
+++ activemq/activemq-dotnet/Apache.NMS.EMS/trunk/vs2008-ems.csproj Fri Sep 25 
23:18:10 2015
@@ -74,6 +74,7 @@
     <Compile Include="src\main\csharp\ConnectionFactory.cs" />
     <Compile Include="src\main\csharp\ConnectionMetaData.cs" />
     <Compile Include="src\main\csharp\ExceptionUtil.cs" />
+    <Compile Include="src\main\csharp\IntrospectionSupport.cs" />
     <Compile Include="src\main\csharp\StreamMessage.cs" />
     <Compile Include="src\main\csharp\QueueBrowser.cs" />
     <Compile Include="src\main\csharp\Destination.cs" />


Reply via email to