/* * 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 { /// /// A Factory that can estbalish NMS connections to TIBCO /// 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 /// /// Creates a new connection to TIBCO. /// 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; } /// /// Creates a new connection to TIBCO. /// 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; } /// /// Configure the newly created connection. /// /// private void ConfigureConnection(IConnection connection) { connection.RedeliveryPolicy = this.redeliveryPolicy.Clone() as IRedeliveryPolicy; connection.ConsumerTransformer = this.consumerTransformer; connection.ProducerTransformer = this.producerTransformer; } /// /// Get/or set the broker Uri. /// 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(')'); } /// /// Get/or set the redelivery policy that new IConnection objects are /// assigned upon creation. /// public IRedeliveryPolicy RedeliveryPolicy { get { return this.redeliveryPolicy; } set { if(value != null) { this.redeliveryPolicy = value; } } } private ConsumerTransformerDelegate consumerTransformer; /// /// 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. /// public ConsumerTransformerDelegate ConsumerTransformer { get { return this.consumerTransformer; } set { this.consumerTransformer = value; } } private ProducerTransformerDelegate producerTransformer; /// /// 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. /// public ProducerTransformerDelegate ProducerTransformer { get { return this.producerTransformer; } set { this.producerTransformer = value; } } #endregion } }