Sunday, 10 November 2013

Oracle Service Bus : Using the Management Java API

Oracle Service Bus 11g
Using the Management Java API


In this post I will share some example Java code which uses the Oracle Service Bus Java API to manipulate OSB resources that have been deployed to a WebLogic Oracle Service Bus domain.

The initial reason I wanted to use the API was to fix some corruption in the OSB resource repository. The benefit of using the API in this situation is that allows you to access resources that the OSB console may not let you see or manipulate.

The full Java API doc for the API can be found in the Oracle Fusion Middleware documentation under the title “Oracle Fusion Middleware Java API Reference for Oracle Service Bus”. The direct URL for the Java API doc current version (11.1.1.7) is: http://docs.oracle.com/cd/E28280_01/apirefs.1111/e15033/toc.htm

I will only be showing a very small example of the functionality provided by the API. I encourage you to take a look at the API doc to get an idea of the full range of functionality it provides. The API allows you to do pretty much anything that could be done via the OSB console.

The trickiest part of using the API is determining what additional JAR libraries are required to use the API. This is not well documented and required a bit of investigation and trial and error by me. This is the resulting list of JAR libraries I came up with:

  • alsb.jar from /<middleware_home>/Oracle_OSB1/lib
  • com.bea.common.configfwk_1.7.0.0.jar from /<middleware_home>/Oracle_OSB1/modules
  • com.bea.core.management.jmx_1.4.2.0.jar from /<middleware_home>/modules
  • sb-kernel-api.jar from /<middleware_home>/Oracle_OSB1/lib
  • sb-kernel-impl.jar from /<middleware_home>/Oracle_OSB1/lib
  • wlfullclient.jar
These libraries are from an install of OSB 11.1.1.7. The version numbers of the libraries may change with other versions of OSB.

The wlfullclient.jar library is not provided by default in a WebLogic install and must be explicitly built by you from an existing WebLogic domain. It's easy to build and there are many posts on the internet describing how to build it. The basic steps are:
  1. cd /<middleware_home>/wlserver_10.3/server/lib
  2. java -jar wljarbulder.jar

I used Eclipse to build the code shown in this blog post, however you should be able to use any other Java IDE to achieve the same result.

There are five main steps to using the API:
  1. Establish a connection to the WebLogic JMX Management Bean running in a WebLogic instance.
  2. Create a new OSB change management session.
  3. Use the API to manipulate OSB resources.
  4. Commit the OSB change management session to save any changes we made.
  5. Close the JMX connection.

Here is the method that establishes the JMX connection:

private static JMXConnector initConnection(String hostname, int port,
String username, String password) throws IOException,
MalformedURLException {
JMXServiceURL serviceURL = new JMXServiceURL("t3", hostname, port,
"/jndi/" + DomainRuntimeServiceMBean.MBEANSERVER_JNDI_NAME);
Hashtable<String, String> h = new Hashtable<String, String>();
h.put(Context.SECURITY_PRINCIPAL, username);
h.put(Context.SECURITY_CREDENTIALS, password);
h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote");
return JMXConnectorFactory.connect(serviceURL, h);
}

Here is the code that creates the OSB change management session:

// Connect to WebLogic JMX
conn = initConnection(host, port, username, password);

// Create the OSB change management session
MBeanServerConnection mbconn = conn.getMBeanServerConnection();
DomainRuntimeServiceMBean domainService = (DomainRuntimeServiceMBean) MBeanServerInvocationHandler
.newProxyInstance(mbconn, new ObjectName(
DomainRuntimeServiceMBean.OBJECT_NAME));
sm = (SessionManagementMBean) domainService.findService(
SessionManagementMBean.NAME, SessionManagementMBean.TYPE,
null);
sm.createSession(sessionName);

After creating the session we need to get a reference to one of the MBeans that are provided for OSB depending on what we want to do. To create and delete resources we can use the ALSBConfigurationMBean as below:

ALSBConfigurationMBean alsbSession = (ALSBConfigurationMBean) domainService
.findService(ALSBConfigurationMBean.NAME + "."
+ "mysession", ALSBConfigurationMBean.TYPE, null);

Some other MBean types that are also available are:
  • CommonServiceConfigurationMBean
  • BusinessServiceConfigurationMBean
  • ProxyServiceConfigurationMBean
  • ServiceDomainMBean
When specifying the resources that you want to manipulate, the API uses a “Ref” object. To create a Ref object you must specify the resource type and name. For example, if I wanted to create a Ref object to represent a Proxy Service named “GetAccountBalancePS” under the Project path “CoreBanking/AccountServices” I would use the following code:

// Construct Ref object
Ref ref = constructRef(“ProxyService”, “CoreBanking/AccountServices/GetAccountBalancePS”);

For a Business Service we would use “BusinessService” as the first parameter above.
For Projects or Folders we should use the predefined values Ref.PROJECT_REF and Ref.FOLDER_REF. For example:

// Construct Ref object
Ref ref = constructRef(Ref.PROJECT_REF, “CoreBanking”);

// Construct Ref object
Ref ref = constructRef(Ref.FOLDER_REF, “CoreBanking/AccountServices”);

After we have manipulated the resources we activate or discard the change session:

sm.activateSession(sessionName, statusmsg);

sm.discardSession(sessionName);

If we activate the session we can provide a comment just like we would do if we used the OSB console.

I have provided the full code for two example scenarios below:
  1. Enable/Disable a Business Service or Proxy Service.
  2. Delete a Project or Folder.
I hope you find these example useful.

Enable/Disable Business or Proxy Service

/**
 *
 */
package osbservicestatusupdate;
import com.bea.wli.config.Ref;
import com.bea.wli.sb.management.configuration.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Hashtable;
import javax.management.*;
import javax.management.remote.*;
import javax.naming.Context;
import weblogic.management.jmx.MBeanServerInvocationHandler;
import weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean;
public class OSBServiceStatusUpdate {
private static JMXConnector initConnection(String hostname, int port,
String username, String password) throws IOException,
MalformedURLException {
JMXServiceURL serviceURL = new JMXServiceURL("t3", hostname, port,
"/jndi/" + DomainRuntimeServiceMBean.MBEANSERVER_JNDI_NAME);
Hashtable<String, String> h = new Hashtable<String, String>();
h.put(Context.SECURITY_PRINCIPAL, username);
h.put(Context.SECURITY_CREDENTIALS, password);
h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote");
return JMXConnectorFactory.connect(serviceURL, h);
}
private static Ref constructRef(String refType, String serviceuri) {
Ref ref = null;
String[] uriData = serviceuri.split("/");
ref = new Ref(refType, uriData);
return ref;
}
public static String changeProxyServiceStatus(String servicetype,
boolean status, String serviceURI, String host, int port,
String username, String password) {
JMXConnector conn = null;
SessionManagementMBean sm = null;
String sessionName = "mysession";
String statusmsg = "";
try {
conn = initConnection(host, port, username, password);
MBeanServerConnection mbconn = conn.getMBeanServerConnection();
DomainRuntimeServiceMBean domainService = (DomainRuntimeServiceMBean) MBeanServerInvocationHandler
.newProxyInstance(mbconn, new ObjectName(
DomainRuntimeServiceMBean.OBJECT_NAME));
sm = (SessionManagementMBean) domainService.findService(
SessionManagementMBean.NAME, SessionManagementMBean.TYPE,
null);
sm.createSession(sessionName);
ALSBConfigurationMBean alsbSession = (ALSBConfigurationMBean) domainService
.findService(ALSBConfigurationMBean.NAME + "."
+ "mysession", ALSBConfigurationMBean.TYPE, null);
if (servicetype.equals("ProxyService")) {
Ref ref = constructRef("ProxyService", serviceURI);
ProxyServiceConfigurationMBean proxyConfigMBean = (ProxyServiceConfigurationMBean) domainService
.findService(ProxyServiceConfigurationMBean.NAME + "."
+ sessionName,
ProxyServiceConfigurationMBean.TYPE, null);
if (status) {
proxyConfigMBean.enableService(ref);
statusmsg = "Enabled the Service : " + serviceURI;
} else {
proxyConfigMBean.disableService(ref);
statusmsg = "Disabled the Service : " + serviceURI;
}
} else if (servicetype.equals("BusinessService")) {
Ref ref = constructRef("BusinessService", serviceURI);
BusinessServiceConfigurationMBean businessConfigMBean = (BusinessServiceConfigurationMBean) domainService
.findService(BusinessServiceConfigurationMBean.NAME
+ "." + sessionName,
BusinessServiceConfigurationMBean.TYPE, null);
if (status) {
businessConfigMBean.enableService(ref);
statusmsg = "Enabled the Service : " + serviceURI;
} else {
businessConfigMBean.disableService(ref);
statusmsg = "Disabled the Service : " + serviceURI;
}
}
sm.activateSession(sessionName, statusmsg);
conn.close();
} catch (Exception ex) {
if (null != sm) {
try {
sm.discardSession(sessionName);
} catch (Exception e) {
System.out.println("able to discard the session");
}
}
statusmsg = "Not able to perform the operation";
ex.printStackTrace();
} finally {
if (null != conn)
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return statusmsg;
}
public static void main(String[] args) {
// changeProxyServiceStatus(servicetype, status, serviceURI, host, port,
// username, password)
System.out.println(changeProxyServiceStatus("ProxyService", true,
"CoreBanking/AccountServices/GetAccountBalancePS", "localhost", 7001,
"weblogic", "welcome1"));
}
}

Delete a Project or Folder

/**
 * 
 */
package osbservicestatusupdate;

import com.bea.wli.config.Ref;
import com.bea.wli.sb.management.configuration.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Collection;
import javax.management.*;
import javax.management.remote.*;

import javax.naming.Context;
import weblogic.management.jmx.MBeanServerInvocationHandler;
import weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean;

public class OSBResourceDelete {
private static JMXConnector initConnection(String hostname, int port,
String username, String password) throws IOException,
MalformedURLException {
JMXServiceURL serviceURL = new JMXServiceURL("t3", hostname, port,
"/jndi/" + DomainRuntimeServiceMBean.MBEANSERVER_JNDI_NAME);
Hashtable<String, String> h = new Hashtable<String, String>();
h.put(Context.SECURITY_PRINCIPAL, username);
h.put(Context.SECURITY_CREDENTIALS, password);
h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote");
return JMXConnectorFactory.connect(serviceURL, h);
}

private static Ref constructRef(String refType, String serviceuri) {
Ref ref = null;
String[] uriData = serviceuri.split("/");
ref = new Ref(refType, uriData);
return ref;
}

public static String deleteResource(String servicetype,
String serviceURI, String host, int port,
String username, String password) {
JMXConnector conn = null;
SessionManagementMBean sm = null;
String sessionName = "mysession";
String statusmsg = "";
try {
conn = initConnection(host, port, username, password);
MBeanServerConnection mbconn = conn.getMBeanServerConnection();
DomainRuntimeServiceMBean domainService = (DomainRuntimeServiceMBean) MBeanServerInvocationHandler
.newProxyInstance(mbconn, new ObjectName(
DomainRuntimeServiceMBean.OBJECT_NAME));
sm = (SessionManagementMBean) domainService.findService(
SessionManagementMBean.NAME, SessionManagementMBean.TYPE,
null);
sm.createSession(sessionName);
ALSBConfigurationMBean alsbSession = (ALSBConfigurationMBean) domainService
.findService(ALSBConfigurationMBean.NAME + "."
+ "mysession", ALSBConfigurationMBean.TYPE, null);

// Construct Ref object
Ref ref = constructRef(servicetype, serviceURI);
// Check if resource exists
boolean resExists = false;
resExists = alsbSession.exists(ref);
System.out.println("Resource '" + serviceURI + "' " + (resExists ? "exists." : "does not exist."));
// Delete the resource
if (resExists) {
ArrayList<Ref> refs = new ArrayList<Ref>();
refs.add(ref);
System.out.println("Deleting " + servicetype + " " + serviceURI);
alsbSession.delete(refs);
sm.activateSession(sessionName, statusmsg);
} else {
sm.discardSession(sessionName);
}
conn.close();
} catch (Exception ex) {
if (null != sm) {
try {
sm.discardSession(sessionName);
} catch (Exception e) {
System.out.println("Not able to discard the session");

}
}
statusmsg = "Not able to perform the operation";
ex.printStackTrace();
} finally {
if (null != conn)
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}

return statusmsg;
}

public static void main(String[] args) {
// changeProxyServiceStatus(servicetype, status, serviceURI, host, port,
// username, password)
System.out.println(deleteResource(Ref.PROJECT_REF,
"Test", "localhost", 7001,
"weblogic", "welcome1"));

}
}






4 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. I have used this info to make a code for FindAndReplace values, thanks a lot. Now I am trying to create a code for importing configuration. Did you do the similar task? Or can you take a look into my code and help me?

    https://www.dropbox.com/s/vyma8iztu6s44um/OSBConfigUpdate1.java?dl=0

    ReplyDelete