Infrastructure at your Service

As stated in Oracle’s documentation, the WebLogic Scripting Tool, or wlst for short, can be extended by adding functions in 2 non mutually exclusive places:

  1. any file located in $WL_HOME/common/wlst
  2. any file located in $WL_HOME/common/wlst/lib/

Files must have the .py extension and will be automatically loaded by wlst when it starts.
In the first alternative, the script files will be included in the current wlst session’s namespace and can directly be invoked by their name. In the second alternative, they will be imported into their own namespace, which is the name of the file without the extension, and need to be prefixed with it when invoked.

Customizations consist in writting jython functions. Depending on the version of WebLogic in use, wlst is based on jython 2.2.1 (up to WebLogic 12.2.x) or jython 2.7.1 (from WebLogic 14.4.1 onwards), the latter being the final 2.x jython release, with a version 3.x on the drawing board. As you can see, jython lags considerably behind python which is currently at release 3.9.5 with 3.10 due later this year. However, jython is largely suitable for the usual administrative tasks in WebLogic, and one should not forget that java is not far away for those more demanding tasks.

One thing that is particularly boring with wlst is that all the commands are jython’s functions that get invoked; this is why one needs to include the () suffix, which is the function call operator. When one would like to type cd /AdminConsole (like in the wlshell of yore, or in the bash shell), one must type cd(‘/AdminConsole’) instead, with parentheses and quotes, pretty clumsy.
OK, but what about print ? In jython 2.x, print is still a statement like if, def, for, etc, and not a function yet. It’ll become one starting in jython 3.x, just like in python, and its syntax will change accordingly for the best or the worse.
In order to suppress the function call operator (), the language itself would need to be modified to introduce new statements in the grammar. Needless to say, this is a bit too geeky for a blog like this.

A few examples

In order to demonstrate the customization, I’ll propose to start with a few very trivial yet useful functions:

def show_output(on_or_off = True):
   """
Enable (on_or_off == True) or disable (on_or_off == False) the output on the terminal;
Note that only the output from java is disabled, i.e. for all the wlst's predefined commands, not the jython's print statement;
   """
   global saved_out
   if on_or_off:
      stopRedirect()
   else:
      redirect('/dev/null', 'false')

def ch():
   """
change the current directory to /;
   """
   cd('/')

def lc(path = None):
   """
list the mbeans and their properties from the optional path or from the current directory is path is omitted;
   """
   ls('c', path)

def la(path = None):
   """
list only the mbeans' properties from the optional path or from the current directory is path is omitted;
   """
   ls('a', path)

def lo(path = None):
   """
list only the mbeans from the optional path or from the current directory is path is omitted;
   """
   ls('o', path)

def ll(path = None):
   """
same as lc(), only more natural as it matches the Unix ls -l command;
   """
   ls(path)

def lh():
   """
same as ls() but for the hierarchy's root;
   """
   ls('/')

def lch(path = '/'):
   """
same as lc() but the default path is the hierarchy's root instead of the current directory;
   """
   ls('c', path)

def lah(path = '/'):
   """
same as la() but the default path is the hierarchy's root instead of the current directory;
   """
   ls('a', path)

def loh(path = '/'):
   """
same as lo() but the default path is the hierarchy's root instead of the current directory;
   """
   ls('o', path)

def llh(path = '/'):
   """
same as ll() but the default path is the hierarchy's root instead of the current directory;
   """
   ls(path)

def ld(path = None):
   """
An attempt at reducing the output on the terminal like when using the * wildcard;
behaves like lc() if no path is given, otherwise ls() all the mbeans that start with path, i.e. functionally ls('*' + path + '*');
   """
   if path == None:
      lc()
   else:
      try:
         show_output(False)
         for d in ls('c').split('\n'):
            if d[7 :].find(path) > -1: print d
      finally:
         # make sure the output is restored;
         show_output(True)

current_path = []
def push(path):
   """
move to directory path after having saved the current one on the stack;
similar to Linux push command;
   """
   global current_path
   current_path.append(pwd())
   cd(path)

def pop():
   """
move back to the preceding directory on top of the stack;
silently ignore the command if already at the top;
   """
   try:
      cd(current_path.pop())
   except:
      pass

def b():
   """
move one level up the mbean hierarchy;
   """
   cd('..')

def conn():
   """
connect to the local administation server on the canonical port;
useful when developing and the cleartext password is not a problem;
   """
   connect('weblogic', 'welcome1', 't3://localhost:7001')

Function show_output() defined on line 1 is for internal use only as it does not make much sense when interacting in wlst.
Function names are quite mnenonic, e.g. ch() for change to home directory, lc() for ls(‘c’), ll() like in Unix ls -l (i.e. full listing, same as ls(‘c’), lh() for ls(‘/’), and so on with the l*h() functions where the default path is home ‘/’.
ld() is more interesting in that it attempts at simulating the * wildcard, which is not supported in wlst. When the optional path is given, it lists all the directories that contain path, just like if one had typed ‘ls -l *<path>*’, examples:

wls:/webcenter/serverConfig/> ls()
dr--   AdminConsole
...
dr--   JDBCStores
dr--   JDBCSystemResources
dr--   JMSBridgeDestinations
dr--   JMSInteropModules
dr--   JMSServers
dr--   JMSSystemResources
...
dr--   ManagedExecutorServiceTemplates
dr--   ManagedExecutorServices
dr--   ManagedScheduledExecutorServiceTemplates
...
dr--   ManagedThreadFactories
dr--   ManagedThreadFactoryTemplates
...
dr--   ResourceGroupTemplates
...
dr--   ServerTemplates
...
-r--   AdminServerName                              AdminServer
...
-r--   MaxConcurrentNewThreads                      50
...

# list all the entries that contain Thread;
wls:/webcenter/serverConfig/> ld('Thread')
dr--   ManagedThreadFactories   
dr--   ManagedThreadFactoryTemplates    
-r--   MaxConcurrentNewThreads                      50   

# list all the entries that contain Template;
wls:/webcenter/serverConfig/> ld('Template')
dr--   ManagedExecutorServiceTemplates   
dr--   ManagedScheduledExecutorServiceTemplates   
dr--   ManagedThreadFactoryTemplates   
dr--   ResourceGroupTemplates   
dr--   ServerTemplates   

One can easily imagine to add support for much more sophisticated wildcards here if need be.

A more complex customization example

In A web-based MBean Navigator for Oracle WebLogic wlst, I presented an utility that wraps wlst’s navigation commands’output into an HTML page for visualization in a browser, with optional recursion. The job was done by essentially 2 functions: list_dir() and sweep_dir(). Let’s make them available to wlst as well.

trees = ['custom', 'domainConfig', 'domainCustom', 'domainRuntime', 'edit', 'editCustom', 'jndi', 'runtime', 'serverConfig', 'serverRuntime']
 
def clean_mbean_name(mbean_name):
   """
remove the [....] part of the mbean name;
   """
   mbean_name = str(mbean_name)
   return mbean_name[mbean_name.find(']') + 1 :]
 
import traceback
def list_dir(path = None, show_output = True):
   """
   return a list of dictionaries, one for each  entries in directory path, e.g.:
      [
         {'is_directory': True, 'name': u'mydomain', 'value': None, 'path_name': '/AdminConsole/', 'value': '....' | None, 'mbean_name': '....' | None}
         ...
      ]
   if the optional path is omitted, it defaults to the current directory;
   """
   entries = []
   saved_path = pwd()
   if path != None:
      try:
         cd(path)
         path = pwd()
      except:
         dumpStack()
         traceback.print_exc()

      # remove the drive part from the path, i.e. the active tree name;
      for t in trees:
         if 0 == path.find(t + ':'):
            path = path[path.find(':') + 1:]
            break
   else:
      path = pwd()
 
   # remove the drive part from the path, i.e. the active tree name;
   for t in trees:
      if 0 == path.find(t + ':'):
         path = path[path.find(':') + 1:]
         break
 
   print(path)
   current_mbean = clean_mbean_name(getMBean(path))
   try:
      cd(path)
      for p in ls().split('\n'):
         if not p:
            continue
         p = p.strip()
         if "" == p:
            continue
         if p[0] not in ("d", "-"):
            # continuation of previous value;
            entries[-1]['value'] += p
            continue
         if 'd' == p[0]:
            entry = {'is_directory': True, 'path_name': path, 'name': p[7:], 'value': None}
            entry['mbean_name'] = clean_mbean_name(getMBean(path + ('/' if '/' != path else '') + entry['name']))
         elif -1 == p.find(' ', 7):
            entry = {'is_directory': False, 'path_name': path, 'name': p[7:], 'value': None, 'mbean_name': None}
         else:
            entry = {'is_directory': False, 'path_name': path, 'name': p[7:p.find(' ', 7)], 'value': p[p.find(' ', 7):].strip(), 'mbean_name': None}
         entries.append(entry)
 
         if entry['is_directory']:
            current_mbean = clean_mbean_name(getMBean(path + "/" + entry['name']))
   except:
      dumpStack()
      traceback.print_exc()
 
   cd(saved_path)
   return (entries, path)
  
# needed because we need the set() constructor but it is overriden by wlst;
import __builtin__
def sweep_dir(path, (cumul, visited) = (None, None)):
   """
   recursively, breadth-first lists path content and return a list of raw entries;
   path is a clean path string, e.g. /AdminServer;
   an attempt at preventing infinite recursion is done but there is a risk that some entries are missed;
   """
   if (cumul, visited) == (None, None):
      (cumul, visited) = ([],  __builtin__.set())
   try:
      temp_ls, path = list_dir(path) #, False)
   except:
      print('exception in sweep_dir()')
      dumpStack()
      traceback.print_exc()
      print(404, "error while listing directory " + path + ", ignoring request ...")
      return None
 
   current_mbean = clean_mbean_name(getMBean(path))
 
   # display attributes first so they are grouped together right below their parent directory;
   try:
      for p in temp_ls:
         if p['is_directory']:
            continue
         cumul.append(p)
 
      # display the sub-directories now;
      for p in temp_ls:
         if not p['is_directory']:
            continue
         cumul.append(p)
    
         for p in temp_ls:
            if p['is_directory']:
               if p['mbean_name'] != current_mbean and p['mbean_name'] in visited:
                  print('(' + p['name'] + ')')
                  continue
               else:
                  visited.add(p['mbean_name'])
                  sweep_dir(path + ('/' if '/' != path[-1] else '') + p['name'], (cumul, visited))
   except:
      dumpStack()
      traceback.print_exc()
   return cumul

def lsR(path):
   """
wrapper around sweep_dir() with a more familiar name similar to the Unix command ls -R;
   """
   start_time = System.currentTimeMillis()
   result = sweep_dir(path)
   end_time = System.currentTimeMillis()
   print("%10.1f seconds elapsed" % ((end_time - start_time)/1000))
   return result

Line 1 defines the different hierachies, or trees, it is possible to navigate in. By just typing “trees” in wlst, one can display that list and subsequently move through the trees by calling the eponym function, e.g.:

# display the trees;
wls:/webcenter/serverConfig/> trees
['custom', 'domainConfig', 'domainCustom', 'domainRuntime', 'edit', 'editCustom', 'jndi', 'runtime', 'serverConfig', 'serverRuntime']

# move to the jndi hierarchy;
wls:/webcenter/serverConfig/> jndi()
Location changed to jndi tree. This is a read-only tree with No root. 
For more help, use help('jndi')

# move to the runtime tree;
wls:/webcenter/jndi/> runtime()
Cannot change to "runtime" tree because the compatibility MBeanServer is no longer supported.

# in effect, it is obsoleted starting in 14.x;
# use serverRuntime() insteed;
wls:/webcenter/jndi/> serverRuntime()

# back to the default serverConfig tree;
wls:/webcenter/serverRuntime/> serverConfig()

Both list_dir() and sweep_dir() can be called directly and output wlst’s ls() result invoked on line 47. However, the latter has a wrapper, lsR() defined on line 122, that adds timing info. Typically, such things are done more pythonically with reusable decorators but this is the only place where it would be used so let’s keep things simple.
In addition, both functions returns the directory entries in a list of dictionaries, which can be further processed interactively in the wlst shell.
Here is an example:

# in wlst;
wls:/webcenter/serverConfig/> a = lsR('CoherenceClusterSystemResources')
/CoherenceClusterSystemResources
dr--   defaultCoherenceCluster

/CoherenceClusterSystemResources/defaultCoherenceCluster
dr--   CoherenceCacheConfigs
dr--   CoherenceClusterResource
dr--   Resource
dr--   SubDeployments
dr--   Targets

-r--   CompatibilityName                            null
-r--   CustomClusterConfigurationFileName           null
-r--   DeploymentOrder                              100
...
...
/CoherenceClusterSystemResources/defaultCoherenceCluster/Targets
dr--   IBR_server1
dr--   UCM_server1
dr--   WC_Portal

(IBR_server1)
(UCM_server1)
(WC_Portal)
(IBR_server1)
(UCM_server1)
(WC_Portal)
(IBR_server1)
(UCM_server1)
(WC_Portal)
     102.0 seconds elapsed

# where parenthesized entries mean that they have already been visited earlier;
# display a;
wls:/webcenter/serverConfig/> a
[{'is_directory': True, 'mbean_name': 'com.bea:Name=defaultCoherenceCluster,Type=CoherenceClusterSystemResource', 'name': u'defaultCoherenceCluster', 'value': None,
 'path_name': u'/CoherenceClusterSystemResources'}, {'is_directory': False, 'mbean_name': None, 'name': u'CompatibilityName', 'value': u'null', 'path_name':
 u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'CustomClusterConfigurationFileName', 'value': u'null',
 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'DeploymentOrder', 'value': u'100', 
'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'DeploymentPrincipalName', 'value': u'null', 
'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'DescriptorFileName', 'value': 
u'coherence/defaultCoherenceCluster-coherence.xml', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 
'name': u'DynamicallyCreated', 'value': u'false', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': 
u'Id', 'value': u'0', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'ModuleType', 'value': 
u'null', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'Name', 'value': 
u'defaultCoherenceCluster', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'Notes', 'value': 
u'null', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'ReportGroupFile', 'value': 
u'em/metadata/reports/coherence/report-group.xml', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 
'name': u'SourcePath', 'value': u'./config/coherence/defaultCoherenceCluster-coherence.xml', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, 
{'is_directory': False, 'mbean_name': None, 'name': u'Tags', 'value': u'null', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': 
False, 'mbean_name': None, 'name': u'Type', 'value': u'CoherenceClusterSystemResource', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, 
{'is_directory': False, 'mbean_name': None, 'name': u'UsingCustomClusterConfigurationFile', 'value': u'false', 'path_name': u'/CoherenceClusterSystemResources
/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'freezeCurrentValue', 'value': u'Void : String(attributeName)', 'path_name': 
u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'getInheritedProperties', 'value': u'String[] : String[]
(propertyNames)', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': 
u'importCustomClusterConfigurationFile', 'value': u'Void : String(file)', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': False, 
'mbean_name': None, 'name': u'isInherited', 'value': u'Boolean : String(propertyName)', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, 
{'is_directory': False, 'mbean_name': None, 'name': u'isSet', 'value': u'Boolean : String(propertyName)', 'path_name': u'/CoherenceClusterSystemResources
defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'unSet', 'value': u'Void : String(propertyName)', 'path_name': 
u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': True, 'mbean_name': 'com.bea:Name=defaultCoherenceCluster,Type=CoherenceClusterSystemResource', 
'name': u'CoherenceCacheConfigs', 'value': None, 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster'}, {'is_directory': True, 'mbean_name': 
'com.bea:Name=defaultCoherenceCluster,Type=weblogic.coherence.descriptor.wl.WeblogicCoherenceBean,Parent=
[webcenter]/CoherenceClusterSystemResources[defaultCoherenceCluster],Path=CoherenceClusterResource[defaultCoherenceCluster]', 'name': u'defaultCoherenceCluster', 'value': None, 
'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource'}, {'is_directory': False, 'mbean_name': None, 'name': 
u'CustomClusterConfigurationFileLastUpdatedTimestamp', 'value': u'0', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource
/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'CustomClusterConfigurationFileName', 'value': u'null', 'path_name': 
u'/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'Name', 
'value': u'defaultCoherenceCluster', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster'}, 
{'is_directory': False, 'mbean_name': None, 'name': u'Version', 'value': u'null', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster
/CoherenceClusterResource/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'isSet', 'value': u'Boolean : String(propertyName)', 'path_name': 
u'/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster'}, {'is_directory': False, 'mbean_name': None, 'name': u'unSet', 
'value': u'Void : String(propertyName)', 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster'}, 
{'is_directory': True, 'mbean_name': 'com.bea:Name=defaultCoherenceCluster,Type=weblogic.coherence.descriptor.wl.WeblogicCoherenceBean,Parent=
[webcenter]/CoherenceClusterSystemResources[defaultCoherenceCluster],Path=CoherenceClusterResource[defaultCoherenceCluster]', 'name': u'CoherenceAddressProviders', 'value': 
None, 'path_name': u'/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster'}, {'is_directory': True, 'mbean_name': 
'com.bea:Name=defaultCoherenceCluster,Type=weblogic.coherence.descriptor.wl.CoherenceAddressProvidersBean,Parent=
[webcenter]/CoherenceClusterSystemResources[defaultCoherenceCluster],Path=
...
...

# how many entries found ?
wls:/webcenter/serverConfig/> len(a)
5209

# display all the mbeans' full path;
wls:/webcenter/serverConfig/> for e in a:
...   if e['is_directory']:
...      print e['path_name'] + '/' + e['name']

/CoherenceClusterSystemResources/defaultCoherenceCluster
/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceCacheConfigs
/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster
/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster/CoherenceAddressProviders
/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster/CoherenceAddressProviders/defaultCoherenceCluster
/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster/CoherenceAddressProviders/defaultCoherenceCluster/CoherenceAddressProviders
...

# as some mbeans are referenced from several places, filter out the duplicated entries;
wls:/webcenter/serverConfig/> uniq=__builtin__.set()
wls:/webcenter/serverConfig/> for e in a:
...   if e['is_directory']:
...      uniq.add(e['path_name'] + '/' + e['name'])
...
wls:/webcenter/serverConfig/> len(uniq)
261

# show the unique mbeans entries;
wls:/webcenter/serverConfig/> uniq
set([u'/CoherenceClusterSystemResources/defaultCoherenceCluster/Targets', u'/CoherenceClusterSystemResources/defaultCoherenceCluster/Targets/IBR_server1/SingleSignOnServices',
 u'/CoherenceClusterSystemResources/defaultCoherenceCluster/Targets/WC_Portal/WebService/WC_Portal/WebServiceBuffering/WC_Portal', u'/CoherenceClusterSystemResources
/defaultCoherenceCluster/Targets/IBR_server1/DataSource/IBR_server1/Targets', u'/CoherenceClusterSystemResources/defaultCoherenceCluster/Targets/WC_Portal/WebService/WC_Portal
/WebServiceBuffering/WC_Portal/WebServiceRequestBufferingQueue', u'/CoherenceClusterSystemResources/defaultCoherenceCluster/Targets/WC_Portal/IIOP/WC_Portal', 
u'/CoherenceClusterSystemResources/defaultCoherenceCluster/Targets/IBR_server1/DefaultFileStore', u'/CoherenceClusterSystemResources/defaultCoherenceCluster/Targets/UCM_server1
/ConfigurationProperties', u'/CoherenceClusterSystemResources/defaultCoherenceCluster/Targets/IBR_server1/CoherenceMemberConfig/IBR_server1', u'/CoherenceClusterSystemResources
/defaultCoherenceCluster/Targets/WC_Portal/Cluster', u'/CoherenceClusterSystemResources/defaultCoherenceCluster/Targets/UCM_server1/XMLRegistry', 
u'/CoherenceClusterSystemResources/defaultCoherenceCluster/Targets/UCM_server1', u'/CoherenceClusterSystemResources/defaultCoherenceCluster/Targets/IBR_server1/DataSource
/IBR_server1/DataSourceLogFile', u'/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster/CoherenceClusterParams
/defaultCoherenceCluster/CoherenceServices', u'/CoherenceClusterSystemResources/defaultCoherenceCluster/Targets/WC_Portal/WebService
...
...

# nicer, sorted output;
wls:/webcenter/serverConfig/> for e in sorted(uniq):
... print e
...
/CoherenceClusterSystemResources/defaultCoherenceCluster
/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceCacheConfigs
/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource
/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster
/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster/CoherenceAddressProviders
/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster/CoherenceAddressProviders/defaultCoherenceCluster
/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster/CoherenceAddressProviders/defaultCoherenceCluster/CoherenceAddressProviders
/CoherenceClusterSystemResources/defaultCoherenceCluster/CoherenceClusterResource/defaultCoherenceCluster/CoherenceClusterParams
...

# etc...

All that interactive work can be done without re-scanning the tree, a valuable time saving.

Conclusion

It is very easy to build oneself a list of frequently used functions that can be loaded each time wlst starts. As they can be written in jython using the wlst command-line API, those customizations can be as sophisticated as needed. For more special cases, dedicated namespaces can be introduced in order to separate different implementations of the same functions, e.g. by domains. I hope you enjoyed this article and that it will be useful to you.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Cesare Cervini
Cesare Cervini

Consultant