Custom Workflow Actions
Developing own/custom
Workflow Actions in
Java requires a Java 7 or newer Standard Edition (SE)
Java Development Kit (JDK) plus the following frameworks/libraries:
Framework/Library
|
Component
|
Version
|
|
|
3.4
|
|
spring-core
|
3.2.x
|
|
spring-context
|
3.2.x
|
|
spring-beans
|
3.2.x
|
You also need
cb.jar from the directory
~/CB-../tomcat/webapps/cb/WEB-INF/lib of the
Codebeamer 7.8.0 or newer installation, you want to develop new custom workflow actions for.
Workflow Actions are
methods of Java
classes. For example:
Create a new baseline:
package com.intland.codebeamer.example.actions;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.intland.codebeamer.controller.ArtifactController;
import com.intland.codebeamer.manager.workflow.ActionCall;
import com.intland.codebeamer.manager.workflow.ActionParam;
import com.intland.codebeamer.manager.workflow.WorkflowAction;
import com.intland.codebeamer.manager.workflow.ActionParam.Type;
import com.intland.codebeamer.manager.workflow.WorkflowPhase;
import com.intland.codebeamer.persistence.dto.ArtifactDto;
import com.intland.codebeamer.persistence.dto.TrackerDto;
import com.intland.codebeamer.persistence.dto.UserDto;
@Component("baselineCreator")
@WorkflowAction(value="baselineCreator", iconUrl="/images/Snapshot.png", helpUrl="https://codebeamer.com/cb/wiki/816624")
public class BaselineCreator {
@Autowired
private ArtifactController artifactController;
@ActionCall(WorkflowPhase.After)
public ArtifactDto createBaseline(HttpServletRequest request, UserDto user, TrackerDto tracker,
@ActionParam(value="baselineScope", options={"project", "tracker"}, required=true) String scope,
@ActionParam(value="baselineName", required=true, width=60) String name,
@ActionParam(value="baselineDescription", type=Type.wikitext, width=60, height=2) String description
) throws Exception {
ArtifactDto baseline = ...
artifactController.createArtifact(request, user, tracker.getProject(), baseline, null);
return baseline;
}
}
We recommend, that the
package
of your custom actions should be a sub-package of
com.intland.codebeamer, e.g.
com.intland.codebeamer.<mycompany>.actions
You can use any package name, but when using a sub-package of
com.intland.codebeamer, your new actions can be automatically detected and deployed by the
Component
scan during
Codebeamer startup:
package com.intland.codebeamer.example.actions;
import org.springframework.stereotype.Component;
@Component("baselineCreator")
public class BaselineCreator {
...
}
The component id/name (if any) should be the same than the @WorkflowAction id/name (see below).
If your custom workflow action is not a
Component
in a sub-package of
com.intland.codebeamer, then you
must provide extra
<bean> configuration
for your custom workflow action in:
~/CB-../tomcat/webapps/cb/WEB-INF/classes/my-ApplicationContext.xml
Classes providing workflow actions must be annotated as @WorkflowAction.
import com.intland.codebeamer.manager.workflow.WorkflowAction;
@WorkflowAction(value="baselineCreator", iconUrl="/images/Snapshot.png", helpUrl="https://codebeamer.com/cb/wiki/816624")
public class BaselineCreator {
...
}
There is
no special
interface
to implement or
base class
to extend.
The
@WorkflowActionannotation
has the following attributes:
• valuethe id/name of the workflow action. This value must not be changed over the lifetime of an action, otherwise configured action invocations will not longer work!
• iconUrlthe relative path to the icon/image of this workflow action (optional). The icon/image must reside in (a subfolder of) ~/CB-../tomcat/webapps/cb.
• helpUrlthe URL of the online help (wiki) page for this workflow action (optional). The URL can be absolute or relative.
If an action implementation needs access to other
Codebeamer APIs
, the action class should simply declare appropriate
@Autowired
variables:
import org.springframework.beans.factory.annotation.Autowired;
import com.intland.codebeamer.controller.ArtifactController;
public class BaselineCreator {
@Autowired
private ArtifactController artifactController;
...
}
Each class annotated as
@WorkflowAction, must have (at least) one
method
annotated with
@ActionCall:
import com.intland.codebeamer.manager.workflow.ActionCall;
import com.intland.codebeamer.manager.workflow.WorkflowAction;
import com.intland.codebeamer.manager.workflow.WorkflowPhase;
@WorkflowAction(value="baselineCreator", iconUrl="/images/Snapshot.png", helpUrl="https://codebeamer.com/cb/wiki/816624")
public class BaselineCreator {
...
@ActionCall(WorkflowPhase.After)
public ArtifactDto createBaseline(...) {
...
}
}
Action methods can have any name and return type and should be public.
The
@ActionCall annotation
has only one parameter, that defines the
phase of event processing, where the method should be called:
• BeforeCall the method before the triggering event is actually executed on the subject item.In this phase of event processing, the method can make modifications to the subject item and also reject/deny executing the event by throwing a VetoException.
• AfterCall the method after the triggering event was successfully executed on the subject item.In this phase of event processing, modifications to the subject item are not allowed/persisted any more but the method can still abort the event processing by throwing an exception.
Methods annotated as @ActionCall must be
Context specific information required by the method, must be declared as
parameters
. The following context information is available:
• BaseEvent<ArtifactDto,TrackerItemDto,ActionData>, to receive the triggering event, where
◦ getUser() is the user, that initiated the event/action.
◦ getRequest() is the request, that triggered the event/action (can be null for automatically triggered events, e.g. escalation).
◦ getSource()is the action source/context, e.g.:
▪ a WorkflowTransitionDto
▪ a TrackerItemEscalationRuleDto
▪ a TrackerViewDto
◦ getSecondarySource() is the tracker item, that is subject of the triggering event.
◦ getData() is additional information about the action source/context/environment.
• UserDto, to receive the user, that executes the action (this is not necessarily the same than the request initiator).
• HttpServletRequest, to receive the request, that triggered the event/action. Can be null, for automatically triggered events, e.g. escalation.
• ActionData, to receive additional information about the action source/context/environment.
• ArtifactDto, to receive the action source/context, e.g.
◦ a WorkflowTransitionDto
◦ a TrackerItemEscalationRuleDto
◦ a TrackerViewDto
• ProjectDto, to receive the context project of the event/action
• TrackerDto, to receive the context tracker of the event/action
• WorkflowActionDto, to receive the current action to execute (including parameters) (read-only)
• TrackerItemDto, to receive the current tracker item to process
You can also declare a parameter with a specific source/context type, e.g. WorkflowTransitionDto. The value of such parameters will be null, if the actual source/context is not an object of this type. Action specific parameters must be annotated as @ActionParam and can have the following supported types:
• String for (Wiki)Text, Country, Language and Color parameters
• int or Integer for integer numbers
• double or Double for floating point numbers
• long or Long for durations (in ms)
• Date for date/time
• boolean or Boolean for true or false
• UserDto for a user
• ArtifactDto for a user group
• RoleDto for a role
• NamedDto for a project member, which can be a
◦ UserDto for a user
◦ RoleDto for a role
◦ ArtifactDto for a user group
◦ TrackerLayoutLabelDto for a member field
• ProjectDto for a project
• TrackerDto for a tracker
• TrackerLayoutLabelDto for a tracker field
• TrackerChoiceOptionDto for a choice option
• TrackerItemDto for a tracker item
• AssociationDto for an association
Parameters with simple types (int, double, long and boolean) are implicitly required. For other parameters the value can be null, unless you declare it explicitly as required=true. If a parameter can have multiple values, you must declare it of the appropriate type as follows:
• Collection,
• List or
• Set
The
@ActionParamannotation
supports the following attributes:
• value is the parameter name (required). This value must not be changed over the lifetime of an action, otherwise actual parameter values of configured action invocations won't be longer assigned to this parameter!
• type is the parameter type. It is typically implicit, but needs to be specified explicitly for ambiguous types, e.g. String can be Text, but also Country, Language, Color and even Choice.
◦ implicit
◦ text
◦ wikitext
◦ integer
◦ decimal
◦ bool
◦ date
◦ duration
◦ country
◦ language
◦ choice
◦ user
◦ group
◦ role
◦ member
◦ project
◦ tracker
◦ field
◦ item
◦ reference
◦ association
• required, whether a parameter value is required (true) or optional (false). Default is required=false.
• options, are the possible choice option names for a choice parameter. E.g.
@ActionParam(value="baselineScope", options={"project", "tracker"}, required=true) String scope
• project, is an optional qualifier for project parameters .E.g.
@ActionParam(value="projects", project=@Project({"Team", "Department"}), required=true) Collection<ProjectDto> projects
to restrict the allowed parameter values, to projects with category "Team" or "Department".
• tracker, is an optional qualifier for tracker parameters .E.g.
@ActionParam(value="tracker", tracker=@Tracker({"Bug", "Task"}), required=true) TrackerDto tracker
to restrict the allowed parameter values to trackers, where
◦ value, the tracker has (one of) the specified type(s) (TrackerTypeDto name).
◦ referring
▪ true : Possible values are trackers (of the specified type), referring to the current tracker via a reference field (with the specified refType)
▪ false: Possible values are trackers (of the specified type) in the current project. This is the default.
◦ refType, reference field name(s) as String or array of Strings . Default is any reference field.
• field, is an optional qualifier for field parameters .E.g.
@ActionParam(value="signer", field=@Field({Type.text, Type.user})) TrackerLayoutLabelDto signerField,
@ActionParam(value="signature", field=@Field(Type.text), required=true) TrackerLayoutLabelDto signatureField
to restrict the allowed parameter values to those tracker fields, where
◦ value, the field has (one of) the specified value type(s)
◦ refType, the field is a type=reference field, that refers to entities of (one of) the specified type(s),
◦ multiple, whether only fields with multiple values should be allowed (true). Default is false.
Methods annotated as
@ActionCall can throw any type of
Exceptions
. Two types of exceptions have a special meaning:
• com.intland.codebeamer.event.util.VetoExceptionCan be thrown to deliberately abandon the event processing (ideally in the
WorkflowPhase.Before). E.g.
Validate the user signature (password) will throw a
VetoException, if the signature/password validation fails.
• com.intland.codebeamer.manager.workflow.ActionWarningCan be thrown to signal an action exception/failure, that should only be logged, but should not abandon the event processing. The logging Level of an ActionWarning can be
◦ WARNING (the default), or
◦ ERROR
All exceptions during an @ActionCall (except ActionWarning) will
• abort (in WorkflowPhase.Before) or
• roll back (in WorkflowPhase.After)
the processing of the triggering event!
Action configuration localization
The
Workflow Actions configuration GUI will show actions and custom action parameters using their
• @WorkflowAction value(name)
• @ActionParam value(name)
Via custom language resource files (see
Codebeamer Localization Guide), you can provide language specific texts for action and parameter names.
E.g. English texts in
~/CB-../tomcat/webapps/cb/WEB-INF/classes/my-ApplicationResources.properties
tracker.action.baselineCreator.label=Create a new baseline
tracker.action.baselineCreator.baselineScope.label=Scope
tracker.action.baselineCreator.baselineScope.tooltip=The scope of the new baseline
tracker.action.baselineCreator.baselineScope.tracker.label=Tracker
tracker.action.baselineCreator.baselineScope.tracker.tooltip=Create a new baseline on the current tracker
tracker.action.baselineCreator.baselineScope.project.label=Project
tracker.action.baselineCreator.baselineScope.project.tooltip=Create a new baseline on the whole project
tracker.action.baselineCreator.baselineName.label=Name
tracker.action.baselineCreator.baselineName.tooltip=The name of the new baseline
tracker.action.baselineCreator.baselineDescription.label=Description
tracker.action.baselineCreator.baselineDescription.tooltip=The description of the new baseline
E.g. German texts in ~/CB-../tomcat/webapps/cb/WEB-INF/classes/my-ApplicationResources_de.properties
tracker.action.baselineCreator.label=Den aktuellen Versionsstand sichern
tracker.action.baselineCreator.baselineScope.label=Umfang
tracker.action.baselineCreator.baselineScope.tooltip=Der Umfang des neuen Versionsstands
tracker.action.baselineCreator.baselineScope.tracker.label=Tracker
tracker.action.baselineCreator.baselineScope.tracker.tooltip=Sichere den Versionsstand des aktuellen Trackers
tracker.action.baselineCreator.baselineScope.project.label=Projekt
tracker.action.baselineCreator.baselineScope.project.tooltip=Sichere den Versionstands des kompletten Projekts
tracker.action.baselineCreator.baselineName.label=Name
tracker.action.baselineCreator.baselineName.tooltip=Der Name des neuen Versionstands
tracker.action.baselineCreator.baselineDescription.label=Beschreibung
tracker.action.baselineCreator.baselineDescription.tooltip=Die Beschreibung des neuen Versionstands
The resource name for label and tooltip of a workflow action is:
• tracker.action.<name>.label
• tracker.action.<name>.tooltip
and the resource name for label and tooltip of a workflow action parameter is:
• tracker.action.<name>.<param>.label
• tracker.action.<name>.<param>.tooltip
and the resource name for label and tooltip of a workflow action choice parameter option is:
• tracker.action.<name>.<param>.<option>.label
• tracker.action.<name>.<param>.<option>.tooltip
where <name> is the @WorkflowAction value(name), <param> is the @ActionParam value(name) and <option> is the name of a choice parameter option.
Context specific actions
If your custom workflow action is only applicable in a specific context, e.g. only for trackers/items of a specific type, then the implementing class should declare an additional predicate/method annotated with @ActionPredicate:
import com.intland.codebeamer.manager.workflow.ActionPredicate;
import com.intland.codebeamer.persistence.dto.TrackerTypeDto;
@WorkflowAction(value="scmChangeFileZipper", iconUrl="/images/cvs_view.gif")
public class ScmChangeFileZipper {
@ActionPredicate
public boolean isApplicable(TrackerTypeDto type) {
return TrackerTypeDto.isTrackerType(type);
}
...
}
Methods annotated with @ActionPredicate must be
• Public
• Return boolean true if the action is applicable, false otherwise.
The method must declare parameters for all required context information, that it needs to make it's decision. The following context information is available:
• ProjectDto is the project, where to configure workflow actions
• TrackerDto is the tracker, where to configure workflow actions
• TrackerTypeDto is the type of the tracker, where to configure workflow actions
• TrackerTypeDto.Kind is the kind of tracker, where to configure workflow actions
◦ Tracker for work items
◦ Category for configuration items
◦ Repository for source code commits/pushs
Deploying workflow actions
To deploy your custom workflow action, the Java code must be compiled and the resulting
*.class file must be uploaded to the appropriate sub-directory under
~/CB-.../tomcat/webapps/cb/WEB-INF/classes/..., where the sub-directory is the equivalent of the action's package name. If you have multiple custom actions (along with custom Wiki Plugins, etc.), you may choose to pack all your custom classes (along with your custom language resource files) into one Java archive (*.jar) and put that into
~/CB-.../tomcat/webapps/cb/WEB-INF/lib. For actions not under
com.intland.codebeamer, or not annotated as
@Component
, you
must also provide extra
<bean> configurations
in
~/CB-../tomcat/webapps/cb/WEB-INF/classes/my-ApplicationContext.xml
Finally you have to restart Codebeamer, for your newly deployed actions to get loaded.