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