The Hunger Site

Friday, July 26, 2013

Oracle Enterprise Manager 12c Release 3: What’s New in EMCLI


If you have been using the classic Oracle Enterprise Manager Command Line interface ( EMCLI ), you are in for a treat. Oracle Enterprise Manager 12c R3 comes with a new EMCLI kit called ‘EMCLI with Scripting Option’. Not my favorite name, as I would have preferred to call this EMSHELL since it truly provides a shell similar to bash or cshell. Unlike the classic EMCLI, this new kit provides a Jython-based scripting environment along with the large collection of verbs to use. This scripting environment enables users to use established programming language constructs like loops (for, or while), conditional statements (if-else), etc in both interactive and scripting mode.

Benefits of ‘EMCLI with Scripting Option’

Some of the key benefits of the new EMCLI are:
  • Jython based scripting environment
  • Interactive and scripting mode
  • Standardized output format using JSON
  • Can connect to any EM environment (no need to run EMCLI setup …)
  • Stateless communication with OMS (no user data is stored with the client)
  • Generic list function for EM resources
  • Ability to run user-defined SQL queries to access published repository views
Before we go any further, there are two topics that warrant some discussion – Jython and JSON.

Jython

Jython is the Java implementation of the Python programming language. I have been working with Python (or CPython) and Jython for the last 10 years, and to me it is the best scripting language ever. It is fun, easy to learn, the syntax is simple, is self formatted, and is dynamically typed. This comic from XKCD summarizes it the best:


There are numerous tutorials for Python/Jython on the web, so feel free to pick anyone you like but just remember that the Jython version supported by the new kit is v2.5.1.

JSON

JSON stands for JavaScript Object Notation. It is a data interchange format, much like XML, which is easier to read and write for both humans and machines, but unlike XML it contains very little metadata (elements and attribute names). JSON format is quite simple; it basically represents data as a collection of name/value pairs. These pairs can be contained within arrays, lists, or maps. Here is a sample:
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
JSON is quite popular. You will often find it used with REST based web services APIs or even with some modern databases like MongoDB. Most programming languages provide libraries to work with JSON.
The EMCLI kit uses JSON as its output format as well. Many of the verbs return output in JSON format for ease of programmatic use. I say many, since there are still some verbs that don’t, but this is only matter of time.
Now let’s get back to EMCLI.

Steps to setup the kit for ‘EMCLI with Scripting Option’

1. To download the new EMCLI kit, go to Setup->Command Line Interface. Here you will notice the new section for ‘EMCLI with Scripting Option’. Click on the link to download the kit to your desktop or desired server.
Download

You can also download the kit directly from the following url:
http(s)://:/em/public_lib_download/emcli/kit/emcliadvancedkit.jar
 
2. Copy the kit (emcliadvancedkit.jar) to a directory where you wish to install EMCLI
kit
3. To install, run the following command. Note that we need the Java version to be 1.6.0_43 or greater.
java -jar emcliadvancedkit.jar client -install_dir=
Verify Java version 
4. The last step to complete the setup is to run ‘sync’. Before using EMCLI you have to connect to the OMS to install all verb-related command line help. In classic EMCLI, this happens automatically when you run the ‘setup’ command. But in the new EMCLI, since we do not run setup, we run the ‘sync’ command instead.
The ‘sync’ verb now accepts some additional arguments. Run the following command:
emcli sync -url=http(s)://:/em -username= -trustall
It will prompt for the user password and then take a few minutes to download and install all the help content.
emcli sync
5. Now confirm the setup with a simple test. We do this using the interactive mode. Just run ‘emcli’, and once you see the prompt run ‘help()’. This will print list all verbs along with their description.
emcli interactive mode
With the setup complete, let’s now have some fun.

Using the ‘EMCLI with Scripting Option’

Connect to the interactive mode by running ‘emcli’ from the command prompt. Now try the following commands:
1. Basic Jython: Since EMCLI is built using the Jython interpreter, you can run Jython commands at the EMCLI prompt. For example, you can try the following:
>>1+2
>>print “Hello Jython”
>>mylist = [1,2,3]
>>print mylist
Jython test
2. EMCLI Status: Next, print the status of the EMCLI session using the ‘status()’ command.
emcli status
You will notice that the EM url and user are not set. To do this we have to set the client_properties. Run ‘help('client_properties')’ for more details.
client properties
The help text instructs us to set the client properties to connect to a specific EM environment. The 4 properties of interest to us are the following:
Name
Details
EMCLI_OMS_URL
The EM url
EMCLI_USERNAME
The EM user to connect as. We will use the login() function to set this.
EMCLI_TRUSTALL
I like to set this to true, but the default is false.
EMCLI_OUTPUT_TYPE
I like to set this to JSON even for interactive mode
To set these properties run the following:
>>set_client_property('EMCLI_OMS_URL','http(s)://:/em')
>>set_client_property('EMCLI_TRUSTALL','TRUE')
>>set_client_property('EMCLI_OUTPUT_TYPE', 'JSON')
>>login(username="",password="")
You should see the message on successful login. Now we are connected to EM.
login
3. Understanding help and verb invocations: Most of the help text presented in EMCLI is tailored towards the classic interface. Since Jython is a programming language, verb invocations are done in the function form. There is a simple mechanism for converting the classic invocation format for use in both interactive and scripting mode. Let’s use the login() verb as an example.
The EMCLI help for login is as follows:
>>help('login')
emcli login
-username=
[-password=]
[-force]
This means, when using classic EMCLI, you would invoke it as follows:
emcli login –username=”foo” –password=”bar” -force
Instead, in the interactive or script mode, the invocation would look like:
login(username="",password="",force=True)
Essentially, all verbs are now functions, and all arguments to the verb are now parameters passed to the function. Since the –force argument does not take any value, it is treated as a Boolean in Jython and takes the values of True or False.
Note: The -force parameter in the login() function is not applicable to the interactive or script mode, but is being used in this example to explain the concept of passing Boolean values. Again, you should never use the -force parameter in the interactive or script mode.
Another such conversion that you may come across is for list of values. For example,
In classic EMCLI, some verbs will ask for the same attribute to be repeated with varying values to represent a list.
emcli grant_privs -name='jan.doe' 
         -privilege="USE_ANY_BEACON"
         -privilege="FULL_TARGET;TARGET_NAME=host1.acme.com:TARGET_TYPE=host"
In interactive or script mode, you can use native Jython listes instead and pass it as parameters. In Jython, lists are represented within square brackets ([]).
>>priv_list = ['USE_ANY_BEACON','FULL_TARGET;TARGET_NAME=host1.acme.com:TARGET_TYPE=host']
>>grant_privs(name='jan.doe',privilege=priv_list)
4. Sample Use Case: Let’s take a very simple use case to demonstrate the interaction with EMCLI in the interactive mode. So our sample use case is to ‘List all targets of type oracle_database and those whose name starts with the characters ‘db’”.
For this use case, we will make use of the new generic ‘list’ verb. Traditionally, each feature in EM provided its own verbs for list, get, show, and describe. Rather than working with multiple such variants, the new generic ‘list’ verb takes a page from the REST web service specification and provides a generic action that can work against different EM resources.
To learn more about this verb, we ru:
>>help('list')
help
The help text shows us the format of this verb. Essentially, there are 3 parameters that we care about:
  • resource = the EM resource which is to be queried
  • columns = specify the different resource attributes to display
  • search = filters to narrow down the result
First, we need to know the list of resources that are supported by this verb. For this we run
>>List(‘help’)
list help
From the output, it is obvious that for our sample use case we want to query the Targets resource.
Second, we need to know which columns are supported by the Targets resource. For this, we run
>>list('help',resource="Targets")

help resourcesl

From the output, we can determine that we need the column related to target name and type. With this we have all the information we need to construct the final function call for our sample use case.
For ease of explanation, I will break down the process of determining the final function call into small incremental steps. Once you gain proficiency, you will be able to define this function in a single pass.
       1. List all targets in the EM environment. For this we run,
>>list(resource="Targets")
This command will spew a lot of text on your screen as there are likely to be numerous targets in your EM environment. So instead of listing all of them on the screen, let’s just get a count. For this, we need to understand the output format of this verb.
Any function that you run in the interactive or script mode returns an object of class Response (). The Response class has 4 key methods:
Function
Description
out()
Provides the verb execution output. The output can be text, or the JSON.
 isJson() method on the Response object can be used to determine whether the output is JSON.
error()
Provides the error text (if any) of the verb execution if there are any errors or exceptions during verb execution.
exit_code()
Provides the exit code of the verb execution. The exit code is zero for a successful execution and non-zero otherwise.
isJson()
Provides details about the type of output. It returns True if response.out() can be parsed into a JSON object.
So let’s look at a code snippet. snippet
For the first function call to list all targets in EM, we store the results into a variable called ‘all_tgts’. This variable contains the response object. ‘all_tgts.out()’ will give us the actual output. The output returned is in JSON format which automatically gets converted into a Jython dictionary (collection of name-value pairs represented by curly brackets). The output dictionary has a key name called ‘data’ which contains all search results in the form of a Jython list as its value. Finally, len() is a native Jython function which returns the number of elements in a Jython list. As seen in the output, we found 878 targets in the EM environment which is clearly not what we desire.
 2. Now we add search parameters to filter our results. We add two search filters, first the target type should be equal to oracle_database, and second the target name be like db%. You can add multiple search filters to the function call, but all these filters should be encapsulated in a Jython list. The search filter supports various operators: =, !=, >, <, >=, <=, like, null, and not null. Similar to a SQL query, you can also control which columns are to be displayed in the output.
So let’s run our final function.
>>search_filters=["TARGET_TYPE ='oracle_database'","TARGET_NAME like 'db%'"]
>>list(resource="Targets", columns="TARGET_NAME,TARGET_TYPE", search=search_filters)
The formatted output looks like this. As mentioned before it is in the form of a Jython dictionary which can be easily accessed programmatically. The value of the ‘data’ key is a Jython list that contains all search results, while the other keys provide other metadata related to the result.
{
'exceedsMaxRows': False,
'columnHeaders': ['TARGET_NAME', 'TARGET_TYPE'],
'columnLength': [256, 64],
'columnNames': ['TARGET_NAME', 'TARGET_TYPE'],
'data':


[

{'TARGET_NAME': 'db9328.acme.com', 'TARGET_TYPE': 'oracle_database'},

{'TARGET_NAME': 'db3092.acme.com', 'TARGET_TYPE': 'oracle_database'},
],
'filler': '\n\n\n'}
You must have noticed that I hardly talk about the scripting mode. This is on purpose, as I believe that interactive mode is the best interface to learn the new EMCLI. Once you master the interactive mode, converting your code snippets into a script is fairly easy. In future blog posts, I will cover scripting mode and numerous other use cases that seem like a perfect fit for the new EMCLI.
In summary, ‘EMCLI with Scripting Option’ is a new kit that is built on top of a Jython interpreter. It is much superior to the classic EMCLI, as it provides a complete programming environment with the ability to use native Jython functions and primitives. The output is presented in the JSON format which is both human and machine readable, and avoids the need for parsing text output. The client is completely stateless, which means no user data is stored with the client. This means numerous sessions can be launched from a single client, each connecting to a different EM environment, and as a different user.
I encourage you to play around with this new EMCLI kit, and post the different use cases that you found interesting and would benefit the community. You can reach me on twitter @AdeeshF.

Additional Reading:

No comments:

Disclaimer

Opinions expressed in this blog are entirely the opinions of the writers of this blog, and do not reflect the position of Oracle corporation. No responsiblity will be taken for any resulting effects if any of the instructions or notes in the blog are followed. It is at the reader's own risk and liability.

Blog Archive