Multiple database configuration in dropwizard.

3,672 views
Skip to first unread message

Ankit Chaudhari

unread,
May 6, 2014, 2:01:57 PM5/6/14
to dropwiz...@googlegroups.com
Hello, 

I've already gone through the already existing questions on this but still not satisfied to the core. 

To add multiple database configuration, following is the info i got so far is - 

1) Update config.yml file -

database1:
  driverClass: com.mysql.jdbc.Driver
  user: user1
  password: user!23
  url: jdbc:mysql://url.to.connect:3306/db1
  properties: charSet: UTF-8
  maxWaitForConnection: 1s
  validationQuery: "/* MyService Health Check */ SELECT 1"
  minSize: 8
  maxSize: 32
  checkConnectionWhileIdle: false
  checkConnectionHealthWhenIdleFor: 10s
  closeConnectionIfIdleFor: 1 minute

database2:
  driverClass: com.mysql.jdbc.Driver
  user: user2
  password: user!23
  url: jdbc:mysql://url.to.connect:3306/db2
  properties: charSet: UTF-8
  maxWaitForConnection: 1s
  validationQuery: "/* MyService Health Check */ SELECT 1"
  minSize: 8
  maxSize: 32
  checkConnectionWhileIdle: false
  checkConnectionHealthWhenIdleFor: 10s
  closeConnectionIfIdleFor: 1 minute

2) Add the changes to java configuration file. 


public class DropWizardConfiguration extends Configuration{

    @Valid
    @NotNull
    @JsonProperty
    private DatabaseConfiguration database1 = new DatabaseConfiguration();
    @Valid
    @NotNull
    @JsonProperty
    private DatabaseConfiguration database2 = new DatabaseConfiguration();
public DatabaseConfiguration getDatabaseConfiguration1()
{
return database1;
        }

        public DatabaseConfiguration getDatabaseConfiguration2()
{
return database2;
        }
}

But after this, I am not sure what configuration to change? 

Appreciate some inputs.

Manikandan K

unread,
May 7, 2014, 2:02:10 PM5/7/14
to dropwiz...@googlegroups.com
you don't need to change anything else.. What is the problem you facing.. it should work fine.
Message has been deleted

Ankit Chaudhari

unread,
May 7, 2014, 2:36:18 PM5/7/14
to dropwiz...@googlegroups.com
 have a web service with endpoint something like - 

endpoint.url.of.the.service:8080/games/getAllGames/2 

I have to select the configuration depending on the value passed in my service method? 
Where exactly am i suppose to handle that? 

what i know is - the db configuration is selected BEFORE the url is processed. 
heres the Service code - 

/*
* Here the configuration is getting selected and then Resource is added to the environment. 
*
*/
public class DropWizardService extends Service<DropWizardConfiguration>{
private final HibernateBundle<DropWizardConfiguration> hibernate = new HibernateBundle<DropWizardConfiguration>(Game.class) {

// @Override
public DatabaseConfiguration getDatabaseConfiguration(DropWizardConfiguration configuration){
return configuration.getDatabaseConfiguration();
}
};
 
@Override
public void initialize(Bootstrap<DropWizardConfiguration> bootstrap) {
bootstrap.addBundle(hibernate);
}
public void run() throws Exception{
this.run(new String[]{"server", "./config.yml"});
}

@Override
public void run(DropWizardConfiguration configuration, Environment environment) throws Exception {
SessionFactory factory = hibernate.getSessionFactory();
environment.addResource(new MyResource(factory));
}



and my Resource class - 


/*
* The resouce class, handles the endpoint url. 
*
*
*/
@Path(value = "/games")
public class MyResource {
SessionFactory sessionFactory;
protected Logger logger = Logger.getLogger(getClass());

public GameResource(SessionFactory factory) {
this.sessionFactory = factory;
}

@GET
@Path(value = "/getAllGames/{envId}")
@Produces(MediaType.APPLICATION_JSON)
public Game getGameById(@PathParam(value = "envId") int envId) {
                /*
                * I have to decide HERE which environment to select! How to do it? 
                *
                */
DaoManager daoManager = new DaoManager(sessionFactory);
return daoManager.getAllGames();
}

Shan Syed

unread,
May 7, 2014, 2:41:36 PM5/7/14
to dropwiz...@googlegroups.com
think of it like this:
- your application has two databases that it writes to for various reasons
- each of these is configured at initialization time of  your app (startup), by way of these configurations that you created
- therefore, in your resource, when at request-time you choose which database you need to write too; the configuration of each of these is already done, you don't need the configuration any more since it's already applied

so see the thing you have called "hibernate"? that's not good enough, you need two: hibernate1 and hibernate2
inject a sessionfactory from each into your resource, and make the choice of which one to write to at request time

easy peasy



On Wed, May 7, 2014 at 2:33 PM, Ankit <ank...@gmail.com> wrote:
I have a web service with endpoint something like - 

endpoint.url.of.the.service:8080/Games/getAllGames/2 
@Path(value = "/getGameById/{casinoId}/{envId}/{gameId}")
@Produces(MediaType.APPLICATION_JSON)
public Game getGameById(@PathParam(value = "envId") int envId) {
                /*
                * I have to decide HERE which environment to select! How to do it? 
                *
                */
DaoManager daoManager = new DaoManager(sessionFactory);
return daoManager.getAllGames();
}
}



--
You received this message because you are subscribed to a topic in the Google Groups "dropwizard-user" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/dropwizard-user/-KJenChwXGQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to dropwizard-us...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Ankit Chaudhari.
There are many ways to move ahead , but only ONE WAY to stand still..
http://www.ankitjc.info

--
You received this message because you are subscribed to the Google Groups "dropwizard-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dropwizard-us...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ankit

unread,
May 7, 2014, 2:56:57 PM5/7/14
to dropwiz...@googlegroups.com
Thank you Shan... 

So you mean to say, currently if i have 15 different environments, DEV, QA1 to 12, staging and live, I have to maintain that many different sessionFactories? 


Shan Syed

unread,
May 7, 2014, 3:00:53 PM5/7/14
to dropwiz...@googlegroups.com
ok, wait - initially when you posed your question, it seemed like you had two databases that your app relied on

but it seems like your app has just one database; you just have different VALUES for the same configuration, depending on environment, correct?

if that is the case, you just need to have one database "configuration" files, and just manage a different YML config for each environment
you can also use the ENVIRONMENT variable @ injection thing that was just recently mentioned on this mailing list


Ankit

unread,
May 7, 2014, 3:13:54 PM5/7/14
to dropwiz...@googlegroups.com
No, I do have separate databases. DEV Db, then QA1 to QA 12 and then STAGING and LIVE. Each on a separate server with independent creds. 

dbDEV:
  driverClass: com.mysql.jdbc.Driver
  user: userDEV
  password: user!23
  url: jdbc:mysql://url.to.connect.to.DEV:3306/db1
  properties: charSet: UTF-8
  maxWaitForConnection: 1s
  validationQuery: "/* MyService Health Check */ SELECT 1"
  minSize: 8
  maxSize: 32
  checkConnectionWhileIdle: false
  checkConnectionHealthWhenIdleFor: 10s
  closeConnectionIfIdleFor: 1 minute

dbQA1:
  driverClass: com.mysql.jdbc.Driver
  user: userQA
  password: user!23
  url: jdbc:mysql://url.to.connect.TO.QA5:3306/db2
  properties: charSet: UTF-8
  maxWaitForConnection: 1s
  validationQuery: "/* MyService Health Check */ SELECT 1"
  minSize: 8
  maxSize: 32
  checkConnectionWhileIdle: false
  checkConnectionHealthWhenIdleFor: 10s
  closeConnectionIfIdleFor: 1 minute 

Shan Syed

unread,
May 7, 2014, 3:15:05 PM5/7/14
to dropwiz...@googlegroups.com
at runtime, when your app is installed in a particular environment - how many databases does it need to do its job?

Flaviano O. Silva

unread,
Jan 15, 2015, 11:38:59 AM1/15/15
to dropwiz...@googlegroups.com
My scenario is as follows:
* I need my DropWizard server meets requests to multiple systems and each system uses a different database (user, password, and even technology), depending on the service will be called a connection. How do I? Tranks

dssystem01:

  driverClass: org.postgresql.Driver
  user: pg-user
  password: 123456
  url: jdbc:postgresql://db.example.com/db-prod
  properties:
    charSet: UTF-8
  maxWaitForConnection: 1s
  minSize: 8
  maxSize: 32
  checkConnectionWhileIdle: false
  evictionInterval: 10s
  minIdleTime: 1 minute

dssystem02:
  driverClass: com.mysql.jdbc.Driver
  user: user
  password: 123456
  url: jdbc:mysql://myserverdb/sistema02?autoReconnect=true
  properties:
    charSet: UTF-8
  maxWaitForConnection: 1s
  minSize: 8
  maxSize: 32
  checkConnectionWhileIdle: false
  evictionInterval: 10s
  minIdleTime: 1 minute

dssystem03:
  driverClass: com.mysql.jdbc.Driver
  user: user_app
  password: app990088
  url: jdbc:mysql://myserverdb/sistema03?autoReconnect=true
  properties:
    charSet: UTF-8
  maxWaitForConnection: 1s
  minSize: 8
  maxSize: 32
  checkConnectionWhileIdle: false
  evictionInterval: 10s
  minIdleTime: 1 minute



Eddie McLean

unread,
Jan 15, 2015, 2:05:11 PM1/15/15
to dropwiz...@googlegroups.com
Flaviano,

Are you simply asking if you can configure multiple databases?  If so the answer is yes, all you need to do is add them to your configuration class then invoke the getters as needed from your service's run method.

eg.
public class FlaviosConfiguration extends Configuration {

  @JsonProperty("dssystem01")
  @NotNull
  private DataSourceFactory dataSource01;

  @JsonProperty("dssystem02")
  @NotNull
  private DataSourceFactory dataSource02;

  public DataSourceFactory getDataSource01(){
    return dataSource01;
  }

  public DataSourceFactory getDataSource02(){
    return dataSource02;
  }
}

Hope this helps

Gene Trog

unread,
Jan 15, 2015, 2:41:50 PM1/15/15
to dropwiz...@googlegroups.com
Another possibility is to use Map<String, DataSourceFactory>:

@NotNull
private Map<String, DataSourceFactory> databases;

And then in your endpoint you could access it accordingly:

@Path("/myPath/{database}")
public void doSomething(@PathParam("database") String database) {
   DataSourceFactory database = configuration.getDatabases().get(database);
   // validate database is not null, etc.
}

Your config would then look something like:

databases:
    dataSource1:
        driverClass: ...
    dataSource2:
        driverClass: ...

And 'dataSource1' and 'dataSource2' would now be keys in this map

RAJASEKHAR shekhary

unread,
Jul 14, 2015, 4:22:04 AM7/14/15
to dropwiz...@googlegroups.com
Hi Guys, I was using DW 0.8.1 for multiple schema's loading. Facing postgresql.active already exists issue,can you please help me out with the quick solution.
appreciated for your quick response.

my yml is having db details for each instance:

yml:-

database01: //details of db01
database01: // details of db02

config class similar to bwlo config..
public class confxyz extends Configuration {

@JsonProperty("db01")
@NotNull
private DataSourceFactory dataSource01;

@JsonProperty("db02")
@NotNull
private DataSourceFactory dataSource02;

public DataSourceFactory getDataSource01(){
return dataSource01;
}

public DataSourceFactory getDataSource02(){
return dataSource02;
}
}

in the Service class I was using the below code snippet.


DBI jdbi = getdbinstace01(env, confxyz ); // db01 instance

final dap daodb01 = jdbi.onDemand(dao01.class);

jdbi = getdbinstance02(env, confxyz ); //db02 instance

final IJCEMCDao daodb02 = jdbi.onDemand(da002.class);

ABC class abc = new ABCResource(daodb01,daodb02);
environment.jersey().register(abc);

When I use the above code snippet I am Facing issue that Postgres instance is already exists while loading the second dbinstance(db02) getting the below issue.


Caused by: MultiException[java.lang.IllegalArgumentException: A metric named io.dropwizard.db.ManagedPooledDataSource.postgresql.active already exists, java.util.concurrent.RejectedExecutionException: org.eclipse.jetty.util.thread.NonBlockingThread@41b52633]
at org.eclipse.jetty.server.Server.doStart(Server.java:329)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68

Gene Trog

unread,
Jul 14, 2015, 9:22:31 AM7/14/15
to dropwiz...@googlegroups.com
This means that somewhere this 'ManagedPooledDataSource' is being instantiated more than once with the same pool name and it creates metrics with the same pool name.  In dropwizard, metrics can't have the same name, so, that's why the exception is being thrown here.  I would check if in building your DataSource, if you're passing in the same name 'postgresql' multiple times (multiple build() calls)


--
You received this message because you are subscribed to a topic in the Google Groups "dropwizard-user" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/dropwizard-user/-KJenChwXGQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to dropwizard-us...@googlegroups.com.

RAJASEKHAR shekhary

unread,
Jul 14, 2015, 9:53:09 AM7/14/15
to dropwiz...@googlegroups.com
Thank you very much for your response. Yes you are right I am doing the postgresql' multiple times (multiple build() calls).
but I have to build with different schema's one is with db01 and the other one is with db02 , if not is there any other way?

  jdbi = factory.build(env, confxyz.getDataSource02(), "postgresql");

In MetricRegistery code we can see if Metric is existing already it was throwing the  the ( postgres) instance already exists.

@SuppressWarnings("unchecked")
    public <T extends Metric> T register(String name, T metric) throws IllegalArgumentException {
        if (metric instanceof MetricSet) {
            registerAll(name, (MetricSet) metric);
        } else {
            final Metric existing = metrics.putIfAbsent(name, metric);
            if (existing == null) {
                onMetricAdded(name, metric);
            } else {
                throw new IllegalArgumentException("A metric named " + name + " already exists");
            }
        }
        return metric;
    }
--
Thanks & Regards
Raj

Carlo Barbara

unread,
Jul 14, 2015, 10:25:13 AM7/14/15
to dropwiz...@googlegroups.com
I haven't confirmed, but I think you need two different DBIs

        final DBIFactory factory = new DBIFactory();
        final DBI dbi1 = factory.build(environment, configuration.getDatabaseConfiguration(), "postgres1");
        final DBI dbi2 = factory.build(environment, configuration.getDatabaseConfiguration(), "postgres2);


--
You received this message because you are subscribed to the Google Groups "dropwizard-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dropwizard-us...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages