Dave wrote:
On 5/17/07, Allen Gilliland <[EMAIL PROTECTED]> wrote:
I think you've identified all of the right changes to make, but I'm not
really seeing how they come together very well as implementations.

I think that for #1 we should flush out more properties than what you
listed there and try to make them as consistent as possible, for example ...

database.installation=[auto,manual]
database.connectionProvider=[built-in,jndi,custom,etc]
database.type=[mysql,oracle,etc]
database.driver=
database.url=
mail.strategy=[built-in,jndi,custom,etc]
mail.hostname=
mail.username=
mail.password=

OK. I added a complete listing of properties to the proposal.


For #2 I think we should be creating some kind of DatabaseProvider class
which knows how to look at the db config properties and provide all the
right kind of database functionality.

I don't think we need "database.connectionProvider" -- if we find JDBC
properties set, we use them otherwise we use the same JNDI setup we've
always used. All we're doing here is decided whether to initialize the
ORM system (i.e. Hibernate or JPA) with a list of JDBC connection
parameters or a JNDI resource name. The ORM system has it's own
internal "DatabaseProvider" which doles out connections.

I still prefer that we have explicit properties to define the strategy for getting db connections or mail sessions. Not only is it more explicit and therefore easier to read the config and know what is supposed to happen, but it also allows you to keep configurations for each option in the config without triggering different behavior.

I know we already have jdbc.* properties being used, but I prefer the database.* property names for consistency sake, so I think we should switch to those.

I also think that when someone chooses database.provider=jndi that we should also support a property for choosing their own jndi name, such as database.jndiName=jdbc/rollerdb.

And while you are correct that ORM solutions have their own DatabaseProvider classes that still does not negate our need for one. The purpose of this class in Roller is still very valid and IMO should be there to handle extracting the proper config properties and creating the DataSource, handling db testing (to see that the db is there), and install/upgrade procedures. I actually think it's preferrable if we inject our own DataSource into the ORM configs when we create the sessionFactory/entityManager rather than forcing the ORM config to look it up itself. For example, in hibernate that just means setting the connection provider to InjectedDataSourceConnectionProvider and making sure to call setDataSource() before building the sessionFactory. That seems like a better way to do it than how we do it now where we dynamically rebuild the hibernate xml config file.




I don't think we want to save
anything to the servlet context.

I removed the words "servlet context," but I would like to store them
somewhere so  they can be shown to the user.

I agree that we want to be able to display errors to users, but with the DatabaseProvider option as I detailed above and the Bootstrapper then this would happen naturally without needing to try and extract errors from the ORM tool and store them somewhere. The workflow would be more natural such as ...

1. container started and contextInitialized() called
2. DatabaseProvider constructed
3. check configured datasource
4. if datasource is good then check for install/upgrade work
5. once install/upgrade work is complete then move on
6. MailProvider constructed
7. check configured mail session
8. if mail session is good then move on
9. bootstrap application

And at any point before #9 if we needed to we could pause and wait for the user to interact with the app to gather input, show errors/status, etc.

-- Allen




#3 sounds right, but doesn't give much details.  Again, I think we want
something like a MailProvider class which wraps the functionality of
looking up the right way to get a mail session.

Yes. A MailProvider class makes sense here.


I think #4 is okay, but I would like to move away from using the roller
context as our initialization class.  I think I had mentioned this
before, but I think what we really want is a standalone Roller
bootstrapper class which can be called from the contextInitialized()
method or other places when needed.  So in the event of install/upgrade
the app can detect that there is work needed before the app should be
bootstrapped and it can do whatever install/upgrade work is needed then
do the bootstrap.

#5 sounds wacky to me.  I don't really want that functionality
implemented as a filter, I think that the db upgrading should be done by
the DatabaseProvider and if we want some kind of UI for interacting with
that then we should allow for that using the bootstrapper idea.  The
only thing I would potentially think a filter could be used for in this
situation is something like the InitFilter that we already have where
that filter can check some kind of flag to see if the app has been
bootstrapped yet and if not then it redirects all requests to the
install/upgrade page.

That's what I meant. I don't want to put upgrade logic in the filter
itself. The filter is just the hook that allows us to detect a problem
and redirect to the error or upgrade pages/actions.


I like #6, but asking the user to restart/redeploy is no fun, so that's
where the independent bootstrapper would be useful.

Yes. That's a good idea and you're right -- a restart should not be necessary.


And #7 is same as #6 really.

Yes, that could be the same action, since they both

- Dave

Reply via email to