Creating Extension Points

You create extension points to extend the Redwood Server user interface with custom context menu actions, create specific servlets for 3rdparty applications, or integrate 3rdparty applications into Redwood Server

The following extension point types are available:

  • Internal extension points
    • Are accessible externally via URL http[s]://<server>:<port>/<context>/api-extension/Internal/<partition>/<name>/
    • Require the user to be authenticated to access the Extension Point
  • External extension points
    • Are accessible externally via URL http[s]://<server>:<port>/<context>/api-extension/External/<partition>/<name>/
    • Does not require authentication, however there is no access to a SchedulerSession to access the Redwood Server scripting API unless an Action Subject is set.

Prerequisites

  • License key Module.ExtensionPoint set to true

CSS Stylesheets

You use the jcsExtensionPointContext.getThemeCSSUrl() method to retrieve the URL to the CSS stylesheet.

Logging

Extension points use the RedwoodScript jcsOutLog logger and support log file rollover. You set the maximum size and number of log files; once a log file reaches the maximum size, a new log file is created. Once the maximum number of log files have been created, the first log file is overwritten.

Procedure

Creating Internal Extension Points

  1. Navigate to Configuration > Extension Points.
  2. Select New Extension Point from the context menu.
  3. Fill the Source field with RedwoodScript code that writes out an HTML page using the jcsResponse implicit object.
  4. On the Deployment Descriptor tab, specify where you want to position the control; note that toolbar controls require an icon.
  5. Click Save & Close.

Example

Internal Extension Point

You want to create a simple extension point that returns the number of currently selected processes:

  1. Navigate to Configuration > Extension Points.
  2. Select New Extension Point from the context menu.
  3. Fill CountObjects into the Name field and the code below into the Source field.
  4. Select Internal in the Visibility field.
  5. On the Deployment Descriptor tab, fill the below deployment descriptor.
  6. Click Save & Close.

Source:

Copy
package com.redwood.scheduler.custom;

public class Action
extends ActionStub
{
  public void execute()
  throws Exception
  {
    jcsResponse.getWriter().write("<html><head></head><body>You have selected ");
    jcsResponse.getWriter().write(String.valueOf(jcsParameters.getObjectCount()));
    jcsResponse.getWriter().write(" objects.");
    jcsResponse.getWriter().write("</body></html>");
  }
}

Deployment Descriptor:

Copy
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE extensionpoint PUBLIC "-//Redwood//DTD Extension Point 1.0//EN" "extensionpoint.dtd">
<extensionpoint version="1.0">
  <extension name="CountObjects" output="popup">
    <description>Object count</description>
    <extends>
      <popupmenu objecttype="JobDefinition" multiselect="true" />
    </extends>
    <parameters>
      <model name="JobDefinition" />
    </parameters>
    <translations default="en">
      <translation lang="en">How many objects</translation>
      <translation lang="fr">Combien d'objets</translation>
      <translation lang="de">Wie viele Objekte</translation>
    </translations>
  </extension>
</extensionpoint>

To test the extension point, navigate to Definitions > Processes and select a number of Process Definitions, from the context menu, choose Extensions > How many objects. Note that this extension point only works for Process Definitions ( JobDefinition ).

You add support for chains ( JobChain ) and event definitions ( EventDefinition ) by adding the following to the deployment descriptor:

Copy
<popupmenu objecttype="JobChain" multiselect="true" />
<popupmenu objecttype="EventDefinition" multiselect="true" />

and

Copy
<model name="JobChain" />
<model name="EventDefinition" />

The deployment descriptor becomes the following:

Copy
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE extensionpoint PUBLIC "-//Redwood//DTD Extension Point 1.0//EN" "extensionpoint.dtd">
<extensionpoint version="1.0">
  <extension name="CountObjects" output="popup">
    <description>Object count</description>
    <extends>
      <popupmenu objecttype="JobDefinition" multiselect="true" />
      <popupmenu objecttype="JobChain" multiselect="true" />
      <popupmenu objecttype="EventDefinition" multiselect="true" />
    </extends>
    <parameters>
      <model name="JobDefinition" />
      <model name="JobChain" />
      <model name="EventDefinition" />
    </parameters>
    <translations default="en">
      <translation lang="en">How many objects</translation>
      <translation lang="fr">Combien d'objets</translation>
      <translation lang="de">Wie viele Objekte</translation>
    </translations>
  </extension>
</extensionpoint>

You can now navigate to Definitions > Processes, Definitions > Chains, or Definitions > Events, select multiple objects and display the count of selected objects.

External Extension Point

You want to retrieve the average runtime of a process using an external extension for your 3rdparty application.

  1. Navigate to Configuration > Extension Points.
  2. Select New Extension Point from the context menu.
  3. Fill RuntimeStats into the Name field and the code below into the Source field.
  4. Select External in the Visibility field.
  5. Select an Action Subject for the SchedulerSession. The RedwoodScript code will be executed as this user.
  6. On the Deployment Descriptor tab, fill the below deployment descriptor.
  7. Click Save & Close.

Source:

Copy
package com.redwood.scheduler.custom;
import com.redwood.scheduler.api.model.*;

public class Action
extends ActionStub
{
  public void execute()
  throws Exception
  {
    String jdn = jcsRequest.getHeader("X-Redwood-JobDefinition");
    jcsResponse.getWriter().write("<html><head></head><body>");
    if (jdn != null)
    {
      jcsResponse.getWriter().write("You have sent " + jdn);
      jcsResponse.getWriter().write("<br />");
      JobDefinition jd = jcsSession.getJobDefinitionByName(jdn);
      if (jd != null)
      {
        jcsResponse.getWriter().write("Average Runtime: "+ String.valueOf(jd.getAverageRunTime()) + "ms");
      }
      else
      {
        jcsResponse.getWriter().write("No such process or " + jcsSession.getUserName() + " cannot see it.");
      }
    }
    else
    {
      jcsResponse.getWriter().write("You have not specified a name in the HTTP header. Please specify a HTTP header in your request named 'X-Redwood-JobDefinition' (without the ') containing a valid name of a Process Definition.");
    }
    jcsResponse.getWriter().write("</body></html>");
  }
}

Deployment Descriptor:

Copy
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE extensionpoint PUBLIC "-//Redwood//DTD Extension Point 1.0//EN" "extensionpoint.dtd">
<extensionpoint version="1.0">
  <extension name="getStatistics" output="popup">
    <description>get parameter</description>
    <extends>
    </extends>
    <translations default="en">
      <translation lang="en">get statistics</translation>
    </translations>
  </extension>
</extensionpoint>

The 3rdparty application sends an HTTP request to http[s]://<server>:<port>/<context>/api-extension/External/GLOBAL/RuntimeStats/, for example http://pr1.example.com:53000/redwood/api-extension/External/GLOBAL/RuntimeStats/, with an additional header named X-Redwood-JobDefinition containing the name of a Process Definition, for example System_Sleep. The Redwood Server will return the average runtime for the Process Definition, here, for System_Sleep on our system:

Copy
You have sent System_Sleep
Average Runtime: 17288ms

To test this extension, you can use cURL or Invoke-WebRequest (Powershell), for example:

Copy
$ curl -H 'X-Redwood-JobDefinition:System_Sleep' http://pr1.masalan.com:50300/redwood/api-extension/External/GLOBAL/RuntimeStats/
<html><head></head><body>You have sent System_Sleep<br />Average Runtime: 17288ms</body></html>
$
Copy
PS > Invoke-WebRequest http://pr1.masalan.com:50300/redwood/api-extension/External/GLOBAL/RuntimeStats/ -Headers @{"X-Redwood-JobDefinition"="System_Sleep"}


StatusCode        : 200
StatusDescription : OK
Content           : <html><head></head><body>You have sent System_Sleep<br />Average Runtime: 17288ms</body></html>
RawContent        : HTTP/1.1 200 OK
[...]
PS > (Invoke-WebRequest http://pr1.masalan.com:50300/redwood/api-extension/External/GLOBAL/RuntimeStats/ -Headers @{"X-Redwood-JobDefinition"="System_Sleep"}).Content
<html><head></head><body>You have sent System_Sleep<br />Average Runtime: 17288ms</body></html>

Extension points