For a comprehensive description of how this Stingray Java Extension operates, check out Yvan Seth's excellent article Making Stingray more RAD with Jython!
Stingray can invoke TrafficScript rules (see Feature Brief: TrafficScript) against requests and responses, and these rules run directly in the traffic manager kernel as high-performance bytecode.
A TrafficScript rule can also reach out to the local JVM to run servlets (Feature Brief: Java Extensions in Stingray Traffic Manager), and the PyRunner.jar library uses the JVM to run Python code against network traffic. This is a great solution if you need to deploy complex traffic management policies and your development expertise lies with Python.
Download and install Jython (http://www.jython.org/downloads.html). This code was developed against Jython 2.5.3, but should run against other Jython versions. For best compatibility across platforms, use the Jython installer from www.jython.org rather than the jython packages distributed by your OS vendor:
$ java -jar jython_installer-2.5.2.jar --console
Select installation option 1 (all components) or explicitly include the src part - this installs additional modules in extlibs that we will use later.
Locate the jython.jar file included in the install and upload this file to your Stingray Java Extensions catalog.
Download the PyRunner.jar file attached to this document and upload that to your Java Extensions catalog. Alternatively, you can compile the Jar file from source:
$ javac -cp servlet.jar:zxtm-servlet.jar:jython.jar PyRunner.java
$ jar -cvf PyRunner.jar PyRunner*.class
You can now run simple Python applications directly from TrafficScript!
Save the following Python code as Hello.py and upload the file to your Catalog > Extra Files catalog:
from javax.servlet.http import HttpServlet import time class Hello(HttpServlet): def doGet(self, request, response): toClient = response.getWriter() response.setContentType ("text/html") toClient.println("<html><head><title>Hello World</title>" + "<body><h1 style='color:red;'>Hello World</h1>" + "The current time is " + time.strftime('%X %x %Z') + "</body></html>")
Assign the following TrafficScript request rule to your Virtual Server:
java.run( "PyRunner", "Hello.py" );
Now, whenever the TrafficScript rule is called, it will run the Hello.py code. The PyRunner extension loads and compiles the Python code, and caches the compiled bytecode to optimize performance.
The PyRunner.jar/jython.jar combination is capable of running simple Python examples, but it does not have access to the full set of Python core libraries. These are to be found in additional jar files in the extlibs part of the Jython installation.
If you install Jython on the same machine you are running the Stingray software on, then you can point PyRunner.jar at that location:
You can install jython in this way on the Stingray Virtual Appliance, but please take be aware that the installation will not be preserved during a major upgrade, and it will not form part of the supported configuration of the virtual appliance.
Here's an updated version of Hello.py that uses the Python and Java md5 implementations to compare md5s for the string 'foo' (they should give the same result!):
from javax.servlet.http import HttpServlet from java.security import MessageDigest from md5 import md5 import time class Hello(HttpServlet): def doGet(self, request, response): toClient = response.getWriter() response.setContentType ("text/html") htmlOut = "<html><head><title>Hello World</title><body>" htmlOut += "<h1>Hello World</h1>" htmlOut += "The current time is " + time.strftime('%X %x %Z') + "<br/>" # try a Python md5 htmlOut += "Python MD5 of 'foo': %s<br/>" % md5("foo").hexdigest() # try a Java md5 htmlOut += "Java MD5 of 'foo': " jmd5 = MessageDigest.getInstance("MD5") digest = jmd5.digest("foo") for byte in digest: htmlOut += "%02x" % (byte & 0xFF) htmlOut += "<br/>" # yes, the Stingray attributes are available htmlOut += "Virtual Server: %s<br/>" % request.getAttribute("virtualserver") # 'args' is the parameter list for java.run(), beginning with the script name htmlOut += "Args: %s<br/>" % ", ".join(request.getAttribute("args")) htmlOut += "</body></html>" toClient.println(htmlOut)
Upload this file to your Extra catalog to replace the existing Hello.py script and try it out.
Check out publish.py - a simple python script that automates the task of uploading your python code to the Extra Files catalog: Deploying Python code to Stingray Traffic Manager