Question

I'm developing a webservice using Dropwizard JDBI framework.

Now, instead of having a db configurations in yaml file, I want to use 'user specified params' what i mean to say is, the db configs will be provided through the endpoint url.

  • Is having custom creds possible through dropwizard jdbi?

if yes, what changes should i be thinking to do in the code while referring this ? ->

http://dropwizard.readthedocs.org/en/latest/manual/jdbi.html

I understand, in normal flow, the service method gets the config details in the run method -

-- Config Class

public class ExampleConfiguration extends Configuration {
    @Valid
    @NotNull
    @JsonProperty
    private DatabaseConfiguration database = new DatabaseConfiguration();

    public DatabaseConfiguration getDatabaseConfiguration() {
        return database;
    }
}

-- Service Class

@Override
        public void run(ExampleConfiguration config,
                        Environment environment) throws ClassNotFoundException {
            final DBIFactory factory = new DBIFactory();
            final DBI jdbi = factory.build(environment, config.getDatabaseConfiguration(), "postgresql");
            final UserDAO dao = jdbi.onDemand(UserDAO.class);
            environment.addResource(new UserResource(dao));
        }

-- and yaml

database:
  # the name of your JDBC driver
  driverClass: org.postgresql.Driver

  # the username
  user: pg-user

  # the password
  password: iAMs00perSecrEET

  # the JDBC URL
  url: jdbc:postgresql://db.example.com/db-prod

But in this case, I might get the config details in the Resource level...

smthing like -

@GET
@Path(value = "/getProduct/{Id}/{dbUrl}/{dbUname}/{dbPass}")
@Produces(MediaType.APPLICATION_JSON)
public Product getProductById(@PathParam(value = "Id") int Id,
        @PathParam(value = "dbUrl") String dbUrl,
        @PathParam(value = "dbUname") String dbUname,
        @PathParam(value = "dbPath") String dbPass) {

     //I have to connect to the DB here! using the params i have.         
     return new Product(); //should return the Product
}

I'd appreciate if someone can point me a direction.

Was it helpful?

Solution

Why not just use JDBI directly?

@GET
@Path(value = "/getProduct/{Id}/{dbUrl}/{dbUname}/{dbPass}")
@Produces(MediaType.APPLICATION_JSON)
public Product getProductById(@PathParam(value = "Id") int id,
    @PathParam(value = "dbUrl") String dbUrl,
    @PathParam(value = "dbUname") String dbUname,
    @PathParam(value = "dbPass") String dbPass) {
  DataSource ds = JdbcConnectionPool.create(dbUrl, dbUname, dbPass);
  DBI dbi = new DBI(ds);
  ProductDAO dao = dbi.open(ProductDao.class);
  Product product = dao.findById(id);
  dao.close();
  ds.dispose();
  return product;
}

@RegisterMapper(ProductMapper.class)
static interface ProductDao {
  @SqlQuery("select id from product_table where id = :id") // Whatever SQL query you need to product the product
  Product findById(@Bind("id") int id);

  @SqlQuery("select * from product_table")
  Iterator<Product> findAllProducts();
}

static class ProductMapper implements ResultSetMapper<Product> {
  public Product map(int index, ResultSet r, StatementContext ctx) throws SQLException {
    return new Product(r.getInt("id")); // Whatever product constructor you need
  }
}

OTHER TIPS

There's a notion in the spring world of using a database router (reference: https://spring.io/blog/2007/01/23/dynamic-datasource-routing/).

You likely could setup a proxy for the database connection factory passed to DBI. That proxy would then get the credentials from a thread local (perhaps) and return the real connection giving you what you're after and still let you use the run type proxies.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top