Class JDBCPairwiseIdStore

  • All Implemented Interfaces:
    DurablePairwiseIdStore, PairwiseIdStore, Component, DestructableComponent, InitializableComponent

    public class JDBCPairwiseIdStore
    extends AbstractInitializableComponent
    implements DurablePairwiseIdStore
    JDBC-based storage management for pairwise IDs.

    The general DDL for the database, which is unchanged for compatibility, is:

     CREATE TABLE shibpid (
          localEntity VARCHAR(255) NOT NULL,
          peerEntity VARCHAR(255) NOT NULL,
          persistentId VARCHAR(50) NOT NULL,
          principalName VARCHAR(50) NOT NULL,
          localId VARCHAR(50) NOT NULL,
          peerProvidedId VARCHAR(50) NULL,
          creationDate TIMESTAMP NOT NULL,
          deactivationDate TIMESTAMP NULL,
          PRIMARY KEY (localEntity, peerEntity, persistentId)
         );
    .

    The first three columns should be defined as the primary key of the table, and the other columns should be indexed.

    Since:
    4.0.0
    • Field Detail

      • log

        @Nonnull
        private final org.slf4j.Logger log
        Class logger.
      • queryTimeout

        @Nonnull
        private Duration queryTimeout
        Timeout of SQL queries.
      • transactionRetry

        @NonNegative
        private int transactionRetry
        Number of times to retry a transaction if it rolls back.
      • transactionIsolation

        private int transactionIsolation
        What transaction isolation do we want?
      • readWriteLock

        private ReadWriteLock readWriteLock
        If non-null we doing local locking.
      • verifyDatabase

        private boolean verifyDatabase
        Whether to fail if the database cannot be verified.
      • tableName

        @Nonnull
        @NotEmpty
        private String tableName
        Name of the database table.
      • issuerColumn

        @Nonnull
        @NotEmpty
        private String issuerColumn
        Name of the issuer entityID column.
      • recipientColumn

        @Nonnull
        @NotEmpty
        private String recipientColumn
        Name of the recipient entityID column.
      • principalNameColumn

        @Nonnull
        @NotEmpty
        private String principalNameColumn
        Name of the principal name column.
      • sourceIdColumn

        @Nonnull
        @NotEmpty
        private String sourceIdColumn
        Name of the source ID column.
      • persistentIdColumn

        @Nonnull
        @NotEmpty
        private String persistentIdColumn
        Name of the persistent ID column.
      • peerProvidedIdColumn

        @Nonnull
        @NotEmpty
        private String peerProvidedIdColumn
        Name of recipient-attached alias column.
      • creationTimeColumn

        @Nonnull
        @NotEmpty
        private String creationTimeColumn
        Name of the creation time column.
      • deactivationTimeColumn

        @Nonnull
        @NotEmpty
        private String deactivationTimeColumn
        Name of the deactivation time column.
      • getByIssuedSelectSQL

        @NonnullAfterInit
        private String getByIssuedSelectSQL
        Parameterized select query for lookup by issued value.
      • getBySourceSelectSQL

        @NonnullAfterInit
        private String getBySourceSelectSQL
        Parameterized select query for lookup by source ID.
      • insertSQL

        @NonnullAfterInit
        private String insertSQL
        Parameterized insert statement used to insert a new record.
      • deactivateSQL

        @NonnullAfterInit
        private String deactivateSQL
        Parameterized update statement used to deactivate an ID.
      • attachSQL

        @NonnullAfterInit
        private String attachSQL
        Parameterized update statement used to attach an alias to an ID.
      • deleteSQL

        @NonnullAfterInit
        private String deleteSQL
        Parameterized delete statement used to clear dummy rows after verification.
      • initialValueStore

        @Nullable
        private PairwiseIdStore initialValueStore
        Optional hook for obtaining initial values from a primary store, usually a computed algorithm.
    • Constructor Detail

      • JDBCPairwiseIdStore

        public JDBCPairwiseIdStore()
        Constructor.
    • Method Detail

      • getDataSource

        @NonnullAfterInit
        public DataSource getDataSource()
        Get the source datasource used to communicate with the database.
        Returns:
        the data source;
      • setDataSource

        public void setDataSource​(@Nonnull
                                  DataSource source)
        Get the source datasource used to communicate with the database.
        Parameters:
        source - the data source;
      • setLocalLocking

        public void setLocalLocking​(boolean what)
        Will we do thread level locking or delegate to the Database?
        Parameters:
        what - do we want to lock locally?
      • isLocalLocking

        public boolean isLocalLocking()
        Do we do thread level locking or delegate to the Database?
        Returns:
        do we lock locally?
      • setTransactionIsolation

        public void setTransactionIsolation​(int what)
        Set the parameter that will be passed to Connection.setTransactionIsolation(int).
        Parameters:
        what - the value to set
      • getQueryTimeout

        @Nonnull
        public Duration getQueryTimeout()
        Get the SQL query timeout.
        Returns:
        the timeout
      • setQueryTimeout

        public void setQueryTimeout​(@Nonnull
                                    Duration timeout)
        Set the SQL query timeout. Defaults to 5s.
        Parameters:
        timeout - the timeout to set
      • getTransactionRetries

        public int getTransactionRetries()
        Get the number of retries to attempt for a failed transaction.
        Returns:
        number of retries
      • setTransactionRetries

        public void setTransactionRetries​(@NonNegative
                                          int retries)
        Set the number of retries to attempt for a failed transaction. Defaults to 3.
        Parameters:
        retries - the number of retries
      • getRetryableErrors

        @Nonnull
        @NonnullElements
        @NotLive
        @Unmodifiable
        public Collection<String> getRetryableErrors()
        Get the error messages to check for classifying a driver error as retryable, generally indicating a lock violation or duplicate insert that signifies a broken database.
        Returns:
        retryable messages
      • setRetryableErrors

        public void setRetryableErrors​(@Nullable @NonnullElements
                                       Collection<String> errors)
        Set the error messages to check for classifying a driver error as retryable, generally indicating a lock violation or duplicate insert that signifies a broken database.
        Parameters:
        errors - retryable messages
      • getVerifyDatabase

        public boolean getVerifyDatabase()
        Get whether to allow startup if the database cannot be verified.
        Returns:
        whether to allow startup if the database cannot be verified
      • setVerifyDatabase

        public void setVerifyDatabase​(boolean flag)
        Set whether to allow startup if the database cannot be verified.

        Verification consists not only of a liveness check, but the successful insertion of a dummy row, a failure to insert a duplicate, and then deletion of the row.

        Parameters:
        flag - flag to set
      • getTableName

        @Nonnull
        @NotEmpty
        public String getTableName()
        Gets the table name.
        Returns:
        table name
        Since:
        4.1.0
      • setTableName

        public void setTableName​(@Nonnull @NotEmpty
                                 String name)
        Set the table name.
        Parameters:
        name - table name
      • setLocalEntityColumn

        public void setLocalEntityColumn​(@Nonnull @NotEmpty
                                         String name)
        Set the name of the issuer entityID column.
        Parameters:
        name - name of issuer column
      • setPeerEntityColumn

        public void setPeerEntityColumn​(@Nonnull @NotEmpty
                                        String name)
        Set the name of the recipient entityID column.
        Parameters:
        name - name of recipient column
      • setPrincipalNameColumn

        public void setPrincipalNameColumn​(@Nonnull @NotEmpty
                                           String name)
        Set the name of the principal name column.
        Parameters:
        name - name of principal name column
      • setSourceIdColumn

        public void setSourceIdColumn​(@Nonnull @NotEmpty
                                      String name)
        Set the name of the source ID column.
        Parameters:
        name - name of source ID column
      • setPersistentIdColumn

        public void setPersistentIdColumn​(@Nonnull @NotEmpty
                                          String name)
        Set the name of the persistent ID column.
        Parameters:
        name - name of the persistent ID column
      • setPeerProvidedIdColumn

        public void setPeerProvidedIdColumn​(@Nonnull @NotEmpty
                                            String name)
        Set the name of the peer-provided ID column.
        Parameters:
        name - name of peer-provided ID column
      • setCreateTimeColumn

        public void setCreateTimeColumn​(@Nonnull @NotEmpty
                                        String name)
        Set the name of the creation time column.
        Parameters:
        name - name of creation time column
      • setDeactivationTimeColumn

        public void setDeactivationTimeColumn​(@Nonnull @NotEmpty
                                              String name)
        Set the name of the deactivation time column.
        Parameters:
        name - name of deactivation time column
      • setGetByIssuedSelectSQL

        public void setGetByIssuedSelectSQL​(@Nonnull @NotEmpty
                                            String sql)
        Set the SELECT statement used to lookup records by issued value.
        Parameters:
        sql - statement text, which must contain three parameters (NameQualifier, SPNameQualifier, value)
      • setGetBySourceSelectSQL

        public void setGetBySourceSelectSQL​(@Nonnull @NotEmpty
                                            String sql)
        Set the SELECT statement used to lookup records by source ID.
        Parameters:
        sql - statement text, which must contain six parameters (NameQualifier, SPNameQualifier, source ID, NameQualifier, SPNameQualifier, source ID)
      • setInsertSQL

        public void setInsertSQL​(@Nonnull @NotEmpty
                                 String sql)
        Set the INSERT statement used to insert new records.
        Parameters:
        sql - statement text, which must contain 8 parameters (NameQualifier, SPNameQualifier, value, principal, source ID, SPProvidedID, creation time, deactivation time)
      • setDeactivateSQL

        public void setDeactivateSQL​(@Nonnull @NotEmpty
                                     String sql)
        Set the UPDATE statement used to deactivate issued values.
        Parameters:
        sql - statement text, which must contain four parameters (deactivation TS, NameQualifier, SPNameQualifier, value)
      • setAttachSQL

        public void setAttachSQL​(@Nonnull @NotEmpty
                                 String sql)
        Set the UPDATE statement used to attach an SPProvidedID to an issued value.
        Parameters:
        sql - statement text, which must contain four parameters (SPProvidedID, NameQualifier, SPNameQualifier, value)
      • setDeleteSQL

        public void setDeleteSQL​(@Nonnull @NotEmpty
                                 String sql)
        Set the DELETE statement used to clear dummy row(s) created during verification.
        Parameters:
        sql - statement text, which must contain one parameter (NameQualifier)
      • getInitialValueStore

        @Nullable
        public PairwiseIdStore getInitialValueStore()
        Get a store to use to produce the first value for a given issuer/recipient pair.
        Returns:
        initial value source
      • setInitialValueStore

        public void setInitialValueStore​(@Nullable
                                         PairwiseIdStore store)
        Set a store to use to produce the first value for a given issuer/recipient pair.

        This is typically used to draw the "first" (often only) value for a given pairwise relationship from an algorithm instead of a random value requiring storage to know.

        Parameters:
        store - initial value source
      • getBySourceValue

        @Nullable
        public PairwiseId getBySourceValue​(@Nonnull
                                           PairwiseId pid,
                                           boolean allowCreate)
                                    throws IOException
        Populate the pairwise ID field for the input object based on the supplied values.

        The input object must contain values for issuer and recipient entityIDs and the principal name, and the pairwise ID will be populated as applicable on output.

        The object returned, if non-null, may be, but does not have to be, the same physical object used as input. The original input object should not be referenced further.

        Specified by:
        getBySourceValue in interface PairwiseIdStore
        Parameters:
        pid - object to populate
        allowCreate - true iff the caller is authorizing the issuance of a new identifier
        Returns:
        object for the given inputs or null if none exists
        Throws:
        IOException - if an error occurs accessing the store
      • getByIssuedValue

        @Nullable
        public PairwiseId getByIssuedValue​(@Nonnull
                                           PairwiseId pid)
                                    throws IOException
        Populate the underlying principal/source fields for the input object based on the supplied values.

        The input object must contain values for issuer and recipient entityIDs and the pairwiseId itself, and the rest of the fields will be populated as applicable on output.

        The object returned, if non-null, will at least contain the principal name and source system ID. It may be, but does not have to be, the same physical object used as input. The original input object should not be referenced further.

        Specified by:
        getByIssuedValue in interface DurablePairwiseIdStore
        Parameters:
        pid - object to populate
        Returns:
        object for the given inputs or null if none exists
        Throws:
        IOException - if an error occurs accessing the store
      • deactivate

        public void deactivate​(@Nonnull
                               PairwiseId pid)
                        throws IOException
        Deactivate/revoke a pairwise ID.

        If the object's deactivation time field is null, then the current time is used.

        Specified by:
        deactivate in interface DurablePairwiseIdStore
        Parameters:
        pid - the object to deactivate/revoke
        Throws:
        IOException - if there is an error updating the store
      • verifyDatabase

        private void verifyDatabase()
                             throws SQLException
        Check the database and the presence of a uniqueness constraint.
        Throws:
        SQLException - if the database cannot be verified