Defining Tasks
For the instantiating of tasks, Basher supports a variety of methods, including:
- Gaderian Services
- Annotations
- Spring Beans
- HiveMind Services
- Simple Classes
- Task Providers
Depending on the methods used, tasks are picked up by Basher in different ways.
When using the Maven 2 plugin, annotated & POJO classes in the test source directory are picked up automatically (as long as the match the **/*Task.java naming convention.
For classes defined in the source directory or elsewhere (in other, dependant jars for example), the task must be either registered with Basher using the Gaderian module configuration or provided through a task provider service.
Lastly, if embedded Basher, tasks can be provided directly to the task manager API. service.
Using Basher Task Interface
Basher tasks can be defined by implementing the task interface. This is how a task is treated internally by Basher, independent of where and how the actual task was instantiated.
Gaderian Services
To enable your task within the Basher (Gaderian) registry, make a contribution to the net.sourceforge.basher.TaskContributions configuration point (in your Gaderian module.xml file), specifying your task.
When defined as a Gaderian service, the service must implement the Task interface.
... <service-point id="HelloWorldTask" interface="net.sourceforge.basher.Task"> <!-- Example Hello World Task for demonstration purposes --> <create-instance class="net.sourceforge.basher.tasks.HelloWorldTask"/> </service-point> <contribution configuration-id="net.sourceforge.basher.TaskContributions"> <!-- Contributes the hello world task which in turn registers it with the task manager --> <task-contribution task="HelloWorldTask"> <configuration max-invocations="560" task-name="HelloWorld"/> <phases> <phase name="SETUP"/> <phase name="RUN"/> </phases> </task-contribution> </contribution>
Using Basher Annotations
Basher provides a rich set of annotations which allows you to create a task without having to implement the Task interface. Using the available set of annotations, you can fine tune the behaviour of your task, without having to clutter your class.
The set of available annotations are:
- BasherTask: Indicates the class should be treated as a Basher task.
- BasherTimedTask: Indicates the class should be treated as a Basher timed task. Note: Not yet supported
- BasherName: Defines the name of the task
- BasherExecuteMethod: Defines the annotated method as the method to use as part of executing the task
- BasherMaxInvocations: Defines the maximum number of times the task may execute
- BasherMaxTime: Defines the maximum amount of time a task is allowed to execute before an error is raised. Defined in seconds
- BasherPhases: Defines the phases in which the Task should execute. Defaults to the RUN phase
- BasherRunFrom: Defines the time before which the task may not be executed. Defined in seconds since beginning of the run
- BasherStopAfter: Defines the time after which the task may not be executed. Defined in seconds since beginning of the run
- BasherWeight: Defines the percentage chance for the task to be invoked if selected for execution. Must be a a value between 1 and 100
- BasherInertia: Defines the amount of which the tasks weight (chance of running) should be incremented by after each successful invocation. Defined as a value between 1.0 and 2.0
- BasherFollowers: Specifies that the annotated method provides followers to the task.
To contribute an annotated task to the Basher runtime, declare the following in your Gaderian module:
<contribution configuration-id="net.sourceforge.basher.TaskContributions"> <!-- Contributes a annotated task, defined as simple class. --> <task-contribution class="HelloWorldTask"/> </contribution>
Alternatively, if embedding Basher, you can add the annotated class to the TaskManager programatically.
Using Spring
Basher uses Gaderian to configure it's runtime and Gaderian supports the lookup of Spring beans. In this case, the bean must implement the Task interface.
In order to use Spring beans from within Gaderian, the following steps must be followed:
- Configure your BeanFactory within Gaderian
<service-point id="SampleSpringBeanFactory" interface="org.springframework.beans.factory.BeanFactory"> <!-- Define a BeanFactory within in Gaderian. This allows tasks to be defined in Spring and used within Basher. The logic of initializing the Spring context is left to the user --> <invoke-factory> <construct class="net.sourceforge.basher.example.tasks.spring.SampleSpringBeanFactory"/> </invoke-factory> </service-point> <contribution configuration-id="gaderian.ApplicationDefaults"> <!-- Override of the default Spring factory provided by Gaderian. Note: the value here is the fully qualified service id (module id + service id) of the BeanFacotry. --> <default symbol="gaderian.utilities.spring-bean-factory" value="service:net.sourceforge.basher.example.spring.SampleSpringBeanFactory"/> </contribution>
- Contribute the task to Basher
<contribution configuration-id="net.sourceforge.basher.TaskContributions"> <!-- Contributes a Spring task, defined as a Spring bean. The name of the --> <!-- bean is SpringBeanTask --> <task-contribution instance="spring:SpringBeanTask"/> <configuration max-invocations="10" task-name="SpringBeanTask"/> <phases> <phase name="SETUP"/> <phase name="RUN"/> </phases> </task-contribution> </contribution>
Please see the Basher Example for more details.
POJO Tasks
POJO tasks are the simplest kind of task you can use. There is no need implement the Task interface or extends any particular abstract class. When using this kind of tasks, Basher will not be able to determine any special task configuration and will use the defaults.
A few rules apply to POJO classes:
- Must have an empty constructor
- Must have a void method (taking no parameters) named executeTask
package net.sourceforge.basher.example.tasks; /** Defines a simple, POJO based task. */ public class PojoTask { // Empty, public constructor public PojoTask() {} /** Defines the exectute method. Basher will use this at runtime when executing the task. */ public void executeTask() { // Work happens here } }
When using Maven and the task is defined in the test source path of the module, Basher will pick the task up automatically.
If the task is not defined in the test source path, contribute the POJO task to the Basher runtime by declaring the following in a Gaderian module:
<contribution configuration-id="net.sourceforge.basher.TaskContributions"> <!-- Contributes a POJO task task, defined as a simple bean. The --> <!-- name of the bean is PlainClassTask --> <task-contribution class="net.sourceforge.examples.tasks.PlainClassTask"> <configuration max-invocations="10" task-name="PlainClassTask""/> <phases> <phase name="SETUP"/> <phase name="RUN"/> </phases> </task-contribution> </contribution>
Task Providers
TaskProviders offer yet another way of adding Tasks to the Basher runtime. By implementing the TaskProvider interface, you allow Basher to retrieve lists of fully configured task contributions, ready to be used by Basher.
public class SimpleTaskProvider implements TaskProvider { public List<TaskContribution> getTaskContributions() { return new ArrayList<TaskContribution>( ); } public List<Class> getTaskClasses() { final ArrayList<Class> classes = new ArrayList<Class>(); classes.add( PlainClassTask.class ); return classes; } }
Provide the TaskProvider to Basher by contributing to the net.sourceforge.basher.TaskProviders configuration point.
<service-point id="SimpleTaskProvider" interface="net.sourceforge.basher.TaskProvider"> <!-- This is a simple definition of a TaskProvider defined in Gaderian. --> <invoke-factory> <construct class="net.sourceforge.basher.example.tasks.SimpleTaskProvider"/> </invoke-factory> </service-point> <contribution configuration-id="net.sourceforge.basher.TaskProviders"> <!-- Contributes a simple TaskProvider to the Basher runtime.--> <task-provider service="service:SimpleTaskProvider"/> </contribution>