This is the third article in the “Java iControl Objects” series in which I define a set of objects that implement the iControl methods in various iControl interfaces.  The previous articles covered the Pool and PoolMember interface.

For this article, I’ve decided to look at the LocalLB Rule interface where you manage the creation of iRules on your BIG-IP LTM.  For those that aren’t familiar with iRules, check out the iRules overview page and/or the iRules wiki for a description and various examples.

Prerequisites

The code in this article, relies on the iControl library for Java that can be downloaded in it’s DevCentral labs project.  If you haven’t watched it already, check out my previous article on Configuring Eclipse for iControl development with Java.

The Class

iRules at their core are essentially just a text string containing the script code with a name identifying the specific iRule.  So, the two main members defining the iRule object are the name and description.  The iControl.interfaces object is in there to define communication to the LTM and I’ve added the storage of a Java Exception for some of the classes where exceptions were caught during the processing.  That way, after the fact you can go and find out what the core problems were if some of the action methods defined below failed for any reason.

Below the member declarations, I’ve included Java-styled accessor methods along with two constructors used to create new objects.  In this example, I’ve included a constructor that takes a iControl.LocalLBRuleRuleDefinition structure as input for assistance in the getList static method defined below.

   1: package iControl.Objects.LTM;
   2:  
   3: public class iRule {
   4:   private iControl.Interfaces _interfaces = null;
   5:   private String _name = null;
   6:   private String _definition = null;
   7:   private Exception _lastException = null;
   8:   
   9:   //-----------------------------------------------------------------------
  10:   // Member Accessors
  11:   //-----------------------------------------------------------------------
  12:   public iControl.Interfaces getInterfaces() { return _interfaces; }
  13:   public void setInterfaces(iControl.Interfaces interfaces) { _interfaces = interfaces; }
  14:  
  15:   public String getName() { return _name;  }
  16:   public void setName(String value) { _name = value; }
  17:   
  18:   public String getDefinition() { return _definition;  }
  19:   public void setDefinition(String value) { _definition = value; }
  20:   
  21:   public Exception getLastException() { return _lastException; }
  22:   
  23:   //-----------------------------------------------------------------------
  24:   // Constructors
  25:   //-----------------------------------------------------------------------
  26:   public iRule(iControl.Interfaces interfaces, String name, String definition)
  27:   {
  28:     _interfaces = interfaces; 
  29:     _name = name;
  30:     _definition = definition;
  31:   }
  32:   public iRule(iControl.Interfaces interfaces, iControl.LocalLBRuleRuleDefinition rule_def)
  33:   {
  34:     _interfaces = interfaces;
  35:     _name = rule_def.getRule_name();
  36:     _definition = rule_def.getRule_definition();
  37:   }

Action Methods

In the iRule interface, there aren’t any additional accessor methods so I skipped those and went right to the action methods.  I’ve defined the following methods

  • save – Save the current iRule.  This first attempts to make a create call and if that fails, it attempts to do a modify.  This way an object can be saved whether it exists or not on the system.
  • load – Load will query the iRule definition for the specified iRule’s name. It will then populate the definition member variable with the iRule syntax.
  • checkSyntax – Not sure whether your iRule is valid syntax?  This method will create a temporary iRule and attempt to save the iRule description.  This will return an error if the syntax is invalid and the error message is stored in the lastException member.
  • delete – This will delete the iRule on the system.  It won’t delete the local variable so if you want to undo your delete, you can just issue the save command.
  • getStatistics – This will return the various performance metrics for the given iRule.  This data is valuable for debugging performance.
  • resetStatistics – This will reset the statistics counters for your iRule.
   1: public boolean save() throws Exception
   2: {
   3:   validateMembers();
   4:   clearException();
   5:   
   6:   boolean bSaved = false;
   7:   ...
   8:   return bSaved;
   9: }
  10:  
  11: public boolean load() throws Exception
  12: {
  13:   validateMembers();
  14:  
  15:   boolean bLoaded = false;
  16:   ...  
  17:   return bLoaded;
  18: }
  19:  
  20: public boolean checkSyntax() throws Exception
  21: {
  22:   clearException();
  23:   validateMembers();
  24:   
  25:   boolean bValid = false;
  26:   ...
  27:   return bValid;
  28: }
  29:  
  30: public void delete() throws Exception
  31: {
  32:   validateMembers();
  33:   
  34:   String [] rule_list = { _name };
  35:   _interfaces.getLocalLBRule().delete_rule(rule_list);
  36: }
  37:  
  38: public iControl.LocalLBRuleRuleStatisticEntry getStatistics() throws Exception
  39: {
  40:   validateMembers();
  41:   
  42:   String [] rule_list = { _name };
  43:   iControl.LocalLBRuleRuleStatistics ruleStats =
  44:     _interfaces.getLocalLBRule().get_statistics(rule_list);
  45:   
  46:   iControl.LocalLBRuleRuleStatisticEntry statsEntry =
  47:     ruleStats.getStatistics()[0];
  48:   
  49:   return statsEntry;
  50: }
  51:  
  52: public void resetStatistics() throws Exception
  53: {
  54:   validateMembers();
  55:   
  56:   String [] rule_list = { _name };
  57:   _interfaces.getLocalLBRule().reset_statistics(rule_list);
  58: }

Static Methods

The iRule interface has a couple of places static methods (methods that can be called without actually creating an instance of the object) can come in handy.  I’ve created the getList() and exists() methods that will allow you to return a list of iRule objects for all the iRules on the systems and allow you to check whether a given iRule name is available.  The code for these routines can be found below.

   1: public static iRule [] getList(iControl.Interfaces interfaces) throws Exception
   2: {
   3:   iRule [] irule_list = null;
   4:   
   5:   iControl.LocalLBRuleRuleDefinition [] rule_defs = 
   6:     interfaces.getLocalLBRule().query_all_rules();
   7:   irule_list = new iRule[rule_defs.length];
   8:   for(int i=0; i<rule_defs.length; i++)
   9:   {
  10:     irule_list[i] = new iRule(interfaces, rule_defs[i]);
  11:   }
  12:   
  13:   return irule_list;
  14: }
  15:  
  16: public static boolean exists(iControl.Interfaces interfaces, String name) throws Exception
  17: {
  18:   boolean bExists = false;
  19:   
  20:   if ( (null != interfaces) && (null != name) )
  21:   {
  22:     iRule [] irule_list = getList(interfaces);
  23:     for(int i=0; i<irule_list.length; i++)
  24:     {
  25:       if ( irule_list[i].getName().equals(name) )
  26:       {
  27:         bExists = true;
  28:         break;
  29:       }
  30:     }
  31:   }
  32:   return bExists;
  33: }

An Example Usage

In this example code, I have a routine that takes as input the host, username, and password for your BIG-IP.  It will then do the following.

  1. Create a new iRule named “JoesCooliRule”.
  2. Change the iRule to an invalid form and attempt to check the syntax.
  3. Reload that iRule from the definition on the LTM.
  4. Query the performance counter statistics for the given iRule.
  5. And finally delete the iRule created in step #1.
   1: public void testiRule(String [] args)
   2: {
   3:   if ( args.length >= 2)
   4:   {
   5:     try
   6:     {
   7:       iControl.Interfaces interfaces = new iControl.Interfaces();
   8:       interfaces.initialize(args[0], args[1], args[2]);
   9:       
  10:       // Create new iRule
  11:       String ruleName = "JoesCooliRule";
  12:       iControl.Objects.LTM.iRule rule =
  13:         new iControl.Objects.LTM.iRule(interfaces,
  14:           ruleName,
  15:           "when HTTP_REQUEST { log \"Joe Rules!\"; }");
  16:       
  17:       boolean bSaved = rule.save();
  18:       if ( bSaved )
  19:       {
  20:         System.out.println("iRule '" + ruleName + "' created");
  21:       }
  22:       else if ( null != rule.getLastException() )
  23:       {
  24:         rule.getLastException().printStackTrace(System.out);
  25:       }
  26:       else
  27:       {
  28:         System.out.println("iRule '" + ruleName + "' not created for unknown error");
  29:       }
  30:         
  31:       
  32:       // change the rule definition and check syntax
  33:       rule.setDefinition("when HTTP_REQUESTS { }");
  34:       boolean bValid = rule.checkSyntax();
  35:       if ( bValid )
  36:       {
  37:         System.out.println("iRule '" + ruleName + "' syntax is valid.");
  38:       }
  39:       else if ( null != rule.getLastException() )
  40:       {
  41:         rule.getLastException().printStackTrace(System.out);
  42:       }
  43:       else
  44:       {
  45:         System.out.println("iRule '" + ruleName + "' syntax is not valid");
  46:       }
  47:       
  48:       
  49:       // Reload the rule
  50:       boolean bLoaded = rule.load();
  51:       if ( bLoaded )
  52:       {
  53:         System.out.println("iRule '" + ruleName + "' was not found.");
  54:       }
  55:       else if ( null != rule.getLastException() )
  56:       {
  57:         rule.getLastException().printStackTrace(System.out);
  58:       }
  59:       else
  60:       {
  61:         System.out.println("iRule '" + ruleName + "' was reloaded");
  62:       }
  63:       
  64:       // Query Statistics
  65:       iControl.LocalLBRuleRuleStatisticEntry statsEntry =
  66:         rule.getStatistics();
  67:       
  68:       System.out.println("Rule Name  : " + statsEntry.getRule_name());
  69:       System.out.println("Event Name : " + statsEntry.getEvent_name());
  70:       System.out.println("Priority   : " + statsEntry.getPriority());
  71:       
  72:       iControl.CommonStatistic [] ruleStatistics = statsEntry.getStatistics();
  73:       System.out.println("  + Statistics");
  74:       for(int i=0; i<ruleStatistics.length; i++)
  75:       {
  76:         iControl.CommonStatisticType type = ruleStatistics[i].getType();
  77:         iControl.CommonULong64 ul64 = ruleStatistics[i].getValue();
  78:         StatisticValue sv = new StatisticValue(ul64);
  79:         
  80:         System.out.println("    [" + type + "] : " + sv.doubleValue());
  81:       }
  82:       
  83:       
  84:       // Delete the rule
  85:       rule.delete();
  86:       System.out.println("Rule Deleted Successfully");
  87:     }
  88:     catch(Exception ex)
  89:     {
  90:       ex.printStackTrace(System.out);
  91:     }
  92:   }
  93: }

View The Source

The source code can be found in the iControl CodeShare under JavaObjectLtmRule.

Related Articles on DevCentral
Technorati Tags: Java, iRules, Objects, Joe Pruitt