Quantcast
Channel: Dario Pardo's cave » Grails
Viewing all articles
Browse latest Browse all 4

Achieving Transparency with JNDI

$
0
0

Enterprise Web Applications are distributed systems. Typically, enterprise solutions are composed of many computers with different Operating Systems, one or more data sources (in many occasions from different vendors) and even of different architecture (relational, hierarchical, dimensional, ISAM, etc…). One important thing to remember is that to the end user it looks like one system.

The advantages of distributed systems are the different types of Transparency:

  1. Enterprise resources should be accessible and how they are accessed should be hidden from the user.
  2. The communication protocols the web application uses (HTTP, SOAP, JMS, JNDI etc…) to interact with other services or applications should be hidden from the user.
  3. The user should not be able to tell that different resources are scattered across the network, neither where they are located.
  4. The user should not have any critical information that might compromise the security/integrity of a subsystem.
  5. Distributed applications should be easy to extend, repair, or even move components around.

In this post I am going to talk about how to achieve Access, Location and Migration Transparency with JNDI (Java Naming Directory Interface).

Problem: Have you ever seen this at your Enterprise?

Oracle Forms & Reports Login

This is a typical log in screen to enterprise applications that use Oracle Forms & Reports technology. Even though this is old technology you will be surprised to see how many enterprises are running business critical applications under this platform; there is nothing really wrong with that, just that there are better enterprise application development platforms in the market than Oracle Forms and its successor APEX. For example J2EE nowadays most commonly known as JavaEE and .NET.

The main disadvantages are as follows:

  1. Oracle Forms only work with Oracle RDBMS (PL/SQL as the language).
  2. Migrating to a new database would require to rewrite your entire business logic to the platform of choice (Java, .NET, T-SQL, SQL PL, Postgres PL, etc…).
  3. Cannot benefit from current agile software trends of Test Driven Development and Continuous Integration (at least to my knowledge).

However,  the biggest problem (what we are going after here according to the topic of the post from the screenshot above) is as follows:

  1. The database text field.
  2. The Database Administrator (DBA) will have to maintain as many database user accounts as users are in the application.

What problems do you see?

  • Since when an end user should know the database name to connect to?  You have violated Access Transparency here.
  • If the application has 100 users for example. Will the DBAs have to maintain 100 users in QA and PROD environments? That sounds like a lot of tedious work and opportunity for mistakes.
  • What happens if you encounter a tech savvy user that manages to create an ODBC connection to your production database? Now you have a big security problem here.
  • Did you enforce all UPDATE, DELETE logic to go through Stored Procedures? Have you given the database user accounts rights to execute Stored Procedures only?
  • If not, the user accounts to the application now have direct rights to execute UPDATES and DELETES on certain tables. Now you have a big security problem here.

A lot of these problems can be easily solved in JavaEE by using JNDI.

Solution: Setup a JNDI Connection Pool with GlassfishV3 App Server

To illustrate the solution I have installed the following components:

  1. GlassFish Server Open Source Edition 3.1: A full blown Java EE 6 compliant application server.
  2. PostgreSQL Database Server 9.0.4: The world’s best open source database.

Note: I have chosen these two components but any other RDBMS (MySQL, MSSQLServer, Oracle, DB2, etc..) and any of these app servers (JBoss, Oracle WebLogic, Websphere) would have a similar way of setting up a JNDI Connection Pool.

Do as follows:

  1. Download the appropriate PostgreSQL JDBC driver jar and place it in C:\glassfish3\glassfish\lib.
  2. Start GlassFish application server by exectuting startserv.bat located at C:\glassfish3\glassfish\bin (or wherever you decided to install it).
  3. Open up a browser tab and go to the GlassFish Administration Console. http://localhost:4848/
  4. In the left navigation menu click on the New… button under Resources/JDBC/JDBC Connection Pools .
  5. Enter a Pool Name and select the appropriate database drivers as follows (Click on the image to enlarge):Create a Connection Pool
  6. Click Next and fill Step two as appropriate based on your settings as follows (Click on the images to enlarge):

    Insert Your Database Vendor Settings

    Insert Your Database Vendor Settings

  7. Click the Ping button. You should see a message as follows:
  8. Click the Finish button.
  9. Now we have created Connection Pool Successfully. Our next step is to make it available through a logical name with JNDI.
  10. In the left navigation menu click on the New… button under Resources/JDBC/JDBC Resources.
  11. Enter a JNDI Name and select the Connection Pool that we have just created and Click OK (Click on the image to enlarge):
    Bind JNDI name to DataSource Connection Pool

Advantages

With this new setup we have the advantages as follows:

  • Access Transparency: We are not giving any clue how the resource is accessed. Now nobody knows the database name.
  • Location Transparency: Only GlassFish administrators and DBA(s) now know where the resource is actually located. Even the developers would not know where the database really is (I know this does not actually happen) but there will be nothing in the application code or configuration files that will unveil that.
  • Migration Transparency: The database now can be moved from one server to another, the DBA might want to change the default port, or the user name and password need reset. Any of these changes will not affect the application at all because it can be manged by an administrator through the GlassFish Admin Console.
  • LDAP Authentication: With this setup we can now delegate the Authentication piece of the application to an LDAP service, which would allow for Single Sign On across the Enterprise.
  • 1 Database User Account Only per Connection Pool: We now have reduced all the database user accounts to one and only one.
  • Same JNDI name, multiple environments: In an Enterprise you will most likely have a GlassFish QA instance and a GlassFish PROD instance. If you set up your JNDI Name to be the same in both (jdbc/grailsRocksApp in our example) you can deploy interchangeably without having to do any changes anywhere.

 

 

Configuring your Spring JDBC application to use JNDI

If you are using Spring JDBC to persist you database, this is what you have to do to obtain a DataSource through JNDI. Usually, in Spring web applications you will separate you context xml files in several as follows:

  • appName-servlet.xml
  • appName-datasource.xml
  • appName-services.xml
  • appName-security.xml

In the appName-datasource.xml put the following snippet:






Configuring your Spring + Hibernate app to use JNDI

If you are using the Hibernate in your Spring application to handle persistance. You would do as follows:







     
         
     



           
           
                               
                  com/companyName/appname/domain/Student.hbm.xml
                  com/companyName/appName/domain/Course.hbm.xml
               
           
           
            
              false
              org.hibernate.cache.NoCacheProvider
              hibernate.grailsRocks
              false
              org.postgresql.Driver
              1
              thread
              postgres
              org.hibernate.dialect.ProgressDialect
              true
              true
              true
              true
              1
              pool_postgres
              yes 'Y', no 'N'
              false
              
              
              true
            
            
        

Configuring your Grails application to use JNDI

If you are developing in Grails and want to use JNDI for connection pooling, you would do as follows in the DataSource.groovy:

dataSource {
     pooled = true
}

hibernate {
    cache.use_second_level_cache=true
    cache.use_query_cache=true
    cache.provider_class='net.sf.ehcache.hibernate.EhCacheProvider'
}

// environment specific settings
environments {

    production {
        dataSource {
            jndiName="jdbc/grailsRocksApp"
        } 
    }
}

 

Conclusions

Asides from the advantages mentioned above we also get the following:

  • Connection pooling management and distributed transactions: If you use a regular DataSource like illustrated in the Spring JDBC example above, it’s ok for very small applications because it is not thread-safe, it’s single threaded. The server will lock down other requests, this will impact performance. So if you are in a concurrent environment you are better off using JNDI as the application server take care of handling connection pools threads for you.

Viewing all articles
Browse latest Browse all 4

Trending Articles