How to setup embeded Jetty to use JDBC sessions - session

I am using embedded jetty (group: 'org.eclipse.jetty', name: 'jetty-webapp', version: '9.4.27.v20200227') and I am trying to programmatically setup it to use JDBC for session storage. All the documentation/examples I can find is about standalone jetty.
Do you know how to setup it?

I don't know all that much about JDBC or session storage, but looking at the documentation Persistent Sessions: JDBC for standalone jetty, it is telling you to enable the module session-store-jdbc. By looking at session-store-jdbc.mod you can see that it uses etc/sessions/jdbc/session-store.xml and these XML files can be directly translated into java code.
So it looks like its adding a JDBCSessionDataStoreFactory as a bean onto the server. So some equivalent code that you could try would look something like:
// Configure a JDBCSessionDataStoreFactory.
JDBCSessionDataStoreFactory sessionDataStoreFactory = new JDBCSessionDataStoreFactory();
sessionDataStoreFactory.setGracePeriodSec(3600);
sessionDataStoreFactory.setSavePeriodSec(0);
sessionDataStoreFactory.setDatabaseAdaptor(...);
JDBCSessionDataStore.SessionTableSchema schema = new JDBCSessionDataStore.SessionTableSchema();
schema.setAccessTimeColumn("accessTime");
schema.setContextPathColumn("contextPath");
// ... more configuration here
sessionDataStoreFactory.setSessionTableSchema(schema);
// Add the SessionDataStoreFactory as a bean on the server.
server.addBean(sessionDataStoreFactory);

Related

Springboot: Spring JPA - How to get datasource properties from server container

I use WAS Liberty Server container which provides server.xml and server.env file for configuring many things in addition to configuring DataSource properties such as url, username, password etc.
For security reasons, these properties are not known to developers for production Liberty servers. However, developers use same server.xml/server.evn files but with different DataSource properties so they can do their work.
So, I might have two server.env files like:
PRODUCTION server.env: dataSourceUrl="server-A-URL" (this URL is not known to developers)
DEVELOPMENT server.env: dataSourceUrl="server-B-URL" (this URL is known to developers)
, then the dataSourceUrl is used in server.xml files in production and development to set the url accordingly.
So, the structure of server.xml/server.env file is same for developers and production, only the DataSource url, username, password are different. This way developers can work using their own DataSource properties and once ready to deploy they app, it is handed to other team which then just changes the DataSource properties to the production values and deploys the application to production server.
With Springboot JPA, I know we can use application.properties file to set these DataSource values. But, we would like to be able to set these to the values located in server.env file. Basically to have something like this in application.properties file:
spring.datasource.url=dataSourceUrl //dataSourceUrl is set in server.env
, then be able to use this value in Java code using #Value injection like:
public class MyClass {
#Value("${spring.datasource.url}")
String dsUrl;
...
}
I have been reading about externalizing properties but I am not able to figure out how to do this
You can use Liberty's jndiEntry elements to make configured values available in JNDI. You will need the jndi-1.0 feature, after which you can configure,
<jndiEntry jndiName="spring/datasource/url" value="${dataSourceUrl}"/>
and access it in your application as:
String dsUrl = InitialContext.doLookup("spring/datasource/url");
Or, from a web or ejb component as:
#Resource(lookup = "spring/datasource/url")
String dsUrl;

How to connect to HSQL which Spring creates when jdbc:embedded-database is used?

I have a HSQL database which Spring automatically creates for me:
<jdbc:embedded-database id="dataSource" type="HSQL">
<jdbc:script location="classpath:scheme.sql" /
</jdbc:embedded-database>
And now I want to connect to this database. My question is how to do this, because I don't known which address I should use.
This embedded HSQL database is all-in-memory and in-process, therefore accessible only from the Spring Java process. If you want to access the database from another tool as well, for example to check the contents with a database manager, you can start an HSQLDB server with an all-in-memory instance, then connect to the server from Spring and other tools.
This is covered in the HSQLDB Guide http://hsqldb.org/doc/2.0/guide/listeners-chapt.html
The server is started with this command:
java -cp ../lib/hsqldb.jar org.hsqldb.Server --database.0 mem:test --dbname.0 test
You need to create a Spring data source with username "SA" and password "". The database driver and URL (from the same machine) to configure the Spring data source are:
org.hsqldb.jdbcDriver
jdbc:hsqldb:hsql://localhost/test
I recomend you to use external Database, but just in case if you want to use HSQL, then this may will help you http://java.dzone.com/articles/spring-3-makes-use-embedded-easy
Embedded-database is an in memory DB and Spring supports HSQL, H2, and Derby . You could go to their respective site for the connection details .
For H2 see here .
For HSQL see here and here.
As far as I understand , the
<jdbc:embedded-database id="dataSource" type="HSQL">
<jdbc:script location="classpath:scheme.sql" /
</jdbc:embedded-database>
uses an in-memory DB and so is not accessible externally . You'll be able to access this within the same VM and same class loader .
You can connect to the embedded database in the normal fashion, (SQL Developer, SQL Explorer etc); I used my debugger to look at the URL property in the embedded database bean I created with Spring, in your case dataSource. I would think your url would be something along the lines of jdbc:hsqldb:mem:dataSource.
For some people a sufficient solution would be to use the h2 console - as described here:
spring boot default H2 jdbc connection (and H2 console)
You must only remember to set hsqldb drivers where needed. This way the database doesn't have to be started separately. You also don't have to install any additional software to browse it.
you can do like this
final ApplicationContext ctx = new ClassPathXmlApplicationContext("dao-context.xml");
final DataSource dataSource = (DataSource)ctx.getBean("dataSource");
final Connection conn = dataSource.getConnection();

Jdbc Connection Pooling - using multiple schema known at runtime only

I am working on an engine that is doing the following:
gets data provider info from DB (that tells me to what database & schema details to connect to get my data)
use that info to connect to the database and get my data, that later I use to build some XML content.
The standard setup to handle and isolate database connection management would be to create a DataSource bean (I'm using Spring to wire my components) and inject that in my ProviderConfigDao (loads connection config) and ContentDao (loads data using connection details loaded previously). This would nicely isolate the handling of the connections from the actual code, thus the DAO classes not needing to know how and when a connection is created/opened/closed etc.
This setup doesn't work unfortunately, as when I create my connection, I need to be able to specify the database schema. I don't know all the different schemas from the beginning, so I can't create a set of DataSource objects to cover all of them, thus the DataSource object must be created at runtime and it's creation hidden from the users.
The only solution I can think of is:
Have another class/interface (DataSourceProvider) having one method:
//Gets the connection URL as parameter (which includes the schema name).
DataSource getDataSource(String url);
Add a bean in Spring config to provide a custom implementation for it that manages creation of DataSource objects for each schema.
Inject that object to my DAO classes instead of the DataSource object.
It's not a bad solution, but I was wondering if there is maybe support for something like this already in some open source package ... I'd rather use something already done and tested then reinvent the wheel.
Cheers,
Stef.
there's a JDBC Utils to get all the metada from a database org.springframework.jdbc.support.JdbcUtils
parameters:
DataSource
Implementation of org.springframework.jdbc.support.DatabaseMetaDataCallback

Overriding the default session manager with embedded tomcat 7 java

I am trying to override the tomcat session manager with an embedded tomcat.
These are the steps preformed in-order to load the context.xml that defines the manager entity.
..
Context context = tomcat.addWebapp(contextPath, appBase);
File configFile = new File ("D:\\context.xml");
context.setConfigFile(configFile.toURI().toURL());
tomcat.start();
..
The session manager seems to be recognized as it's constructor is being invoked but the startInternal() method is never invoked and the session manager being used is the old tomcat session manager.
The weird thing is that when defining the same configuration in a non embedded tomcat, the session manager is being overridden without problems.
Would appriciate any help on the subject.
Non embedded tomcat uses server.xml and embedded tomcat does not uses server.xml file rather we need to pass the arguments in the method.

How to use HSQLDB as a datasource in Websphere Application Server?

I try to set up a local development infrastructure and I want to use HSQLDB as a datasource with my WAS 6.1. I already know that I have to use Apache DBCP to get a connection pooling, but I'm stuck when my application tries to get the first connection.
What I've done
In WAS I created a JDBC provider with the class org.apache.commons.dbcp.cpdsadapter.DriverAdapterCPDS and removed everything from the classpath input field. Then I put commons-dbcp.jar, commons-pool.jar and hsqldb.jar in MYAPPSERVERDIRECTORY/lib/ext.
Then I created a new datasource with that provider. I added the following custom properties:
driver=org.hsqldb.jdbc.JDBCDriver
url=jdbc:hsqldb:file:///C:/mydatabase.db;shutdown=true
user=SA
password=
My Problem
When I run my application and the first connection to the database is made, I get the following exception:
---- Begin backtrace for Nested Throwables
java.sql.SQLException: No suitable driverDSRA0010E: SQL-Status = 08001, Fehlercode = 0
at java.sql.DriverManager.getConnection(DriverManager.java:592)
at java.sql.DriverManager.getConnection(DriverManager.java:196)
at org.apache.commons.dbcp.cpdsadapter.DriverAdapterCPDS.getPooledConnection(DriverAdapterCPDS.java:205)
at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper$1.run(InternalGenericDataStoreHelper.java:918)
at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper.getPooledConnection(InternalGenericDataStoreHelper.java:955)
at com.ibm.ws.rsadapter.spi.WSRdbDataSource.getPooledConnection(WSRdbDataSource.java:1437)
at com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl.createManagedConnection(WSManagedConnectionFactoryImpl.java:1089)
at com.ibm.ejs.j2c.FreePool.createManagedConnectionWithMCWrapper(FreePool.java:1837)
at com.ibm.ejs.j2c.FreePool.createOrWaitForConnection(FreePool.java:1568)
at com.ibm.ejs.j2c.PoolManager.reserve(PoolManager.java:2338)
at com.ibm.ejs.j2c.ConnectionManager.allocateMCWrapper(ConnectionManager.java:909)
at com.ibm.ejs.j2c.ConnectionManager.allocateConnection(ConnectionManager.java:599)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:439)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:408)
Any tips on this? I suspect I'm using a wrong class from hsqldb, or maybe my JDBC url is wrong...
In the example given in BDCP docs, the org.hsqldb.jdbcDriver class is used as the driver. The org.hsqldb.jdbc.JDBCDriver is supported only in HSQLDB 2.x, but the other class is supported by all versions of HSQLDB.

Resources