Skip to content

Commit

Permalink
Refactored Spacelift, added TaskFactory
Browse files Browse the repository at this point in the history
* Now using Spacelift as entry point
* Ability to register factories
* Automatic registration of tasks
* Removed Arquillian related events
  • Loading branch information
kpiwko committed Jan 31, 2015
1 parent 45a733a commit 35c10d8
Show file tree
Hide file tree
Showing 76 changed files with 606 additions and 1,695 deletions.
27 changes: 5 additions & 22 deletions README.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,7 @@ In your project, import following artifact:
</dependency>
----

You can use Spacelift both with and without Arquillian. If you use extension without Arquillian, you need to make sure that you initialize factory for task execution.

[source,java]
----
Tasks.setDefaultExecutionServiceFactory(new DefaultExecutionServiceFactory());
----

If you are running from an extension, after +ExecutionServiceInitialized+ event factory is initialized. There is also +ToolRegistryInitialized+ event, which denotes that all tools were registered and you can use them (TBD).
You can use Spacelift both with and without Arquillian.

== How to use the extension

Expand All @@ -35,11 +28,11 @@ Arquillian Spacelift provides you a concept of a task. Task is isolated amount o
Task is always executed asynchronously.

How do I create new tasks?::
Task is defined by class that represents its payload. You prepare tasks by calling +Tasks+ utility
Task is defined by class that represents its payload. You prepare tasks by calling +Spacelift+ utility
+
[source,java]
----
Tasks.prepare(DownloadTool.class)
Spacelift.task(DownloadTool.class)
----
+
Once task is created, you get access to API defined by task class itself.
Expand All @@ -49,7 +42,7 @@ How do I run more tasks together?::
Task can be chained together by using +then(NextTaskName.class)+ call. There is following rules for chaining tasks: Input of next task must much output of current task.
If next task input is type of +Object+, it can be chained to any task. +Object+ usually means that you don't care about input of next task at all.
I already have input for a task. How do I pass it to the task?::
Just call +Tasks.chain(input, NextTaskName.class)+
Just call +Spacelift.task(input, NextTaskName.class)+
How do I create my own tasks?::
Extend abstract class +Task+ and implement +process(INPUT)+ method.

Expand All @@ -68,17 +61,7 @@ Terminating execution::
behavior cannot be guaranteed for all types of tasks, as execution might be atomic. In such circumstances, task should return +null+ if it figures out if was forcefully terminated
before it finished the work.

=== Tool

Tool is a task that additionally defines a string based name. This name is used by +Installation+ steps to determine what tasks should be run
in order to install additional stuff to your test environment.

How do I create a tool?::
You can use +Tasks.prepare(TheTool.class)+
How do I create my own tool?::
Extends abstract class +Tool+ and implement +process(INPUT)+ and +aliases()+ methods.

Current tools are:
Current tasks are:

* DownloadTool: _Nothing -> File, download_ can download anything to a file
* UnzipTool: _File -> File, unzip_ can unzip an archive to a directory
Expand Down
3 changes: 1 addition & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@
<!-- Modules -->
<modules>
<module>spacelift-api</module>
<module>spacelift-impl</module>
<module>spacelift-spi</module>
<module>spacelift-impl</module>
</modules>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.arquillian.spacelift.execution;
package org.arquillian.spacelift;

import org.arquillian.spacelift.execution.ExecutionServiceFactory;

/**
* Utility capable of loading interface implementations available on classpath indirectly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.arquillian.spacelift.execution;
package org.arquillian.spacelift;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.arquillian.spacelift.execution;
package org.arquillian.spacelift;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
Expand Down Expand Up @@ -95,7 +95,7 @@ private static <T> T newInstance(final Class<?> clazz, final Class<?>[] argument
+ " instance, access refused by SecurityManager.", e);
} catch (InvocationTargetException e) {
throw new RuntimeException(
String.format("Unable to instantiate tool via %s: %s",
String.format("Unable to instantiate task via %s: %s",
getConstructorName(clazz.getName(), argumentTypes),
e.getCause()), // this provides the message of the ITE cause, which is also important!
e.getCause()); // this provides stack trace of the ITE cause
Expand Down Expand Up @@ -177,4 +177,4 @@ public ClassLoader run() {

}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.arquillian.spacelift;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.arquillian.spacelift.Invokable.InvocationException;
import org.arquillian.spacelift.execution.ExecutionServiceFactory;
import org.arquillian.spacelift.task.InjectTask;
import org.arquillian.spacelift.task.Task;
import org.arquillian.spacelift.task.TaskRegistry;

public class Spacelift {

public static <IN, OUT, TASK extends Task<? super IN, OUT>> TASK task(Class<TASK> taskDef) {
return new SpaceliftInstance().registry().find(taskDef);
}

public static <IN, OUT, TASK extends Task<? super IN, OUT>> TASK task(IN input, Class<TASK> taskDef) {
@SuppressWarnings("unchecked")
InjectTask<IN> task = new SpaceliftInstance().registry().find(InjectTask.class);
return task.passToNext(input).then(taskDef);
}

@SuppressWarnings({ "unchecked" })
public static class SpaceliftInstance {
private static final Logger log = Logger.getLogger(Spacelift.class.getName());

private static ExecutionServiceFactory lastFactory;
private static TaskRegistry registry;
static {
try {
lastFactory = ImplementationLoader.implementationOf(ExecutionServiceFactory.class);
} catch (InvocationException e) {
log.log(Level.SEVERE,
"Unable to find default implemenation of {0} on classpath, make sure that you set one programatically.",
ExecutionServiceFactory.class.getName());
}
try {
registry = ImplementationLoader.implementationOf(TaskRegistry.class);
// register inject task for chaining
registry.register(InjectTask.class);
} catch (InvocationException e) {
log.log(Level.SEVERE,
"Unable to find default implemenation of {0} on classpath, make sure that you set one programatically.",
TaskRegistry.class.getName());
}
}

public TaskRegistry registry() {
return registry;
}

public ExecutionServiceFactory service() {
return lastFactory;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
import java.util.concurrent.TimeUnit;

import org.arquillian.spacelift.process.Command;
import org.arquillian.spacelift.tool.Tool;
import org.arquillian.spacelift.task.Task;

/**
* Tool to execute a task, based on {@link Callable}, {@link Command} or {@link Tool}.
* Wrapper to execute a task, based on {@link Callable}, {@link Command} or {@link Task}.
* Allows both synchronous and asynchronous task execution
*
* @author <a href="kpiwko@redhat.com">Karel Piwko</a>
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 35c10d8

Please sign in to comment.