WAS v8.5 > Administer applications and their environment > Welcome to administering Data access resources > Administer data access applications > Configure a JDBC provider and data source

Configure a JDBC provider and data source using the JMX API

If the application requires access to a relational database using the JDBC API, we can create the necessary JDBC provider and data source objects using the Java Management Extensions (JMX) API exclusively. Alternatively, we can use the JMX API in combination with the wsadmin scripting tool. Best practice: If we are using the JMX API to create a data source, you should use one of the product-provided templates if one exists for the specific JDBC provider. WAS v8.5 provides a template for every supported JDBC provider. See the topic, Data source minimum required settings, by vendor, for a list of all of the supported JDBC providers. When we use the dmgr console to select one of the provided templates, the dmgr console prompts you for values for all of the required properties for that data source. See the topic, Configuring a JDBC provider and data source, for more information about how to use the dmgr console to create a data source. If you decide to use the wsadmin scripting tool to create a data source, see the topic, Data source minimum required settings, by vendor, for a list of the required settings. .


Subtopics


Example


Use the JMX API to create the configuration objects necessary to access relational databases. This code sample demonstrates how to use the WebSphere Application Server MBeans to create and configure the objects which are required to access a relational database from an enterprise application. These objects include: a JDBC provider, either XA or non-XA capable, a data source, an authentication alias, and optionally a Container Managed Persistence (CMP) connection factory. Details of configuring these options can be found in the header comments of the following source code. The sample also demonstrates how to use the data source MBean to reload the configuration changes into the running server.

/**
 * COPYRIGHT LICENSE: This information contains sample code provided in  * source code form. You may copy, modify, and distribute this sample
 * program in any form without payment to IBM for the purposes of  * developing, using, marketing or distributing application programs  * conforming to the application programming interface for the operating  * platform for which the sample code is written. Notwithstanding anything
 * to the contrary, IBM PROVIDES THE SAMPLE SOURCE CODE ON AN "AS IS" BASIS
 * AND IBM DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT
 * LIMITED TO, ANY IMPLIED WARRANTIES OR CONDITIONS OF MERCHANTABILITY,
 * SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND ANY
 * WARRANTY OR CONDITION OF NON-INFRINGEMENT. IBM SHALL NOT BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING
 * OUT OF THE USE OR OPERATION OF THE SAMPLE SOURCE CODE. IBM HAS NO
 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
 * MODIFICATIONS TO THE SAMPLE SOURCE CODE.
 * 
 * © Copyright IBM Corp. 2011.
 * All Rights Reserved. Licensed Materials - Property of IBM.
 */

import java.util.Properties;
import java.util.Set;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

import com.ibm.websphere.management.AdminClient;
import com.ibm.websphere.management.AdminClientFactory;
import com.ibm.websphere.management.Session;
import com.ibm.websphere.management.configservice.ConfigServiceHelper;
import com.ibm.websphere.management.configservice.SystemAttributes;
import com.ibm.websphere.management.exception.ConnectorException;

/**
 * This sample code demonstrates the use of the WebSphere JMX APIs to create  * a DB2 jdbc provider and data source with an authentication alias. 
 * This sample code may be configured to:
 * - Create either node or server scoped objects  * - Create either an XA or non-XA jdbc provider  * - Create a connection factory so the data source may be used by CMP beans,  * otherwise the data source may be used by BMP beans, session beans, or  * servlets  * These are configured by setting the value of class constants
 * (see "Program configuration settings" below)
 * The jdbc provider, data source and CMP connection factory (if configured)
 * are created using predefined templates, which is a best practice.  
 * Note: there are templates which will create both the jdbc provider and a  * data source at once, this sample intentionally creates both objects  * separately for thoroughness
 * 
 * To compile and run this program, put the admin client bundle
 * was_install_root\runtimes\com.ibm.ws.admin.client_8.0.0.jar
 * on the classpath in addition to the classfile that was obtained when 
 * this source file was built. 
 * 
 * Once compiled, this program is run in it's own JVM and  * uses the WebSphere Admin Client API to interact with a WebSphere  * Application Server either locally or remotely to create the  * JDBC resources discussed above.
 */

public class JDBCResourcesWithJMX {

    // program configuration settings     // if true, an XA capable jdbc provider is created, otherwise non-XA
    private static final boolean createXAJDBCProvider = true;
    // if true, a CMP connection factory will be created for use by CMP beans,     // otherwise the data source created can be used with BMP beans, session     // beans, or servlets     private static final boolean createCMPConnectionFactory = true;
    // if true, create node-scoped objects, otherwise create server     private static final boolean createNodeScopedCfgObjs = true;
    // end program configuration settings     
    private static final String jdbcProviderName =
        "Sample DB2 JDBC Provider";
    private static final String jdbcProviderTemplateNameXA =
        "DB2 Using IBM JCC Driver Provider Only (XA)";
    private static final String jdbcProviderTemplateName =
        "DB2 Using IBM JCC Driver Provider Only";
    // an alias for authentication data     private static final String authDataAlias = "db2admin";
    private static final String authAliasDescription =
        "Sample authentication alias";
    private static final String authAliasUserID = "db2admin"; // user ID
    private static final String authAliasPassword = "db2admin"; // password     private static final String dataSourceProviderTemplateNameXA =
        "DB2 Using IBM JCC Driver - XA DataSource";
    private static final String dataSourceHelperClassName =
        "com.ibm.websphere.rsadapter.DB2DataStoreHelper";
    private static final String cmpConnFactTemplateName =
        "CMPConnectorFactory";
    // display name for data source(DS)and connection factory(CF)
    private static final String dataSourceName = "SampleDataSource";
    private static final String dataSourceTemplateName =
        "DB2 Using IBM JCC Driver - DataSource";

    @SuppressWarnings("unused")
    private static final String dbName = "SamplesDB"; // the database name 
    public static void main(String[] args) {
        JDBCResourcesWithJMX cds = new JDBCResourcesWithJMX();

        try {
            cds.run(args);
        }
        catch (Exception ex) {
            System.out.println("Caught exception: " + ex);
            ex.printStackTrace();
        }
    }

    /**
     * Creates a jdbc provider, data source, auth alias and connection      * factory, if so configured. Neither the data source or conn factory, if      * created, is bound into namespace until the server is restarted or an      * application using it is started
     */
    private void run(String[] args) throws Exception {

        // Initialize the AdminClient.
        Properties adminProps = new Properties();
        adminProps.setProperty(AdminClient.CONNECTOR_TYPE,
            AdminClient.CONNECTOR_TYPE_SOAP);
        adminProps.setProperty(AdminClient.CONNECTOR_HOST, "localhost");
        adminProps.setProperty(AdminClient.CONNECTOR_PORT, "8880");
        AdminClient adminClient =
            AdminClientFactory.createAdminClient(adminProps);

        Session session = new Session();

        // use node scope to create config objects         ObjectName scope = null;
        if (createNodeScopedCfgObjs) {
            scope = ConfigServiceHelper.createObjectName(null, "Node", null);
        }
        else { // unless server scope is configured             scope = ConfigServiceHelper.createObjectName(null, "Server",
                "server1");
        }
        
        // retrieve the ConfigService MBean         ObjectName configServiceMBean =
            retrieveJMXMBean(adminClient, "ConfigService");

        // invoke mbean queryConfigObjects operation         // to find either a server or node         ObjectName[] matches = (ObjectName[])adminClient.invoke(
            configServiceMBean,
            "queryConfigObjects",
            // parameters for operation             new Object[] {session, null, scope, null},
            // signature of bean method to invoke             new String[] {"com.ibm.websphere.management.Session",
                "javax.management.ObjectName",
                "javax.management.ObjectName",
                "javax.management.QueryExp"});
        scope = matches[0]; // use the first server or node object found

        // create a jdbc provider at the specified scope
        ObjectName jdbcProv =
            createJDBCProvider(adminClient, session, scope, 
            configServiceMBean);

        // create an auth alias for the data source         createAuthAlias(adminClient, session, configServiceMBean);

        // Retrieve built-in WebSphere Relational Resource Adapter (RRA) at         // same scope as above
        ObjectName rra =
            ConfigServiceHelper.createObjectName(null, "J2CResourceAdapter",
                null);

        // invoke mbean queryConfigObjects operation         matches = (ObjectName[])adminClient.invoke(
            configServiceMBean,
            "queryConfigObjects",
            // parameters for operation             new Object[] {session, scope, rra, null},
            // signature of bean method to invoke             new String[] {"com.ibm.websphere.management.Session",
                "javax.management.ObjectName",
                "javax.management.ObjectName",
                "javax.management.QueryExp"});
        rra = matches[0]; // use the first object found at this scope

        // create a data source using the jdbc provider         ObjectName dataSource =
            createDataSource(adminClient, session, scope, jdbcProv, rra,
                configServiceMBean);

        // if configured to do so, create a Connection Factory on the         // built-in WebSphere RRA for use by CMP beans         if (createCMPConnectionFactory) {
            createConnectionFactory(adminClient, session, rra, dataSource,
                configServiceMBean);
        }

        // invoke mbean save operation to persist the changes         // to the configuration repository, if platform is ND
        // will also need to perform a node sync
        adminClient.invoke(
            configServiceMBean,
            "save",
            // parameters for operation             new Object[] {session, false},
            // signature of bean method to invoke             new String[] {"com.ibm.websphere.management.Session",
                "boolean"});
        
        System.out.println("Configuration changes saved");

        // reload data source MBean         reload(adminClient, session);
    }

    /**
     * Use the ConfigService MBean to create an authentication alias      */
    private void createAuthAlias(AdminClient adminClient, Session session,
        ObjectName configServiceMBean) throws Exception {

        // Find the parent security object         ObjectName security =
            ConfigServiceHelper.createObjectName(null, "Security", null);
        // invoke mbean queryConfigObjects operation         Object result = adminClient.invoke(
            configServiceMBean,
            "queryConfigObjects",
            // parameters for operation             new Object[] {session, null, security, null},
            // signature of bean method to invoke             new String[] {"com.ibm.websphere.management.Session",
                "javax.management.ObjectName",
                "javax.management.ObjectName",
                "javax.management.QueryExp"});
        security = ((ObjectName[])result)[0];
        
        // Prepare the attribute list         AttributeList authAliasAttrs = new AttributeList();
        authAliasAttrs.add(new Attribute("alias", authDataAlias));
        authAliasAttrs.add(new Attribute("userId", authAliasUserID));
        authAliasAttrs.add(new Attribute("password", authAliasPassword));
        authAliasAttrs.add(
            new Attribute("description", authAliasDescription));

        // invoke jmx createConfigData operation         result = adminClient.invoke(configServiceMBean, "createConfigData",
            // parameters for operation             new Object[] {session, security, "authDataEntries",
            "JAASAuthData", authAliasAttrs},
            // signature of bean method to invoke             new String[] {"com.ibm.websphere.management.Session",
                "javax.management.ObjectName",
                "java.lang.String",
                "java.lang.String",
                "javax.management.AttributeList"});
        
        System.out.println("Created authorization alias: " + authDataAlias);
    }

    /*
     * Use the ConfigService MBean to create a CMP connection factory
     * on the built-in WebSphere RRA      */
    private void createConnectionFactory(AdminClient adminClient,
        Session session, ObjectName rra, ObjectName dataSource,
        ObjectName configServiceMBean)
        throws Exception {
        
        // Prepare the attribute list         AttributeList cfAttrs = new AttributeList();
        cfAttrs.add(new Attribute("name", dataSourceName + "_CF"));
        cfAttrs .add(new Attribute("authMechanismPreference",
            "BASIC_PASSWORD"));
        cfAttrs.add(new Attribute("authDataAlias", authDataAlias));
        cfAttrs.add(new Attribute("cmpDatasource", dataSource));
        
        // invoke jmx queryTemplates operation         Object result = adminClient.invoke(
            configServiceMBean,
            "queryTemplates",
            // parameters for operation             new Object[] {session, "CMPConnectorFactory",},
            // signature of bean method to invoke             new String[] {"com.ibm.websphere.management.Session",
                "java.lang.String"});

        // find the template with the desired display name attribute         ObjectName connFactTemplate = null;
        if (result != null) {
            ObjectName[] templates = (ObjectName[])result;
            for (ObjectName template: templates) {
                if (cmpConnFactTemplateName.equals(template.getKeyProperty(
                    SystemAttributes._WEBSPHERE_CONFIG_DATA_DISPLAY_NAME))) {
                    connFactTemplate = template;
               }
            }
        }

        // use the template found above to create the CMP connection factory
        // invoke jmx createConfigDataByTemplate operation         adminClient.invoke(
            configServiceMBean,
            "createConfigDataByTemplate",
            // parameters for operation             new Object[] {session, rra, "CMPConnectorFactory",
                cfAttrs, connFactTemplate},
            // signature of bean method to invoke             new String[] {"com.ibm.websphere.management.Session",
                "javax.management.ObjectName",
                "java.lang.String",
                "javax.management.AttributeList",
                "javax.management.ObjectName"
                });

        System.out.println("Created CMP Connection factory: " +
            dataSourceName + "_CF");
    }

    /**
     * Use the ConfigService MBean to create a data source at the      * specified scope from one of the predefined templates
     */
    private ObjectName createDataSource(AdminClient adminClient,
        Session session, ObjectName scope, ObjectName jdbcProv,
        ObjectName rra, ObjectName configServiceMBean)
        throws Exception {

        // the template name to use based on whether this example is         // configured to use an XA data source or not         String templateName = dataSourceProviderTemplateNameXA;
        if (!createXAJDBCProvider) {
            templateName = dataSourceTemplateName;
        }
        
        // the attribute DataSource.relationResourceAdapter is required         // in addition to the attributes in the template         AttributeList dsAttrs = new AttributeList();
        dsAttrs.add(new Attribute("name", dataSourceName));
        // override some other props in the template         dsAttrs.add(new Attribute("description", dataSourceName));
        dsAttrs.add(new Attribute("jndiName", "jdbc/" + dataSourceName));
        dsAttrs.add(new Attribute("datasourceHelperClassname",
            dataSourceHelperClassName));
        // link to the built-in WebSphere RRA         dsAttrs.add(new Attribute("relationalResourceAdapter", rra));
        dsAttrs.add(new Attribute("authDataAlias", authDataAlias));

        // invoke jmx queryTemplates operation         Object result = adminClient.invoke(
            configServiceMBean,
            "queryTemplates",
            // parameters for operation             new Object[] {session, "DataSource"},
            // signature of bean method to invoke             new String[] {"com.ibm.websphere.management.Session",
                "java.lang.String"});

        // find the template with the desired display name attribute         ObjectName db2Template = null;
        if (result != null) {
            ObjectName[] templates = (ObjectName[])result;
            for (ObjectName template: templates) {
                if (templateName.equals(template.getKeyProperty(
                    SystemAttributes._WEBSPHERE_CONFIG_DATA_DISPLAY_NAME))) {
                    db2Template = template;
               }
            }
        }

        // use the template found above to create the data source         // invoke jmx createConfigDataByTemplate operation         ObjectName dataSource = (ObjectName)adminClient.invoke(
            configServiceMBean,
            "createConfigDataByTemplate",
            // parameters for operation             new Object[] {session, jdbcProv, "DataSource",
                dsAttrs, db2Template},
            // signature of bean method to invoke             new String[] {"com.ibm.websphere.management.Session",
                "javax.management.ObjectName",
                "java.lang.String",
                "javax.management.AttributeList",
                "javax.management.ObjectName"
                });

        System.out.println("Created data source: " + dataSourceName +
            " at " + (createNodeScopedCfgObjs ? "node" : "server") +
            " scope");
        return dataSource;
    }

    /**
     * Get the DataSourceCfgHelper MBean and call reload() on it      * This causes the newly created configuration objects to      * be available.
     */
    private void reload(AdminClient adminClient, Session session)
        throws Exception {

        // retrieve the DataSourceCfgHelper MBean         ObjectName mBean =
            retrieveJMXMBean(adminClient, "DataSourceCfgHelper");

        // call the reload operation         Object result =
            adminClient.invoke(
                mBean,
                "reload",
                new Object[] {},
                new String[] {});

        if (result != null) {
            System.err.println(
                "DataSourceCfgHelper MBean reload operation failed: "
                + result);
        }
        else {
            System.out.println("Reloaded DataSourceCfgHelper MBean");
        }
    }
    
    /**
     * Use the ConfigService MBean to create a jdbc provider at the specified      * scope from one of the predefined templates
     */
    private ObjectName createJDBCProvider(
        AdminClient adminClient, Session session, ObjectName scope,         ObjectName configServiceMBean) throws Exception {

        // the template name to use based on whether this example is         // configured to use an XA jdbc provider or not         String templateName = jdbcProviderTemplateNameXA;
        if (!createXAJDBCProvider) {
            templateName = jdbcProviderTemplateName;
        }
                    
        // invoke jmx queryTemplates operation         Object result = adminClient.invoke(
            configServiceMBean,
            "queryTemplates",
            // parameters for operation             new Object[] {session, "JDBCProvider"},
            // signature of bean method to invoke             new String[] {"com.ibm.websphere.management.Session",
                "java.lang.String"});

        // find the template with the desired display name attribute         ObjectName db2Template = null;
        if (result != null) {
            ObjectName[] templates = (ObjectName[])result;
            for (ObjectName template: templates) {
                if (templateName.equals(template.getKeyProperty(
                    SystemAttributes._WEBSPHERE_CONFIG_DATA_DISPLAY_NAME))) {
                    db2Template = template;
                }
            }
        }

        // the attribute JDBCProvider.name is required in addition         // to the attributes in the template         AttributeList provAttrs = new AttributeList();
        provAttrs.add(new Attribute("name", jdbcProviderName
            + (createXAJDBCProvider ? " (XA)" : "")));
        // override the description in the template         provAttrs.add(new Attribute("description", jdbcProviderName
            + (createXAJDBCProvider ? " (XA)" : "")));
        
        // use the template found above to create the jdbc provider         // invoke jmx createConfigDataByTemplate operation         ObjectName jdbcProvider = (ObjectName)adminClient.invoke(
            configServiceMBean,
            "createConfigDataByTemplate",
            // parameters for operation             new Object[] {session, scope, "JDBCProvider",
                provAttrs, db2Template},
            // signature of bean method to invoke             new String[] {"com.ibm.websphere.management.Session",
                "javax.management.ObjectName",
                "java.lang.String",
                "javax.management.AttributeList",
                "javax.management.ObjectName"
                });
        
        System.out.println("Created JDBC provider: " + jdbcProviderName
            + (createXAJDBCProvider ? " (XA)" : "")  +
            " at " + (createNodeScopedCfgObjs ? "node" : "server") +
            " scope");
        return jdbcProvider;
    }

    // find the specified MBean     @SuppressWarnings("unchecked")
    private ObjectName retrieveJMXMBean(AdminClient adminClient,
        String beanName)
        throws MalformedObjectNameException, ConnectorException {
        // retrieve the ConfigService MBean         ObjectName mBean = null;
        ObjectName queryName =
            new ObjectName("WebSphere:type=" + beanName + ",*");
        Set names = adminClient.queryNames(queryName, null);
        if (!names.isEmpty()) {
            mBean = (ObjectName) names.iterator().next();
        }
        return mBean;
    }}


Subtopics


Related concepts:

JDBC providers
Data sources


Related


Configure a JDBC provider and data source
Configure data access with wsadmin scripting


Reference:

Test connection service
Data source (WAS V4) page
Data source page
CMP connection factories page
JDBC provider page
Data source minimum required settings, by vendor


+

Search Tips   |   Advanced Search