<commit_before>/*
 * $Log: IfsaFacade.java,v $
 * Revision 1.14  2004-07-22 11:01:04  L190409
 * added configurable timeOut
 *
 * Revision 1.13  2004/07/20 16:37:47  <NAME> <<EMAIL>>
 * toch maar niet IFSA-mode timeout
 *
 * Revision 1.12  2004/07/20 13:28:07  <NAME> <<EMAIL>>
 * implemented IFSA timeout mode
 *
 * Revision 1.11  2004/07/19 13:20:20  <NAME> <<EMAIL>>
 * increased logging + close connection on 'close'
 *
 * Revision 1.10  2004/07/15 07:35:44  <NAME> <<EMAIL>>
 * cosmetic changes
 *
 * Revision 1.9  2004/07/08 12:55:57  <NAME> <<EMAIL>>
 * logging refinements
 *
 * Revision 1.8  2004/07/08 08:56:46  <NAME> <<EMAIL>>
 * show physical destination after configure
 *
 * Revision 1.7  2004/07/06 14:50:06  <NAME> <<EMAIL>>
 * included PhysicalDestination
 *
 * Revision 1.6  2004/07/05 14:29:45  <NAME> <<EMAIL>.<EMAIL>>
 * restructuring to align with IFSA naming scheme
 *
 */
package nl.nn.adapterframework.extensions.ifsa;

import com.ing.ifsa.*;

import nl.nn.adapterframework.core.HasPhysicalDestination;
import nl.nn.adapterframework.core.INamedObject;
import nl.nn.adapterframework.configuration.ConfigurationException;

import org.apache.commons.lang.StringUtils;

import org.apache.log4j.Logger;
import org.apache.commons.lang.builder.ToStringBuilder;

import java.util.Hashtable;
import java.util.Map;

import javax.naming.*;
import javax.jms.*;

/**
 * Base class for IFSA 2.0 functions.
 * <br/>
 * <p>Descenderclasses must set either Requester or Provider behaviour in their constructor.</p>
 * <p><b>Configuration:</b>
 * <table border="1">
 * <tr><th>attributes</th><th>description</th><th>default</th></tr>
 * <tr><td>classname</td><td>nl.nn.adapterframework.extensions.ifsa.IfsaFacade</td><td>&nbsp;</td></tr>
 * <tr><td>{@link #setName(String) name}</td><td>name of the object</td><td>&nbsp;</td></tr>
 * <tr><td>{@link #setApplicationId(String) applicationId}</td><td>the ApplicationID, in the form of "IFSA://<i>AppId</i>"</td><td>&nbsp;</td></tr>
 * <tr><td>{@link #setServiceId(String) serviceId}</td><td>only for Requesters: the ServiceID, in the form of "IFSA://<i>ServiceID</i>"</td><td>&nbsp;</td></tr>
 * <tr><td>{@link #setMessageProtocol(String) messageProtocol}</td><td>protocol of IFSA-Service to be called. Possible values 
 * <tr><td>{@link #setTimeOut(long) listener.timeOut}</td><td>receiver timeout, in milliseconds</td><td>defined by IFSA expiry</td></tr>
 * <ul>
 *   <li>"FF": Fire & Forget protocol</li>
 *   <li>"RR": Request-Reply protocol</li>
 * </ul></td><td>&nbsp;</td></tr>
 * </table>
 * 
 * @author <NAME> / <NAME>
 * @since 4.2
 */
public class IfsaFacade implements INamedObject, HasPhysicalDestination {
	public static final String version="$Id: IfsaFacade.java,v 1.14 2004-07-22 11:01:04 L190409 Exp $";
    protected Logger log = Logger.getLogger(this.getClass());
    
	private final static String IFSA_INITIAL_CONTEXT_FACTORY="com.ing.ifsa.IFSAContextFactory";
	private final static String IFSA_PROVIDER_URL="IFSA APPLICATION BUS";

	private String name;
	private String applicationId;
	private String serviceId;
	private IfsaMessageProtocolEnum messageProtocol;

	private long timeOut = -1; // when set (>=0), overrides IFSA-expiry


    private IFSAQueueConnectionFactory ifsaQueueConnectionFactory = null;
    private IFSAContext context = null;
    private QueueConnection connection = null;
	private Queue queue;
	
	private boolean requestor=false;
	private boolean provider=false;

	public IfsaFacade(boolean asProvider) {
		super();
		if (asProvider) {
			provider=true;
		}
		else
			requestor=true;
	}
	
	protected String getLogPrefix() {
		
		String objectType;
		String serviceInfo="";
		try {
			if (isRequestor()) {
				objectType = "IfsaRequester";
				serviceInfo = "of Application ["+getApplicationId()+"] "; 
			} else {
				objectType = "IfsaProvider";				
				serviceInfo = "for Application ["+getApplicationId()+"] "; 
			} 
		} catch (IfsaException e) {
			log.debug("Exception determining objectType in getLogPrefix",e);
			objectType="Object";
			serviceInfo = "of Application ["+getApplicationId()+"]"; 
		}
		
		return objectType + "["+ getName()+ "] " + serviceInfo;  
	}

	/**
	 * Checks if messageProtocol and serviceId (only for Requestors) are specified
	 */
	public void configure() throws ConfigurationException {
		// perform some basic checks
		try {
			if (isRequestor() && StringUtils.isEmpty(getServiceId()))
				throw new ConfigurationException(getLogPrefix()+"serviceId is not specified");
			if (getMessageProtocolEnum() == null)
				throw new ConfigurationException(getLogPrefix()+
					"invalid messageProtocol specified ["
						+ getMessageProtocolEnum()
						+ "], should be one of the following "
						+ IfsaMessageProtocolEnum.getNames());
		} catch (IfsaException e) {
			throw new ConfigurationException("exception checking configuration",e);
		}
	}

	/** 
	 * Prepares object for communication on the IFSA bus.
	 * Obtains a connection and a serviceQueue.
	 */
	public void openService() throws IfsaException {
		getConnection();   // obtain and cache connection, then start it.
		getServiceQueue(); // obtain and cache service queue
	}

	/** 
	 * Stops communication on the IFSA bus.
	 * Releases references to serviceQueue and connection.
	 */
	public void closeService() throws IfsaException {
	    try {
	        if (connection != null) {
	            connection.close();
                log.debug(getLogPrefix()+"closed connection for service");
	        }
	    } catch (JMSException e) {
	        throw new IfsaException("exception closing service",e);
	    } finally {
	    	// make sure all objects are reset, to be able to restart after IFSA parameters have changed (e.g. at iterative installation time)
	        queue = null;
	        connection = null;
			ifsaQueueConnectionFactory = null;
			context = null;
	    }
	}
	
	
	private IFSAContext getContext() throws IfsaException {
		try {
			if (context == null) {
				Hashtable env = new Hashtable(11);
				env.put(Context.INITIAL_CONTEXT_FACTORY, IFSA_INITIAL_CONTEXT_FACTORY);
				env.put(Context.PROVIDER_URL, IFSA_PROVIDER_URL);
				// Create context as required by IFSA 2.0. Ignore the deprecation....
				context = new IFSAContext((Context) new InitialContext(env));
			}
			return context;
		} catch (NamingException e) {
			throw new IfsaException("could not obtain context", e);
		}
	}

	/**
	 * Looks up the <code>serviceId</code> in the <code>IFSAContext</code>.<br/>
	 * <p>The method is knowledgable of Provider versus Requester processing.
	 * When the request concerns a Provider <code>lookupProviderInput</code> is used,
	 * when it concerns a Requester <code>lookupService(serviceId)</code> is used.
	 * This method distinguishes a server-input queue and a client-input queue
	 */
	protected Queue getServiceQueue() throws IfsaException {
		if (queue == null) {
			try {
				if (isRequestor()) {
					queue = (Queue) getContext().lookupService(getServiceId());
					if (log.isDebugEnabled()) {
						log.debug(getLogPrefix()+ "got Queue to send messages on "+getPhysicalDestinationName());
					}
				} else {
					queue = (Queue) getContext().lookupProviderInput();
					if (log.isDebugEnabled()) {
						log.debug(getLogPrefix()+ "got Queue to receive messages from "+getPhysicalDestinationName());
					}
				}
	
			} catch (NamingException e) {
				throw new IfsaException("could not obtain serviceQueue", e);
			}
		}
		return queue;
	}

	/**
	 * Returns a connection for the queue corresponding to the service
	 */
	protected QueueConnection getConnection() throws IfsaException {
		try {
			if (connection == null) {
				connection = getIfsaQueueConnectionFactory().createQueueConnection();
				connection.start();
			}
			return connection;
		} catch (Exception e) {
			throw new IfsaException("could not obtain connection", e);
		}
	}

	/**
	 *  Create a session on the connection to the service
	 */
	public QueueSession createSession() throws IfsaException {
		try {
//			return connection.createQueueSession(isTransacted(), Session.AUTO_ACKNOWLEDGE + IFSAConstants.QueueSession.IFSA_MODE);
			return connection.createQueueSession(isTransacted(), Session.AUTO_ACKNOWLEDGE);
		} catch (JMSException e) {
			throw new IfsaException(e);
		}
	}

	
	protected QueueSender createSender(QueueSession session, Queue queue)
	    throws IfsaException {
	<commit_msg>let requestor receive IFSATimeOutMessages<commit_after>/*
 * $Log: IfsaFacade.java,v $
 * Revision 1.15  2004-07-22 13:19:02  L190409
 * let requestor receive IFSATimeOutMessages
 *
 * Revision 1.14  2004/07/22 11:01:04  <NAME> <<EMAIL>>
 * added configurable timeOut
 *
 * Revision 1.13  2004/07/20 16:37:47  <NAME> <<EMAIL>>
 * toch maar niet IFSA-mode timeout
 *
 * Revision 1.12  2004/07/20 13:28:07  <NAME> <<EMAIL>>
 * implemented IFSA timeout mode
 *
 * Revision 1.11  2004/07/19 13:20:20  <NAME> <<EMAIL>>
 * increased logging + close connection on 'close'
 *
 * Revision 1.10  2004/07/15 07:35:44  <NAME> <<EMAIL>>
 * cosmetic changes
 *
 * Revision 1.9  2004/07/08 12:55:57  <NAME> <<EMAIL>>
 * logging refinements
 *
 * Revision 1.8  2004/07/08 08:56:46  <NAME> <<EMAIL>>
 * show physical destination after configure
 *
 * Revision 1.7  2004/07/06 14:50:06  <NAME> <<EMAIL>>
 * included PhysicalDestination
 *
 * Revision 1.6  2004/07/05 14:29:45  <NAME> <<EMAIL>>
 * restructuring to align with IFSA naming scheme
 *
 */
package nl.nn.adapterframework.extensions.ifsa;

import com.ing.ifsa.*;

import nl.nn.adapterframework.core.HasPhysicalDestination;
import nl.nn.adapterframework.core.INamedObject;
import nl.nn.adapterframework.configuration.ConfigurationException;

import org.apache.commons.lang.StringUtils;

import org.apache.log4j.Logger;
import org.apache.commons.lang.builder.ToStringBuilder;

import java.util.Hashtable;
import java.util.Map;

import javax.naming.*;
import javax.jms.*;

/**
 * Base class for IFSA 2.0 functions.
 * <br/>
 * <p>Descenderclasses must set either Requester or Provider behaviour in their constructor.</p>
 * <p><b>Configuration:</b>
 * <table border="1">
 * <tr><th>attributes</th><th>description</th><th>default</th></tr>
 * <tr><td>classname</td><td>nl.nn.adapterframework.extensions.ifsa.IfsaFacade</td><td>&nbsp;</td></tr>
 * <tr><td>{@link #setName(String) name}</td><td>name of the object</td><td>&nbsp;</td></tr>
 * <tr><td>{@link #setApplicationId(String) applicationId}</td><td>the ApplicationID, in the form of "IFSA://<i>AppId</i>"</td><td>&nbsp;</td></tr>
 * <tr><td>{@link #setServiceId(String) serviceId}</td><td>only for Requesters: the ServiceID, in the form of "IFSA://<i>ServiceID</i>"</td><td>&nbsp;</td></tr>
 * <tr><td>{@link #setMessageProtocol(String) messageProtocol}</td><td>protocol of IFSA-Service to be called. Possible values 
 * <tr><td>{@link #setTimeOut(long) listener.timeOut}</td><td>receiver timeout, in milliseconds</td><td>defined by IFSA expiry</td></tr>
 * <ul>
 *   <li>"FF": Fire & Forget protocol</li>
 *   <li>"RR": Request-Reply protocol</li>
 * </ul></td><td>&nbsp;</td></tr>
 * </table>
 * 
 * @author <NAME> / <NAME>
 * @since 4.2
 */
public class IfsaFacade implements INamedObject, HasPhysicalDestination {
	public static final String version="$Id: IfsaFacade.java,v 1.15 2004-07-22 13:19:02 L190409 Exp $";
    protected Logger log = Logger.getLogger(this.getClass());
    
	private final static String IFSA_INITIAL_CONTEXT_FACTORY="com.ing.ifsa.IFSAContextFactory";
	private final static String IFSA_PROVIDER_URL="IFSA APPLICATION BUS";

	private String name;
	private String applicationId;
	private String serviceId;
	private IfsaMessageProtocolEnum messageProtocol;

	private long timeOut = -1; // when set (>=0), overrides IFSA-expiry


    private IFSAQueueConnectionFactory ifsaQueueConnectionFactory = null;
    private IFSAContext context = null;
    private QueueConnection connection = null;
	private Queue queue;
	
	private boolean requestor=false;
	private boolean provider=false;

	public IfsaFacade(boolean asProvider) {
		super();
		if (asProvider) {
			provider=true;
		}
		else
			requestor=true;
	}
	
	protected String getLogPrefix() {
		
		String objectType;
		String serviceInfo="";
		try {
			if (isRequestor()) {
				objectType = "IfsaRequester";
				serviceInfo = "of Application ["+getApplicationId()+"] "; 
			} else {
				objectType = "IfsaProvider";				
				serviceInfo = "for Application ["+getApplicationId()+"] "; 
			} 
		} catch (IfsaException e) {
			log.debug("Exception determining objectType in getLogPrefix",e);
			objectType="Object";
			serviceInfo = "of Application ["+getApplicationId()+"]"; 
		}
		
		return objectType + "["+ getName()+ "] " + serviceInfo;  
	}

	/**
	 * Checks if messageProtocol and serviceId (only for Requestors) are specified
	 */
	public void configure() throws ConfigurationException {
		// perform some basic checks
		try {
			if (isRequestor() && StringUtils.isEmpty(getServiceId()))
				throw new ConfigurationException(getLogPrefix()+"serviceId is not specified");
			if (getMessageProtocolEnum() == null)
				throw new ConfigurationException(getLogPrefix()+
					"invalid messageProtocol specified ["
						+ getMessageProtocolEnum()
						+ "], should be one of the following "
						+ IfsaMessageProtocolEnum.getNames());
		} catch (IfsaException e) {
			throw new ConfigurationException("exception checking configuration",e);
		}
	}

	/** 
	 * Prepares object for communication on the IFSA bus.
	 * Obtains a connection and a serviceQueue.
	 */
	public void openService() throws IfsaException {
		getConnection();   // obtain and cache connection, then start it.
		getServiceQueue(); // obtain and cache service queue
	}

	/** 
	 * Stops communication on the IFSA bus.
	 * Releases references to serviceQueue and connection.
	 */
	public void closeService() throws IfsaException {
	    try {
	        if (connection != null) {
	            connection.close();
                log.debug(getLogPrefix()+"closed connection for service");
	        }
	    } catch (JMSException e) {
	        throw new IfsaException("exception closing service",e);
	    } finally {
	    	// make sure all objects are reset, to be able to restart after IFSA parameters have changed (e.g. at iterative installation time)
	        queue = null;
	        connection = null;
			ifsaQueueConnectionFactory = null;
			context = null;
	    }
	}
	
	
	private IFSAContext getContext() throws IfsaException {
		try {
			if (context == null) {
				Hashtable env = new Hashtable(11);
				env.put(Context.INITIAL_CONTEXT_FACTORY, IFSA_INITIAL_CONTEXT_FACTORY);
				env.put(Context.PROVIDER_URL, IFSA_PROVIDER_URL);
				// Create context as required by IFSA 2.0. Ignore the deprecation....
				context = new IFSAContext((Context) new InitialContext(env));
			}
			return context;
		} catch (NamingException e) {
			throw new IfsaException("could not obtain context", e);
		}
	}

	/**
	 * Looks up the <code>serviceId</code> in the <code>IFSAContext</code>.<br/>
	 * <p>The method is knowledgable of Provider versus Requester processing.
	 * When the request concerns a Provider <code>lookupProviderInput</code> is used,
	 * when it concerns a Requester <code>lookupService(serviceId)</code> is used.
	 * This method distinguishes a server-input queue and a client-input queue
	 */
	protected Queue getServiceQueue() throws IfsaException {
		if (queue == null) {
			try {
				if (isRequestor()) {
					queue = (Queue) getContext().lookupService(getServiceId());
					if (log.isDebugEnabled()) {
						log.info(getLogPrefix()+ "got Queue to send messages on "+getPhysicalDestinationName());
					}
				} else {
					queue = (Queue) getContext().lookupProviderInput();
					if (log.isDebugEnabled()) {
						log.info(getLogPrefix()+ "got Queue to receive messages from "+getPhysicalDestinationName());
					}
				}
	
			} catch (NamingException e) {
				throw new IfsaException("could not obtain serviceQueue", e);
			}
		}
		return queue;
	}

	/**
	 * Returns a connection for the queue corresponding to the service
	 */
	protected QueueConnection getConnection() throws IfsaException {
		try {
			if (connection == null) {
				connection = getIfsaQueueConnectionFactory().createQueueConnection();
				connection.start();
			}
			return connection;
		} catch (Exception e) {
			throw new IfsaException("could not obtain connection", e);
		}
	}

	/**
	 *  Create a session on the connection to the service
	 */
	public QueueSession createSession() throws IfsaException {
		try {
			int mode = Session.AUTO_ACKNOWLEDGE; 
			if (isRequestor()) {
				mode += IFSAConstants.QueueSession.IFSA_MODE; // let requestor receive IFSATimeOutMessages
			}
			return connection.createQueueSession(isTransacted(), mode);
		} catch (JMSException e) {
			throw new IfsaException(e);
		}
	}

	
	protected QueueSender createSender(QueueSession session, Queue queue)
	    throws IfsaException {
	
{'fraction_non_alphanumeric': 0.12925572858073303, 'fraction_numerical': 0.023506424299840133, 'mean_word_length': 3.9472759226713534, 'pattern_counts': {'":': 4, '<': 227, '<?xml version=': 0, '>': 229, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3227566', 'n_tokens_mistral': 5938, 'n_tokens_neox': 5158, 'n_words': 1384}