Oracle BI EE 11g – Systems Management API – JMX & MBeans – Dynamic User Generation

BI EE 11g introduces a new API for Systems Management called BI Systems Management API. This API has multitude of uses especially at places where complete automation/control of resources/system deployment is required. This API uses the Java JMX MBeans to expose the functionality externally. BI EE 11g Enterprise Manager uses this API internally to make updates/configuration changes. There are a total of 4 different ways of using the API. They are

1. Using Pre-Configured Enterprise Manager 2. Using System MBeans Browser 3. Using Java to connect through JMX 4. Using Weblogic Scripting

Enterprise Manager(EM) more or less exposes all the functionality to an Administrator. But the drawback with EM is that, it is a pure point & click application. When we have a lot of instances that require similar configuration updates/changes, we need an automated approach. This is where using the API directly through Java/Weblogic Scripting can be really helpful. The documentation of the API currently is limited only to certain administration aspects of BI EE. But actual methods available in the API is very exhaustive and can be used to build quite a lot of automated applications/utilities. In today's blog post, lets look at how we can use the API through Java and then perhaps use further non documented API methods to automate key configuration changes i.e create a new Weblogic user using JMX.

We start off with first looking at the documented Java Interfaces that we have as part of the systems management API.

The interface documentation is available at {ORACLE_HOME}\doc\javadoc\bifoundation\jmxapi\index.html (part of the BI EE install). Each of these interfaces basically point to various configurable tabs that we have within the Enterprise Manager.

For example, the PerformanceConfigurationMBean provides methods & attributes that can be queried and updated, similar to the operations that are available in the Performance tab of the Enterprise Manager.

In the same way, we can use these JMX methods to do vertical clustering, Email updates, Log Configuration, SSO configuration etc. But once you start using these APIs, you will start noticing that almost every aspect of weblogic can be updated/queried using JMX. So, how do we actually get the other methods/attributes. This is where the System MBean Browser will be extremely helpful. MBean browser basically shows almost all the JMX endpoints that are exposed for integration. This can be invoked from the Enterprise Manager as shown below (right click on the bifoundation_domain under the WebLogic Domain in Enterprise Manager)

As you see, this MBeans browser shows all the JMX end points available for external API calls. The methods that are documented for BI EE Administration (interfaces in the screenshot above) can be found at Application Defined MBeans -> oracle.biee.admin -> Domain: bifoundation_domain

Each bean has 2 parts. One is an Attribute and the other is an Implementing Method. Attributes are like variables that can be updated using static values like Port Numbers, Number of BI Servers etc (InstanceConfig.xml settings etc). For example, AvailabilityConfigurationMBean shown below has multiple updatable attributes which can be seen from the MBean Browser.

Implementing Methods are like normal Java Methods that can be used for typical invocation operations. For example, Starting and Stopping components are considered as Implementing Methods of a Java Bean. The screenshot below shows the Start and Stop methods for a specific BI Server.

The entry point to each interface (to update attributes or call methods) are done through the JMX names. For example,

oracle.biee.admin:oracleInstance=instance1, type=BIDomain.BIInstanceDeployment.BIComponent, biInstance=coreapplication, process=coreapplication_obis1,group=Service is the unique JMX name for the master BI Server.

In Java speak, one will have to use the above name to create a new Object and then use that object for updating Attributes or Calling Methods. The code snippet below shows an example of updating the BI Server Cache attribute (ENABLE = YES; entry in NQSConfig.ini)

biPerformanceMBeanName = new ObjectName("oracle.biee.admin:type=BIDomain.BIInstance.PerformanceConfiguration,biInstance=coreapplication,group=Service");
System.out.println("Found BI Cache MBean: " + biPerformanceMBeanName);
mbs.invoke(biDomainMBeanName, "lock", args1, sig1);
mbs.setAttribute(biPerformanceMBeanName,new Attribute("BIServerCacheEnabled",true);

The above is documented (the methods & attributes). But what is not documented are the other aspects of the JMX API. For example, a typical requirement is to add new users to the Default Authenticator through a script. To do that we need to first identify the MBean where the security aspects of Weblogic are exposed. The MBean is available under Runtime MBeans->Security->Domain: bifoundation_domain->myRealmDefaultAuthenticator

This MBean supports quite a lot of Attributes (properties that we typically update from Weblogic Console) and Methods (adding a user, listing users etc)

Let's use the createUser method to create a new user. The code snippet below demonstrates how to add a new user programmatically using JMX & Java.

ObjectName securityMBeanName = new ObjectName("Security:Name=myrealmDefaultAuthenticator");
System.out.println("Found BI Instance Deployment MBean: " + securityMBeanName);
Object[] objuser = {new String ("NewUser"), new String ("welcome1"), new String ("New User from JMX")};
String[] objstr = {new String ("java.lang.String"),new String ("java.lang.String"),new String ("java.lang.String")};
mbs.invoke(securityMBeanName,"createUser",objuser,objstr);

To execute custom JMX methods through Java, we need 2 jar files in our class path. They are wlclient.jar and wljmxclient.jar. Both of these files will be present under C:\oracle\Middleware\Oracle_BI1\opmn\lib folder. The full sample java code for updating the cache entry and create a new user is given below

package bieesysmgmt;
import java.util.Hashtable;

import javax.jws.WebMethod;
import javax.jws.WebService;

import javax.management.Attribute;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;
@WebService

public class bieecacheentry {

     @WebMethod
     public static String bieecacheupdate(String cacheEntry) throws Exception {

          String Status = "";

         try {
          MBeanServerConnection mbs = null;
          ObjectName biDomainMBeanName;
          ObjectName biInstanceMBeanName;
          ObjectName biPerformanceMBeanName;
          ObjectName biComponentMBeanName;

             String hostname = "venkatbiee";
             String port = "7001";
             String username = "weblogic";
             String password = "welcome1";

          String jmxUrl = "service:jmx:t3://" + hostname + ":" + port +                "/jndi/weblogic.management.mbeanservers.domainruntime";
          System.out.println("Connecting using URL: " + jmxUrl + " ...");

          Hashtable h = new Hashtable();
          h.put(Context.SECURITY_PRINCIPAL,    username);
          h.put(Context.SECURITY_CREDENTIALS, password);
          h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,                "weblogic.management.remote");
          JMXConnector jmxConnector = JMXConnectorFactory.connect(new                 JMXServiceURL(jmxUrl), h);
          mbs = jmxConnector.getMBeanServerConnection();
          Status = "Connected OK";

          biDomainMBeanName = new                 ObjectName("oracle.biee.admin:type=BIDomain,group=Service");
          biInstanceMBeanName = new ObjectName("oracle.biee.admin:type=BIDomain.BIInstance,biInstance=coreapplication,group=Service");

          Status = Status + "-----" + "BIInstanceSuccess" + biInstanceMBeanName;

          biPerformanceMBeanName = new ObjectName("oracle.biee.admin:type=BIDomain.BIInstance.PerformanceConfiguration,biInstance=coreapplication,group=Service");

             Status = Status + "-----" + "BICacheSuccess"+biPerformanceMBeanName;

          System.out.println("Cache MBean Yes/No: " + mbs.getAttribute(biPerformanceMBeanName, "BIServerCacheEnabled"));
             Status = Status + "-----"+ "Cache Original Value: "+ mbs.getAttribute(biPerformanceMBeanName, "BIServerCacheEnabled");

           Object[] args1 = new Object[]{};
           String[] sig1   = new String[]{};

              mbs.invoke(biDomainMBeanName, "lock", args1, sig1);

           System.out.println("Cache MBean Yes/No: " + mbs.getAttribute(biDomainMBeanName,"Locked"));
           System.out.println("Locked domain OK");

           mbs.setAttribute(biPerformanceMBeanName,new Attribute("BIServerCacheEnabled", Boolean.parseBoolean(cacheEntry)));

           // Commit Changes

           mbs.invoke(biDomainMBeanName, "commit", args1, sig1);
           System.out.println("Committed changes OK");
            Status = Status + "-----"+ "Cache Updated Value: "+ mbs.getAttribute(biPerformanceMBeanName, "BIServerCacheEnabled");

          biComponentMBeanName = new ObjectName("oracle.biee.admin:oracleInstance=instance1,type=BIDomain.BIInstanceDeployment.BIComponent,biInstance=coreapplication,process=coreapplication_obis1,group=Service");

          mbs.invoke(biComponentMBeanName,"stop",args1,sig1);
          mbs.invoke(biComponentMBeanName,"start",args1,sig1);

          ObjectName securityMBeanName = new ObjectName("Security:Name=myrealmDefaultAuthenticator");
          System.out.println("Found BI Instance Deployment MBean: " + securityMBeanName);

             Object[] objuser = {new String ("NewUser"), new String ("welcome1"), new String ("New User from JMX")};
             String[] objstr = {new String ("java.lang.String"),new String ("java.lang.String"),new String ("java.lang.String")};
             mbs.invoke(securityMBeanName,"createUser",objuser,objstr);
          return "Done";
          }
         catch (Exception ex){
           ex.getMessage();
         }
           return "Yes";

         }
                              {
        }
     @WebMethod
     public String helperMethod (String helperInput) {
       return ("Success");
     }

     public static void main(String[] args){

         try{
     System.out.println("Output"+ bieecacheupdate("false"));
         }
         catch (Exception ex)
         {System.out.println(ex.getMessage());}

     }
}

Executing the above method should automatically update the ENABLE=NO; in NQSConfig.ini. Also, a new user in weblogic called NewUser will be created.

JMX was available even in BI EE 10g. But in 11g, most of the operations(that can be done from Java) have been exposed through JMX. So, all the more easier now to integrate BI EE into any external applications/admin tools etc.