[jboss-user] [IronJacamar] - Re: Feature request:Add an interface to allow end-user to have a second chance to create a normal database connection after failling to get connection because of database password error

Yaguo Zhou do-not-reply at jboss.com
Tue Jan 8 22:50:54 EST 2013

Yaguo Zhou [https://community.jboss.org/people/zhouyaguo] created the discussion

"Re: Feature request:Add an interface to allow end-user to have a second chance to create a normal database connection after failling to get connection because of database password error"

To view the discussion, visit: https://community.jboss.org/message/789554#789554

Appreciate for your reply and sorry for my late response because of my busy work.
Let me describe  my new feature's scenario more clearly:

For financial security reason, DBA in our company must change our database's password every 2 or 3 months, but unfortunately, every time after passwods are changed, we have to modify datasource password in java application server(we are using JBoss 5.1) and restart it, meanwhile, we sometimes forgot to change and restart one of our jboss instances, because  we have dozens of web application located on many jboss instance.so what we want is that after DBA changed passwords,  jboss can get the new password when receive a new http request and store the password in memory(in mbean or one property of class).

so we think about a solution and have finished it already:
step1. we developed a socket server program which is used to receive command message to save password and query password of databases(socket message format is design by our own and we call the socket server as DBPM server)
step2. DBA change the password through IBM Tivoli that is extended by our programmer to send password to DBPM server meanwhile, and DBPM server will store it centrally.
step3. I hack the code org.jboss.resource.adapter.jdbc.local.LocalManagedConnectionFactory.java as follows:

> private LocalManagedConnection getLocalManagedConnection(Properties props,Properties copy) 
>                        throws JBossResourceException
>    {
>              boolean debug = log.isDebugEnabled();
>        Connection con = null;
>              try
>              {
>                        String url = getConnectionURL();
>                        Driver d = getDriver(url); 
>                        // alreay got the new password
>                        if(this.newPasswordFromDbpm != null){
>                                  copy.setProperty("password", newPasswordFromDbpm);
>                        }
>                        try{
>                                  con = d.connect(url, copy);
>                        }catch(SQLException e){
>                                  if(debug){
>                                            log.debug("ErrorCode:"+e.getErrorCode() + " " + "SQLState:"+e.getSQLState());
>                                  }
>                                  // for mysql and db2
>                                  if("28000".equals(e.getSQLState())){
>                                            if(debug){
>                                                      log.debug("we catch a SQLException(SQLState=28000), so try to get new password from DBPM server, and then reconnect the database");
>                                            }
>                                           String dbName = url.split(":")[3].split("/")[1]; // get database name from url
>                                           String dbUserNm = copy.getProperty("user");
>                                           //try to get password!
>                                           String dbpmPassword = DsPasswdGetter.doGetPasswd(dbName, dbUserNm, false);
>                                           if(dbpmPassword != null){
>                                                     if(debug){
>                                                               log.debug("get dbpmPassword ok.. begin to reconnect the database");
>                                                     }
>                                                     copy.setProperty("password", dbpmPassword);
>                                                     this.newPasswordFromDbpm = dbpmPassword;
>                                                     //write it to xml configuration file
>                                                     if(securityDomain != null){
>                                                               Properties prop = new Properties();
>                                                               prop.setProperty(securityDomain, dbpmPassword);
>                                                               if(debug){
>                                                                         log.debug("begin to write dbpmPassword to login-config.xml");
>                                                               }
>                                                               UpdateJdbcPassword.doModifyPasswd(prop);
>                                                     }else{
>                                                               throw new JBossResourceException("securityDomain is null");
>                                                     }
>                                                     //begin to reconnect
>                                                     con = d.connect(url, copy);
>                                           }else{
>                                                     //error to get password from DBPM server
>                                                     throw new JBossResourceException("Can not get password from dbmp server for [dbName:"+dbName+", dbUserNm:"+dbUserNm+"]");
>                                           }
>                                 }
>                                 if(con==null)
>                                   throw new JBossResourceException("Wrong driver class for this connection URL");
>                        }
>                        return new LocalManagedConnection(this, con, props, transactionIsolation, preparedStatementCacheSize);
>              }
>              catch (Throwable e)
>              {
>                  if (con != null)
>                  {
>                     try
>                     {
>                        con.close();
>                     }
>                     catch (Throwable ignored)
>                     {
>                     }
>                  }
>                        throw new JBossResourceException("Could not create connection", e);
>              }
>    }
step4. now suppose a http request arrived and all existing connected connections in pool are busy, so jca try to establish a new connection , and then flow into my code above.
step5. my code above will fetch the correct password back and reconnect successfully.
step6. jca return a correct connection to web application. i am happy to see that web application don't even know jca has helped him to get the correct password.
step7. so now we don't need to modify and restart jboss instance any more.

The problem is that my hacked code doesn't merge into upstream trunk , and now it's in my own branch. so i will very happy to *implements* a interface to do things above to avoid hacking the jca source code. many thanks!

Best Regards,

Reply to this message by going to Community

Start a new discussion in IronJacamar at Community

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jboss-user/attachments/20130108/0cea1a8d/attachment-0001.html 

More information about the jboss-user mailing list