Re: Runtime Cloning of DataSource for Different DB?

2016-12-19 Thread Christopher Schultz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA256

Jerry,

On 12/16/16 3:39 PM, Jerry Malcolm wrote:
> On 6/27/2016 4:35 PM, Jerry Malcolm wrote:
>> Mark,
>> 
>> On 6/27/2016 1:07 PM, Mark Thomas wrote:
>>> On 27/06/2016 17:44, Jerry Malcolm wrote:
>>> 
 I'm assuming that context.lookup(...) simply locates the
 "jdbc/myDB"  tag in the context.xml file, pulls all
 of the parms out of that tag, creates a DataSource object
 utilizing the parms, and returns it.If that's the case,
 couldn't I create a variation/subclass of the Context object
 that modifies the url parm that it found in the resource tag
 and puts the desired db name into the url before constructing
 the DataSource?
>>> Sure.
>>> 
>>> You need to implement the appropriate factory and then specify
>>> your factory class explicitly in the Resource element using the
>>> factory attribute.
>>> 
>>> You probably want to start here for ideas on how to code up
>>> your factory: 
>>> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/fac
tory/
>>>
>>>
>>>
>>> 
or for a more specific example:
>>> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbc
p/dbcp2/BasicDataSourceFactory.java?view=annotate
>>>
>>>
>>>
>>>
>>> 
Mark
>>> 
>> 
> Mark, It's been several months since we corresponded on this
> thread.  I've been working on other aspects of the project. But the
> time has arrived that I have to get this working.  Refresher I
> want to have one generic  .
> When I need an instance, I pass a dbname to the factory and it
> builds the correct URL substituting the desired dbName into the
> URL.
> 
> I have coded a subclass of BasicDataSourceFactory that has a new 
> getInstance( databaseName ) method on it.  All I'm doing there is 
> getting the URL property from the common/generic  tag
> and appending databaseName to the URL, then calling the parent 
> createDataSource( properties ) method.  I believe that will do what
> I need.  Plus it compiles successfully.
> 
> Where I'm falling apart now is defining the resource tag(s) and 
> successfully coding the request to get an instance.   Normally when
> I reference a "" tag in my code [ ds = 
> (DataSource)envContext.lookup( dataSourceName );  ] the lookup 
> apparently uses the default datasourcefactory and returns a
> datasource. Fine.  But now I want to tell it use my subclass
> factory instead, and I need to pass a parameter (the db name) in.
> So I 'think' I need to get an instance of MyDataSourceFactory, then
> call my new method on it.  But how do I tell "envContext.lookup()"
> that I want to use my own factory and my own custom method (with
> the additional parameter) to get the instance from the factory?
> Or do I use "envContext.lookup() to lookup and give me an
> instance of my FACTORY, and then simply call my method on my 
> factory to get the ds?  Either way, I'm hitting wall on how to do
> it.

It's all in the configuration; your code shouldn't have to do anything.



NOTE: I have no idea if this is the right code here, but conceptually
it sounds like what you are trying to do.

package fully.qualified;
public class MyDataSourceFactory {
  public void setDBName(String name) { ... };
  public static String getDBName() { ... };
  public Object createDataSource(Properties props) {
String dbURL = getURL().replaceAll("%dbName%", getDBName());

props.put("url", dbURL");
return super.createDataSource(props);
  }
}

I think that's all you're looking for.

It occurs to me that your *code* might need to provide the dbname to
the factory. In that case you might have to provide some environmental
context for this. Maybe a ThreadLocal.



[The "unsharable" scope means that every call to ctx.lookup() will
return a new pooled DataSource. That means you don't want to use JNDI
as your application's stash for the DataSource... you're going to want
to store it instead in e.g. the application scope.]

package fully.qualified;
public class MyDataSourceFactory {
  public ThreadLocal dbName = new ThreadLocal();
  public Object createDataSource(Properties props) {
String dbURL = getURL().replaceAll("%dbName%", dbName.get());

props.put("url", dbURL");
return super.createDataSource(props);
  }
}

// client code
MyDataSourceFactory.dbName.set("explicitDBName");
DataSource dx = ctx.lookup(jndiPath);

I'm not sure if the servlet spec or Tomcat provide any guarantees
about the current thread being used to call the factory's
createDataSource method, but I don't see a reason why Tomcat would use
another thread for that purpose.

- -chris
-BEGIN PGP SIGNATURE-
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBCAAGBQJYWCXzAAoJEBzwKT+lPKRYZH8QALuuG0XTNaJg1qFJi0p25Bbx
Gp7UbIZqOiIpFAavs/pco8+knnas9deX5DLLS8/CfQWK0l9SByAuR+0ltOJa8oCp
KpQXBhBWiJEQggQ1j4Moii/KWLO4Rt0fVAv800fFZ4DVvAEytm5JNP9J1cT9vRJx
RucK9FgFnRi8tKTvhjP0LXly3myFPwr+gHciki7Sh5W8lrKAkSEmOBPZIRyNvFr7

Re: Runtime Cloning of DataSource for Different DB?

2016-12-16 Thread Jerry Malcolm

On 6/27/2016 4:35 PM, Jerry Malcolm wrote:

Mark,

On 6/27/2016 1:07 PM, Mark Thomas wrote:

On 27/06/2016 17:44, Jerry Malcolm wrote:


I'm assuming that context.lookup(...) simply locates the "jdbc/myDB"
 tag in the context.xml file, pulls all of the parms out of
that tag, creates a DataSource object utilizing the parms, and returns
it.If that's the case, couldn't I create a variation/subclass of 
the

Context object that modifies the url parm that it found in the resource
tag and puts the desired db name into the url before constructing the
DataSource?

Sure.

You need to implement the appropriate factory and then specify your
factory class explicitly in the Resource element using the factory
attribute.

You probably want to start here for ideas on how to code up your 
factory:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/factory/ 



or for a more specific example:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java?view=annotate 




Mark




Mark,
It's been several months since we corresponded on this thread.  I've 
been working on other aspects of the project. But the time has arrived 
that I have to get this working.  Refresher I want to have one 
generic  .   When I need an 
instance, I pass a dbname to the factory and it builds the correct URL 
substituting the desired dbName into the URL.


I have coded a subclass of BasicDataSourceFactory that has a new 
getInstance( databaseName ) method on it.  All I'm doing there is 
getting the URL property from the common/generic  tag and 
appending databaseName to the URL, then calling the parent 
createDataSource( properties ) method.  I believe that will do what I 
need.  Plus it compiles successfully.


Where I'm falling apart now is defining the resource tag(s) and 
successfully coding the request to get an instance.   Normally when I 
reference a "" tag in my code [ ds = 
(DataSource)envContext.lookup( dataSourceName );  ] the lookup 
apparently uses the default datasourcefactory and returns a datasource.  
Fine.  But now I want to tell it use my subclass factory instead, and I 
need to pass a parameter (the db name) in. So I 'think' I need to get an 
instance of MyDataSourceFactory, then call my new method on it.  But how 
do I tell "envContext.lookup()" that I want to use my own factory and my 
own custom method (with the additional parameter) to get the instance 
from the factory?  Or do I use "envContext.lookup() to lookup and 
give me an instance of my FACTORY, and then simply call my method on my 
factory to get the ds?  Either way, I'm hitting wall on how to do it.


Thanks.

Jerry



-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Runtime Cloning of DataSource for Different DB?

2016-06-29 Thread Terence M. Bandoian

On 6/29/2016 1:44 AM, Mark Thomas wrote:

On 29/06/2016 05:12, Terence M. Bandoian wrote:

On 6/28/2016 3:56 AM, Mark Thomas wrote:

On 27/06/2016 22:35, Jerry Malcolm wrote:

Mark,

On 6/27/2016 1:07 PM, Mark Thomas wrote:

On 27/06/2016 17:44, Jerry Malcolm wrote:


I'm assuming that context.lookup(...) simply locates the "jdbc/myDB"
 tag in the context.xml file, pulls all of the parms out of
that tag, creates a DataSource object utilizing the parms, and returns
it.If that's the case, couldn't I create a variation/subclass
of the
Context object that modifies the url parm that it found in the
resource
tag and puts the desired db name into the url before constructing the
DataSource?

Sure.

You need to implement the appropriate factory and then specify your
factory class explicitly in the Resource element using the factory
attribute.

You probably want to start here for ideas on how to code up your
factory:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/factory/


or for a more specific example:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java?view=annotate




Mark


Thanks so much.  This looks doable.  Just to make sure I have the big
picture correct

1) I will define a new custom resource that returns a custom context
object that I write.
2) On the  tag for my custom context resource I can put all of
the standard DataSource parms
3) I then call lookup() on this custom context passing the dbName in
4) This custom context will build an appropriate Reference object with
all the parms, instantiate a BasicDataSourceFactory, and call
getInstance(.) on the factory.

When I need an instance of the datasource:
   Context initContext = new InitialContext();
   Context envContext  =
(Context)initContext.lookup("java:/comp/env");
   MyDataSourceContext dsContext = (MyDataSourceContext)
envContext.lookup( "dsContext/myDSContext" );
   DataSource myDS = (DataSource) dsContext.getInstance(
"dbName" );

Am I getting close?

Yes, but I don't think you want to use custom NamingContexts. I think
there is a simpler way.

1. Write a custom DataSource factory that provides a getDataSource(...)
method that allows you to pass in whatever per instance config you need.
This DataSource factory will need to use bean style setters (like the
example I linked to) to pick up the other config from the 

2. Write a custom resource factory that returns an instance of your
DataSource factory.

3. Add a context Resource element for your DataSource factory,
remembering to use the factory element and specify the custom resource
factory from 2.

HTH,

Mark


If external configuration were not required, would there be a problem
instantiating a DataSource directly and setting any required properties
programmatically?  Would any functionality be lost?

The option of a global resource shared between multiple web apps is lost.

You'd need a mechanism (a statics would work) to store and retrieve the
DataSource.


Also, if there were base properties set in a  element, would
there be a problem using a copy of the properties from that data source,
modified as necessary, to instantiate a new DataSource?

No, but you'd need to be careful since multiple requests for the same
DataSource should return the same object. You'd need to be able to
differentiate between a request for a new DataSourece and a previously
created one.

Mark



Thanks!

-Terence


-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Runtime Cloning of DataSource for Different DB?

2016-06-29 Thread Mark Thomas
On 29/06/2016 05:12, Terence M. Bandoian wrote:
> On 6/28/2016 3:56 AM, Mark Thomas wrote:
>> On 27/06/2016 22:35, Jerry Malcolm wrote:
>>> Mark,
>>>
>>> On 6/27/2016 1:07 PM, Mark Thomas wrote:
 On 27/06/2016 17:44, Jerry Malcolm wrote:

> I'm assuming that context.lookup(...) simply locates the "jdbc/myDB"
>  tag in the context.xml file, pulls all of the parms out of
> that tag, creates a DataSource object utilizing the parms, and returns
> it.If that's the case, couldn't I create a variation/subclass
> of the
> Context object that modifies the url parm that it found in the
> resource
> tag and puts the desired db name into the url before constructing the
> DataSource?
 Sure.

 You need to implement the appropriate factory and then specify your
 factory class explicitly in the Resource element using the factory
 attribute.

 You probably want to start here for ideas on how to code up your
 factory:
 http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/factory/


 or for a more specific example:
 http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java?view=annotate




 Mark

>>> Thanks so much.  This looks doable.  Just to make sure I have the big
>>> picture correct
>>>
>>> 1) I will define a new custom resource that returns a custom context
>>> object that I write.
>>> 2) On the  tag for my custom context resource I can put all of
>>> the standard DataSource parms
>>> 3) I then call lookup() on this custom context passing the dbName in
>>> 4) This custom context will build an appropriate Reference object with
>>> all the parms, instantiate a BasicDataSourceFactory, and call
>>> getInstance(.) on the factory.
>>>
>>> When I need an instance of the datasource:
>>>   Context initContext = new InitialContext();
>>>   Context envContext  =
>>> (Context)initContext.lookup("java:/comp/env");
>>>   MyDataSourceContext dsContext = (MyDataSourceContext)
>>> envContext.lookup( "dsContext/myDSContext" );
>>>   DataSource myDS = (DataSource) dsContext.getInstance(
>>> "dbName" );
>>>
>>> Am I getting close?
>> Yes, but I don't think you want to use custom NamingContexts. I think
>> there is a simpler way.
>>
>> 1. Write a custom DataSource factory that provides a getDataSource(...)
>> method that allows you to pass in whatever per instance config you need.
>> This DataSource factory will need to use bean style setters (like the
>> example I linked to) to pick up the other config from the 
>>
>> 2. Write a custom resource factory that returns an instance of your
>> DataSource factory.
>>
>> 3. Add a context Resource element for your DataSource factory,
>> remembering to use the factory element and specify the custom resource
>> factory from 2.
>>
>> HTH,
>>
>> Mark
> 
> 
> If external configuration were not required, would there be a problem
> instantiating a DataSource directly and setting any required properties
> programmatically?  Would any functionality be lost?

The option of a global resource shared between multiple web apps is lost.

You'd need a mechanism (a statics would work) to store and retrieve the
DataSource.

> Also, if there were base properties set in a  element, would
> there be a problem using a copy of the properties from that data source,
> modified as necessary, to instantiate a new DataSource?

No, but you'd need to be careful since multiple requests for the same
DataSource should return the same object. You'd need to be able to
differentiate between a request for a new DataSourece and a previously
created one.

Mark


-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Runtime Cloning of DataSource for Different DB?

2016-06-28 Thread Terence M. Bandoian

On 6/28/2016 3:56 AM, Mark Thomas wrote:

On 27/06/2016 22:35, Jerry Malcolm wrote:

Mark,

On 6/27/2016 1:07 PM, Mark Thomas wrote:

On 27/06/2016 17:44, Jerry Malcolm wrote:


I'm assuming that context.lookup(...) simply locates the "jdbc/myDB"
 tag in the context.xml file, pulls all of the parms out of
that tag, creates a DataSource object utilizing the parms, and returns
it.If that's the case, couldn't I create a variation/subclass of the
Context object that modifies the url parm that it found in the resource
tag and puts the desired db name into the url before constructing the
DataSource?

Sure.

You need to implement the appropriate factory and then specify your
factory class explicitly in the Resource element using the factory
attribute.

You probably want to start here for ideas on how to code up your factory:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/factory/

or for a more specific example:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java?view=annotate



Mark


Thanks so much.  This looks doable.  Just to make sure I have the big
picture correct

1) I will define a new custom resource that returns a custom context
object that I write.
2) On the  tag for my custom context resource I can put all of
the standard DataSource parms
3) I then call lookup() on this custom context passing the dbName in
4) This custom context will build an appropriate Reference object with
all the parms, instantiate a BasicDataSourceFactory, and call
getInstance(.) on the factory.

When I need an instance of the datasource:
  Context initContext = new InitialContext();
  Context envContext  =
(Context)initContext.lookup("java:/comp/env");
  MyDataSourceContext dsContext = (MyDataSourceContext)
envContext.lookup( "dsContext/myDSContext" );
  DataSource myDS = (DataSource) dsContext.getInstance( "dbName" );

Am I getting close?

Yes, but I don't think you want to use custom NamingContexts. I think
there is a simpler way.

1. Write a custom DataSource factory that provides a getDataSource(...)
method that allows you to pass in whatever per instance config you need.
This DataSource factory will need to use bean style setters (like the
example I linked to) to pick up the other config from the 

2. Write a custom resource factory that returns an instance of your
DataSource factory.

3. Add a context Resource element for your DataSource factory,
remembering to use the factory element and specify the custom resource
factory from 2.

HTH,

Mark



If external configuration were not required, would there be a problem 
instantiating a DataSource directly and setting any required properties 
programmatically?  Would any functionality be lost?


Also, if there were base properties set in a  element, would 
there be a problem using a copy of the properties from that data source, 
modified as necessary, to instantiate a new DataSource?


-Terence Bandoian


-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Runtime Cloning of DataSource for Different DB?

2016-06-28 Thread Mark Thomas
On 27/06/2016 22:35, Jerry Malcolm wrote:
> Mark,
> 
> On 6/27/2016 1:07 PM, Mark Thomas wrote:
>> On 27/06/2016 17:44, Jerry Malcolm wrote:
>>
>>> I'm assuming that context.lookup(...) simply locates the "jdbc/myDB"
>>>  tag in the context.xml file, pulls all of the parms out of
>>> that tag, creates a DataSource object utilizing the parms, and returns
>>> it.If that's the case, couldn't I create a variation/subclass of the
>>> Context object that modifies the url parm that it found in the resource
>>> tag and puts the desired db name into the url before constructing the
>>> DataSource?
>> Sure.
>>
>> You need to implement the appropriate factory and then specify your
>> factory class explicitly in the Resource element using the factory
>> attribute.
>>
>> You probably want to start here for ideas on how to code up your factory:
>> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/factory/
>>
>> or for a more specific example:
>> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java?view=annotate
>>
>>
>>
>> Mark
>>
> Thanks so much.  This looks doable.  Just to make sure I have the big
> picture correct
> 
> 1) I will define a new custom resource that returns a custom context
> object that I write.
> 2) On the  tag for my custom context resource I can put all of
> the standard DataSource parms
> 3) I then call lookup() on this custom context passing the dbName in
> 4) This custom context will build an appropriate Reference object with
> all the parms, instantiate a BasicDataSourceFactory, and call
> getInstance(.) on the factory.
> 
> When I need an instance of the datasource:
>  Context initContext = new InitialContext();
>  Context envContext  =
> (Context)initContext.lookup("java:/comp/env");
>  MyDataSourceContext dsContext = (MyDataSourceContext)
> envContext.lookup( "dsContext/myDSContext" );
>  DataSource myDS = (DataSource) dsContext.getInstance( "dbName" );
> 
> Am I getting close?

Yes, but I don't think you want to use custom NamingContexts. I think
there is a simpler way.

1. Write a custom DataSource factory that provides a getDataSource(...)
method that allows you to pass in whatever per instance config you need.
This DataSource factory will need to use bean style setters (like the
example I linked to) to pick up the other config from the 

2. Write a custom resource factory that returns an instance of your
DataSource factory.

3. Add a context Resource element for your DataSource factory,
remembering to use the factory element and specify the custom resource
factory from 2.

HTH,

Mark


-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Runtime Cloning of DataSource for Different DB?

2016-06-27 Thread David Kerber

On 6/27/2016 1:07 AM, Jerry Malcolm wrote:


On 6/26/2016 8:27 PM, David Kerber wrote:

On 6/26/2016 1:32 AM, Jerry Malcolm wrote:

I have a webapp that runs on a single host.  It has one primary
database.  But it has many secondary databases.  There is one
secondary database for each of my clients that use my app. These
client databases come and go regularly as clients signup and leave.
I don't want to have to edit Tomcat conf files adding and deleting
 tags for the secondary databases and then have to bounce
Tomcat several times a day as clients come onboard or leave.

I have one  tag for the primary database.  The id/pw and
everything else in the resource tag is the same for all of the
databases.  Is there a way to specify/override the url (i.e. the
database name) at runtime to connect to whatever secondary database I
need for the particular client?  Or is there a way to clone a
datasource for a different url/database?  I still would like to use
the one resource tag in the context.xml.default conf file to specify
the id/pw for the secondary DBs.  I'd prefer not to hardcode id/pw in
the java code.  But if that is the only option, I can do it.

Hopefully there is some way to dynamically select the db in a
datasource at runtime... (??) Suggestions?


You can move your authentication code into your application, rather
than having TC handle it.  Then you can pick any database or data
source you want.



I know I can hardcode the connection in the code.  But that is not
going to provide connection pooling.  That 's a huge performance hit.
I really want the same capability I get with jdbc datasources, only
without hardcoding hundreds of them in the conf files.


You would need to handle your own pooling (which isn't particularly 
difficult), but there's certainly no need to hard-code anything. All of 
your db connection info can be in a "master" database, in Tomcat's 
configurations, or anywhere else that is accessible by your code.  If 
you can build connection strings from login information, it would be 
super simple.





-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Runtime Cloning of DataSource for Different DB?

2016-06-27 Thread Jerry Malcolm

Mark,

On 6/27/2016 1:07 PM, Mark Thomas wrote:

On 27/06/2016 17:44, Jerry Malcolm wrote:


I'm assuming that context.lookup(...) simply locates the "jdbc/myDB"
 tag in the context.xml file, pulls all of the parms out of
that tag, creates a DataSource object utilizing the parms, and returns
it.If that's the case, couldn't I create a variation/subclass of the
Context object that modifies the url parm that it found in the resource
tag and puts the desired db name into the url before constructing the
DataSource?

Sure.

You need to implement the appropriate factory and then specify your
factory class explicitly in the Resource element using the factory
attribute.

You probably want to start here for ideas on how to code up your factory:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/factory/

or for a more specific example:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java?view=annotate


Mark

Thanks so much.  This looks doable.  Just to make sure I have the big 
picture correct


1) I will define a new custom resource that returns a custom context 
object that I write.
2) On the  tag for my custom context resource I can put all of 
the standard DataSource parms

3) I then call lookup() on this custom context passing the dbName in
4) This custom context will build an appropriate Reference object with 
all the parms, instantiate a BasicDataSourceFactory, and call 
getInstance(.) on the factory.


When I need an instance of the datasource:
 Context initContext = new InitialContext();
 Context envContext  = 
(Context)initContext.lookup("java:/comp/env");
 MyDataSourceContext dsContext = (MyDataSourceContext) 
envContext.lookup( "dsContext/myDSContext" );

 DataSource myDS = (DataSource) dsContext.getInstance( "dbName" );

Am I getting close?

Thx.

Jerry


-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Runtime Cloning of DataSource for Different DB?

2016-06-27 Thread Mark Thomas
On 27/06/2016 17:44, Jerry Malcolm wrote:

> I'm assuming that context.lookup(...) simply locates the "jdbc/myDB"
>  tag in the context.xml file, pulls all of the parms out of
> that tag, creates a DataSource object utilizing the parms, and returns
> it.If that's the case, couldn't I create a variation/subclass of the
> Context object that modifies the url parm that it found in the resource
> tag and puts the desired db name into the url before constructing the
> DataSource?

Sure.

You need to implement the appropriate factory and then specify your
factory class explicitly in the Resource element using the factory
attribute.

You probably want to start here for ideas on how to code up your factory:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/factory/

or for a more specific example:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java?view=annotate


Mark

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Runtime Cloning of DataSource for Different DB?

2016-06-27 Thread Jerry Malcolm


On 6/27/2016 1:03 AM, Mark Eggers wrote:

Jerry,

On 6/26/2016 10:07 PM, Jerry Malcolm wrote:

On 6/26/2016 8:27 PM, David Kerber wrote:

On 6/26/2016 1:32 AM, Jerry Malcolm wrote:

I have a webapp that runs on a single host.  It has one primary
database.  But it has many secondary databases.  There is one
secondary database for each of my clients that use my app. These
client databases come and go regularly as clients signup and
leave. I don't want to have to edit Tomcat conf files adding and
deleting  tags for the secondary databases and then
have to bounce Tomcat several times a day as clients come onboard
or leave.

I have one  tag for the primary database.  The id/pw
and everything else in the resource tag is the same for all of
the databases.  Is there a way to specify/override the url (i.e.
the database name) at runtime to connect to whatever secondary
database I need for the particular client?  Or is there a way to
clone a datasource for a different url/database?  I still would
like to use the one resource tag in the context.xml.default conf
file to specify the id/pw for the secondary DBs.  I'd prefer not
to hardcode id/pw in the java code.  But if that is the only
option, I can do it.

Hopefully there is some way to dynamically select the db in a
datasource at runtime... (??) Suggestions?

You can move your authentication code into your application,
rather than having TC handle it.  Then you can pick any database or
data source you want.



I know I can hardcode the connection in the code.  But that is not
going to provide connection pooling.  That 's a huge performance hit.
I really want the same capability I get with jdbc datasources, only
without hardcoding hundreds of them in the conf files.

 From what I remember of your environment, it's the following:

1. Monolithic web application
2. No WAR file
3. Much of the configuration is in Tomcat-wide locations

To me (and I don't mean to sound harsh) this violates the software
architecture principle of separating things that change from things that
remain the same (speed of change being relative).

This lack of separation leads to a lot of operational challenges (which
you've written about in the past).

In an ideal world, I'd use versioned WAR files and a CI / CD server (we
use Jenkins) to manage the deployment. Keep context.xml in version
control, and you end up with the potential for a zero down time update.

There are a lot of wrinkles to the above solution that I could go over,
but since this is not your architecture I won't fill up the mailing list
with some likely scenarios.

That being said, I can see three paths for you to go down.

1. Put everything into context.xml

You'll have to edit it and upload the file. When context.xml is changed
Tomcat will reload the web application. You'll experience some downtime,
but with your current architecture I don't see an easy way around that.

2. Roll your own pools

There are several JDBC connection libraries available. You would roll
your own pool management, and then create an administrator application
to add and delete pools.

3. Move to an application server

Wildfly and Glassfish both have administrative interfaces that allow you
to add and delete JNDI JDBC pools. Unfortunatly, the last time I tried
Glassfish the interface to manage JNDI JDBC pools was broken. I don't
know if they've fixed that yet. I've not worked with WildFly, but it
appears to have an administrative interface with this capability.

We're also looking at Elastic Beanstalk, but there are a lot of wrinkles
we need to work out before deciding to move in that direction.

. . . just my two cents
/mde/

I'm not sure what you mean by 'monolithic'.  I have 10 virtual hosts 
each with about 10 individual webapps.  Everything is configured in 
individual \conf\Catalina\\context and web.xml files.


I am not using WAR files.  But only because when I change one jsp or one 
jar I don't want to have to wait 15 minutes for an entire WAR refresh 
over a slow internet link.  But otherwise my architecture is identical 
to using WAR files.


None of my configuration is in a Tomcat-wide location.

But I'm not sure what any of this has to do with being able to create a 
DataSource using a variable for the database URL.  If Wildfly and 
Glassfish can do it, it would seem that I would be able to do the same 
thing.


I currently use three lines of code to get a DataSource:
 Context initContext = new InitialContext();
 Context envContext  = 
(Context)initContext.lookup("java:/comp/env");

 DataSource ds = (DataSource)envContext.lookup( "jdbc/myDB" );

I'm assuming that context.lookup(...) simply locates the "jdbc/myDB" 
 tag in the context.xml file, pulls all of the parms out of 
that tag, creates a DataSource object utilizing the parms, and returns 
it.If that's the case, couldn't I create a variation/subclass of the 
Context object that modifies the url parm that it found in the resource 
tag and puts the desired 

Re: Runtime Cloning of DataSource for Different DB?

2016-06-27 Thread Anthony Biacco
On Sun, Jun 26, 2016 at 11:07 PM, Jerry Malcolm 
wrote:

>
> On 6/26/2016 8:27 PM, David Kerber wrote:
>
>> On 6/26/2016 1:32 AM, Jerry Malcolm wrote:
>>
>>> I have a webapp that runs on a single host.  It has one primary
>>> database.  But it has many secondary databases.  There is one
>>> secondary database for each of my clients that use my app. These
>>> client databases come and go regularly as clients signup and leave.
>>> I don't want to have to edit Tomcat conf files adding and deleting
>>>  tags for the secondary databases and then have to bounce
>>> Tomcat several times a day as clients come onboard or leave.
>>>
>>> I have one  tag for the primary database.  The id/pw and
>>> everything else in the resource tag is the same for all of the
>>> databases.  Is there a way to specify/override the url (i.e. the
>>> database name) at runtime to connect to whatever secondary database I
>>> need for the particular client?  Or is there a way to clone a
>>> datasource for a different url/database?  I still would like to use
>>> the one resource tag in the context.xml.default conf file to specify
>>> the id/pw for the secondary DBs.  I'd prefer not to hardcode id/pw in
>>> the java code.  But if that is the only option, I can do it.
>>>
>>> Hopefully there is some way to dynamically select the db in a
>>> datasource at runtime... (??) Suggestions?
>>>
>>
>> You can move your authentication code into your application, rather than
>> having TC handle it.  Then you can pick any database or data source you
>> want.
>>
>>
>> I know I can hardcode the connection in the code.  But that is not going
> to provide connection pooling.  That 's a huge performance hit.  I really
> want the same capability I get with jdbc datasources, only without
> hardcoding hundreds of them in the conf files.
>
>
I seem to recall DBCP having a per-user pool data source feature, where you
can pass different credentials to the same base Resource. Whether you can
change the database too, i don't remember.
You might want to check the docs or ask those guys a couple doors down.

-Tony





> -
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>


Re: Runtime Cloning of DataSource for Different DB?

2016-06-27 Thread Mark Eggers
Jerry,

On 6/26/2016 10:07 PM, Jerry Malcolm wrote:
> 
> On 6/26/2016 8:27 PM, David Kerber wrote:
>> On 6/26/2016 1:32 AM, Jerry Malcolm wrote:
>>> I have a webapp that runs on a single host.  It has one primary 
>>> database.  But it has many secondary databases.  There is one 
>>> secondary database for each of my clients that use my app. These 
>>> client databases come and go regularly as clients signup and
>>> leave. I don't want to have to edit Tomcat conf files adding and
>>> deleting  tags for the secondary databases and then
>>> have to bounce Tomcat several times a day as clients come onboard
>>> or leave.
>>> 
>>> I have one  tag for the primary database.  The id/pw
>>> and everything else in the resource tag is the same for all of
>>> the databases.  Is there a way to specify/override the url (i.e.
>>> the database name) at runtime to connect to whatever secondary
>>> database I need for the particular client?  Or is there a way to
>>> clone a datasource for a different url/database?  I still would
>>> like to use the one resource tag in the context.xml.default conf
>>> file to specify the id/pw for the secondary DBs.  I'd prefer not
>>> to hardcode id/pw in the java code.  But if that is the only
>>> option, I can do it.
>>> 
>>> Hopefully there is some way to dynamically select the db in a 
>>> datasource at runtime... (??) Suggestions?
>> 
>> You can move your authentication code into your application,
>> rather than having TC handle it.  Then you can pick any database or
>> data source you want.
>> 
>> 
> I know I can hardcode the connection in the code.  But that is not
> going to provide connection pooling.  That 's a huge performance hit.
> I really want the same capability I get with jdbc datasources, only 
> without hardcoding hundreds of them in the conf files.

From what I remember of your environment, it's the following:

1. Monolithic web application
2. No WAR file
3. Much of the configuration is in Tomcat-wide locations

To me (and I don't mean to sound harsh) this violates the software
architecture principle of separating things that change from things that
remain the same (speed of change being relative).

This lack of separation leads to a lot of operational challenges (which
you've written about in the past).

In an ideal world, I'd use versioned WAR files and a CI / CD server (we
use Jenkins) to manage the deployment. Keep context.xml in version
control, and you end up with the potential for a zero down time update.

There are a lot of wrinkles to the above solution that I could go over,
but since this is not your architecture I won't fill up the mailing list
with some likely scenarios.

That being said, I can see three paths for you to go down.

1. Put everything into context.xml

You'll have to edit it and upload the file. When context.xml is changed
Tomcat will reload the web application. You'll experience some downtime,
but with your current architecture I don't see an easy way around that.

2. Roll your own pools

There are several JDBC connection libraries available. You would roll
your own pool management, and then create an administrator application
to add and delete pools.

3. Move to an application server

Wildfly and Glassfish both have administrative interfaces that allow you
to add and delete JNDI JDBC pools. Unfortunatly, the last time I tried
Glassfish the interface to manage JNDI JDBC pools was broken. I don't
know if they've fixed that yet. I've not worked with WildFly, but it
appears to have an administrative interface with this capability.

We're also looking at Elastic Beanstalk, but there are a lot of wrinkles
we need to work out before deciding to move in that direction.

. . . just my two cents
/mde/



signature.asc
Description: OpenPGP digital signature


Re: Runtime Cloning of DataSource for Different DB?

2016-06-26 Thread Jerry Malcolm


On 6/26/2016 8:27 PM, David Kerber wrote:

On 6/26/2016 1:32 AM, Jerry Malcolm wrote:

I have a webapp that runs on a single host.  It has one primary
database.  But it has many secondary databases.  There is one
secondary database for each of my clients that use my app. These
client databases come and go regularly as clients signup and leave.
I don't want to have to edit Tomcat conf files adding and deleting
 tags for the secondary databases and then have to bounce
Tomcat several times a day as clients come onboard or leave.

I have one  tag for the primary database.  The id/pw and
everything else in the resource tag is the same for all of the
databases.  Is there a way to specify/override the url (i.e. the
database name) at runtime to connect to whatever secondary database I
need for the particular client?  Or is there a way to clone a
datasource for a different url/database?  I still would like to use
the one resource tag in the context.xml.default conf file to specify
the id/pw for the secondary DBs.  I'd prefer not to hardcode id/pw in
the java code.  But if that is the only option, I can do it.

Hopefully there is some way to dynamically select the db in a
datasource at runtime... (??) Suggestions?


You can move your authentication code into your application, rather 
than having TC handle it.  Then you can pick any database or data 
source you want.



I know I can hardcode the connection in the code.  But that is not going 
to provide connection pooling.  That 's a huge performance hit.  I 
really want the same capability I get with jdbc datasources, only 
without hardcoding hundreds of them in the conf files.


-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Runtime Cloning of DataSource for Different DB?

2016-06-26 Thread David Kerber

On 6/26/2016 1:32 AM, Jerry Malcolm wrote:

I have a webapp that runs on a single host.  It has one primary
database.  But it has many secondary databases.  There is one
secondary database for each of my clients that use my app. These
client databases come and go regularly as clients signup and leave.
I don't want to have to edit Tomcat conf files adding and deleting
 tags for the secondary databases and then have to bounce
Tomcat several times a day as clients come onboard or leave.

I have one  tag for the primary database.  The id/pw and
everything else in the resource tag is the same for all of the
databases.  Is there a way to specify/override the url (i.e. the
database name) at runtime to connect to whatever secondary database I
need for the particular client?  Or is there a way to clone a
datasource for a different url/database?  I still would like to use
the one resource tag in the context.xml.default conf file to specify
the id/pw for the secondary DBs.  I'd prefer not to hardcode id/pw in
the java code.  But if that is the only option, I can do it.

Hopefully there is some way to dynamically select the db in a
datasource at runtime... (??) Suggestions?


You can move your authentication code into your application, rather than 
having TC handle it.  Then you can pick any database or data source you 
want.





Thanks.

Jerry


-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org





-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Runtime Cloning of DataSource for Different DB?

2016-06-25 Thread Jerry Malcolm
I have a webapp that runs on a single host.  It has one primary 
database.  But it has many secondary databases.  There is one secondary 
database for each of my clients that use my app.  These client databases 
come and go regularly as clients signup and leave.   I don't want to 
have to edit Tomcat conf files adding and deleting  tags for 
the secondary databases and then have to bounce Tomcat several times a 
day as clients come onboard or leave.


I have one  tag for the primary database.  The id/pw and 
everything else in the resource tag is the same for all of the 
databases.  Is there a way to specify/override the url (i.e. the 
database name) at runtime to connect to whatever secondary database I 
need for the particular client?  Or is there a way to clone a datasource 
for a different url/database?  I still would like to use the one 
resource tag in the context.xml.default conf file to specify the id/pw 
for the secondary DBs.  I'd prefer not to hardcode id/pw in the java 
code.  But if that is the only option, I can do it.


Hopefully there is some way to dynamically select the db in a datasource 
at runtime... (??) Suggestions?


Thanks.

Jerry


-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org