blob: 2b7f10b7262b8690f0d4ebd8873b5154468134b9 [file] [log] [blame]
/*
* 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
}
}