/* | |
* 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.Collections; | |
using System.Collections.Specialized; | |
using Apache.NMS.EMS.Util; | |
using Apache.NMS.Policies; | |
using Apache.NMS.Util; | |
namespace Apache.NMS.EMS | |
{ | |
/// <summary> | |
/// A Factory that can estbalish NMS connections to TIBCO | |
/// </summary> | |
public class ConnectionFactory : Apache.NMS.IConnectionFactory | |
{ | |
public TIBCO.EMS.ConnectionFactory tibcoConnectionFactory; | |
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(); | |
public ConnectionFactory() | |
{ | |
try | |
{ | |
this.tibcoConnectionFactory = new TIBCO.EMS.ConnectionFactory(); | |
ConfigureConnectionFactory(); | |
} | |
catch(Exception ex) | |
{ | |
Apache.NMS.Tracer.DebugFormat("Exception instantiating TIBCO.EMS.ConnectionFactory: {0}", ex.Message); | |
ExceptionUtil.WrapAndThrowNMSException(ex); | |
} | |
VerifyConnectionFactory(); | |
} | |
public ConnectionFactory(Uri serverUrl) | |
: this(serverUrl, string.Empty) | |
{ | |
} | |
public ConnectionFactory(Uri serverUrl, string clientId) | |
: this(serverUrl, clientId, null) | |
{ | |
} | |
public ConnectionFactory(string serverUrl) | |
: this(new Uri(serverUrl)) | |
{ | |
} | |
public ConnectionFactory(string serverUrl, string clientId) | |
: this(new Uri(serverUrl), clientId) | |
{ | |
} | |
public ConnectionFactory(string serverUrl, string clientId, Hashtable properties) | |
: this(new Uri(serverUrl), clientId, properties) | |
{ | |
} | |
public ConnectionFactory(Uri serverUrl, string clientId, Hashtable properties) | |
{ | |
try | |
{ | |
this.clientId = clientId; | |
this.properties = properties; | |
this.BrokerUri = serverUrl; | |
} | |
catch(Exception ex) | |
{ | |
Apache.NMS.Tracer.DebugFormat("Exception instantiating TIBCO.EMS.ConnectionFactory: {0}", ex.Message); | |
ExceptionUtil.WrapAndThrowNMSException(ex); | |
} | |
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) | |
{ | |
throw new Apache.NMS.NMSException("Error instantiating TIBCO connection factory object."); | |
} | |
} | |
#region Connection Factory Properties (configure via URL parameters) | |
public bool ExceptionOnFTEvents | |
{ | |
get { return this.exceptionOnFTEvents; } | |
set | |
{ | |
this.exceptionOnFTEvents = value; | |
TIBCO.EMS.Tibems.SetExceptionOnFTEvents(value); | |
} | |
} | |
public bool ExceptionOnFTSwitch | |
{ | |
get { return this.exceptionOnFTSwitch; } | |
set | |
{ | |
this.exceptionOnFTSwitch = value; | |
TIBCO.EMS.Tibems.SetExceptionOnFTSwitch(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> | |
/// Creates a new connection to TIBCO. | |
/// </summary> | |
public Apache.NMS.IConnection CreateConnection() | |
{ | |
Apache.NMS.IConnection connection = null; | |
try | |
{ | |
connection = EMSConvert.ToNMSConnection(this.tibcoConnectionFactory.CreateConnection()); | |
ConfigureConnection(connection); | |
} | |
catch(Exception ex) | |
{ | |
ExceptionUtil.WrapAndThrowNMSException(ex); | |
} | |
return connection; | |
} | |
/// <summary> | |
/// Creates a new connection to TIBCO. | |
/// </summary> | |
public Apache.NMS.IConnection CreateConnection(string userName, string password) | |
{ | |
Apache.NMS.IConnection connection = null; | |
try | |
{ | |
connection = EMSConvert.ToNMSConnection(this.tibcoConnectionFactory.CreateConnection(userName, password)); | |
ConfigureConnection(connection); | |
} | |
catch(Exception ex) | |
{ | |
ExceptionUtil.WrapAndThrowNMSException(ex); | |
} | |
return connection; | |
} | |
/// <summary> | |
/// Configure the newly created connection. | |
/// </summary> | |
/// <param name="connection"></param> | |
private void ConfigureConnection(IConnection connection) | |
{ | |
connection.RedeliveryPolicy = this.redeliveryPolicy.Clone() as IRedeliveryPolicy; | |
connection.ConsumerTransformer = this.consumerTransformer; | |
connection.ProducerTransformer = this.producerTransformer; | |
} | |
/// <summary> | |
/// Get/or set the broker Uri. | |
/// </summary> | |
public Uri BrokerUri | |
{ | |
get { return this.brokerUri; } | |
set | |
{ | |
try | |
{ | |
// Create or Re-create the TIBCO connection factory. | |
this.brokerUri = ParseUriProperties(value); | |
if(null == this.brokerUri) | |
{ | |
this.tibcoConnectionFactory = new TIBCO.EMS.ConnectionFactory(); | |
} | |
else | |
{ | |
string brokerPath = TrimParens(this.brokerUri.AbsolutePath); | |
if(null == this.clientId) | |
{ | |
this.tibcoConnectionFactory = new TIBCO.EMS.ConnectionFactory(brokerPath); | |
} | |
else | |
{ | |
if(null == this.properties) | |
{ | |
this.tibcoConnectionFactory = new TIBCO.EMS.ConnectionFactory(brokerPath, this.clientId); | |
} | |
else | |
{ | |
this.tibcoConnectionFactory = new TIBCO.EMS.ConnectionFactory(brokerPath, this.clientId, this.properties); | |
} | |
} | |
} | |
ConfigureConnectionFactory(); | |
} | |
catch(Exception ex) | |
{ | |
ExceptionUtil.WrapAndThrowNMSException(ex); | |
} | |
} | |
} | |
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. | |
/// </summary> | |
public IRedeliveryPolicy RedeliveryPolicy | |
{ | |
get { return this.redeliveryPolicy; } | |
set | |
{ | |
if(value != null) | |
{ | |
this.redeliveryPolicy = value; | |
} | |
} | |
} | |
private ConsumerTransformerDelegate consumerTransformer; | |
/// <summary> | |
/// A Delegate that is called each time a Message is dispatched to allow the client to do | |
/// any necessary transformations on the received message before it is delivered. The | |
/// ConnectionFactory sets the provided delegate instance on each Connection instance that | |
/// is created from this factory, each connection in turn passes the delegate along to each | |
/// Session it creates which then passes that along to the Consumers it creates. | |
/// </summary> | |
public ConsumerTransformerDelegate ConsumerTransformer | |
{ | |
get { return this.consumerTransformer; } | |
set { this.consumerTransformer = value; } | |
} | |
private ProducerTransformerDelegate producerTransformer; | |
/// <summary> | |
/// A delegate that is called each time a Message is sent from this Producer which allows | |
/// the application to perform any needed transformations on the Message before it is sent. | |
/// The ConnectionFactory sets the provided delegate instance on each Connection instance that | |
/// is created from this factory, each connection in turn passes the delegate along to each | |
/// Session it creates which then passes that along to the Producers it creates. | |
/// </summary> | |
public ProducerTransformerDelegate ProducerTransformer | |
{ | |
get { return this.producerTransformer; } | |
set { this.producerTransformer = value; } | |
} | |
#endregion | |
} | |
} |