Quantcast
Channel: The definitive Pythonmeister » Python
Viewing all articles
Browse latest Browse all 2

Getting the maximum out of UC4 with [JP]ython: Part 1, Say hello to the UC4 Application API

$
0
0

UC4 offers the so called Application API, a collection of Java classes to interact with the scheduler.
It is also the base for there own UI and some other components, but separatly made available.
To be able to work with the system, you need these steps:

1. Open a connection
This is done with the class com.uc4.communication.Connection and connects you to the CP of your choice.
2. Login to a client
This is done with the login() method of the connection object from step 1, and gives you a session (which you see in the system overview).
3. Create one or more request objects and send them to the UC4 system
There are many different request objects (all under com.uc4.communication.requests); create on of them and hand it over to the UC4 system with con.sendRequestAndWait().
If all went well, your request object will be populated with the requested information.
Depending on the sort of request (create a object, query users) you might need to do much more and refer to the results from earlier requests.
4. Close the connection
This is the close() method of your connection object.

To give you an idea, below is a Java example which connects to the system and queries the agents available in the client and prints some information about them:

// this might serve as Hello, World! for UC4 Application API in Java
import java.util.Iterator;
import gnu.getopt.Getopt;
import com.uc4.communication.Connection;
import com.uc4.communication.ConnectionAttributes;
import com.uc4.communication.requests.CreateSession;
import com.uc4.communication.requests.AgentList;
import com.uc4.api.systemoverview.AgentListItem;

public class UC4AgentLicenseReport {
    public static void main(String[] args) {
        // we need these later
        String server = "";
        int port = 2217;
        String user = "";
        String workgroup = "";
        String password = "";
        int client = 0;
        String system ="";
        Getopt g = new Getopt("uc4agentlicrep",args,"s:p:u:w:P:c:");
        int c;
        while((c = g.getopt()) != -1) {
            switch(c) {
                case 's':
                    server = g.getOptarg();
                    break;
                case 'p':
                    port = Integer.parseInt(g.getOptarg());
                    break;
                case 'u':
                    user = g.getOptarg();
                    break;
                case 'w':
                    workgroup = g.getOptarg();
                    break;
                case 'P':
                    password = g.getOptarg();
                    break;
                case 'c':
                    client = Integer.parseInt(g.getOptarg());
                    break;
                default:
                    System.err.println("Command line option not supported");
                    System.exit(1);
            }
        }
        // command line parameters are correctly parsed
        try {
            // connect to UC4 CP
            Connection con = Connection.open(server, port);
            // login to client
            CreateSession session = con.login(client, user, workgroup, password, 'E');
            // if we are logged in, get session id
            if(session.isLoginSuccessful()) {
                ConnectionAttributes attr = con.getSessionInfo();
                System.out.println("Connected to " + attr.getSystemName() + ", Session " + attr.getSessionId());
                system = attr.getSystemName();
            }
            // create XML request for a list of agents
            AgentList agents = new AgentList(); 
            // send request to UC4 system
            con.sendRequestAndWait(agents);
            // if error message returned, we stop here and exit
            if(agents.getMessageBox() != null) {
                System.err.println("Could not get list of UC4 agents: " + agents.getMessageBox());
                con.close();
                System.exit(1);
            } 
            // iterate over agent list
            Iterator<AgentListItem> it = agents.iterator();
            AgentListItem agent;
            while(it.hasNext()) {
                agent = it.next();
                System.out.println( system +";"+
                                    agent.getName() +";"+ 
                                    agent.getSoftware() +";"+ 
                                    agent.getSoftwareVersion() +";"+ 
                                    agent.getLicenseCategory() +";"+ 
                                    agent.getLicenseClass());
            }
            // we are finished, close
            con.close();
        } 
        catch (java.io.IOException e){
            System.err.println("Could not connect to " + server + " " + port);
            System.exit(1);
        }
    }
}

As I promised earlier, it is also possible to use the API with Jython.
Here is the same identical program as a Jython script:

# this might serve as Hello, World! for UC4 Application API in Jython
import sys
import os
import getopt
sys.path.insert(0,'uc4.jar')
try:
	from com.uc4.communication import Connection,ConnectionAttributes
	from com.uc4.communication.requests import CreateSession,AgentList
	from com.uc4.api.systemoverview import AgentListItem
except ImportError,e:
	print >>sys.stderr,"Could not load UC4 classes"
	os._exit(1)

if __name__=='__main__':
        server, port, user, workgroup, password, client, system = "", 2217, "", "", "", 0, ""
        try:
            opts,args = getopt.getopt(sys.argv[1:],'s:p:u:w:P:c:')
            for o,a in opts:
                if o == '-s':
                    server = a.strip()
                elif o == '-p':
                    port = int(a.strip())
                elif o == '-u':
                    user = a.strip()
                elif o == '-w':
                    workgroup = a.strip()
                elif o == '-P':
                    password = a.strip()
                elif o == '-c':
                    client = int(a.strip())
                else:
                    print >>sys.stderr,"Unknown switch '%s'" % o
                    os._exit(1)
        except Exception,e:
            print >>sys.stderr,"Error while parsing command line arguments:" + str(e)
            os._exit(1)
        try:
            # connect to UC4 CP
            con = Connection.open(server, port)
            # login to client
            session = con.login(client, user, workgroup, password, 'E')
            # if we are logged in, get session id
            if session.isLoginSuccessful():
                attr = con.getSessionInfo()
                system = attr.getSystemName()
                print "Connected to %s, Session %s" % (system, attr.getSessionId())
            else:
                print >>sys.stderr,"Could not login"
                con.close()
                os._exit(1)
            # create XML request for a list of agents
            agents = AgentList()
            # send request to UC4 system
            con.sendRequestAndWait(agents)
            # if error message returned, we stop here and exit
            if agents.getMessageBox():
                print >>sys.stderr,"Could not get list of UC4 agents: %s" % agents.getMessageBox()
                con.close()
                os._exit(1)
            for agent in agents.iterator():
                print "%s;%s;%s;%s;%s;%s" % (system, 
                                                agent.getName(),
                                                agent.getSoftware(),
                                                agent.getSoftwareVersion(),
                                                agent.getLicenseCategory(),
                                                agent.getLicenseClass())
            # we are finished, close
            con.close()
        except Exception,e:
            print >>sys.stderr,"Something went wrong: %s" % str(e)
            os._exit(1)

You might say now, that 19 lines less code for a dynamic language is not that much - compared to the first version in Java.
That is right, but let me highlight a few things:

1. The turnaround cycle gets faster
You can even start a interactive Jython session and do something on the fly.

2. Some things a bit easier to write and read
Java:

Iterator<AgentListItem> it = agents.iterator();
            AgentListItem agent;
            while(it.hasNext()) {
                agent = it.next();
                System.out.println( system +";"+
                                    agent.getName() +";"+ 
                                    agent.getSoftware() +";"+ 
                                    agent.getSoftwareVersion() +";"+ 
                                    agent.getLicenseCategory() +";"+ 
                                    agent.getLicenseClass());
            }

Jython:

for agent in agents.iterator():
                print "%s;%s;%s;%s;%s;%s" % (system, 
                                                agent.getName(),
                                                agent.getSoftware(),
                                                agent.getSoftwareVersion(),
                                                agent.getLicenseCategory(),
                                                agent.getLicenseClass())

The magic of casting, un-/boxing is done behind the scenes.

3. It just works ™
You now have a choice.
Some parts are in UC4 internally scripted with Groovy, which is another JSR 223 script engine provider.
It is a lot like Python, but I do prefer Python, just because I know best.

4. It is a bit slower
Yes, the startup of the program takes more time. The Java version, once compiled, runs instantly.
The Jython version takes about 2 sec to start.
Once started, the difference is neglectable.
And you should definitely use a Java 7 runtime.

5. Line count difference gets bigger
The bigger the program, the more you benefit from dynamic languages in terms of lines of code, because you don't need to keep track of type, do casts etc.

6. Python programs are usually easier to write
Not for professional programmers, but perhaps for UC4 administrators in the need to get a task done,
which would otherwise require really nasty workarounds.
If you know UC4.Script and perhaps some other scripting language like Ruby, Lua, Perl or PowerShell you
should get the basic knowledge in couple of days.

So much for this part 1.
Next time, we'll do real things ;-)

Update:

- for the Java program to work, you will need the GNU getopt Java port.
- I used the latest available jython beta.
- I forgot to write how to start the jython script (named uc4agentreport.py), with uc4.jar in the same directory:

java -cp . -jar jython-standalone-2.7-b1.jar uc4agentreport.py -s server -p 2217 -u username -w workgroup -P password -c client


Viewing all articles
Browse latest Browse all 2

Trending Articles