Skip to content

Instantly share code, notes, and snippets.

@mrserverless
Last active February 17, 2017 09:52
Show Gist options
  • Save mrserverless/618eaa54eec1a726ae21 to your computer and use it in GitHub Desktop.
Save mrserverless/618eaa54eec1a726ae21 to your computer and use it in GitHub Desktop.
Dropwizard MultiTenant DataSource using RequestScope injected Schema object
public class MultiTenantDataSource implements ManagedDataSource {
private final ManagedDataSource managedDataSource;
private final SchemaResolver schemaResolver;
public MultiTenantDataSource( final ManagedDataSource managedDataSource, final SchemaResolver schemaResolver )
{
this.managedDataSource = managedDataSource;
this.schemaResolver = schemaResolver;
}
@Override
public Connection getConnection() throws SQLException
{
final Connection connection = managedDataSource.getConnection();
setSchema(connection, resolveConnectionSchema() );
return connection;
}
private String resolveConnectionSchema()
{
final Optional<Schema> agencyOptional = schemaResolver.resolve();
String schema = "public";
if (agencyOptional.isPresent()) {
schema = agencyOptional.get().getName();
}
return schema;
}
private void setSchema( final Connection connection, final String schema ) throws SQLException
{
System.out.println("Setting schema to " + schema);
try (Statement statement = connection.createStatement()) {
final String sql = String.format( "set search_path = '%s'", schema );
statement.execute( sql );
}
}
@Override
public Connection getConnection( final String username, final String password ) throws SQLException
{
return managedDataSource.getConnection( username, password );
}
@Override
public PrintWriter getLogWriter() throws SQLException
{
return managedDataSource.getLogWriter();
}
@Override
public void setLogWriter( final PrintWriter out ) throws SQLException
{
managedDataSource.setLogWriter( out );
}
@Override
public void setLoginTimeout( final int seconds ) throws SQLException
{
managedDataSource.setLoginTimeout( seconds );
}
@Override
public int getLoginTimeout() throws SQLException
{
return managedDataSource.getLoginTimeout();
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException
{
return managedDataSource.getParentLogger();
}
@Override
public void start() throws Exception
{
managedDataSource.start();
}
@Override
public void stop() throws Exception
{
managedDataSource.stop();
}
@Override
public <T> T unwrap( final Class<T> iface ) throws SQLException
{
return managedDataSource.unwrap( iface );
}
@Override
public boolean isWrapperFor( final Class<?> iface ) throws SQLException
{
return managedDataSource.isWrapperFor( iface );
}
}
@RequestScoped
public class Schema
{
private String name;
public void setName( final String name )
{
this.name = name;
}
public String getName()
{
return name;
}
}
@javax.ws.rs.ext.Provider
public class TenantFilter implements ContainerRequestFilter {
private final Provider<Schema> schemaProvider;
@Inject
public TenantFilter(Provider<Schema> schemaProvider) {
this.schemaProvider = schemaProvider;
}
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
final Schema schema = schemaProvider.get();
schema.setName(requestContext.getHeaderString("tenant"));
}
}
public class SchemaResolver
{
@Inject
Provider<Schema>schemaProvider;
public Optional<Schema> resolve() {
Schema schema = schemaProvider.get();
if ( schema.getName() != null)
{
return Optional.of( schema );
}
else {
return Optional.empty();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment