Oracle WebLogic RESTful Management Services:
From Command Line to JavaFX

by William Markito Oliveira

August 2012

Summary

Oracle WebLogic Server 12c is a major release and includes several new features, including Java EE 6, Maven integration, and JDK 7 support. This release also includes additional features that are important for administration and monitoring of an Oracle WebLogic domain. This article will focus on one such feature: RESTful Management Services.

Starting with Oracle WebLogic12c, RESTful services can now be used to monitor several aspects of a running server instance, including:

  • Applications
  • Clusters
  • Data Sources
  • Servers

The most interesting part of this feature is the ability to call such services from any RESTful client, including different programming languages. This article will illustrate how the following tools can be used to accomplish that task:

  • A built-in web client
  • cURL
  • A Python script
  • A JavaFX application

It is also possible to consume such services from other tools, but those details are beyond the scope of this article.

To access the complete reference and details about the API please see the Oracle WebLogic Server documentation page, as listed in the References section of this article.

Requirements

  • Oracle WebLogic Server 12c
  • Python 2.7+
  • JDK 7u04 (with built-in JavaFX support)
  • Any operating system (preferably Unix-like:Linux, OSX, etc.)

In order to use the RESTful Management Services, you must enable the feature through the Oracle WebLogic Administration Console:

  1. Under Domain structure, click on the domain name
  2. Under Configuration > General, expand the Advanced section
  3. Select the check box RESTful Management Services and click Save.
oliveira-wls-rest-javafx-fig01
Figure 1: Enabling RESTful Management Services
  1. Restart the server. You will see the following output after the server Running message:
<Jun 27, 2012 3:01:44 PM BRT> <Notice> <WebLogicServer> <BEA-000360> <The server
started in RUNNING mode.> 
<Jun 27, 2012 3:01:44 PM BRT> <Warning> <Server> <BEA-002611> <The hostname
"localhost", maps to multiple IP addresses: 127.0.0.1, 0:0:0:0:0:0:0:1,
fe80:0:0:0:0:0:0:1%1.> 
Jun 27, 2012 3:01:48 PM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
  weblogic.management.rest.resources
  weblogic.management.rest.provider
Jun 27, 2012 3:01:48 PM com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
  class weblogic.management.rest.resources.DataSourceResource
  class weblogic.management.rest.resources.ApplicationResource
  class weblogic.management.rest.resources.ServerResource
  class weblogic.management.rest.resources.ClusterResource
  class weblogic.management.rest.resources.TestResource
Jun 27, 2012 3:01:48 PM com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Provider classes found:
  class weblogic.management.rest.provider.ItemResponseXmlProvider
  class weblogic.management.rest.provider.CollectionResponseXmlProvider
  class weblogic.management.rest.provider.CollectionResponseJsonProvider
  class weblogic.management.rest.provider.ItemResponseJsonProvider
  class weblogic.management.rest.provider.ItemResponseHtmlProvider
  class weblogic.management.rest.provider.CollectionResponseHtmlProvider
Jun 27, 2012 3:01:48 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.9 09/02/2011 11:17 AM

RESTful Management Services

The RESTful management services can be accessed through a common URL that follows a common format:

http(s)://[host]:[port]/management/tenant-monitoring/[path]

Where:

host - The host where Oracle WebLogic Admin Server is running

port - The HTTP or HTTPS port

path - The relative path that identifies an individual resource. For example, the path to a server instance would be: servers/AdminServer, datasources/myDataSource…

The implementation of the services is based on Jersey, the JAX-RS Reference Implementation, and supports the following representation of the results:

  • JSON ("application/json")
  • XML (""application/xml")
  • HTML

The HTML is the default output, but you can modify that behavior by specifying the Accept: HTTP header when calling the API.

More details about the API and the complete reference of values and attributes that can be retrieved by each resource are available via the Oracle WebLogic Server documentation page, listed in the References section of this article.

The next sections present some REST client examples. It is important to mention that you can access these services using any web browser. For example, type the following URL in your browser after you have enabled the RESTful services in a running Oracle WebLogic domain:

http://localhost:7001/management/tenant-monitoring/servers

Note: The first time you access the URL you will be prompted to input Username and Password. Only users that belong to the Administrators group or the Monitors group are allowed access to the RESTful Management Services.

This article uses the default user name weblogic and the password welcome1.

After a successful authentication, your browser output should be similar to this:

  • body
    • items
      1.
      • name AdminServer
      • state RUNNING
      • health HEALTH_OK
  • messages

As mentioned, the default output is HTML, so this is a simple HTML page.

The "Hidden" Native Client

Oracle WebLogic 12c also includes a built-in web client that can be used to call the services. This web client supports several output formats, including XML, JSON, and HTML.

Note: This client is intended solely for testing purposes. No support is offered.

Access this client via the following URL:

http://localhost:7001/management/ajaxtest.html

Figures 2, 3, and 4 illustrate usage examples on a selection of resources:

oliveira-wls-rest-javafx-fig02
Figure 2: Native Client - Listing all servers
oliveira-wls-rest-javafx-fig03
Figure 3: Native Client - Listing all clusters
oliveira-wls-rest-javafx-fig04
Figure 4: Native Client - Checking specific server information in XML format

The native client makes it easier and faster to use than the Administration console to access common information about the available resources—if you know the exact path to the information you need.

cURL - (libcurl)

The Linux Manual defines cURL as:

"A tool to transfer data from or to a server, using one of the supported protocols (DICT, "FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP). The command is designed to work without user interaction…cURL offers a busload of useful tricks like proxy support, user authentication, FTP upload, HTTP post, SSL connections, cookies, file transfer resume and more."

cURL is a good tool for creating simple shell scripts that can query data from a running Oracle WebLogic domain. The following are snippets of cURL scripts:

Code Listing 1 - Check Server Information - Raw JSON output
(markito@luke)$ curl -s --user weblogic -H "Accept: application/json"
http://localhost:7001/management/tenant-monitoring/servers/
Enter host password for user 'weblogic':
{"body":{"items":[{"name":"AdminServer","state":"RUNNING","health":"HEALTH_OK"},
{"name":"managedA","state":"SHUTDOWN"},{"name":"managedB","state":"SHUTDOWN"}]},
"messages":[]} 
Code Listing 2 - Check Server current free Heap Memory
(markito@luke)$ curl -s --user weblogic -H "Accept: application/json"
http://localhost:7001/management/tenant-monitoring/servers/AdminServer | grep -Po
'"heapFreeCurrent":[ 0-9]*'
Enter host password for user 'weblogic': "heapFreeCurrent":464249712
Code Listing 3 - Show total number of database connections created
(markito@luke)$ curl -s --user weblogic -H "Accept: application/json"
http://localhost:7001/management/tenant-monitoring/datasources/myDataSource | grep -Po
'"connectionsTotalCount":[ 0-9]*'
Enter host password for user 'weblogic':
"connectionsTotalCount":10

Several options are available to parse the output from command line tools, which usually including awk, sed and grep. New tools, including jsawk, focus on JSON parsing. Choose wisely for your use case.

Python Client

Python is a powerful language that's very popular among a wide range of professionals, including application developers, web developers, system administrators, and scientific researchers. Besides its power, Python is also very easy to learn and has a clear goal to provide code readability through whitespaces and indentation.

Since Python is installed by default in most Linux servers, many system administrators write Python scripts to monitor several machine aspects, including memory, CPU usage, file systems, and network. This article will add Oracle WebLogic Server to that list.

Script #1 — Monitor Server Status

In this first script we will list all existing Oracle WebLogic servers and show the status of each. While nothing fancy, this script can easily be added to the Linux/Unix CRON and run during intervals (1 minute, 30 seconds) to check if all Oracle WebLogic servers are up and running. The response of the REST call in this case is JSON. Python's JSON library can be used to parse the result into dictionaries and lists.

Code Listing 4 - Check Server Status using Python
#!/usr/bin/python
'''
Created on Jul 2, 2012 Check Weblogic Server Status @author: markito
'''
import urllib2, json

####################
# Modify the server information accordingly
####################
host = "localhost"
port = "7001"
username = "weblogic"  
password = "welcome1"
    
################################################################################
def main():

    baseURL = "http://%s:%s/management/tenant-monitoring/servers" % (host,port)
    
    # HTTP Authentication
    passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
    passman.add_password(None, baseURL, username, password)    
    authhandler = urllib2.HTTPBasicAuthHandler(passman)
    opener = urllib2.build_opener(authhandler)
    urllib2.install_opener(opener)
    
    try:
        req = urllib2.Request(baseURL, None, {'Accept': 'application/json'})
        raw = urllib2.urlopen(req).read()
        data = json.loads(raw)
        items = data['body']['items']
        
        for item in items:
            print "Server: " + item['name'] + " [ " + item['state'] + " ]" 
            
    except urllib2.HTTPError, e:
        print "HTTP error: %d" % e.code
        
    except urllib2.URLError, e:
        print "Network error: %s" % e.reason.args[1]
################################################################################
if __name__ == '__main__':
    main()

In order to execute the script, just copy the statements above and save into an executable python script (e.g.: serverStatus.py). The output of this script should resemble the following:

(markito@luke)$ ./serverStatus.py 
Server: AdminServer [ RUNNING ]
Server: managedA [ SHUTDOWN ]
Server: managedB [ SHUTDOWN ]

Of course, it is possible to achieve almost the same results using Oracle WebLogic Scripting Tool (WLST), but there are few differences that should be considered. For example:

  • Python x Jython: Python is a multi-purpose language constructed in C. When interpreted and compiled it generates .pyc files. Python also has its own Garbage Collection implementation. Jython is a port of Python, but 100% written in Java. Jython can be executed by any JVM. When compiled, the code produces .class files and uses the Java Garbage Collection implementations. WLST scripts are written in Jython.
  • Classpath Requirements: In order to execute WLST, you need to set some specific libraries in your environment, which usually means that you need to execute the setDomainEnv.sh script (available under /bin directory of an Oracle WebLogic domain) before executing WLST scripts.
  • Protocol: Using WLST, the connection uses an Oracle WebLogic-specific protocol called T3. When using Python and REST this is an HTTP connection.
  • Execution: The Python language is lightweight. Running the scripts several times consistently showed that WLST takes more time to execute than Python.

It is important to note that through WLST it is possible to manage a Oracle WebLogic domain (start, stop servers) and also modify server settings or create new resources (Data sources, JMS Queues, etc.). In this release, Oracle WebLogic RESTful Management Services are strictly limited to monitoring, so there is no way to update or modify any value on the server.

Code Listing 5 - Check Server Status - Oracle WebLogic Scripting tool version (WLST)
'''
Created on Jul 4, 2012 @author: Markito @file: serverStatusWLST.py
'''

####################
# Modify the server information accordingly
####################
username = 'weblogic'
password = 'welcome1'
URL='t3://localhost:7001'

################################################################################
connect(username,password,URL)
domainConfig()
serverList=cmo.getServers();

domainRuntime()
cd('/ServerLifeCycleRuntimes/')

for server in serverList:
     name=server.getName()
     cd(name)
     serverState=cmo.getState()
     
     print "Server: " + name + " [ " + serverState + " ]"
     cd('..')

In order to execute the script above, save it to a file called serverStatusWLST.py. Remember to call the setDomainEnv.sh script (source setDomainEnv.sh or . /setDomainEnv.sh) and then execute the following command: java weblogic.WLST serverStatusWLST.py

Script #2 — Fancy Python Client

This second script includes several extra options to monitor additional information for a running Oracle WebLogic domain. It's important to note that the script doesn't have a fixed URL, Username or Password for Oracle WebLogic, which is more secure than the previous approach. Everything is passed as parameters to the script, including the type of resource you want to monitor:

  • -h or --host: Oracle WebLogic Admin server address
  • -u or --user: Username for authentication
  • -p or --password: Asks for password
  • -s or --server: Server Monitoring
  • -d or --datasource: Data source Monitoring
  • -a or --application: Application Monitoring
  • -c or --cluster: Cluster monitoring

 

Code Listing 6 - Python script with more monitoring options
#!/usr/bin/python
''' Created on Jun 26, 2012 @author: Markito @file: WLSTRESTPy.py '''
import getopt, sys, getpass
import urllib2

__version__ = 0.1

def main():
    
    wls = WLSREST()
    
    try:
        opts, args = getopt.getopt(sys.argv[1:], "h:o:u:pvs:d:a:c", 
["host=", "output=", "user=","password","version", "server=",
 "datasource=", "application=", "cluster="])
    except getopt.GetoptError, err:
        print str(err)
        wls.usage()
        sys.exit(2)
        
    ###############
    ## iterate and parse each parameter and input value
    ###############
    for opt, value in opts:
        if (opt in ('-v', '--version')):
            print 'Version %(v)s' % {'v':  __version__ }
            
        elif (opt in ('-h', '--host')):
            host = value
            wls.baseURL = "%s/management/tenant-monitoring/" % (host)     
                  
        elif (opt in ('-p', '--password')):
            wls.password = getpass.getpass("Password: ")
   
        elif (opt in ('-u', '--user')):
            wls.username = value
    
        elif (opt in ('-s', '--server')):
            wls.checkServer(value)
            
        elif (opt in ('-d', '--datasource')):
            wls.checkDataSource(value)
            
        elif (opt in ('-a', '--application')):
            wls.checkApplication(value)
            
        elif (opt in ('-c', '--cluster')):
            wls.checkCluster(value)
        else: 
            wls.usage()
            
    ###########
    # Simple print the results but could parse it from here or from 
    # each wls monitoring method (checkServer, checkCluster...)
    ###########
    print wls.GET()
        

''' WLSRest class that encapsulate the monitoring methods,
authentication and GET call  ''' 
class WLSREST():
     
    def setURL(self, url):
        self.baseURL = url
        return self
    
    def usage(self):
        print("Please check the command options and syntax")
        print("Syntax: ./WLSRESTPy.py -h [http://adminServerHost:port]
[-sacd] [parameter] -u [username] -p")
        print("For example: ./WLSRESTPy.py -h http://localhost:7001 -s     
AdminServer -u weblogic -p")
        
    def checkServer(self, server):
        return self.setURL(self.baseURL + "servers/%s" % server)
        return self
    
    def checkDataSource(self, dataSource):
        return self.setURL(self.baseURL + "datasources/%s" % dataSource)
    
    def checkApplication(self, application):
        return self.setURL(self.baseURL + "applications/%s" % application)
        
    def checkCluster(self, cluster):
        return self.setURL(self.baseURL + "clusters/%s" % cluster)
    
    def GET(self):
        # HTTP Authentication
        passman = urllib2.HTTPPasswordMgrWithdefaultRealm()
        passman.add_password(None, self.baseURL, self.username, self.password)    
        authhandler = urllib2.HTTPBasicAuthHandler(passman)
        opener = urllib2.build_opener(authhandler)
        urllib2.install_opener(opener)
        
        try:
            data = ""
            req = urllib2.Request(self.baseURL, None, {'Accept': 'application/json'})
            data = urllib2.urlopen(req).read()
            
            return data
            
        except urllib2.HTTPError, e:
            print "HTTP error: %d" % e.code
            self.usage()
            
        except urllib2.URLError, e:
            print "Network error: %s" % e.reason.args[1]
            self.usage()
            
########################################################################
if __name__ == '__main__':
    main()

For simplicity's sake this script includes no special treatment on the response of the service calls. It will simply print the JSON response to the output. However, the first Python example in this article provides information that will aid in understanding how to parse the content using the built-in json library that Python provides.

Some example calls to the script are below:

Code Listing 7 - List all servers status - Python script
(markito@luke)$ ./WLSRESTPy.py -h http://localhost:7001 -s ''  -u weblogic -p
Password: 
{"body":{"items":[{"name":"AdminServer","state":"RUNNING","health":"HEALTH_OK"},
{"name":"managedA","state":"SHUTDOWN"},{"name":"managedB","state":"SHUTDOWN"}]},
"messages":[]
Code Listing 8 - Check Server Information - Python script
(markito@luke)$ ./WLSRESTPy.py -h http://localhost:7001 -s 'AdminServer' -u weblogic -p
Password: 
{"body":{"item":{"name":"AdminServer","state":"RUNNING","health":"HEALTH_OK",
"clusterName":null,"currentMachine":"","weblogicVersion":"WebLogic Server 
Temporary Patch for 13340309 Thu Feb 16 18:30:21 IST 2012\nWebLogic Server 
Temporary Patch for 13019800 Mon Jan 16 16:53:54 IST 2012\nWebLogic Server 
Temporary Patch for BUG13391585 Thu Feb 02 10:18:36 IST 2012\nWebLogic Server 
Temporary Patch for 13516712 Mon Jan 30 15:09:33 IST 2012\nWebLogic Server 
Temporary Patch for BUG13641115 Tue Jan 31 11:19:13 IST 2012\nWebLogic Server 
Temporary Patch for BUG13603813 Wed Feb 15 19:34:13 IST 2012\nWebLogic Server 
Temporary Patch for 13424251 Mon Jan 30 14:32:34 IST 2012\nWebLogic Server 
Temporary Patch for 13361720 Mon Jan 30 15:24:05 IST 2012\nWebLogic Server 
Temporary Patch for BUG13421471 Wed Feb 01 11:24:18 IST 2012\nWebLogic Server 
Temporary Patch for BUG13657792 Thu Feb 23 12:57:33 IST 2012\nWebLogic Server 
12.1.1.0  Wed Dec 7 08:40:57 PST 2011 1445491 ","openSocketsCurrentCount":1,
"heapSizeCurrent":530186240,"heapFreeCurrent":
486465744,"heapSizeMax":530186240,"javaVersion":"1.6.0_33","oSName":"Mac OS X",
"oSVersion":"10.7.4"}},"messages":[]}
Code Listing 9 - Check Application Information - Python Script (using medrec application)
(markito@luke)$ ./WLSRESTPy.py -h http://localhost:7001 -a medrec -u weblogic -p
Password: 
{"body":{"item":{"name":"medrec","type":"ear","state":"STATE_NEW",
"targetStates":[{"target":"myCluster","state":"STATE_NEW"},
{"target":"AdminServer","state":"STATE_FAILED"}],"dataSources":[],
"workManagers":[],"minThreadsConstraints":[],"maxThreadsConstraints":[],
"requestClasses":[]}},"messages":[]}

JavaFX Client

Some people still consider JavaFX a new or experimental technology. But since Sun Microsystems released JavaFX in 2007, the idea of a powerful technology that can enable rich clients in cellphones, TVs, in car systems, browsers, and other devices, has become very important and more widely accepted. JavaFX can be used to create complex applications with several aspects. In this next section, however, we're going to build a simple monitoring tool for Oracle WebLogic that will consume the RESTful Management services. If you are new to JavaFX and want to take a quick look at what's going on, see the Ensemble application example in the JavaFX 2 Sample Showcase.

While the basics of JavaFX are beyond the scope of this article, the Oracle WebLogic JavaFX Monitor example will be explained below, with a focus on the main components.

REST Client

The client is created based on the Jersey's com.sun.jersey.api.client.Client and com.sun.jersey.api.client.WebResource classes and process authentication for requests against Oracle WebLogic's Security Realm. For the sake of simplicity, we'll deal only with JSON requests on the application, but the same client could easily return XML or HTML with little modification.

Code Listing 10 - Java REST Client
// code with some parts ommited
public class WLSClient {
…

    public final void initClient() {
        final Client client = Client.create();
        client.addFilter(new HTTPBasicAuthFilter(getUsername(), getPassword()));
        this.webResource = client.resource(getEndpoint());
    }
… 
    public ClientResponse getCall(final String uriPath) {

        if (webResource == null) {
            initClient();
        }

        final ClientResponse response = 
		 webResource.path(uriPath).accept(MEDIA_TYPE).get(ClientResponse.class);

        return response;
    }
…

Commands

Now that we can call the REST Management Services and perform authentication, there are a few classes that it is possible to monitor, one for each type of resource. The process follows the Command design pattern. Depending on the client, it is possible to call these classes from different Threads. All commands implement the java.util.concurrent.Callable interface, which represents a Task that returns a result and can throw an exception. There is also a method to parse the results from the REST call and put them into a java.util.Map object using the org.codehaus.jackson.map.ObjectMapper class from Jackson JSON library. This is the default behavior for all commands in this example.

Code Listing 11 - Abstract class that bases other commands in the application
// code with some parts omitted
public abstract class AbstractCommand implements Callable<Map> {
…
    protected AbstractCommand(WLSClient client) {
        this.client = client;
        this.mapper = new ObjectMapper();
    }
… 
    public Map parseResults(final String jsonResponse) throws JSONException,
	 IOException {

        Map
Code Listing 12 - Example of command class that can monitor Oracle WebLogic Server information
// imports omitted -
public class ServerCommand extends AbstractCommand {

    private String server;

    public ServerCommand(WLSClient client, String server) {
        super(client);
        this.server = server;
    }

    public Map getServerInfo() throws WebApplicationException, JSONException,
	 IOException {
        setCommandPath("/servers/" + ((server != null) ? server : ""));

        Map

The commands are easily converted into javafx.concurrent.Services or javafx.concurrent.Tasks, which encapsulate the work on background threads, while keeping the UI Thread (JavaFX Application Thread) free to process new user events.

Other Application Components

The other components of the application will not be described in detail here, since the focus of the article is the REST Management Services, but the complete source code is available for evaluation: WLSMonitor.zip.

A brief overview of these components:

  • GUI - The Graphical User Interface (GUI) was created used JavaFX Scene Tool (available here) There are couple ways to create your UI using JavaFX. This article uses an FXML file and a Java class as a Controller for GUI actions.
oliveira-wls-rest-javafx-fig05
Figure 5: JavaFX Scene Tool - Designing JavaFX applications
  • WorkManager - In order to group the Threads and provide better isolation of the service request execution, an ExecutorService is used and shared between the multiple calls to the commands.

The result can be seen in the screenshots below:

oliveira-wls-rest-javafx-fig06
Figure 6: WLSFXMonitor - Configuration settings
oliveira-wls-rest-javafx-fig07
Figure 7: WLSFXMonitor - Result Tabs and History
oliveira-wls-rest-javafx-fig08
Figure 8: WLSFXMonitor - Server Health information

Conclusion

Oracle WebLogic 12c aggregates more functionality in several aspects of the application server, including like RESTful Management Services and other modern monitoring APIs.

Providing RESTful access to APIs is a great way to offer more possibilities to application developers and system administrators to use different tools and programming languages to collect important information. With this concept in mind, and modern approaches with JavaFX and other rich-media alternatives, you can create simple but very useful applications for Application Server monitoring that can run on web browsers or as stand-alone clients.

References

About the Author

William Markito Oliveira is a Senior Technologist with the Oracle Platform Technology Solutions team in Brazil where he focuses in Middleware, SOA and Java technologies. He is also member of the official Java EE Tutorial providing write-ups and code examples for CDI, EJB 3.1 and JAX-RS.