Class AbstractJdbcListener

java.lang.Object
org.frankframework.jdbc.JdbcFacade
org.frankframework.jdbc.AbstractJdbcListener
All Implemented Interfaces:
FrankElement, HasApplicationContext, HasName, HasPhysicalDestination, IConfigurable, IListener<Serializable>, IPeekableListener<Serializable>, IPullingListener<Serializable>, IScopeProvider, NameAware, TransactionAware, ConfigurableLifecycle, org.springframework.beans.factory.Aware, org.springframework.context.ApplicationContextAware, org.springframework.context.Lifecycle, org.springframework.context.Phased, org.springframework.context.SmartLifecycle
Direct Known Subclasses:
JdbcListener, StatelessJdbcListener

public abstract class AbstractJdbcListener extends JdbcFacade implements IPeekableListener<Serializable>
Abstract base class for JDBC listeners (excluding the deprecated and broken "SimpleJdbcListener").
  • Field Details

    • ADDITIONAL_QUERY_FIELDS_KEY

      public static final String ADDITIONAL_QUERY_FIELDS_KEY
      See Also:
    • selectQuery

      protected String selectQuery
    • messageField

      protected String messageField
    • messageIdField

      protected String messageIdField
    • correlationIdField

      protected String correlationIdField
    • preparedSelectQuery

      protected String preparedSelectQuery
    • preparedPeekQuery

      protected String preparedPeekQuery
    • peekQuery

      protected String peekQuery
    • keyField

      protected String keyField
    • additionalFields

      protected String additionalFields
    • additionalFieldsList

      protected @NonNull List<String> additionalFieldsList
    • peekUntransacted

      protected boolean peekUntransacted
    • trace

      protected boolean trace
  • Constructor Details

    • AbstractJdbcListener

      public AbstractJdbcListener()
  • Method Details

    • configure

      public void configure() throws ConfigurationException
      Description copied from interface: IConfigurable
      Configure this component.

      configure() is called once at startup of the framework in the configure method of the owner of this IConfigurable. Purpose of this method is to check whether the static configuration of the object is correct. As much as possible class-instantiating should take place in the configure(), to improve performance.

      In the case of a container, this will propagate the configure signal to all components that apply.

      Specified by:
      configure in interface IConfigurable
      Overrides:
      configure in class JdbcFacade
      Throws:
      ConfigurationException - in case it was not able to configure the component.
    • openThread

      public @NonNull Map<String,Object> openThread()
      Description copied from interface: IPullingListener
      Prepares a thread for receiving messages. Called once for each thread that will listen for messages.
      Specified by:
      openThread in interface IPullingListener<Serializable>
      Returns:
      the threadContext for this thread. The threadContext is a Map in which thread-specific data can be stored. May not be null, must be a mutable map type.
    • closeThread

      public void closeThread(@NonNull Map<String,Object> threadContext)
      Description copied from interface: IPullingListener
      Finalizes a message receiving thread. Called once for each thread that listens for messages, just before IListener.stop() is called.
      Specified by:
      closeThread in interface IPullingListener<Serializable>
    • hasRawMessageAvailable

      public boolean hasRawMessageAvailable() throws ListenerException
      Specified by:
      hasRawMessageAvailable in interface IPeekableListener<Serializable>
      Throws:
      ListenerException
    • getColumnValueOrDefault

      protected @Nullable String getColumnValueOrDefault(@NonNull ResultSet rs, @Nullable String columnName, @Nullable String defaultValue) throws SQLException
      Get column value from ResultSet, or the default if either the column-name is empty (unconfigured) or if the result-set does not contain a column of this name.
      Notably, if the column exists in the resultset but has a null value, null is returned instead of the defaultValue.
      Parameters:
      rs - The ResultSet from which to get the column.
      columnName - The name of the column, can be null or empty.
      defaultValue - Default value for the column if columnName was empty, or not present in the ResultSet. Can be null.
      Returns:
      Value from the ResultSet, or the default if columName was empty or not present in the ResultSet.
      Throws:
      SQLException - Propagates the SQLException which may be thrown from the ResultSet.
    • addAdditionalValuesToMessageWrapper

      protected void addAdditionalValuesToMessageWrapper(ResultSet rs, MessageWrapper<Serializable> mw) throws SQLException
      Throws:
      SQLException
    • execute

      protected boolean execute(@NonNull Connection conn, @Nullable String query, @NonNull List<String> parameters) throws ListenerException
      Throws:
      ListenerException
    • extractRawMessage

      protected @NonNull MessageWrapper<Serializable> extractRawMessage(@NonNull ResultSet rs) throws SQLException, IOException, DbmsException
      This method returns a MessageWrapper containing contents of the message stored in the database.
      Parameters:
      rs - JDBC ResultSet from which to extract message data.
      Returns:
      Either a String being the message key, or a MessageWrapper. The message key as String is returned if messageField, messageIdField and correlationIdField all are not set. If messageIdField and / or correlationIdField are set but messageField is not, then the message key is returned as value of a Message wrapped in a MessageWrapper. Otherwise the message is loaded from the rs parameter and returned wrapped in a MessageWrapper.
      Throws:
      SQLException - If loading the message resulted in a database exception.
      IOException - If loading the message resulted in an IO exception
      DbmsException
    • extractMessage

      public Message extractMessage(@NonNull RawMessageWrapper<Serializable> rawMessage, @NonNull Map<String,Object> context) throws ListenerException
      Description copied from interface: IListener
      Extracts data from message obtained from IPullingListener.getRawMessage(Map) or IPushingListener.wrapRawMessage(Object, PipeLineSession). May also extract other parameters from the message and put those into the context.

      The Receiver does not call this method when the listener implementation returned an instance of MessageWrapper from IPullingListener.getRawMessage(Map) or * IPushingListener.wrapRawMessage(Object, PipeLineSession).

      Specified by:
      extractMessage in interface IListener<Serializable>
      Parameters:
      rawMessage - The RawMessageWrapper from which to extract the Message.
      context - Context to populate. Either a PipeLineSession or a Map threadContext depending on caller.
      Returns:
      input Message for adapter.
      Throws:
      ListenerException
    • getMessageKeyOrNull

      protected static @Nullable String getMessageKeyOrNull(RawMessageWrapper<Serializable> messageWrapper)
      Get the storage-key for the Message from the RawMessageWrapper, or NULL allowing for key-field not being configured for the listener.
    • setSelectQuery

      protected void setSelectQuery(String string)
    • setPeekUntransacted

      public void setPeekUntransacted(boolean b)
      Description copied from interface: IPeekableListener
      when true, then PollingListener container will execute getRawMessage() only when hasRawMessageAvailable() has returned true. This avoids rolling back a lot of XA transactions, that appears to be problematic on MS SQL Server
      Specified by:
      setPeekUntransacted in interface IPeekableListener<Serializable>
    • setPeekQuery

      public void setPeekQuery(String string)
      (only used when peekUntransacted=true) peek query to determine if the select query should be executed. Peek queries are, unlike select queries, executed without a transaction and without a rowlock
      Default value
      selectQuery
    • setKeyField

      public void setKeyField(String fieldname)
      Primary key field of the table, used to identify and differentiate messages. NB: there should be an index on this field!
    • setMessageField

      public void setMessageField(String fieldname)
      Field containing the message data
      Default value
      same as keyField
    • setMessageIdField

      public void setMessageIdField(String fieldname)
      Field containing the messageId. NB: If this column is not, or set to a column which cannot be found in the query result, the default (primary key) keyField will be used as messageId!
      Default value
      same as keyField
    • setCorrelationIdField

      public void setCorrelationIdField(String fieldname)
      Field containing the correlationId. NB: If this column is not set, or set to a column which cannot be found in the query result, the messageId and correlationId will be the same!
      Default value
      same as messageIdField
    • setAdditionalFields

      public void setAdditionalFields(String fieldNames)
      Comma-separated list of additional fields to be loaded from the table, besides Message, Key, MessageID and CorrelationID. Any fields listed here will be added to the session as session-variables, with the prefix ADDITIONAL_QUERY_FIELDS_KEY. So if for example you specify additionalFields = "updated_at", then in the session there will be a variable ADDITIONAL_QUERY_FIELDS.updated_at.