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
- Are accessible externally via URL
- 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.
- Are accessible externally via URL
Prerequisites
- License key
Module.ExtensionPoint
set totrue
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
- Navigate to Configuration > Extension Points.
- Select New Extension Point from the context-menu.
- Fill the Source field with RedwoodScript code that writes out an HTML page using the
jcsResponse
implicit object. - On the Deployment Descriptor tab, specify where you want to position the control; note that toolbar controls require an icon.
- Choose Save & Close.
Example
Internal Extension Point
You want to create a simple extension point that returns the number of currently selected processes:
- Navigate to Configuration > Extension Points.
- Select New Extension Point from the context-menu.
- Fill
CountObjects
into the Name field and the code below into the Source field. - Select
Internal
in the Visibility field. - On the Deployment Descriptor tab, fill the below deployment descriptor.
- Choose Save & Close.
Source:
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:
<?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:
<popupmenu objecttype="JobChain" multiselect="true" />
<popupmenu objecttype="EventDefinition" multiselect="true" />
and
<model name="JobChain" />
<model name="EventDefinition" />
The deployment descriptor becomes the following:
<?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.
- Navigate to Configuration > Extension Points.
- Select New Extension Point from the context-menu.
- Fill
RuntimeStats
into the Name field and the code below into the Source field. - Select
External
in the Visibility field. - Select an Action Subject for the SchedulerSession. The RedwoodScript code will be executed as this user.
- On the Deployment Descriptor tab, fill the below deployment descriptor.
- Choose Save & Close.
Source:
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:
<?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:
You have sent System_Sleep
Average Runtime: 17288ms
To test this extension, you can use cURL or Invoke-WebRequest (Powershell), for example:
$ 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>
$
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