Trigger Service - Easy HowTo

1. Purpose

The purpose of this Easy HowTo is to introduce the GT4/MDS4 component known as the Trigger, as well as to provide an example of setting one up successfully. The current GT 4.1 documentation serves as a reference, but for those of you who would like to get a simple trigger working without going through all of the documentation, mailing lists, as well as the time spent experimenting on your own: this document is for you.

We will be writing a simple trigger from scratch, and setting it up completely. To get the basic idea of how this is done, we will only use elements available in the default GT4 installation to show you how to use triggers.

2. Prerequisites

  • Basic GT4 installation (one of the following):

    • GT 4.0.4 Installation (including Java WS Core and WS MDS Aggregator Framework), in addition to this update patch.

      Patching GT 4.0.4 is as simple as getting the proper patch and issuing the following command:

      $GLOBUS_LOCATION/sbin/gpt-build  -update globus_wsrf_mds_trigger-0.33.tar.gz
    • GT 4.1.1 Installation (including Java WS Core and WS MDS Aggregator Framework).

  • Basic XML Path Language (XPath)

3. Introduction

Triggers collect information from information providers using the same mechanism as the Index service (within the context of the common aggregator framework); but once that data is collected, we can configure a trigger to perform an action based on that data.

Once the conditions are prepared, and the collected data is evaluated, the data will be compared to the conditions and, if there's a match, the trigger will set an action to occur.

Learning to use triggers involves understanding what you are doing conceptually and knowing how to configure everything properly. Below we'll go through an example trigger configuration file and discuss what you could edit in the file. Generally when setting up a trigger you should follow the steps outlined in this tutorial.

First let's explain what we are doing. We're going to set up a trigger to monitor the Default Index Service, and to tell us when a new entry is added to the Default Index Service. When a new entry is added, our trigger will execute a script that will create a [log] file in our $GLOBUS_LOCATION directory [and every two minutes that the new entry is still registered, we'll add a notification to this log file]. This is not necessarily a practical example of how you would use a trigger, but it's simple enough to give you a basic idea of how to set one up. So let's get started!

4. Trigger Tutorial

This tutorial requires a working GT 4.1.1, recent CVS install, or a patched GT 4.0.4 installation (see above). We will be using a patched GT 4.0.4 in this example.

  1. Trigger File Configuration:

    Fill out the trigger configuration file. For this example, we will walk through a new trigger configuration, setup and registration.

    Let's create the configuration file in the following location:

    $GLOBUS_LOCATION/etc/globus_wsrf_mds_trigger/our-simple-trigger-config.xml

    The entire config file is located further below. The following table breaks it down:

    A. Preliminaries
    <?xml version="1.0" encoding="UTF-8" ?>
    <ServiceGroupRegistrations
        xmlns="http://mds.globus.org/servicegroup/client"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
        xmlns:agg="http://mds.globus.org/aggregator/types"
        xmlns:trigger="http://mds.globus.org/2004/08/trigger/types">
    </ServiceGroupRegistrations>
                      

    As this is an XML document, it must be properly formatted XML.

    Start your file with the appropriate header.

    The ServiceGroupRegistration node is the root of the document.

    B. Aggregator Sink / Service Group Registration Information (for more information, go here).
    <?xml version="1.0" encoding="UTF-8" ?>
      <ServiceGroupRegistrations
            xmlns="http://mds.globus.org/servicegroup/client"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
            xmlns:agg="http://mds.globus.org/aggregator/types"
            xmlns:trigger="http://mds.globus.org/2004/08/trigger/types">
        <defaultServiceGroupEPR>
        </defaultServiceGroupEPR>
      </ServiceGroupRegistrations>
                      

    Although many service group registration blocks may be present, in this example we'll only create one.

    <?xml version="1.0" encoding="UTF-8" ?>
      <ServiceGroupRegistrations
              xmlns="http://mds.globus.org/servicegroup/client"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
              xmlns:agg="http://mds.globus.org/aggregator/types"
              xmlns:trigger="http://mds.globus.org/2004/08/trigger/types">
        <defaultServiceGroupEPR>
            <wsa:Address>
              https://localhost:8443/wsrf/services/DefaultTriggerService
            </wsa:Address>
        </defaultServiceGroupEPR>
      </ServiceGroupRegistrations>
                    

    We will be using the Trigger Service as our main service group. All registrations from this configuration will be registered to this service.

    You can test that the DefaultTriggerService is up and functioning by typing (in one line):

    $GLOBUS_LOCATION/bin/wsrf-query -s https://localhost:8443/wsrf/services/DefaultTriggerService

    C. Aggregator Source Configuration (for more information, go here).
    <?xml version="1.0" encoding="UTF-8" ?>
      <ServiceGroupRegistrations
              xmlns="http://mds.globus.org/servicegroup/client"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
              xmlns:agg="http://mds.globus.org/aggregator/types"
              xmlns:trigger="http://mds.globus.org/2004/08/trigger/types">
          <defaultServiceGroupEPR>
              <wsa:Address>
              https://localhost:8443/wsrf/services/DefaultTriggerService
              </wsa:Address>
          </defaultServiceGroupEPR>
          <ServiceGroupRegistrationParameters>
                xmlns="http://mds.globus.org/servicegroup/client"
                xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
                xmlns:agg="http://mds.globus.org/aggregator/types">
          </ServiceGroupRegistrationParameters>
      </ServiceGroupRegistrations>
                    

    Now we will specify the parameters used to register a resource (e.g. information provider) to the service group (i.e. our trigger service).

    ...
      <ServiceGroupRegistrationParameters
            xmlns="http://mds.globus.org/servicegroup/client"
            xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
            xmlns:agg="http://mds.globus.org/aggregator/types">
          <RegistrantEPR
            xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
            <wsa:Address>
                https://localhost:8443/wsrf/services/DefaultIndexService
            </wsa:Address>
          </RegistrantEPR>
      </ServiceGroupRegistrationParameters>
      ...
                      

    We will set the RegistrantEPR to the entity (or information provider) to be monitored; in this case, we will be monitoring the DefaultIndexService.

    ...
    <ServiceGroupRegistrationParameters
          xmlns="http://mds.globus.org/servicegroup/client"
          xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
          xmlns:agg="http://mds.globus.org/aggregator/types">
      <RegistrantEPR
          xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
          <wsa:Address>
              https://localhost:8443/wsrf/services/DefaultIndexService
          </wsa:Address>
      </RegistrantEPR>
      <RefreshIntervalSecs>600</RefreshIntervalSecs>
    </ServiceGroupRegistrationParameters>
      ...
                      

    Set this to the number of seconds upon which the registration will be renewed (this is to keep the registration from expiring): 600.

    "600" means that we'll renew the registration every 10 minutes.

    ...
    <ServiceGroupRegistrationParameters
          xmlns="http://mds.globus.org/servicegroup/client"
          xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
          xmlns:agg="http://mds.globus.org/aggregator/types">
      <RegistrantEPR
          xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
          <wsa:Address>
              https://localhost:8443/wsrf/services/DefaultIndexService
          </wsa:Address>
      </RegistrantEPR>
      <RefreshIntervalSecs>600</RefreshIntervalSecs>
       <Content xsi:type="agg:AggregatorContent"
                  xmlns:agg="http://mds.globus.org/aggregator/types">
            <agg:AggregatorConfig xsi:type="agg:AggregatorConfig">
            </agg:AggregatorConfig>
            <agg:AggregatorData />
       </Content>
    </ServiceGroupRegistrationParameters>
      ...
                      

    Now we configure aggregator-source-specific configuration parameters.

    Note: The AggregatorData element must be present, and it is also an empty element.

    ...
      <Content xsi:type="agg:AggregatorContent"
              xmlns:agg="http://mds.globus.org/aggregator/types">
        <agg:AggregatorConfig xsi:type="agg:AggregatorConfig">
            <agg:GetResourcePropertyPollType 
                    xmlns:wssg="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ServiceGroup-1.2-draft-01.xsd">
                <agg:PollIntervalMillis>120000</agg:PollIntervalMillis>
            </agg:GetResourcePropertyPollType>
        </agg:AggregatorConfig>
        <agg:AggregatorData />
      </Content>
      ...
                      

    Set this to how often you'll be polling the information provider for data and refreshing the current information: 120000.

    "120000" means that you'll be checking the information provider every 2 minutes.

    The xmlns:wssg attribute should all be in one line.

    ...
      <Content xsi:type="agg:AggregatorContent"
                xmlns:agg="http://mds.globus.org/aggregator/types">
        <agg:AggregatorConfig xsi:type="agg:AggregatorConfig">
            <agg:GetResourcePropertyPollType 
                xmlns:wssg="http://docs.oasis-open.org/wsrf/2004/06/\
                            wsrf-WS-ServiceGroup-1.2-draft-01.xsd">
                <agg:PollIntervalMillis>120000</agg:PollIntervalMillis>
                <agg:ResourcePropertyName>wssg:Entry</agg:ResourcePropertyName>
            </agg:GetResourcePropertyPollType>
        </agg:AggregatorConfig>
        <agg:AggregatorData />
      </Content>
      ...
                      

    Set this to the name of the resource property that the data is accessed by: wssg:Entry. wssg:Entry is one of the few resource properties available in the current implementation (this will likely change in future versions)

    [The format is rp_namespace:rp_localname]

    You can view some active ResourcePropertyNames as you poll the DefaultIndexService. For this example, this parameter is mostly irrelevant.

    D. Trigger Configuration Information (for more information: go here).
    ...
      <Content xsi:type="agg:AggregatorContent"
                        xmlns:agg="http://mds.globus.org/aggregator/types">
        <agg:AggregatorConfig xsi:type="agg:AggregatorConfig">
          <agg:GetResourcePropertyPollType 
                  xmlns:wssg="http://docs.oasis-open.org/wsrf/2004/06/\
                                            wsrf-WS-ServiceGroup-1.2-draft-01.xsd">
            <agg:PollIntervalMillis>120000</agg:PollIntervalMillis>
            <agg:ResourcePropertyName>wssg:Entry</agg:ResourcePropertyName>
          </agg:GetResourcePropertyPollType>
             <trigger:TriggerRuleType>
             </trigger:TriggerRuleType>
        </agg:AggregatorConfig>
        <agg:AggregatorData />
      </Content>
      ...
                      

    Now that we've set up the aggregator source to monitor an information provider (the Default Index Service) and set a trigger (the Default Trigger service) as the aggregator service/sink, we will configure the trigger.

    ...
      <trigger:TriggerRuleType>
        <trigger:matchingRule>
              count(//*[local-name()="Entry"])>3
        </trigger:matchingRule>
      </trigger:TriggerRuleType>
      ...
                      

    Set this to the XPath rule you wish to compare and match against incoming data:

    count(//*[local-name()="Entry"])>3

    For our simple trigger example we will set up the trigger to alert us whenever someone adds a new entry to the DefaultIndexService.

    When we poll the DefaultIndexService later below for information (using the following command): $GLOBUS_LOCATION/bin/wsrf-query -s https://localhost:8443/wsrf/services/DefaultIndexService 'count(//*[local-name()="Entry"])'

    we are told that there are 3 entries.

    When the entries are greater than 3 entries, we would like to have the trigger execute our script.

    Right now, the result of the following query is false:

    $GLOBUS_LOCATION/bin/wsrf-query -s https://localhost:8443/wsrf/services/DefaultIndexService 'count(//*[local-name()="Entry"])>3'

    and the result of the following query is true:

    $GLOBUS_LOCATION/bin/wsrf-query -s https://localhost:8443/wsrf/services/DefaultIndexService 'count(//*[local-name()="Entry"])>=3'

    (Optional parameter)
    ...
    <trigger:TriggerRuleType>
      <trigger:matchingRule>
          count(//*[local-name()="Entry"])>3
      </trigger:matchingRule>
        <trigger:namespaceMappings>
        </trigger:namespaceMappings>
    </trigger:TriggerRuleType>
    ...
                      

    If you use namespace prefixes in the above XPath matchingRule, you can specify an array of namespace mappings that will be used to resolve the namespace prefixes.

    The format is: xmlns:foo=http://foo.bar

    This functionality will work in GT 4.0.4 (with the update patch) and GT 4.1.1+.

    (Optional parameter, but required for this example)
    ...
    <trigger:TriggerRuleType>
      <trigger:matchingRule>
          count(//*[local-name()="Entry"])>3
      </trigger:matchingRule>
      <trigger:evaluateBoolean>true</trigger:evaluateBoolean>
    </trigger:TriggerRuleType>
    ...
                      

    Without using this parameter, the trigger will fire if the matchingRule evaluates to true or false. As long as data is returned, the trigger will fire. This parameter is essential in order to change this behavior to a proper boolean evaluation of the XPath query.

    This functionality will work in GT 4.0.4 (with the update patch) and GT 4.1.1+.

    ...
      <trigger:TriggerRuleType>
        <trigger:matchingRule>
            count(//*[local-name()="Entry"])>3
        </trigger:matchingRule>
        <trigger:evaluateBoolean>true</trigger:evaluateBoolean>
        <trigger:actionScript>our-simple-trigger</trigger:actionScript>
      </trigger:TriggerRuleType>
      ...
                      

    Set this to the name of the action script that will be executed when the matchingRule matches any nodes of incoming data: our-simple-trigger

    This logical name must be mapped to a physical file name located in the $GLOBUS_LOCATION/libexec/trigger/ directory.

    The logical-to-physical filename mapping is specified in the executableMappings parameter of the triggerConfiguration block of the file: $GLOBUS_LOCATION/etc/globus_wsrf_mds_trigger/jndi-config.xml.

    Don't worry about these files now, we'll revisit them in the next section.

    ...
      <trigger:TriggerRuleType>
        <trigger:matchingRule>
            count(//*[local-name()="Entry"])>3
        </trigger:matchingRule>
        <trigger:evaluateBoolean>true</trigger:evaluateBoolean>
        <trigger:actionScript>our-simple-trigger</trigger:actionScript>
        <trigger:minimumFiringInterval>60</trigger:minimumFiringInterval>
      </trigger:TriggerRuleType>
      ...
                      

    Set this to the number of seconds no more than which you want the actionScript to be executed: 60

    Here, "60" indicates the actionScript will be executed no more than once every minute.

    If unspecified, there will be no minimum interval and it will be fired whenever incoming data matches the matchingRule.

    (Optional parameter, but required for this example)
    ...
    <trigger:TriggerRuleType>
      <trigger:matchingRule>
          count(//*[local-name()="Entry"])>3
      </trigger:matchingRule>
      <trigger:evaluateBoolean>true</trigger:evaluateBoolean>
      <trigger:actionScript>our-simple-trigger</trigger:actionScript>
      <trigger:minimumFiringInterval>60</trigger:minimumFiringInterval>
      <trigger:minimumMatchTime>30</trigger:minimumMatchTime>
    </trigger:TriggerRuleType>
    ...
                      

    Set this to how long the matchingRule must be true before the actionScript will be executed: 30

    Here, "30" indicates the condition must be true for 30 seconds before the actionScript will be eligible to fire.

    If unspecified, the trigger will be eligible to fire immediatedly after the matchingRule properly matches incoming data.

    (Optional parameter, but required for this example)
    ...
    <trigger:TriggerRuleType>
      <trigger:matchingRule>
          count(//*[local-name()="Entry"])>3
      </trigger:matchingRule>
      <trigger:evaluateBoolean>true</trigger:evaluateBoolean>
      <trigger:actionScript>our-simple-trigger</trigger:actionScript>
      <trigger:minimumFiringInterval>60</trigger:minimumFiringInterval>
      <trigger:minimumMatchTime>30</trigger:minimumMatchTime>
        <trigger:enableFilteredActionScriptInput>
            true
        </trigger:enableFilteredActionScriptInput>
    </trigger:TriggerRuleType>
    ...
                      

    This functionality will work in GT 4.0.4 (with the update patch) and GT 4.1.1+.

    If you are using these versions, set this to true.

    (Optional parameter, but required for this example)
    ...
    <trigger:TriggerRuleType>
      <trigger:matchingRule>
          count(//*[local-name()="Entry"])>3
      </trigger:matchingRule>
      <trigger:evaluateBoolean>true</trigger:evaluateBoolean>
      <trigger:actionScript>our-simple-trigger</trigger:actionScript>
      <trigger:minimumFiringInterval>60</trigger:minimumFiringInterval>
      <trigger:minimumMatchTime>30</trigger:minimumMatchTime>
      <trigger:enableFilteredActionScriptInput>
          true
      </trigger:enableFilteredActionScriptInput>
        <trigger:disableUnmodifiedActionScriptInput>
            true
        </trigger:disableUnmodifiedActionScriptInput>
    </trigger:TriggerRuleType>
    ...
                      

    This functionality will work in GT 4.0.4 (with the update patch) and GT 4.1.1+.

    If you are using these versions, set this to true.

    Let's review the complete configuration file just so you can check that you have included everything properly:

    $GLOBUS_LOCATION/etc/globus_wsrf_mds_trigger/our-simple-trigger-config.xml

    <ServiceGroupRegistrations
      xmlns="http://mds.globus.org/servicegroup/client"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
      xmlns:agg="http://mds.globus.org/aggregator/types"
      xmlns:trigger="http://mds.globus.org/2004/08/trigger/types">
      <defaultServiceGroupEPR>
        <wsa:Address>https://localhost:8443/wsrf/services/DefaultTriggerService</wsa:Address>
      </defaultServiceGroupEPR>
      <ServiceGroupRegistrationParameters
        xmlns="http://mds.globus.org/servicegroup/client"
        xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
        xmlns:agg="http://mds.globus.org/aggregator/types">
        <RegistrantEPR
          xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
          <wsa:Address>https://localhost:8443/wsrf/services/DefaultIndexService</wsa:Address>
        </RegistrantEPR>
        <RefreshIntervalSecs>600</RefreshIntervalSecs>
        <Content xsi:type="agg:AggregatorContent"
          xmlns:agg="http://mds.globus.org/aggregator/types">
          <agg:AggregatorConfig xsi:type="agg:AggregatorConfig">
            <agg:GetResourcePropertyPollType 
              xmlns:wssg="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ServiceGroup-1.2-draft-01.xsd">
              <agg:PollIntervalMillis>120000</agg:PollIntervalMillis>
              <agg:ResourcePropertyName>wssg:Entry</agg:ResourcePropertyName>
            </agg:GetResourcePropertyPollType>
            <trigger:TriggerRuleType>
              <trigger:matchingRule>count(//*[local-name()="Entry"])>3</trigger:matchingRule>
              <trigger:evaluateBoolean>true</trigger:evaluateBoolean>
              <trigger:actionScript>our-simple-trigger</trigger:actionScript>
              <trigger:minimumFiringInterval>60</trigger:minimumFiringInterval>
              <trigger:minimumMatchTime>30</trigger:minimumMatchTime>
            </trigger:TriggerRuleType>
          </agg:AggregatorConfig>
          <agg:AggregatorData />
        </Content>
      </ServiceGroupRegistrationParameters>
    </ServiceGroupRegistrations>    
            

    You could simply copy these file contents and change the "localhost" to your hostname. Great! Now that we've got the configuration file set up, we need to register it with the Default Trigger Service, so that the Trigger Service knows what to look out for.

  2. Trigger Action Script Configuration: Now that we have the trigger configuration file set to execute an action whenever our conditions are met, we need to determine what those actions are. We do this by setting up a Trigger Action Script.

    In our trigger configuration file, we specified the name of our action script ("our-simple-trigger") using the <trigger:actionScript> node.

    1. First we must edit the file:

      $GLOBUS_LOCATION/etc/globus_wsrf_mds_trigger/jndi-config.xml

      Find the executableMappings section of the file, and we will add our trigger action script mapping to the file.

       <jndiConfig>
        <global>
          <resource name="triggerConfiguration">
            <resourceParams>
              <parameter>  1
                <name>executableMappings</name>
                <value>test-trigger=test-trigger-action.sh,
                  glue-trigger=glue-trigger-action.sh,
                    echo-trigger=echo-trigger-action.sh,  2
                    our-simple-trigger=our-simple-trigger-action.sh
                </value>
              </parameter>
            </resourceParams>
          </resource>
        </global>
      </jndiConfig>
                  

      1 PLEASE note that this section is commented out by default. You must uncomment it!
      2 Don't forget to add a comma here.

    2. Now we actually write the action script:

      We'll make it very simple:

      #!/bin/sh
      
      DATE=`date`
      
      echo "OUR LOG: New Index Service Entry: $DATE" >> $GLOBUS_LOCATION/our_new_entry_detected
      
      cat <<EOF
      <?xml version="1.0" encoding="UTF-8"?>
      <OurActionScriptOutput>
        <OurDataDetected>true</OurDataDetected>
      </OurActionScriptOutput>
      EOF
                  

      Save this file as: $GLOBUS_LOCATION/libexec/trigger/our-simple-trigger-action.sh

      [Important]Important

      Be sure that this file is executable! (e.g. chmod u+x our-simple-trigger-action.sh)

  3. Registration:

    The registration step is necessary to connect the information source with the Trigger (aggregator service). This step provides access to the information source data so that the trigger can then make this information available and act on it accordingly.

    --> Now start the container:

    $GLOBUS_LOCATION/bin/globus-start-container

    You may also need to set up your environment variables, and/or generate a new proxy certificate:

              source $GLOBUS_LOCATION/etc/globus-user-env.sh
              $GLOBUS_LOCATION/bin/grid-proxy-init -verify -debug
            

    But before we create the trigger, let's just quickly test how many Entries are being registered by the Index Service. Type the following command in one line:

    $GLOBUS_LOCATION/bin/wsrf-query -s https://localhost:8443/wsrf/services/DefaultIndexService 'count(//*[local-name()="Entry"])'

    On our setup we get: 3.

  4. Create Trigger:

    Once the configurations have been properly set, it's easy to register them with the Trigger service.

    We will create the example trigger by running mds-servicegroup-add to perform the registrations specified in the configuration file.

    This tool takes an XML configuration file listing registrations, and causes those registrations to be made.

    Run the following command:

    $GLOBUS_LOCATION/bin/mds-servicegroup-add -s https://localhost:8443/wsrf/services/DefaultTriggerService $GLOBUS_LOCATION/etc/globus_wsrf_mds_trigger/our-simple-trigger-config.xml
    [Important]Important

    Be sure the above command is on one line.

    If everything went well, you should get something like:

    Processing configuration file...
    Processed 1 registration entries
    Successfully registered https://localhost:8443/wsrf/services/DefaultIndexService to \
    servicegroup at https://localhost:8443/wsrf/services/DefaultTriggerService
                
  5. Test Trigger:

    Now that our trigger is registered, it's ready to perform actions. We set our trigger to fire when it detected a new entry in the Default Index Service. As it stands, since there are no new entries, the trigger will not fire. So let's add an entry to the Index Service so that we can be sure that our trigger is working properly.

    1. Create a new index configuration file (very simplistic):

      $GLOBUS_LOCATION/etc/globus_wsrf_mds_index/our-test-index-registration.xml

      You can just copy these file contents for now, editing your hostname.

      <?xml version="1.0" encoding="UTF-8"?>
      <ServiceGroupRegistrations
        xmlns="http://mds.globus.org/servicegroup/client"
        xmlns:sgc="http://mds.globus.org/servicegroup/client"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
        xmlns:agg="http://mds.globus.org/aggregator/types"
        xmlns:gram="http://www.globus.org/namespaces/2004/10/gram/job">
        <sgc:defaultServiceGroupEPR>
          <wsa:Address>https://localhost:8443/wsrf/services/DefaultIndexService</wsa:Address>
        </sgc:defaultServiceGroupEPR>
        
        <sgc:defaultRegistrantEPR>
          <wsa:Address>https://localhost:8443/wsrf/services/ManagedJobFactoryService</wsa:Address>
          <wsa:ReferenceProperties><gram:ResourceID>Fork</gram:ResourceID></wsa:ReferenceProperties>
        </sgc:defaultRegistrantEPR>
        
        <sgc:ServiceGroupRegistrationParameters>
          <sgc:RefreshIntervalSecs>1440</sgc:RefreshIntervalSecs>
          <sgc:Content xsi:type="agg:AggregatorContent" xmlns:agg="http://mds.globus.org/aggregator/types">
            <agg:AggregatorConfig xsi:type="agg:AggregatorConfig">
              <agg:GetResourcePropertyPollType
                xmlns:glue="http://mds.globus.org/glue/ce/1.1" >
                <agg:PollIntervalMillis>120000</agg:PollIntervalMillis>
                <agg:ResourcePropertyName>glue:GLUECE</agg:ResourcePropertyName>
              </agg:GetResourcePropertyPollType>
            </agg:AggregatorConfig>
            <agg:AggregatorData/>
          </sgc:Content>
        </sgc:ServiceGroupRegistrationParameters>
      </ServiceGroupRegistrations>
                  
    2. Register this config file with the Default Index Service:

      $GLOBUS_LOCATION/bin/mds-servicegroup-add  -s https://localhost:8443/wsrf/services/DefaultIndexService $GLOBUS_LOCATION/etc/globus_wsrf_mds_index/our-test-index-registration.xml
      [Important]Important

      Be sure the above command is on one line.

    3. Test the registration by typing the following command:

      $GLOBUS_LOCATION/bin/wsrf-query -s https://localhost:8443/wsrf/services/DefaultIndexService 'count(//*[local-name()="Entry"])'
      [Important]Important

      Be sure the above command is on one line.

    4. If you previously issued this command above (during the trigger file configation), and it said 3, it should now result in 4. Basically we've added a new entry to the Default Index Service. Because of this, our trigger should fire (if everything is properly set).

    5. After a few minutes, the trigger will have fired and executed the action script we wrote. To verify this, type:

      cat $GLOBUS_LOCATION/our_new_entry_detected

      You should see some output like the following:

      OUR LOG: New Index Service Entry: Fri Mar  9 09:32:32 CST 2007
      OUR LOG: New Index Service Entry: Fri Mar  9 09:34:32 CST 2007
      OUR LOG: New Index Service Entry: Fri Mar  9 09:36:32 CST 2007
      OUR LOG: New Index Service Entry: Fri Mar  9 09:38:32 CST 2007
                  

5. Congratulations!

You have now successfully setup, configured, registered, and tested a trigger created from scratch!

Next Steps: Check out the documentation and create more triggers to perform actions more relevant to your own objectives. Experiment with the XPath queries to expand the possibilities of what you can use them for. If you have questions, feel free to contact us!