Issue #4894 use schema and/or catalog name when creating sessions table (#4908)

Signed-off-by: Jan Bartel <janb@webtide.com>
This commit is contained in:
Jan Bartel 2020-05-27 13:42:01 +02:00 committed by GitHub
parent 85b500fc15
commit aae64f181c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 14 deletions

View File

@ -85,6 +85,16 @@ db-connection-type=datasource
#jetty.session.jdbc.schema.maxIntervalColumn=maxInterval
#jetty.session.jdbc.schema.mapColumn=map
#jetty.session.jdbc.schema.table=JettySessions
# Optional name of the schema used to identify where the session table is defined in the database:
# "" - empty string, no schema name
# "INFERRED" - special string meaning infer from the current db connection
# name - a string defined by the user
#jetty.session.jdbc.schema.schemaName
# Optional name of the catalog used to identify where the session table is defined in the database:
# "" - empty string, no catalog name
# "INFERRED" - special string meaning infer from the current db connection
# name - a string defined by the user
#jetty.session.jdbc.schema.catalogName
----
jetty.session.gracePeriod.seconds::
@ -111,4 +121,14 @@ jetty.session.jdbc.driverUrl::
Url of the database which includes the driver type, host name and port, service name and any specific attributes unique to the database, such as a username.
As an example, here is a mysql connection with the username appended: `jdbc:mysql://127.0.0.1:3306/sessions?user=sessionsadmin`.
The `jetty.sessionTableSchema` values represent the names for the columns in the JDBC database and can be changed to suit your environment.
The `jetty.session.jdbc.schema.*` values represent the names of the table and columns in the JDBC database used to store sessions and can be changed to suit your environment.
There are also two special, optional properties: `jetty.session.jdbc.schema.schemaName` and `jetty.session.jdbc.schema.catalogName`.
The exact meaning of these two properties is dependent on your database vendor, but can broadly be described as further scoping for the session table name.
See https://en.wikipedia.org/wiki/Database_schema and https://en.wikipedia.org/wiki/Database_catalog.
These extra scoping names can come into play at startup time when jetty determines if the session table already exists, or otherwise creates it on-the-fly.
If you have employed either of these concepts when you pre-created the session table, or you want to ensure that jetty uses them when it auto-creates the session table, then you have two options: either set them explicitly, or let jetty infer them from a database connection (obtained using either a Datasource or Driver according to the `db-connection-type` you have configured).
To set them explicitly, uncomment and supply appropriate values for the `jetty.session.jdbc.schema.schemaName` and/or `jetty.session.jdbc.schema.catalogName` properties.
To allow jetty to infer them from a database connection, use the special string `INFERRED` instead.
If you leave them blank or commented out, then the sessions table will not be scoped by schema or catalog name.

View File

@ -54,6 +54,12 @@
<Set name="mapColumn">
<Property name="jetty.session.jdbc.schema.mapColumn" default="map" />
</Set>
<Set name="schemaName">
<Property name="jetty.session.jdbc.schema.schemaName" />
</Set>
<Set name="catalogName">
<Property name="jetty.session.jdbc.schema.catalogName" />
</Set>
<Set name="tableName">
<Property name="jetty.session.jdbc.schema.table" default="JettySessions" />
</Set>

View File

@ -55,3 +55,14 @@ db-connection-type=datasource
#jetty.session.jdbc.schema.maxIntervalColumn=maxInterval
#jetty.session.jdbc.schema.mapColumn=map
#jetty.session.jdbc.schema.table=JettySessions
# Optional name of the schema used to identify where the session table is defined in the database:
# "" - empty string, no schema name
# "INFERRED" - special string meaning infer from the current db connection
# name - a string defined by the user
#jetty.session.jdbc.schema.schemaName
# Optional name of the catalog used to identify where the session table is defined in the database:
# "" - empty string, no catalog name
# "INFERRED" - special string meaning infer from the current db connection
# name - a string defined by the user
#jetty.session.jdbc.schema.catalogName

View File

@ -66,9 +66,11 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
public static class SessionTableSchema
{
public static final int MAX_INTERVAL_NOT_SET = -999;
public static final String INFERRED = "INFERRED";
protected DatabaseAdaptor _dbAdaptor;
protected String _schemaName = null;
protected String _catalogName = null;
protected String _tableName = "JettySessions";
protected String _idColumn = "sessionId";
protected String _contextPathColumn = "contextPath";
@ -87,7 +89,20 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
{
_dbAdaptor = dbadaptor;
}
public void setCatalogName(String catalogName)
{
if (catalogName != null && StringUtil.isBlank(catalogName))
_catalogName = null;
else
_catalogName = catalogName;
}
public String getCatalogName()
{
return _catalogName;
}
public String getSchemaName()
{
return _schemaName;
@ -95,8 +110,10 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
public void setSchemaName(String schemaName)
{
checkNotNull(schemaName);
_schemaName = schemaName;
if (schemaName != null && StringUtil.isBlank(schemaName))
_schemaName = null;
else
_schemaName = schemaName;
}
public String getTableName()
@ -484,28 +501,48 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
//make the session table if necessary
String tableName = _dbAdaptor.convertIdentifier(getTableName());
String schemaName = _dbAdaptor.convertIdentifier(getSchemaName());
try (ResultSet result = metaData.getTables(null, schemaName, tableName, null))
if (INFERRED.equalsIgnoreCase(schemaName))
{
//use the value from the connection -
//NOTE that this value will also now be prepended to ALL
//table names in queries/updates.
schemaName = connection.getSchema();
setSchemaName(schemaName);
}
String catalogName = _dbAdaptor.convertIdentifier(getCatalogName());
if (INFERRED.equalsIgnoreCase(catalogName))
{
//use the value from the connection
catalogName = connection.getCatalog();
setCatalogName(catalogName);
}
try (ResultSet result = metaData.getTables(catalogName, schemaName, tableName, null))
{
if (!result.next())
{
if (LOG.isDebugEnabled())
LOG.debug("Creating table {} schema={} catalog={}", tableName, schemaName, catalogName);
//table does not exist, so create it
statement.executeUpdate(getCreateStatementAsString());
}
else
{
if (LOG.isDebugEnabled())
LOG.debug("Not creating table {} schema={} catalog={}", tableName, schemaName, catalogName);
//session table exists, check it has maxinterval column
ResultSet colResult = null;
try
{
colResult = metaData.getColumns(null, schemaName, tableName,
colResult = metaData.getColumns(catalogName, schemaName, tableName,
_dbAdaptor.convertIdentifier(getMaxIntervalColumn()));
}
catch (SQLException sqlEx)
{
LOG.warn("Problem checking if " + getTableName() +
" table contains " + getMaxIntervalColumn() + " column. Ensure table contains column definition: \"" +
getMaxIntervalColumn() + " long not null default -999\"");
LOG.warn("Problem checking if {} table contains {} column. Ensure table contains column with definition: long not null default -999",
getTableName(), getMaxIntervalColumn());
throw sqlEx;
}
try
@ -519,9 +556,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
}
catch (SQLException sqlEx)
{
LOG.warn("Problem adding " + getMaxIntervalColumn() +
" column. Ensure table contains column definition: \"" + getMaxIntervalColumn() +
" long not null default -999\"");
LOG.warn("Problem adding {} column. Ensure table contains column definition: long not null default -999", getMaxIntervalColumn());
throw sqlEx;
}
}
@ -538,7 +573,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
boolean index1Exists = false;
boolean index2Exists = false;
try (ResultSet result = metaData.getIndexInfo(null, schemaName, tableName, false, true))
try (ResultSet result = metaData.getIndexInfo(catalogName, schemaName, tableName, false, true))
{
while (result.next())
{
@ -559,8 +594,8 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
@Override
public String toString()
{
return String.format("%s[%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s]", super.toString(),
_schemaName, _tableName, _idColumn, _contextPathColumn, _virtualHostColumn, _cookieTimeColumn, _createTimeColumn,
return String.format("%s[%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s]", super.toString(),
_catalogName, _schemaName, _tableName, _idColumn, _contextPathColumn, _virtualHostColumn, _cookieTimeColumn, _createTimeColumn,
_expiryTimeColumn, _accessTimeColumn, _lastAccessTimeColumn, _lastNodeColumn, _lastSavedTimeColumn, _maxIntervalColumn);
}
}