ActiveVOS XML and JSON Bindings for Services

ActiveVOS 7.1 or later exposes all its processes and services via simple XML and JavaScript Object Notation (JSON) bindings in addition to SOAP, REST and JMS. The XML (and JSON) binding makes it easy for application developers already familiar with XML/JSON-based REST application development to invoke processes and obtain responses from them.

Using XML or JSON bindings frees developers from needing to obtain and learn SOAP libraries to build applications that leverage ActiveVOS service-based processes. This approach allows JavaScript developers to use various libraries such as jQuery to build process-enabled applications.

ActiveVOS uses the JSON binding for ActiveVOS Central request and task forms. This implementation provides functions that are available for use by developers for process-enabled application projects. Examples of the use of these functions are provided in this document.

This document contains the following sections

  1. Service Endpoints
  2. XML Binding
  3. JSON Binding
  4. JSON/XML Conversion Tool
  5. Invoking a Process Using JSON
  6. JSON Process Invoke Examples
  7. Accessing the WS-HumanTask (WSHT) API via JSON
  8. Working with Schema Date and Time Types
  9. Using Designer to Create HTML Forms
  10. Making Cross Domain AJAX Requests

Service Endpoints

This table shows the endpoints for a given service exposed by ActiveVOS using various bindings. The ServiceName indicates the name of the service - LoanApprovalService for example.

Binding Service Endpoint Description
SOAP 1.1 http://host:port/active-bpel/services/ServiceName Default SOAP endpoint for all services except for REST style services Note: The ActiveVOS engine Administration API service (ActiveBpelAdmin) is available only at the SOAP 1.1 endpoint.
SOAP 1.2 http://host:port/active-bpel/services/soap12/ServiceName SOAP 1.2 endpoint. All services are exposed via this endpoint except the REST and ActiveBpelAdmin services.
REST http://host:port/active-bpel/services/REST/ServiceName Endpoint for REST binding. Excludes the ActiveBpelAdmin service.
XML http://host:port/active-bpel/services/XML/ServiceName Endpoint for simple XML binding. Excludes REST and ActiveBpelAdmin services.
JSON http://host:port/active-bpel/services/JSON/ServiceName Endpoint for JSON binding. Excludes REST and ActiveBpelAdmin services.

Note that the ActiveVOS Administration service API (ActiveBpelAdmin) is available only at the SOAP 1.1 address. This service is not available in SOAP 1.2, XML or JSON bindings.

XML Binding

Processes deployed to the ActiveVOS server are available as simple XML bindings in addition to the standard SOAP binding providing that the process and deployment is WS-I compliant:

Invoking a Process

To invoke a process using a XML binding endpoint, you need to:

  1. Set the POST header content-type header to text/xml
  2. Set the POST payload (body content) to be the request xml element
  3. Include authorization headers if needed
  4. Send an HTTP POST message to the service XML endpoint

The response from the POST will be an HTTP 200/OK response with a content-type of text/xml. The response body will contain the service’s response xml. The following snippet shows the HTTP request used to invoke the Loan Approval process via humantaskProcessDemoService service.

POST /active-bpel/services/XML/humantaskProcessDemoService HTTP/1.1
Content-Length: 710
Content-Type: text/xml; charset=UTF-8
Authorization: Basic YWVhZG1pbjphZWFkbWlu
Host: localhost:8080

<loan:loanProcessRequest xmlns:loan="http://schemas.active-endpoints.com/sample/LoanRequest/2008/02/loanRequest.xsd">
 <loan:loanType>Automobile</loan:loanType>
 <loan:firstName>John</loan:firstName>
 <loan:lastName>Smith</loan:lastName>
 <loan:dayPhone>2039299400</loan:dayPhone>
 <loan:nightPhone>2035551212</loan:nightPhone>
 <loan:socialSecurityNumber>123-45-6789</loan:socialSecurityNumber>
 <loan:amountRequested>15000</loan:amountRequested>
 <loan:loanDescription>Application to finance the purchase of a Toyota Prius</loan:loanDescription>
 <loan:otherInfo>Down payment is US$7500</loan:otherInfo>
 <loan:responseEmail>john.smith@example.com</loan:responseEmail>
</loan:loanProcessRequest>

The response looks like:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Wed, 10 Mar 2010 22:53:40 GMT

<loan:status xmlns:loan="http://www.active-endpoints.com/wsdl/humantaskdemo">
  Thank you for applying for the Automobile loan for the amount of US$15000. 
  Your loan is currently pending approval. You will receive an email once a decision has 
  been made.
</loan:status>
Fault Response

A fault is indicated with an HTTP response code of 500 and the content-type of text/xml (instead of text/html or text/plain indicating a generic "internal server error"). An example of a fault response is shown here:

HTTP/1.1 500 Internal Server Error
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Thu, 11 Mar 2010 19:09:51 GMT
Connection: close

<aex:Fault xmlns:aex="http://www.active-endpoints.com/2004/06/bpel/extensions/">
   <faultcode name="systemError" namespace="http://www.active-endpoints.com/2004/06/bpel/extensions/"/>
   <faultstring>Could not find match for Operation from given parameters</faultstring>
</aex:Fault>
Attachments

When sending attachments the payload of the HTTP body must be multipart/related content, with the first part being the message xml payload (text/xml), followed by additional parts representing the attachments. Attachments sent with the payload are bound the process variable associated with the message Receive activity.

POST /active-bpel/services/XML/humantaskProcessDemoService HTTP/1.1
Content-Type: multipart/related; type="text/xml"; start="<part1_id>"; boundary="the_boundry"
Content-Length: 1410
MIME-Version: 1.0
Host: localhost:8080

--the_boundry
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: 8bit
Content-ID: <part1_id>

<loan:loanProcessRequest xmlns:loan="http://schemas.active-endpoints.com/sample/LoanRequest/2008/02/loanRequest.xsd">
 <loan:loanType>Automobile</loan:loanType>
 <loan:firstName>John</loan:firstName>
 <loan:lastName>Smith</loan:lastName>
 <loan:dayPhone>2039299400</loan:dayPhone>
 <loan:nightPhone>2035551212</loan:nightPhone>
 <loan:socialSecurityNumber>123-45-6789</loan:socialSecurityNumber>
 <loan:amountRequested>15000</loan:amountRequested>
 <loan:loanDescription>Application to finance the purchase of a Toyota Prius</loan:loanDescription>
 <loan:otherInfo>Down payment is US$7500</loan:otherInfo>
 <loan:responseEmail>john.smith@example.com</loan:responseEmail>
</loan:loanProcessRequest>
--the_boundry
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-ID: <part2_id>

[...Text Attachment Content...]
--the_boundry
Content-Type: image/jpeg
Content-ID: <part3_id>
Content-Transfer-Encoding: BASE64
Content-Description: Picture A

[...Image Content...]
--the_boundry--

For testing you can use any HTTP client testing tool available to you. For example, SOAP-UI, cURL (a popular command line tool) and RESTClient, a Java based application to test RESTful web services.

Using RESTClient Tool

RESTClient is a Java application used to test RESTful services. It can be used to test a variety of HTTP communications including invoking ActiveVOS processes using the XML binding endpoint. To use the GUI version of this tool, download the jar restclient-ui-2.3-jar-with-dependencies.jar library from http://code.google.com/p/rest-client/downloads/list.

To launch the application, run the command java -jar restclient-ui-2.3-jar-with-dependencies.jar. This will bring up the GUI application similar to the screenshot shown below.

  1. 1. To invoke the sample process in provided with this SDK, ensure that your server is running and that you have deployed the humantaskProcessDemo bpr provided with this SDK to it.

  2. To send a XML POST message to invoke a service, set the service URL for the XML binding. For example, http://localhost:8080/active-bpel/services/XML/humantaskProcessDemoService.

  3. In the Method tab, set the HTTP Method to POST.
  4. In the Body tab, set content-type to text/xml.
  5. In the Body tab, provide the xml request element. You can copy the <loan:loanProcessRequest> sample shown in the previous section.

  6. Set authorization information if needed via Auth tab.

  7. Press the >> Go button to send the request
  8. The response from the service is then shown in the Body tab in the HTTP Response area.

Java Example

The following snippet shows one approach to sending an HTTP POST to a service endpoint. The complete code is available in com.activevos.examples.xmlbinding.SimpleXmlServiceRequest class provided to you in the examples folder.

public class SimpleXmlServiceRequest {
   /**
    * Class to hold service response data.
    */
   static class ServiceResponse {
      static final int SUCCESS = 0;
      static final int FAULTED = 1;
      static final int ERROR = 2;
      /** Code indicating if the service invoke was a success, fault or other error.*/
      int responseCode;
      /** Response xml data */
      String responseData;      
   }
   
   /**
    * Invokes XML service using POST method returns service response.
    */
   public static ServiceResponse invokeService(URL aXmlServiceUrl, String aXmlPayload, 
         String aUsername, String aPassword) throws IOException {
      HttpURLConnection httpConnection = null;
      BufferedReader reader = null;
      OutputStreamWriter writer = null;
      try
      {
         // create connection
         URLConnection c = aXmlServiceUrl.openConnection();
         httpConnection = (HttpURLConnection)c;
         httpConnection.setRequestProperty("Content-Type", "text/xml");
         httpConnection.setRequestProperty("Content-Length", Integer.toString(aXmlPayload.length()));

         // Set credentials (if secured using BASIC auth).
         if (aUsername != null && aPassword != null) {
            // code to set the authorization header (e.g. BASIC)
         }
         httpConnection.setDoOutput(true);
         httpConnection.setInstanceFollowRedirects(true);

         // send the payload
         writer = new OutputStreamWriter(httpConnection.getOutputStream());
         writer.write(aXmlPayload);
         writer.flush();

         // read response
         if ( httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK
               || httpConnection.getResponseCode() == HttpURLConnection.HTTP_ACCEPTED ) {
            reader = new BufferedReader(new InputStreamReader(httpConnection.getInputStream()));
         } else {
            reader = new BufferedReader(new InputStreamReader(httpConnection.getErrorStream()));
         }
         // read response
         StringBuilder sb = new StringBuilder();
         String line = null;
         while ((line = reader.readLine()) != null) {
            sb.append(line);
         }
                  
         ServiceResponse response = new ServiceResponse();
         response.responseData = sb.toString();
         if ( httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK
               || httpConnection.getResponseCode() == HttpURLConnection.HTTP_ACCEPTED ) {
            // Success!
            response.responseCode = ServiceResponse.SUCCESS;
         } else if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_INTERNAL_ERROR
               && httpConnection.getContentType().toLowerCase().startsWith("text/xml") ) {
            // Faulted! (response code is 500 and content-type is text/xml 
            response.responseCode = ServiceResponse.FAULTED;
         } else {
            // http/transport or other error
            response.responseCode = ServiceResponse.ERROR;
         }
         return response;
      }
      finally {
          //
         // clean up code goes here. E.g.: close writer, reader and disconnect http connection.
      }
   }

   public static void main(String[] args) {
      // Create sample request. In this example, the sample request is created using
      // a string. Ideally, the XML element should be built using DOM i.e. with DocumentBuilderFactory,
      // and DocumentBuilder.
      String xmlRequest = "<loan:loanProcessRequest xmlns:loan=\"http://schemas.active-endpoints.com/sample/LoanRequest/2008/02/loanRequest.xsd\">\n"
            + " <loan:loanType>Automobile</loan:loanType>\n"
            + " <loan:firstName>John</loan:firstName>\n"
            + " <loan:lastName>Smith</loan:lastName>\n"
            + " <loan:dayPhone>2039299400</loan:dayPhone>\n"
            + " <loan:nightPhone>2035551212</loan:nightPhone>\n"
            + " <loan:socialSecurityNumber>123-45-6789</loan:socialSecurityNumber>\n"
            + " <loan:amountRequested>15000</loan:amountRequested>\n"
            + " <loan:loanDescription>Application to finance the purchase of a Toyota Prius</loan:loanDescription>\n"
            + " <loan:otherInfo>Down payment is US$7500</loan:otherInfo>\n"
            + " <loan:responseEmail>john.smith@example.com</loan:responseEmail>\n"
            + "</loan:loanProcessRequest>";
            
      try {
         
         URL loanRequestUrl = new URL(
               "http://localhost:8080/active-bpel/services/XML/humantaskProcessDemoService");         
         System.out.println("Invoking service...");
         ServiceResponse response = invokeService(loanRequestUrl, xmlRequest, "username", "password");
         
         if ( response.responseCode == ServiceResponse.SUCCESS ) {
            System.out.println("Success:");
         } else if ( response.responseCode == ServiceResponse.FAULTED ) {
            System.out.println("Faulted:");
         } else {
            System.out.println("Error:");
         }
         System.out.println(response.responseData);
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

JSON Binding

Processes deployed to the ActiveVOS server are available as JSON (JavaScript Object Notation) bindings. Similar to services with XML binding, the services must be WS-I compliant:

JSON Representation of XML Content

In order to invoke a service using JSON, the service request message, which is normally defined in XML must be represented in JSON. The ActiveVOS server represents XML elements in JSON notation based on the methodology described by Google GData convention at http://code.google.com/apis/gdata/json.html.

  1. XML element is represented as a JSON object.

    <contactInfo />
    
    JSON equivalent:
    { 
      "contactInfo" : {}
    }  
    
  2. Attributes: Element attributes are represented as string properties.

    <contactInfo type="home" default="true" />
    
    JSON equivalent:
    { 
      "contactInfo" : {
                     "type"   : "home",
                     "default": "true"
                    }
    }  
    

    In JavaScript, accessing attributes can be done as follows (assuming the JSON data is assigned to variable named doc)

     
     var doc = { "contactInfo" : { 
                       "type": "home",
                       "default": "true"
                  }
               };
     // type attribute is accessed via doc.contactInfo["type"] or doc.contactInfo.type.  
     alert("contact information type: " + doc.contactInfo.type);
    
  3. Child elements are converted to Object type properties.

    <contactInfo type="home" default="true" >
       <phone />  
    </contactInfo>
    
    JSON equivalent (see 'phone' element object in line 5):
    { 
      "contactInfo" : {
                     "type"   : "home",
                     "default": "true",
                     "phone" : {}
                    }
    }  
    
  4. Element text: Text values of elements are converted to string property named $t. The following shows how the <phone/> element text value (203-555-1212) is represented.

    <contactInfo type="home" default="true" >
       <phone type="voice">203-555-1212</phone>  
    </contactInfo>
    
    JSON:
    { 
      "contactInfo" : {
                        "type"   : "home",
                        "default": "true",
                        "phone"  : {
                                    "type" : "voice",
                                    "$t"   : "203-555-1212"
                                   }
                     }
    }  
    
    Example JavaScript:
     
    // JavaScript:
    var doc = { .... }; // define json 
    // the phone number is doc.contactInfo.phone.$t  
    alert("phone number: " + doc.contactInfo.phone.$t);
    
  5. Repeating elements: Elements that may appear more than once are converted to an array of objects.

    <contactInfo type="home" default="true" >
       <phone type="voice">203-555-1212</phone>  
       <phone type="fax">203-555-1213</phone>
    </contactInfo>
    
    JSON:
    { 
      "contactInfo" : {
                        "type"   : "home",
                        "default": "true",
                        "phone"  : [ 
                                      {
                                       "type" : "voice",
                                       "$t"   : "203-555-1212"
                                      },
                                      {
                                       "type" : "fax",
                                       "$t"   : "203-555-1213"
                                      }
                                    ]
                                   
                      }
    }  
    
    Example:
     
    // JavaScript:  
    // Access phone via array index: doc.contactInfo.phone[0].$t
    var i;
    for (i=0; i < doc.contactInfo.phone.length; i++) {
      alert("phone " + i + " = " + doc.contactInfo.phone[i].$t);
    }
    
  6. If an element has a namespace prefix, the prefix and element name are concatenated using "$". Attribute prefixes are also presented in the same way. For example, <c:contactInfo> is represented as { c$contactInfo: {} }. Attribute xmlns:c="urn:ns:contactinfo" is represented as xmlns$c:"urn:ns:contactinfo". The following example xml uses prefixed elements xmlns:p="urn:ns:person", xmlns:c="urn:ns:contactinfo" and also two elements that are unqualified (email and photo).

     
    <p:person xmlns:p="urn:ns:person">
       <p:firstName>John</p:firstName>
       <p:lastName>Smith</p:lastName>
       <c:contactInfo xmlns:c="urn:ns:contactinfo" type="home" default="true" >
          <c:phone type="voice">203-555-1212</c:phone>  
          <c:phone type="fax">203-555-1213</c:phone>
          <email>jsmith@example.com</email>
       </c:contactInfo>
       <photo>http://example.com/jsmith/profile.png</photo>
    </p:person>
    
    JSON
     
    {
      "p$person" : {
        "xmlns$p" : "urn:ns:person",
        "p$firstName" : {
          "$t" : "John"
        },
        "p$lastName" : {
          "$t" : "Smith"
        },
        "c$contactInfo" : {
          "xmlns$c" : "urn:ns:contactinfo",
          "default" : "true",
          "type" : "home",     
          "c$phone" : [
            {
              "type" : "voice",
              "$t" : "203-555-1212"
            },
            {
              "type" : "fax",
              "$t" : "203-555-1213"
            }
          ],
          "email" : {
            "$t" : "jsmith@example.com"
          }
        },
        "photo" : {
          "$t" : "http://example.com/jsmith/profile.png"
        }
      }
    }
    
    Example:
     
    // JavaScript:
    var doc = { ... }; // JSON representation of person.
    // first Name: /p:person/p:firstName/text()
    alert("firstName =" + doc.p$person.p$firstName.$t);
    
    // photo /p:person/photo/text()
    alert("photo =" + doc.p$person.photo.$t);
    
    // email /p:person/c:contactInfo/email/text()
    alert("email =" + doc.p$person.c$contactInfo.email.$t);
    
    var i;
    for (i=0; i < doc.p$person.c$contactInfo.c$phone.length; i++) {
     alert("phone " + i + "=" + doc.p$person.c$contactInfo.c$phone[i].$t);
    }
    
  7. Default namespace: Instead of using elements with prefixes, you can declare the namespace on each element. For example instead of <c:contactInfo xmlns:c="urn:ns:contactinfo">, you can use <contactInfo xmlns="urn:ns:contactinfo">. This results in JSON object properties without the "$" in middle of the property name which is easier to use. E.g. contactInfo instead of c$contactInfo. The ActiveVOS server always uses this methodology when it serializes (converts) XML to JSON.

    The prefixed element <p:person xmlns:p="urn:ns:person"> used above can be represented using the default namespace of each element (when the namespace changes):

     
    <person xmlns="urn:ns:person">
       <firstName>John</firstName>
       <lastName>Smith</lastName>
       <contactInfo xmlns="urn:ns:contactinfo" type="home" default="true" >
          <phone type="voice">203-555-1212</phone>  
          <phone type="fax">203-555-1213</phone>
          <email xmlns="">jsmith@example.com</email>
       </contactInfo>
       <photo xmlns="">http://example.com/jsmith/profile.png</photo>
    </person>
    

    The following shows the JSON representation and its usage in JavaScript. Note that is easier to read and use compared to JSON properties that are based on concatenation of prefix/element with a $. Both formats work with ActiveVOS, but ActiveVOS always uses the non-prefix method when it converts XML to JSON.

     
    {
      "person" : {
        "xmlns" : "urn:ns:person",
        "firstName" : {
          "$t" : "John"
        },
        "lastName" : {
          "$t" : "Smith"
        },
        "contactInfo" : {
          "xmlns" : "urn:ns:contactinfo",
          "default" : "true",
          "type" : "home",     
          "phone" : [
            {
              "type" : "voice",
              "$t" : "203-555-1212"
            },
            {
              "type" : "fax",
              "$t" : "203-555-1213"
            }
          ],
          "email" : {
            "xmlns" : "",
            "$t" : "jsmith@example.com"
          }
        },
        "photo" : {
          "xmlns" : "",
          "$t" : "http://example.com/jsmith/profile.png"
        }
      }
    }
    
    Example:
     
    // JavaScript:
    var doc = { ... }; // JSON representation of person using default namespace (and no prefixes).
    // first Name:
    alert("firstName =" + doc.person.firstName.$t);
    // (compare above to prefixed version doc.p$person.p$firstName.$t)
    
    // photo 
    alert("photo =" + doc.person.photo.$t);
    // (compare to prefixed version doc.p$person.photo.$t)
    
    // email /p:person/c:contactInfo/email/text()
    alert("email =" + doc.person.contactInfo.email.$t);
    // (compare to doc.p$person.c$contactInfo.email.$t)
    
    var i;
    for (i=0; i < doc.person.contactInfo.phone.length; i++) {
     alert("phone " + i + "=" + doc.person.contactInfo.phone[i].$t);
    }
    

    One advantage of using the non-prefixed method when dealing with JSON representations is that you do not have to determine the actual prefix bound to the element at runtime to access element properties. So, instead of doc.ns1$person.ns5$contactInfo.email.type, you can use doc.person.contactInfo.email.type.

Restrictions on JSON Representation of XML Content

Using AE_JSON_NODE_UTIL JavaScript library

The AE_JSON_NODE_UTIL Javascript object provided by the ae-avc-util.js script file included with this SDK contains a few helper functions that can be used when working with JSON representation of XML data.

FunctionDescription
AE_JSON_NODE_UTIL.getElements(aJsonObject)

Returns JSON objects in an array. Use this when the JSON object represents a repeating element.

  var phones = AE_JSON_NODE_UTIL.getElements(doc.person.contactInfo.phone);
  // phones is an array.
AE_JSON_NODE_UTIL.getText(aJsonObject, aDefaultText)

Returns the text value (the value of $t property) given the JSON object. If the text node does not exist, then the default string value is returned.

  var phones = AE_JSON_NODE_UTIL.getElements(doc.person.contactInfo.phone);
  // get first number or return "Not Available" if number does not exist.
  var phone_number = AE_JSON_NODE_UTIL.getText(phones[0], "Not Available");
  // phone_number is 203-555-1212.
AE_JSON_NODE_UTIL.isXsiNil(aJsonObject)

Returns true if the aJsonObject element exists and it is XSI nilled.

AE_JSON_NODE_UTIL.getAttribute(aJsonObj, aAttributeName, aDefault)

Returns attribute value given its name. If the attribute does not exist, then the default value is returned. Normally you do not have to use this function as you can directly access JSON properties (attributes). This method is useful if your XML has a case where an element child and attribute have the same name (see restrictions above).

  // get list of phones
  var phones = AE_JSON_NODE_UTIL.getElements(doc.person.contactInfo.phone);
  // get phone type (voice, fax etc.)
  var phone_type = AE_JSON_NODE_UTIL.getAttribute(phones[0], "type", "Not Available");
  // phone_type is 'voice'.

JSON/XML Conversion Tool

During development you can use the JSON/XML online conversion tool provided by the ActiveVOS at http://host:port/active-bpel/jsonConverter.html where host and port is the host and port where ActiveVOS server is installed (e.g., localhost:8080). This tool allows you to enter well-formed XML content and convert it to JSON, or enter JSON content and convert it to XML.

Invoking a Process Using JSON

Invoking a process using JSON is similar to the method described for the XML binding endpoint:

  1. Prepare to send an HTTP POST message to the service JSON endpoint at http://host:port/active-bpel/services/JSON/serviceName.
  2. Set the POST header content-type to application/json.
  3. Set POST payload (body content) to be the string version of the JSON request.
  4. Include authorization headers if needed.
  5. Send an HTTP POST message to the service JSON endpoint.

The response from the POST is a HTTP 200/OK response with content-type of application/json. The response body will contain a json service response (as a string). The following snippet shows the HTTP request used to invoke the Loan Approval process via humantaskProcessDemoService service. .

POST /active-bpel/services/JSON/humantaskProcessDemoService HTTP/1.1
Content-Length: 581
Content-Type: application/json; charset=UTF-8
Authorization: Basic YWVhZG1pbjphZWFkbWlu
Host: localhost:8080

{"loanProcessRequest":
  {"xmlns":"http:\/\/schemas.active-endpoints.com\/sample\/LoanRequest\/2008\/02\/loanRequest.xsd",
   "loanType":{"$t":"Automobile"},
   "firstName":{"$t":"John"},
   "lastName":{"$t":"Smith"},
   "dayPhone":{"$t":"2039299400"},
   "nightPhone":{"$t":"2035551212"},
   "socialSecurityNumber":{"$t":"123-45-6789"},
   "amountRequested":{"$t":"15000"},
   "loanDescription":{"$t":"Application to finance the purchase of a Toyota Prius"},
   "otherInfo":{"$t":"Down payment is US$7500"},
   "responseEmail":{"$t":"john.smith@example.com"}
  }
 }

The response to the above request looks like:

HTTP/1.1 200 OK
Content-Type: application/json;charset=utf-8

{"status":
  {"xmlns":"http:\/\/www.active-endpoints.com\/wsdl\/humantaskdemo",
      "$t":"Thank you for applying for the Automobile loan for the amount of US$15000. Your loan is currently pending approval."
  }
}
Faults

A fault response is returned with HTTP error code 500 and content-type application/json:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json;charset=utf-8

{"Fault":
   {"xmlns":"http:\/\/www.active-endpoints.com\/2004\/06\/bpel\/extensions\/",
    "faultcode": 
           {"name":"invalidVariables",
            "namespace": "http:\/\/docs.oasis-open.org\/wsbpel\/2.0\/process\/executable",
            "xmlns":""
            },
     "faultstring":
           {"xmlns":"",
            "$t":" fault error message"
           }
  }
}
Attachments

Similar to XML process invokes, the payload of the HTTP body must be multipart/related content, with the first part being the JSON payload with content-type application/json, followed by additional parts representing the attachments.

POST /active-bpel/services/JSON/humantaskProcessDemoService HTTP/1.1
Content-Type: multipart/related; type="application/json"; start="<part1_id>"; boundary="the_boundary"
Content-Length: 1234
MIME-Version: 1.0
Host: localhost:8080

--the_boundary
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit
Content-ID: <part1_id>

{"loanProcessRequest":
  {"xmlns":"http:\/\/schemas.active-endpoints.com\/sample\/LoanRequest\/2008\/02\/loanRequest.xsd",
   "loanType":{"$t":"Automobile"},
   "firstName":{"$t":"John"},
   "lastName":{"$t":"Smith"},
   "dayPhone":{"$t":"2039299400"},
   "nightPhone":{"$t":"2035551212"},
   "socialSecurityNumber":{"$t":"123-45-6789"},
   "amountRequested":{"$t":"15000"},
   "loanDescription":{"$t":"Application to finance the purchase of a Toyota Prius"},
   "otherInfo":{"$t":"Down payment is US$7500"},
   "responseEmail":{"$t":"john.smith@example.com"}
  }
 }
--the_boundary
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-ID: <part2_id>

[...Text Attachment Content...]
--the_boundary
Content-Type: image/jpeg
Content-ID: <part3_id>
Content-Transfer-Encoding: BASE64
Content-Description: Picture A

[...Image Content...]
--the_boundary--
Attachments Using Multipart/Form-Data

Processes can be invoked using a multipart/form-data type payload (normally used by HTML forms). When using this content-type, ActiveVOS server requires the form-data to contain one field with name _json. The value of this field must contain the JSON request.

POST /active-bpel/services/JSON/humantaskProcessDemoService HTTP/1.1
Content-Type: multipart/form-data; boundary="the_boundary"
Content-Length: 3449
MIME-Version: 1.0
Host: localhost:8080

--the_boundary
Content-Disposition: form-data; name="_json"

{"loanProcessRequest":{"xmlns":"http:\/\/schemas.active-endpoints.com\/sample\/LoanRequest\/2008\/02\/loanRequest.xsd","loanType":{"$t":"Automobile"},"firstName":{"$t":"John"},"lastName":{"$t":"Smith"},"dayPhone":{"$t":"2039299400"},"nightPhone":{"$t":"2035551212"},"socialSecurityNumber":{"$t":"123-45-6789"},"amountRequested":{"$t":"15000"},"loanDescription":{"$t":"Application to finance the purchase of a Toyota Prius"},"otherInfo":{"$t":"Down payment is US$7500"},"responseEmail":{"$t":"john.smith@example.com"}}}
--the_boundary
Content-Disposition: form-data; name="file_1"; filename="picture.gif"
Content-Type: image/gif

[image content]
--the_boundary--

The above request was generated by the HTML form:

<form method='POST'
   enctype='multipart/form-data' action='http://localhost:8080/active-bpel/services/JSON/humantaskProcessDemoService'>

   <!-- JSON message payload in a hidden field named '_json'  -->
   <input type="hidden" name="_json" value='{"loanProcessRequest":{"xmlns":"http:\/\/schemas.active-endpoints.com\/sample\/LoanRequest\/2008\/02\/loanRequest.xsd","loanType":{"$t":"Automobile"},"firstName":{"$t":"FileUploadJohn"},"lastName":{"$t":"Smith"},"dayPhone":{"$t":"2039299400"},"nightPhone":{"$t":"2035551212"},"socialSecurityNumber":{"$t":"123-45-6789"},"amountRequested":{"$t":"15000"},"loanDescription":{"$t":"Application to finance the purchase of a Toyota Prius"},"otherInfo":{"$t":"Down payment is US$7500"},"responseEmail":{"$t":"john.smith@example.com"}}}' />

   File1: <input type="file" name="file_1" /> <br/>

   <input type="submit" value="Upload File"/>
</form>

Normally the multipart/form-data request generation and handling of the response is done using JavaScript (for AJAX style browser applications). Note that the response to a process invoke (with or without attachments) using multipart/form-data, is an application/json response (as shown in previous examples). Since a response from a process can have attachments in addition to the response message (JSON), you can limit the response to the message (JSON) only by specifying messageOnly=true in the query string. Similarly, to restrict the response to contain only the attachments (if the process sends back attachments), use attachmentOnly=true in the query string.

Wrapping JSON Response in a HTML Tag

(Note: the following applies to ActiveVOS 7.1.2 or later.)

Some AJAX based form submit scripts that support file upload expect the return content-type to be text/html (instead of application/json) because of the way scripts target iFrames. In these cases you specify parameter responseContentType=text/html. If the responseContentType present, ActiveVOS uses the value defined by the parameter as the response content-type instead of the default application/json.

A few AJAX Fileupload scripts such as the jQuery Forms Plugin also require responses to multipart/form-data forms POSTs to be wrapped in a HTML element such as the textarea tag. This can be accomplished by using the responseWrap parameter. The value of this paramter should be the HTML element tag name.

The following shows HTML file upload form used by jQuery Forms plugins which requires the response to be returned wrapped in a HTML textarea tag with content-type head of text/html:

<form method='POST'
   enctype='multipart/form-data' action='http://localhost:8080/active-bpel/services/JSON/humantaskProcessDemoService'>

   <!-- JSON message payload in a hidden field named '_json'  -->
   <input type="hidden" name="_json" value='{"loanProcessRequest":{"xmlns":"http:\/\/schemas.active-endpoints.com\/sample\/LoanRequest\/2008\/02\/loanRequest.xsd","loanType":{"$t":"Automobile"},"firstName":{"$t":"FileUploadJohn"},"lastName":{"$t":"Smith"},"dayPhone":{"$t":"2039299400"},"nightPhone":{"$t":"2035551212"},"socialSecurityNumber":{"$t":"123-45-6789"},"amountRequested":{"$t":"15000"},"loanDescription":{"$t":"Application to finance the purchase of a Toyota Prius"},"otherInfo":{"$t":"Down payment is US$7500"},"responseEmail":{"$t":"john.smith@example.com"}}}' />

   <!-- Force response content-type to text/html -->
   <input type="hidden" name="responseContentType" value="text/html" />
   <!-- Return response wrapped in a textarea element -->
   <input type="hidden" name="responseWrap" value="textarea" />   

   File1: <input type="file" name="file_1" /> <br/>

   <input type="submit" value="Upload File"/>
</form>
RESTClient

You can use the RESTClient test application to send JSON data to the ActiveVOS server. Note that the content-type of the payload should be set to application/json.

Invoking a Process with jQuery

The following example shows how to invoke a process using AJAX with jQuery. The scripts used for the request require jQuery 1.3.2+ (http://www.jquery.com) and json2.js (http://www.JSON.org/json2.js). The json2.js script is used to convert a JSON object to a string.

var loanRequestJSON = {"loanProcessRequest":
                    {"xmlns":"http:\/\/schemas.active-endpoints.com\/sample\/LoanRequest\/2008\/02\/loanRequest.xsd",
                     "loanType":{"$t":"Automobile"},
                     "firstName":{"$t":"John"},
                     "lastName":{"$t":"Smith"},
                     "dayPhone":{"$t":"2039299400"},
                     "nightPhone":{"$t":"2035551212"},
                     "socialSecurityNumber":{"$t":"123-45-6789"},
                     "amountRequested":{"$t":"15000"},
                     "loanDescription":{"$t":"Application to finance the purchase of a Toyota Prius"},
                     "otherInfo":{"$t":"Down payment is US$7500"},
                     "responseEmail":{"$t":"john.smith@example.com"}
                    }
                   };
// convert JSON to string using function in json2.js script
var jsonStr = JSON.stringify(loanRequestJSON);

// Send jQuery AJAX POST to http://localhost:8080/active-bpel/services/JSON/humantaskProcessDemoService
$.ajax( {
   url : "http://localhost:8080/active-bpel/services/JSON/humantaskProcessDemoService",
   type : "POST",
   contentType : "application/json; charset=utf-8",
   data : jsonStr, // JSON payload
   dataType : "json", // expected return data type   
   cache : false,
   
   success : function(aJsonResponse, aTextStatus) {
      // callback function on success   
      alert("status=" + aJsonResponse.status.$t);
   },
   
   error : function(aXmlHttpReq, aTextStatus, aErrorThrown) {
     // callback function when an error occurs - including faults.
     // code that checks for response status code and data
     // to determine the type of error and fault.
     // var resp_contentType = aXmlHttpReq.getResponseHeader("Content-Type");
     // var http_statusCode = aXmlHttpReq.status;
     // var http_statusMsg = aTextStatus;
   }
});

The AE_AJAX_SERVICE_UTIL Javascript object in the ae-avc-util.js script included with the SDK provides has a convenience function postJSON(url, jsonRequest, successCallbackFn, faultCallbackFn, errorCallbackFn) helper function to POST JSON data.

var loanRequestJSON = {"loanProcessRequest":
                    {"xmlns":"http:\/\/schemas.active-endpoints.com\/sample\/LoanRequest\/2008\/02\/loanRequest.xsd",
                     "loanType":{"$t":"Automobile"},
                     "firstName":{"$t":"John"},
                     "lastName":{"$t":"Smith"},
                     "dayPhone":{"$t":"2039299400"},
                     "nightPhone":{"$t":"2035551212"},
                     "socialSecurityNumber":{"$t":"123-45-6789"},
                     "amountRequested":{"$t":"15000"},
                     "loanDescription":{"$t":"Application to finance the purchase of a Toyota Prius"},
                     "otherInfo":{"$t":"Down payment is US$7500"},
                     "responseEmail":{"$t":"john.smith@example.com"}
                    }
};
AE_AJAX_SERVICE_UTIL.postJSON(
 // service url
 "http://localhost:8080/active-bpel/services/JSON/humantaskProcessDemoService",
 
 // JSON request object (not string)
 loanRequestJSON,
 
 // success callback of JSON data
 function(aJsonResponse) {
   alert("status=" + aJsonResponse.status.$t);
 },
 
 // fault callback of JSON data
 function(aJsonFault) {
   // handle fault
 }, 
  
 // http error callback
 function(aStatusCode, aStatusMessage) {
   // handle transport error
 }
);

Here is another example that uses the WS-HumanTask (WSHT) API getMyTasks operation via JSON. This example fetches tasks via the API and populates a HTML table with the results.

 <! --  html snippet -->
<table cellpadding="2" border="1">
   <thead>
      <tr><th colspan="5">Get My Tasks Response (from JSON):</th></tr>
      <tr><th>Task ID</th> <th>Status</th><th>Owner</th><th>PresentationName</th><th>PresentationSubject</th></tr>
   </thead>
   <! --  the table body will be populated using JavaScript -->
   <tbody id="taskList">
   </tbody>
</table> 
// getMyTasks reqests
var getMyTasksRequest = { 
     "getMyTasks" : {
             "xmlns" : "http://www.example.org/WS-HT/api/xsd",
             "taskType" : { "$t" : "TASKS" },
             "genericHumanRole" : { "$t" : "POTENTIAL_OWNERS" },
             "status" : { "$t" : "READY" },
             "maxTasks" : { "$t" : "10" }
   }
};

 // send JSON 
AE_AJAX_SERVICE_UTIL.postJSON(
    // task-client service url
    "http://localhost:8080/active-bpel/services/JSON/AeB4PTaskClient-taskOperations",    
    // req.
    getMyTasksRequest,    
    // success callback of JSON data
    function(aJsonResponse) {
      // display results in a table
      populateTaskList(aJsonResponse);
    },    
    // fault callback of JSON data
    function(aJsonFault) {
       alert("Fault!");
    },      
    // http error callback
    function(aStatusCode, aStatusMessage) {        
      alert("Transport error: " + aStatusCode + " " + aStatusMessage);
    }
);

//
// This function takes a getMyTasksResponse element (in JSON) and populates
// the tasks in an HTML table.
//
function populateTaskList(aJsonResponse) {
    // Note: aJsonResponse contains getMyTasksResponse object)
    // clear current contents by removing all children of the table (table rows)
    $("#taskList").empty();
    // check to make sure response exists.
    if (!aJsonResponse.getMyTasksResponse) {
        alert("Response 'getMyTasksResponse' expected.");
        return;
    }
    // get list of task abstracts (//htdt:getMyTasksResponse/htdt:taskAbstract)
    var taskAbstracts = AE_JSON_NODE_UTIL.getElements(aJsonResponse.getMyTasksResponse.taskAbstract);
    var i;
    // for each taskAbstract, build the html row and append to table tbody.
    for (i = 0; i < taskAbstracts.length; i++) {
      var html =  "<tr>";
      html += "<td>" + AE_JSON_NODE_UTIL.getText(taskAbstracts[i].id, "n/a") + "</td>";
      html += "<td>" + AE_JSON_NODE_UTIL.getText(taskAbstracts[i].status, "n/a") + "</td>";
      html += "<td>" + AE_JSON_NODE_UTIL.getText(taskAbstracts[i].actualOwner, "n/a") + "</td>";
      html += "<td>" + AE_JSON_NODE_UTIL.getText(taskAbstracts[i].presentationName, "n/a") + "</td>";
      html += "<td>" + AE_JSON_NODE_UTIL.getText(taskAbstracts[i].presentationSubject, "n/a") + "</td>";
      html += "</tr>";
      // append to table
      $("#taskList").append(html);
    };    
}

Using AE_AJAX_SERVICE_UTIL Functions

The AE_AJAX_SERVICE_UTIL Javascript object (in ae-avc-util.js) has the following utility functions related to making JSON invokes.

FunctionDescription
AE_AJAX_SERVICE_UTIL.getActiveVOSServiceUrl(serviceNamePath)

A helper function that creates the endpoint URL to the given service name by appending the service name to a predefined engine endpoint. The engine URL should be assigned (at the start of your script) to the global variable AE_ACTIVEVOS_ENGINE_URL. If a value to AE_ACTIVEVOS_ENGINE_URL is not assigned, then http://localhost:8080/active-bpel is used.

If a value is assigned to the global variable AE_ACTIVEVOS_PROXY_URL, then this function returns the proxy URL with service URL in the query string in a parameter named destination. See example below.

// Define engine context URL and optional proxy URL at the start of your script.
// If the engine URL is not given, then 'http://localhost:8080/active-bpel' is used.

// Note: AE_ACTIVEVOS_ENGINE_URL is global variable declared in ae-avc-util.js. 
// You only need to assign it a value (to server /active-bpel context).
AE_ACTIVEVOS_ENGINE_URL = "http://demoserver:81/active-bpel"; 

// Optionally, if you are using a proxy for AJAX requests, you can 
// assign it a value here:
// AE_ACTIVEVOS_PROXY_URL = "http://localhost:8080/proxy";

// E.g. JSON service URL.
var loanServiceXmlUrl = AE_AJAX_SERVICE_UTIL.getActiveVOSServiceUrl("JSON/humantaskProcessDemoService");
// loanServiceXmlUrl is now equivalent to: AE_ACTIVEVOS_ENGINE_URL + "/services/" + "JSON/humantaskProcessDemoService"
// e.g. : http://demoserver:81/active-bpel/JSON/humantaskProcessDemoService

// If a value to AE_ACTIVEVOS_PROXY_URL is assigned, then the 'loanServiceXmlUrl' becomes part of
// the proxy url string parameter named 'destination'.
// e.g: http://localhost:8080/proxy?destination=http://demoserver:81/active-bpel/JSON/humantaskProcessDemoService

// E.g. XML service URL.
var loanServiceXmlUrl = AE_AJAX_SERVICE_UTIL.getActiveVOSServiceUrl("XML/humantaskProcessDemoService");
AE_AJAX_SERVICE_UTIL.postJSON(aServiceUrl, aJsonData, aOnSuccessFn, aOnFaultFn, aOnErrorFn, aTimeOut)

Sends the JSON request to the server using HTTP POST and calls back with the JSON response. This function also handles error responses and callbacks either the JSON fault handler or the HTTP transport level error handler. Only the aServiceUrl and aJsonData are required.

var serviceUrl = "http://localhost:8080/active-bpel/JSON/humantaskProcessDemoService";
// or serviceUrl=AE_AJAX_SERVICE_UTIL.getActiveVOSServiceUrl("JSON/humantaskProcessDemoService");

// send JSON 
AE_AJAX_SERVICE_UTIL.postJSON(
  serviceUrl, // service url
  jsonRequest, // request JSON object
 
 function(aJsonResponse) { // success callback of JSON data
   // handle success response
   alert("Success!");
 },    
 
 function(aJsonFault) { // fault callback of JSON data
    alert("Fault!");
 },      
 
 function(aStatusCode, aStatusMessage) { // http error callback
   alert("Transport error: " + aStatusCode + " " + aStatusMessage);
 }
);

JSON Process Invoke Examples

Complete working JSON Process Invoke examples can be found in the /examples/javascript/ directory.

  • json-loanRequest.html : shows how to submit an html form to invoke the Loan process using JSON
  • json-getMyTasks.html : shows how to interact with the WSHT getMyTasks API operation using JSON
  • json-getMyTasks_JSONP.html : same as above, but using JSONP.
  • json-getInstance.html : shows how to interact with the Active Endpoints WSHT API extension. This example uses the getInstance() operation to fetch task instance details, including input and output data
  • To use these examples, you must deploy all files in this folder to the application server or web server where the ActiveVOS engine is deployed. For example, when using the Designer and its embedded server, you can deploy the provided activevos-javascript-examples.war:

    1. Navigate to the embedded server active-bpel webapps folder. E.g:

      C:\Program Files\ActiveVOS\Designer\designer\dropins\activevos\eclipse\plugins\org.activebpel.enginep_7.1.2\server\webapps\

    2. Copy the /examples/activevos-javascript-examples.war war file to web apps folder.
    3. Start the embeded server.

    The examples should be available at http://localhost:8080/active-bpel/activevos-javascript-examples/index.html

    Accessing the WS-Human Tasks (WSHT) API via JSON

    Constants for Common String Literals

    The AE_TASK_GLOBALS in ae-avc-tasks.js contains common constants that can be used from your code. For example, the string 'illegalArgument' (WSHT fault name) is defined in AE_TASK_GLOBALS.TASK_FAULT_NAMES.ILLEGAL_ARGUMENT. The 'http://www.example.org/WS-HT' namespace is defined in AE_TASK_GLOBALS.NAMESPACES.XMLNS_HTD. Additional details are available in the AeTaskGlobals class in ae-avc-tasks.js script.

    Utility Functions

    The getMyTasks example provided in the Invoking a Process with jQuery section (the full example is located in json-getTasks.htm) demonstrated how to send a WSHT getMyTasks request to the server using AE_AJAX_SERVICE_UTIL.postJSON() util function. The ae-avc-tasks.js script contains AE_TASK_UTIL instance with the following convenience functions:

    FunctionDescription
    AE_TASK_UTIL.getFaultData(aJsonFault)

    Returns an object {faultName : "wshtFaultName", message : "faultMessageStr"} or null if the aJsonFault is not a WSHT SOAP fault. The 'wshtFaultName' values are per WSDL - illegalArgument, illegalAccess, illegalOperation and recipientNotAllowed.

    // code that handles fault due to a human task operation invoke.
    // check if this is a WSHT fault
    var faultData = AE_TASK_UTIL.getFaultData(aJsonFault);
    if (faultData != null) {
      // wsht fault.
      if (faultData.faultName == AE_TASK_GLOBALS.TASK_FAULT_NAMES.ILLEGAL_ARGUMENT) {
          alert("illegal arg fault: " + faultData.message);
      }
    } else {
      // system soap fault?
      var soapFaultData = AE_AJAX_SERVICE_UTIL.getSystemFault(aJsonFault);
      if (soapFaultData != null) {
        alert("SOAP fault. Fault name:" + soapFaultData.name 
               + ", message:" + soapFaultData.message);
      }
    }
    
    AE_TASK_UTIL.isFault(aJsonResponse)

    Returns true if the json object 'aJsonResponse' is a known WSHT fault (per WSDL).

    AE_TASK_UTIL.createGetTasksRequest(aParams, aGetTasksTemplate)

    Creates a generic request getTasks request and returns the JSON object. The params object contains the optional values. The options are:

    • taskType : string - ALL, TASKS or NOTIFICATIONS. Default is TASKS.
    • genericHumanRole : string - generic human role such as potential owners.
    • status : string or array of strings for the task status (such as READY).
    • whereClause : string
    • maxTasks : integer - maximum number of tasks to retrieve. Default is 20.
    • taskIndexOffset : integer - task list start offset index.
    • searchBy: search by string.

    Provide a value of null to remove existing elements.

    If the optional aGetTasksTemplate object, which is an existing JSON request is given, then aGetTasksTemplate is first cloned, and then the params are applied.

    To create the following request:

    <aeb:getTasks 
     xmlns:aeb="http://schemas.active-endpoints.com/b4p/wshumantask/2007/10/aeb4p-task-state-wsdl.xsd" >
        <htdt:getMyTasks xmlns:htdt="http://www.example.org/WS-HT/api/xsd">
           <htdt:taskType>TASKS</htdt:taskType>
           <htdt:genericHumanRole>POTENTIAL_OWNERS</htdt:genericHumanRole>
           <htdt:status>READY</htdt:status>
           <htdt:status>RESERVED</htdt:status>
           <htdt:maxTasks>5</htdt:maxTasks>
       </htdt:getMyTasks>
       <aeb:taskIndexOffset>0</aeb:taskIndexOffset>
    </aeb:getTasks>
    

    Normally, you will need to create the JSON object:

    var getTasksRequest = {
      "getTasks" : {
        "xmlns" : "http://schemas.active-endpoints.com/b4p/wshumantask/2007/10/aeb4p-task-state-wsdl.xsd",
        "getMyTasks" : {
          "xmlns" : "http://www.example.org/WS-HT/api/xsd",
          "taskType" : { "$t" : "TASKS" },
          "genericHumanRole" : { "$t" : "POTENTIAL_OWNERS" },
          "status" : [ {"$t" : "READY"} , {"$t" : "RESERVED"} ],
          "maxTasks" : { "$t" : "5"}
        },
        "taskIndexOffset" : { "$t" : "0" }
      }
    }
    

    With the AE_TASK_UTIL.createGetTasksRequest() function, the code to create the above request is:

    var getTasksRequest = AE_TASK_UTIL.createGetTasksRequest( {
         taskType : "TASKS",
         genericHumanRole : "POTENTIAL_OWNERS",
         status : ["READY", "RESERVED"],
         maxTasks : 5,
         taskIndexOffset : 0
     });
     // getTasksRequest contains JSON for <getTasks/> element used 
     // in getTasks operation for AE specific API extension at AEB4P-aeTaskOperations
     // service.
     
     // The WSHT getMyTasks request can be extracted in the following way:
     var wshtGetMyTasksRequest = { "getMyTasks" : getTasksRequest.getTasks.getMyTasks };
    
    WSHT API

    The AeTaskApi class (in ae-avc-tasks.js script) can be used to access and operate on tasks. A few common functions are shown below. Please refer to AeTaskApi in ae-avc-tasks.js for additional functions and details.

    FunctionDescription
    getTasks(aGetTasksRequest, aSuccessCallbackFn, aFaultCallbackFn, aErrorCallbackFn)

    Invokes the getTasks operation for Active Endpoints (AE) specific API extension at AEB4P-aeTaskOperations service. On success the response callback returns the JSON equivalent of the <htdt:getMyTasksResponse/> element.

     
    // Assign the server URL to AE_ACTIVEVOS_ENGINE_URL global variable. This is where the service
    // requests are sent. (note: AE_ACTIVEVOS_ENGINE_URL is global variable declared in ae-avc-util.js.)
    AE_ACTIVEVOS_ENGINE_URL = "http://localhost:8080/active-bpel"; 
    
    
    // create JSON request for getTasks operation. E.g. get upto 10 unclaimed tasks.
    var getTasksRequest = AE_TASK_UTIL.createGetTasksRequest( {
         taskType : AE_TASK_GLOBALS.GETMYTASKS_TASK_TYPE.TASKS, // same as string "TASKS"
         genericHumanRole : AE_TASK_GLOBALS.GENERIC_HUMAN_ROLE.POTENTIAL_OWNERS, // same as string "POTENTIAL_OWNERS"
         status : AE_TASK_GLOBALS.TASK_STATUS.READY,  // "READY"
         maxTasks : 10
    });
    
    // Create AeTaskApi object and get the task list via getTasks() operation.
    var taskApi = new AeTaskApi();
    taskApi.getTasks(
       getTasksRequest, // request JSON object
       
       function(aJsonResponse) { // success callback of JSON data
          // handle success response
          alert("Success!");
          // get list of task abstracts (//htdt:getMyTasksResponse/htdt:taskAbstract)
          var jsonTaskAbstracts = AE_JSON_NODE_UTIL.getElements(aJsonResponse.getMyTasksResponse.taskAbstract);  
          var i;
          for (i = 0; i < jsonTaskAbstracts.length; i++) {
             // wrap json data in AeTaskAbstract object for convenience accessors. 
             // (see ae-avc-tasks.js for AeTaskAbstract)
             
             var taskAbstractObj = new AeTaskAbstract( jsonTaskAbstracts[i] );
             alert( "Task id: " + taskAbstractObj.getId() );
             alert( "Task name: " + taskAbstractObj.getName() );
             alert( "Task status: " + taskAbstractObj.getStatus() );          
          }          
       },    
     
       function(aJsonFault) { // fault callback of JSON data
          alert("Fault!");
       },      
     
       function(aStatusCode, aStatusMessage) { // http error callback
          alert("Transport error: " + aStatusCode + " " + aStatusMessage);
       }
    );
     
    getInstance(aTaskId, aSuccessCallbackFn, aFaultCallbackFn, aErrorCallbackFn)

    Invokes the AE specific getInstance() operation on the extension service at AEB4P-aeTaskOperations service. On success the callback is an AeTask object (see ae-avc-tasks.js).

    // ...
    // setup AE_ACTIVEVOS_ENGINE_URL etc.
    // ...
    
    var taskApi = new AeTaskApi();
    taskApi.getInstance(
       "urn:b4p:1235", // task ID   
       
       function(aTask) { // handle success response      
          // aTask is an instance of AeTask (see ae-avc-tasks.js).
          alert( "Got task, id=" + aTask.getId() );
          alert( "Task name: " + aTask.getName() );
          alert( "Task status: " + aTask.getStatus() ); 
          // aTask.getJson() returns the underlying raw JSON data structer.
          // aTask.getOwner() returns current owner.
          var inputPartJson = aTask.getInput(); (// for input by partname, use aTask.getInput('nameOfPart');
       },    
     
       function(aJsonFault) {
          alert("Fault!");
       },       
       function(aStatusCode, aStatusMessage) {
          alert("Transport error: " + aStatusCode + " " + aStatusMessage);
       }
    );
    
    invokeSimpleWshtRequest(aCommand, aTaskId, aSuccessCallbackFn, aFaultCallbackFn, aErrorCallbackFn)

    Invokes a simple WSHT operation such as claim against the given task id. The supported list of operation commands are defined in AE_TASK_GLOBALS.SIMPLE_WSHT_OPERATIONS constant.

    var taskApi = new AeTaskApi();
    var taskId = "urn:b4p:1234";
    // claim
    taskApi.invokeSimpleWshtRequest(
       AE_TASK_GLOBALS.SIMPLE_WSHT_OPERATIONS.CLAIM,
       taskId,
       function(aClaimResponse) {
          // success (json data)
       },
       function(aFaultResponse) {
          // fault (json data)
       },
       function(aStatusCode, aStatusMessage) {
          //error
       }
    );
    
    // start
    taskApi.invokeSimpleWshtRequest(
       AE_TASK_GLOBALS.SIMPLE_WSHT_OPERATIONS.START,
       taskId,
       function(aStartResponse) {
          // success (json data)
       },
       // ... fault and error handlers omitted for brevity ...
    );
    
    // complete
    taskApi.invokeSimpleWshtRequest(
       AE_TASK_GLOBALS.SIMPLE_WSHT_OPERATIONS.COMPLETE,
       taskId,
       function(aStartResponse) {
          // success (json data)
       },
       // ... fault and error handlers omitted for brevity ...
    );    
    
    setOutput(aTaskId, aPartName, aOutputPart, aSuccessCallbackFn, aFaultCallbackFn, aErrorCallbackFn)

    Sets the task output data given the task ID, the output part name and the output JSON data

    var taskApi = new AeTaskApi();
    var taskId = "urn:b4p:1234";
    // message part name per wsdl
    var partName = "response";
    // the <loan:loanApprovalResponse /> in JSON. 
    var outputJson = {"loanApprovalResponse":
                         {
                           "xmlns":"http:\/\/schemas.active-endpoints.com\/avoscentral\/LoanRequest\/2009\/07\/avc-loanapproval.xsd",
                           // other attributes and elements omitted for brevity.
                         }
                    };
    // set output data
    taskApi.setOutput(
       taskId,
       partName,
       outputJson,
       function(aSetOutputResponse) {
          // success (json data)
       },
       function(aFaultResponse) {
          // fault (json data)
       },
       function(aStatusCode, aStatusMessage) {
          //error
       }
    );
    
    
    AeTask

    The AeTask class (in ae-avc-tasks.js script) is a wrapper for the <taskInstance /> element. This wrapper provides getters and setters for frequently used properties.

    One way to get an instance of AeTask is using the AeTaskApi.getInstance(...) function:

    // ...
    // setup AE_ACTIVEVOS_ENGINE_URL etc.
    // ...
    
    var taskApi = new AeTaskApi();
    taskApi.getInstance(
       "urn:b4p:1235", // task ID   
       
       function(aTask) { // handle success response      
          // aTask is an instance of AeTask (see ae-avc-tasks.js).
          alert( "Got task, id: " + aTask.getId() );
          alert( "Task name: " + aTask.getName() );
          alert( "Task status: " + aTask.getStatus() ); 
          // aTask.getJson() returns the underlying raw JSON data structer.
          // aTask.getOwner() returns current owner.
       },    
     
       function(aJsonFault) {
          alert("Fault!");
       },       
       function(aStatusCode, aStatusMessage) {
          alert("Transport error: " + aStatusCode + " " + aStatusMessage);
       }
    );
    

    Please refer to AeTask in ae-avc-tasks.js for additional functions and details. Getters and Setters to task input/output data are described below:

    FunctionDescription
    getInputPart(aPartName)

    Returns the task input part data given the part name (per WSDL message). If the aPartName is not given, then the first available part is returned.

    //
    // task is an instance of AeTask, obtained via AeTaskApi.getInstance(...)
    // (assuming using the Loan Approval human task example)
    //
    //   <message name="WshtLoanInput">
    //      <part name="request" element="loan:loanProcessRequest" />
    //   </message>
    //   <message name="WshtLoanOutput">
    //      <part name="response" element="loan:loanApprovalResponse" />
    //   </message> 
    
    var loanRequestInput = task.getInput("request"); // 'request' is the part name
    // note: task.getInput() returns first available part since part name is not given.
    alert("Firt Name = " + loanRequestInput.loanProcessRequest.firstName);
    alert("Loan Amount = " + loanRequestInput.loanProcessRequest.amountRequested);
    
    getOutputPart(aPartName)

    Returns the task out part data given the part name (per WSDL message). If the aPartName is not given, then the first available part is returned. If part data is not available, then null is returned.

    
    var loanOutput = task.getOutput("response"); // 'response' is the output part name
    // check for null in case output is not set.
    if (loanOutput != null) {
       alert("Approved? = " + loanOutput.loanApprovalResponse.responseToLoanRequest);
    }
    
    setOutputPart(aPartName, aPartData)

    Sets the output part data in the AeTask instance (in-memory). This method does not 'save' (invoke WSHT setOutput on the server). To save, you must either use AeTask.saveOutputParts (preferred) or AeTaskApi.setOutput(...).

    // First time use, create JSON output:
    //  var loanOutput = { {"loanApprovalResponse" : ... }};
    // or getOutput() to access current value if the output has already been set.
    var loanOutput = task.getOutput("response");
    // modify data
    AE_JSON_NODE_UTIL.setText(loanOutput.loanApprovalResponse.responseDescription, "Some Text");
    
    // Set output (in-memory only)
    task.setOutput("response", loanOutput);
    
    // Now, save all available parts to the server using the AeTaskApi.
    var taskApi = new AeTaskApi();
    task.saveOutputParts(
       taskApi,
       function(aSetOutputResponse) {
          // success (json data)
       },
       function(aFaultResponse) {
          // fault (json data)
       },
       function(aStatusCode, aStatusMessage) {
          //error
       }
    );   
    
    Task Attachment URL

    In some cases, you may want to display attachment information on a web page. In order to do this, you need to access the list of attachment meta data (attachment infos) from the WSHT getAttachmentInfos operation or via the attachmentInfo elements that are part of taskInstance (obtained from getInstance extension operation).

    The URL to the attachment content can be built using the AE_TASK_UTIL.getAttachmentUrl(taskId, attachmentName, attachmentId) function.

    //
    // 1) Using getAttachmentInfos wsht API call.
    //
    var taskId = "urn:b4p:1235"; // task id
    var getAttachmentInfosReq = {
      "getAttachmentInfos" : {
        "xmlns" : "http://www.example.org/WS-HT/api/xsd",
        "identifier" : {
          "$t" : taskId
        }
      }
    };
    AE_AJAX_SERVICE_UTIL.postJSON(
        // task-client service url
        "http://localhost:8080/active-bpel/services/JSON/AeB4PTaskClient-taskOperations",    
        // req.
        getAttachmentInfosReq,    
        // success callback of JSON data
        function(aJsonResponse) {
          // handle getAttachmentInfosResponse
          var attachmentInfoList =  AE_JSON_NODE_UTIL.getElements(aJsonResponse.getAttachmentInfosResponse.info);
          var i;
          for (i = 0; i < attachmentInfoList; i++) {
             var info = attachmentInfoList[i];
             var attachmentId = AE_JSON_NODE_UTIL.getText(info.attachmentId);
             var attachmentName = AE_JSON_NODE_UTIL.getText(info.name);  // file name
             var contentType = AE_JSON_NODE_UTIL.getText(info.contentType);  // mime type.       
             var attachUrl = AE_TASK_UTIL.getAttachmentUrl(taskId, attachmentName, attachmentId);         
             // do something with this info such as displaying on page.
             // (the attachUrl can be used for href attribute in <a> tags and src in <img> tags)
          }  
        },    
        // fault callback of JSON data
        function(aJsonFault) {
           alert("Fault!");
        },      
        // http error callback
        function(aStatusCode, aStatusMessage) {        
          alert("Transport error: " + aStatusCode + " " + aStatusMessage);
        }
    );
    
    //
    // 2) Alternate method of getting attachment info via AeTask object.
    //
    var taskApi = new AeTaskApi();
    taskApi.getInstance(
       "urn:b4p:1235", // task ID   
       
       function(aTask) { // handle success response
          var attachmentInfoList =  aTask.getAttachments();
          var i;
          for (i = 0; i < attachmentInfoList; i++) {
             var info = attachmentInfoList[i].attachmentInfo;
             var attachmentId = AE_JSON_NODE_UTIL.getText(info.attachmentId);
             var attachmentName = AE_JSON_NODE_UTIL.getText(info.name);  // file name
             var contentType = AE_JSON_NODE_UTIL.getText(info.contentType);  // mime type.       
             var attachUrl = AE_TASK_UTIL.getAttachmentUrl(aTask.getId(), attachmentName, attachmentId);         
             // do something with this info such as displaying on page.
             // (the attachUrl can be used for href attribute in <a> tags and src in <img> tags
          }  
       },    
     
       function(aJsonFault) {
          alert("Fault!");
       },       
       function(aStatusCode, aStatusMessage) {
          alert("Transport error: " + aStatusCode + " " + aStatusMessage);
       }
    );
    
    

    Working with Schema Date and Time Types

    In cases where the request and response contains xsd:dateTime type elements, the contents of these elements take the form YYYY-MM-DDTHH:MM:SS.sssZ (UTC time). However the user interface in a browser deals with local time instead of UTC. The following functions in the AE_UTIL object in the included ae-avc-utils.js can be used.

    FunctionDescription
    AE_UTIL.xsdDateTimeToJsDateTime(xsdDateTimeStr)

    Parses the ISO8601 xsd dateTime (YYYY-MM-DDTHH:MM:SS.sssZ) string and returns JavaScript Date object.

    // task created on date. E.g: "2010-03-15T17:15:00.881Z" (12.15PM Eastern Time/GMT-5).
    var createdOnXsdStr = AE_JSON_NODE_UTIL.getText(taskAbstracts[i].createdOn);
    // convert to a JavaScript date object.
    var createdDate = AE_UTIL.xsdDateTimeToJsDateTime(createdOnXsdStr);
    
    AE_UTIL.xsdDateToJsDate(xsdDateStr)

    Parses the xsd date (YYYY-MM-DD) string and returns JavaScript Date object.

    AE_UTIL.xsdTimeToJsTime(xsdTimeStr)

    Parses the xsd time (HH:MM:SS) string and returns JavaScript Date object. The returned date object contains the parsed time (but uses current date).

    AE_UTIL.toXsdDateTime(date)

    Converts a JavaScript Date object into a ISO8601 dateTime string (YYYY-MM-DDTHH:MM:SS.sssZ).

    AE_UTIL.toXsdDateTimeFromDateAndTimeStr(date, time)

    The date and time parameters are both JavaScript date objects. This function converts a date and time JavaScript Date objects into a ISO8601 dateTime string (YYYY-MM-DDTHH:MM:SS.sssZ).

    AE_UTIL.toXsdDate(date)

    Converts a JavaScript Date object into a ISO8601 date string (YYYY-MM-DD). Timezone information is not used.

    AE_UTIL.toXsdTime(date)

    Converts a JavaScript Date object into a ISO8601 time string (HH:MM:SS). Timezone information is not used.

    When working with forms that use date and time types, first convert the raw JSON the date/time information (ISO8601) to a Javascript Date object before presenting it to the user (e.g. via AE_UTIL.xsdDateTimeToJsDateTime(...) ). Conversely, the local date/time information from the user should be first converted to a ISO8601 (e.g. via AE_UTIL.toXsdDateTime(...)) before sending it to the ActiveVOS server.

    Using Designer to Create HTML Forms

    You can create HTML forms and basic supporting JavaScript using ActiveVOS Designer (7.1 or later). The Process Request Form action available under File -> New -> Other -> Orchestration brings up a wizard style dialog. From this dialog you can choose your request WSDL, port-type, operation and the destination where the generated HTML file is saved.

    (Click to view larger images)

    Select WSDL port-type and operation.


    Select location where the HTML file will be saved.

    The generated html forms looks similar to (in the case of Loan Approval process):

    The basic structure of a generated request form HTML looks like the following:

    <html>
       <head>
         <!-- header content -->
       </head>
       <body>
    
         <!-- 
               Main DIV that contains all markup
               related to this request form UI
         -->
         <div id="processRequestForm$ID">
    
             <!-- DIV that contains UI related request form and data entry -->
             <div id="processRequestForm$ID">
             
                 <div>Display Name UI</div>
                 
                 <!-- container for the form UI controls -->
                 <div>
                 
                   <form id="loanApplicationInputForm$ID">
                      <!-- actual form content, for example: -->
                      First Name: <input id="firstName$ID" name="firstName" value="" size="50" /> <br/>
                       Last Name: <input id="lastName$ID"  name="lastName" value="" size="50" /> <br/>
                   </form>
                   
                   <!-- Send button -->
                   <input type="button" id="sendRequest$ID" value="Send Request" />
                   
                 </div>
             
             </div>
    
             <!-- 
                  DIV that contains html to show
                  the results after submitting a form (invoking a process).
                  Note this DIV is initially hidden, and only shown when
                  response data needs to be displayed.
             -->
             <div id="responseContainer$ID" style="display: none;">
             </div>
         </div>
         
         <!-- Script -->
         <script type="text/javascript">
           // <![CDATA[
           // JavaScript to implement JSON process invoke
           // ]]>
         </script>
              
       </body>
    </html>
    

    The HTML above is a skeleton used to illustrate various elements used in ActiveVOS Designer generated forms. The actual form may be a little more detailed and is targeted for use with jQuery and jQueryUI. Note that all elements used in the form have an id attribute. The id attribute is used as the primary selector when ActiveVOS needs to access various elements within the HTML document. Also note that the id attribute values that are generated end with the $ID suffix (for example processRequestForm$ID in <div id="processRequestForm$ID">).

    All elements in an HTML document must have unique values for the id attribute. In cases where you need to display the same form more than once (a requirement of ActiveVOS Central), the elements cannot be duplicated with the same values for the id attribute. When the forms are used with ActiveVOS Central, the forms server automatically replaces the $ID suffix with a unique value so that a form can be cloned and used in the same HTML document. For example, at runtime ActiveVOS Central may have two loan request form instances <div id="processRequestForm_01"> and <div id="processRequestForm_02"> (note where $ID has been replaced with _01 and _02 in this example).

    Since this document pertains to using single instance of forms (outside of ActiveVOS Central), you can use the generated html as is after performing a search-and-replace of $ID suffix with any string that does not have a $. For example, if all occurrences of $ID is replaced with an empty value, you essentially remove the $ID suffix. E.g. <div id="processRequestForm$ID"> becomes <div id="processRequestForm">.

    Using jQuery form input data can be used with the id selectors. For example getting the current value of the firstName input field is $("#firstName$ID").val(). The field value can be prepopulated with data using $("#firstName$ID").val("John"). The complete script that drives the form can be found at the end of the form in the <script> section. The basic mechanics of the script looks similar to following skeleton code :

    // The jQuery 'ready' event is fired once the page (form) is loaded and ready for processing. 
    $(document).ready(function() {
       // bind button click event handler code when the Send button is pressed.
       $("#sendRequest$ID").click( function() {
           sendForm();  // see fn below.
       });
    });
    
    // send form
    function sendForm() {
      // first grab data entered by user.
      var firstNameStr = $("#firstName$ID").val();
      // ..
      // .. get other UI data such as loanType, lastName, phone etc.
      // ..
      
      // build JSON request
      var loanRequestJSON = {"loanProcessRequest":
         {"xmlns":"http:\/\/schemas.active-endpoints.com\/sample\/LoanRequest\/2008\/02\/loanRequest.xsd",
          "loanType":{"$t": loanTypeStr},
          "firstName":{"$t":  firstNameStr},
          "lastName":{"$t":  lastNameStr},
          "dayPhone":{"$t":  dayPhoneStr},
          "nightPhone":{"$t":  nightPhoneStr,
          "socialSecurityNumber":{"$t":  ssnStr},
          "amountRequested":{"$t":  loanAmount},
          "loanDescription":{"$t":  loanDesc},
          "responseEmail":{"$t":  email}         
         }
      };
      
      // JSON endpoint URL (e.g: http://localhost:8080/active-bpel/services/JSON/humantaskProcessDemoService)
      var loanServiceUrl = AE_AJAX_SERVICE_UTIL.getActiveVOSServiceUrl("JSON/humantaskProcessDemoService");
      
      // send JSON request 
      AE_AJAX_SERVICE_UTIL.postJSON(
        loanServiceUrl,
        loanRequestJSON,
        function(aJsonResponse) {
          // success result handler:      
          // show <status/> element text in the response div.
          var statusText = AE_JSON_NODE_UTIL.getText(aJsonResponse.status);
          // (above is same as aJsonResponse.status.$t)
          
          // append the status text string to the <div id="responseContainer$ID" /> div
          $("#responseContainer$ID").html("<p>Status=" + statusText + "</p>");
          
          // show the div (since it was initially hidden)
          $("#responseContainer$ID").show();
        },    
        function(aJsonFault) {
           alert("Fault!");
        },      
        function(aStatusCode, aStatusMessage) {        
          alert("Transport error: " + aStatusCode + " " + aStatusMessage);
        }
      );  
    }
    

    The code above demonstrates the approach taken to handle form submissions. The actual code in the generated form is a little more detailed, but still follows the methodology described above. In the generated code the script related to a form is enclosed in a function:

    // Function that encapsulates the form script.
    var AeRequestForm$ID = function() {
         // variable defining the name of service
         var mServiceName = "humantaskProcessDemoService";
         
         //
         // internal functions: pseudo code shown below for brevity
         //
         
         // This function is called when the form is loaded.
         function documentReady() {
           // initialize and populate UI here.
           // code to bind the SendButton click event to invoke _submitRequest() function
           // also invoke _setupValidation();
         }
    
         // function is called (by documentReady() )
         function _setupValidation() {
           // optional code to setup & initialize your form data validation
         }
         
         // Function returns the JSON data structure for this operation
         function getInputRequest() {
           // code that creates JSON object. For example:
           // var json = { "loanProcessRequest": {...} };
           // return json; 
         }
              
         // function called when the Send Request button is pressed.
         function _submitRequest() {
           // 1. validate the form by calling avcform_validate(). 
           // 2. var jsonReq = getInputRequest();
           // 3. get form UI data and populate jsonReq object
           // 4. serviceUrl = AE_AJAX_SERVICE_UTIL.getActiveVOSServiceUrl("JSON/" + mServiceName);
           // 5. invoke json request via:
           //      AE_REQUESTS_UTIL.postJSON(serviceUrl, jsonReq, _showResponseCallback,  ....);
           //    
         }
         
         // validate the form
         function avcform_validate() {
          // check form date and validate (e.g. verify required fields have data etc.)
          // return true if user submitted data is valid
         }
         
         // Called by postJSON(..) code in _submitRequest() function.   
         function _showResponseCallback(aJsonResponse) {
          // called to display response from a json invoke
         }
         
         // Called by postJSON(..) code in _submitRequest() function.   
         function _showFaultCallback(aJsonFault) {
          // handle fault
         }
       
         // Called by postJSON(..) code in _submitRequest() function.   
         function _communicationErrorCallback(aStatusCode, aError) {
          // error handler code
         }  
    }
    
    // The jQuery 'ready' event is fired once the page (form) is loaded 
    // and ready for processing. 
    $(document).ready(function() {   
       // Create Request Form JavaScript object
       var requestForm = new AeRequestForm$ID();
       // initialize form
       requestForm.documentReady();   
    });
    

    Making Cross Domain AJAX Requests

    Cross Domain Proxy

    One approach to making cross domain AJAX request is to use a proxy. In this scenario, your script calls an endpoint on your web application server that is hosting your script and application. That endpoint in turn forwards (proxies) all requests to the actual destination (e.g. ActiveVOS engine where your services are hosted).

    JSON with Padding (JSONP)

    (Note: the following applies to ActiveVOS 7.1.2 or later.)

    JSONP requests are supported in ActiveVOS 7.1.2 engine. When making JSONP request, the string version of the JSON data must be sent in a parameter named _json and the callback function name via parameter named callback (if a value is not given, then the engine will callback on a function named jsonpCallback). Since JSONP requests are based on HTTP GET method, the amount of data that can be sent in a HTTP query string is limited. This means, JSONP requests are better suited for request messages whose payload is small. Note that attachments are not supported with JSONP.

    The basic format of a JSONP request to service deployed on ActiveVOS is:

    http://host:port/active-bpel/services/JSON/serviceName?callback=callbackFnName&_json=string_version_of_json
    

    You can use the helper function AE_AJAX_SERVICE_UTIL.getJSON(...) for JSONP.

    var getTasksRequest = {
        "getMyTasks" : 
          {
           "xmlns" : "http://www.example.org/WS-HT/api/xsd",
           "taskType" : { "$t" : "TASKS" },
           "genericHumanRole" : { "$t" : "POTENTIAL_OWNERS" },
           "status" : [ {"$t" : "READY"} , {"$t" : "RESERVED"} ],
           "maxTasks" : { "$t" : "5"}
          }
    };
    
    // get task list using JSONP
    AE_AJAX_SERVICE_UTIL.getJSON(
         // task-client service url
         "http://localhost:8080/active-bpel/services/JSON/AeB4PTaskClient-taskOperations",   
         // req.
         getMyTasksRequest,   
         // success callback of JSON data
         function(aJsonResponse) {
           alert("Success!");
           // handle result. e.g. display results in a table
         },   
         // fault callback of JSON data
         function(aJsonFault) {
            alert("Fault!");
         },     
         // http error callback
         function(aStatusCode, aStatusMessage) {       
           alert("Transport error: " + aStatusCode + " " + aStatusMessage);
         }
    );