vADC Docs

PyRunner.jar: Running Python code in Stingray Traffic Manager

by on ‎04-18-2013 10:47 AM - edited on ‎07-06-2015 02:56 PM by PaulWallace (2,213 Views)

For a comprehensive description of how this Stingray Java Extension operates, check out Yvan Seth's excellent article Making Stingray more RAD with Jython!

 

Overview

 

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.

 

Requirements

 

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!

 

A simple 'HelloWorld' example

 

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.

 

More sophisticated Python examples

 

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:

 

  • Install Jython in a known location, such as /usr/local/jython - make sure to install all components (option 1 in the installation types) or explicitly add the src part
  • Navigate to Catalogs > Java > PyRunner and add a parameter named python_home, set to /usr/local/jython (or other location as appropriate)
  • In Catalogs > Java, delete the WEB-INF files generated previously - they won't be required any more
  • From the System > Traffic Managers page, restart your Java runner.

 

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.

 

Rapid test and development

 

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

Contributors