diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..38d69ecc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,32 @@
+*~
+.#*
+*#
+*.sw*
+_site/
+.factorypath
+.gradletasknamecache
+.DS_Store
+/application.yml
+/application.properties
+asciidoctor.css
+atlassian-ide-plugin.xml
+bin/
+build/
+dump.rdb
+out
+spring-shell.log
+target/
+test-output
+
+# Eclipse artifacts, including WTP generated manifests
+.classpath
+.project
+.settings/
+.springBeans
+spring-*/src/main/java/META-INF/MANIFEST.MF
+
+# IDEA artifacts and output dirs
+*.iml
+*.ipr
+*.iws
+.idea/*
diff --git a/README.adoc b/README.adoc
new file mode 100644
index 00000000..ed432e5f
--- /dev/null
+++ b/README.adoc
@@ -0,0 +1,32 @@
+= Spring Cloud Task
+
+Is a project centered around the idea of processing on demand. A user is able to develop
+a “task” that can be deployed, executed and removed on demand, yet the result of the
+process persists beyond the life of the task for future reporting.
+
+
+== Requirements:
+
+* Java 7 or Above
+
+== Build:
+
+[source,shell,indent=2]
+----
+$ mvn clean install
+----
+
+== Example:
+
+[source,java,indent=2]
+----
+@Task("imSampleB")
+public class SampleB implements CommandLineRunner {
+
+ @Override
+ public void run(String... args) {
+ System.out.println("hello world");
+ }
+
+}
+----
diff --git a/README.md b/README.md
deleted file mode 100644
index 2e538a09..00000000
--- a/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# spring-cloud-task
diff --git a/pom.xml b/pom.xml
new file mode 100755
index 00000000..d5c5a3d3
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ 1.3.0.RELEASE
+ pom
+ import
+
+
+
+
+ 4.0.0
+
+ org.springframework.cloud
+ spring-cloud-task-parent
+ pom
+ spring-cloud-task-parent
+ 1.0.0.BUILD-SNAPSHOT
+ Spring Cloud Task Parent
+
+
+ spring-cloud-task-core
+
+
+
+
+
diff --git a/spring-cloud-task-core/pom.xml b/spring-cloud-task-core/pom.xml
new file mode 100755
index 00000000..702ac861
--- /dev/null
+++ b/spring-cloud-task-core/pom.xml
@@ -0,0 +1,27 @@
+
+
+
+ 4.0.0
+
+
+ org.springframework.cloud
+ spring-cloud-task-parent
+ 1.0.0.BUILD-SNAPSHOT
+
+
+ org.springframework.cloud
+ spring-cloud-task-core
+ jar
+ spring-cloud-task-core
+ 1.0.0.BUILD-SNAPSHOT
+ Spring Cloud Task
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+
+
diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/annotation/Task.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/annotation/Task.java
new file mode 100644
index 00000000..94add499
--- /dev/null
+++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/annotation/Task.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.task.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.cloud.task.config.DefaultTaskConfigurer;
+import org.springframework.context.annotation.Import;
+import org.springframework.stereotype.Component;
+
+/**
+ * Annotation that identifies a class as a task. This annotation will serve as the
+ * main “hook” to activate the various Spring Cloud Task features.
+ *
+ * @author Glenn Renfro
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@Component
+@Import({ DefaultTaskConfigurer.class })
+public @interface Task {
+
+ /**
+ * Establishes the name associated with the task. The default is empty.
+ */
+ public String value() default "";
+
+}
diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/config/DefaultTaskConfigurer.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/config/DefaultTaskConfigurer.java
new file mode 100644
index 00000000..11e22494
--- /dev/null
+++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/config/DefaultTaskConfigurer.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.task.config;
+
+import org.springframework.cloud.task.repository.LoggerTaskRepository;
+import org.springframework.cloud.task.repository.TaskRepository;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Scope;
+
+/**
+ * If no TaskConfigurer is present this configuration will be used.
+ * @author Glenn Renfro
+ */
+@Configuration
+public class DefaultTaskConfigurer {
+
+ @Bean
+ @Scope("prototype")
+ public TaskHandler taskHandler() {
+ return new TaskHandler();
+ }
+
+
+ @Bean
+ public TaskRepository taskRepository() {
+ return new LoggerTaskRepository();
+ }
+
+}
diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/config/TaskConfigurer.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/config/TaskConfigurer.java
new file mode 100644
index 00000000..7ce5b1fa
--- /dev/null
+++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/config/TaskConfigurer.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.task.config;
+
+import org.springframework.cloud.task.repository.TaskRepository;
+
+/**
+ * Provides a strategy interface for providing configuration
+ * customization to the task system.
+ *
+ * @author Glenn Renfro
+ */
+public interface TaskConfigurer {
+
+ /**
+ * Create a Task Repository for the Task.
+ *
+ * @return A TaskRepository
+ */
+ public TaskRepository taskRepository();
+
+}
diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/config/TaskHandler.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/config/TaskHandler.java
new file mode 100644
index 00000000..8bed88f8
--- /dev/null
+++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/config/TaskHandler.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.cloud.task.config;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ExitCodeGenerator;
+import org.springframework.cloud.task.annotation.Task;
+import org.springframework.cloud.task.repository.TaskExecution;
+import org.springframework.cloud.task.repository.TaskRepository;
+import org.springframework.context.ApplicationContext;
+
+/**
+ * Offers the advice on how to record tasks to the repository for both applicationrunner
+ * and commandlinerunner spring boot applications.
+ *
+ * @author Glenn Renfro
+ */
+@Aspect
+public class TaskHandler {
+
+ @Autowired
+ private ApplicationContext context;
+
+ @Autowired
+ private TaskRepository repository;
+
+ private String taskName;
+
+ private String executionId;
+
+ private TaskExecution taskExecution;
+
+ /**
+ * Looks for any CommandLineRunner.run method with its class annotated with @Task
+ * and calls the repository implementation to store the start of the task in the repo
+ * before the run starts.
+ *
+ * @param joinPoint
+ */
+ @Before("within( @org.springframework.cloud.task.annotation.Task *) && (execution(* org.springframework.boot.CommandLineRunner.run(..)) || execution(* org.springframework.boot.ApplicationRunner.run(..)))")
+ public void beforeCommandLineRunner(JoinPoint joinPoint) {
+ executionId = UUID.randomUUID().toString();
+ taskExecution = new TaskExecution();
+
+ Task a = joinPoint.getTarget().getClass().getAnnotation(Task.class);
+ taskName = a.value();
+ if (taskName == null || taskName.length() == 0) {
+ taskName = joinPoint.getTarget().getClass().getName();
+ }
+
+ taskExecution.setTaskName(taskName);
+ taskExecution.setStartTime(new Date());
+ taskExecution.setExecutionId(executionId);
+ repository.createTaskExecution(taskExecution);
+ }
+
+ /**
+ * Looks for any CommandLineRunner.run method with its class annotated with @Task
+ * and calls repository implementation to store the exit of the task in the repo after
+ * run returns result.
+ *
+ * @param joinPoint
+ */
+ @AfterReturning("within( @org.springframework.cloud.task.annotation.Task *) && (execution(* org.springframework.boot.CommandLineRunner.run(..)) || execution(* org.springframework.boot.ApplicationRunner.run(..)))")
+ public void afterReturnCommandLineRunner(JoinPoint joinPoint) {
+ int result = 0;
+ List generators = new ArrayList();
+ generators
+ .addAll(context.getBeansOfType(ExitCodeGenerator.class).values());
+ for (ExitCodeGenerator generator : generators) {
+ result = generator.getExitCode();
+ }
+ taskExecution.setEndTime(new Date());
+ taskExecution.setExitCode(result);
+ repository.update(taskExecution);
+ }
+
+ /**
+ * Looks for any CommandLineRunner. run method with its class annotated with @Task
+ * and calls the repository implementation to store the exitCode of 1
+ * for the task in the repo in the case of an exception.
+ *
+ * @param joinPoint
+ */
+ @AfterThrowing("within( @org.springframework.cloud.task.annotation.Task *) && (execution(* org.springframework.boot.CommandLineRunner.run(..)) || execution(* org.springframework.boot.ApplicationRunner.run(..)))")
+ public void logExceptionCommandLineRunner(JoinPoint joinPoint) {
+ taskExecution.setEndTime(new Date());
+ taskExecution.setExitCode(1);
+ repository.update(taskExecution);
+ }
+
+}
diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/LoggerTaskRepository.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/LoggerTaskRepository.java
new file mode 100644
index 00000000..4fb85f7c
--- /dev/null
+++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/LoggerTaskRepository.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.task.repository;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Glenn Renfro
+ */
+public class LoggerTaskRepository implements TaskRepository {
+ private final static Logger logger = LoggerFactory.getLogger(LoggerTaskRepository.class);
+
+ @Override
+ public void update(TaskExecution taskExecution) {
+ logger.info("Updating: " + taskExecution.toString());
+ }
+
+ @Override
+ public void createTaskExecution(TaskExecution taskExecution) {
+ logger.info("Creating: " + taskExecution.toString());
+ }
+}
diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/TaskExecution.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/TaskExecution.java
new file mode 100644
index 00000000..a07adde5
--- /dev/null
+++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/TaskExecution.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.task.repository;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Represents the state of the Task for each execution.
+ *
+ * @author Glenn Renfro
+ */
+
+public class TaskExecution {
+
+ public TaskExecution() {
+ }
+
+ public TaskExecution(String executionId, int exitCode, String taskName,
+ Date startTime, Date endTime, String statusCode,
+ String exitMessage, List parameters) {
+ this.executionId = executionId;
+ this.exitCode = exitCode;
+ this.taskName = taskName;
+ this.startTime = startTime;
+ this.endTime = endTime;
+ this.statusCode = statusCode;
+ this.exitMessage = exitMessage;
+ this.parameters = parameters;
+ }
+
+ /**
+ * The unique id associated with the task execution.
+ */
+ private String executionId;
+
+ /**
+ * The recorded exit code for the task.
+ */
+ private int exitCode;
+
+ /**
+ * User defined name for the task.
+ */
+ private String taskName;
+
+ /**
+ * Time of when the task was started.
+ */
+ private Date startTime;
+
+ /**
+ * Timestamp of when the task was completed/terminated.
+ */
+ private Date endTime;
+
+ /**
+ * TBD.
+ */
+ private String statusCode;
+
+ /**
+ * Message returned from the task or stacktrace.parameters.
+ */
+ private String exitMessage;
+
+ /**
+ * The parameters that were used for this task execution.
+ */
+ private List parameters;
+
+ public String getExecutionId() {
+ return executionId;
+ }
+
+ public void setExecutionId(String executionId) {
+ this.executionId = executionId;
+ }
+
+ public int getExitCode() {
+ return exitCode;
+ }
+
+ public void setExitCode(int exitCode) {
+ this.exitCode = exitCode;
+ }
+
+ public String getTaskName() {
+ return taskName;
+ }
+
+ public void setTaskName(String taskName) {
+ this.taskName = taskName;
+ }
+
+ public Date getStartTime() {
+ return startTime;
+ }
+
+ public void setStartTime(Date startTime) {
+ this.startTime = startTime;
+ }
+
+ public Date getEndTime() {
+ return endTime;
+ }
+
+ public void setEndTime(Date endTime) {
+ this.endTime = endTime;
+ }
+
+ public String getStatusCode() {
+ return statusCode;
+ }
+
+ public void setStatusCode(String statusCode) {
+ this.statusCode = statusCode;
+ }
+
+ public String getExitMessage() {
+ return exitMessage;
+ }
+
+ public void setExitMessage(String exitMessage) {
+ this.exitMessage = exitMessage;
+ }
+
+ public List getParameters() {
+ return parameters;
+ }
+
+ public void setParameters(List parameters) {
+ this.parameters = parameters;
+ }
+
+ @Override
+ public String toString() {
+ return "TaskExecution{" +
+ "executionId='" + executionId + '\'' +
+ ", exitCode=" + exitCode +
+ ", taskName='" + taskName + '\'' +
+ ", startTime=" + startTime +
+ ", endTime=" + endTime +
+ ", statusCode='" + statusCode + '\'' +
+ ", exitMessage='" + exitMessage + '\'' +
+ ", parameters=" + parameters +
+ '}';
+ }
+}
diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/TaskExplorer.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/TaskExplorer.java
new file mode 100644
index 00000000..acacfd76
--- /dev/null
+++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/TaskExplorer.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.task.repository;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Offers methods that allow users to query the task executions that are available.
+ *
+ * @author Glenn Renfro
+ */
+public interface TaskExplorer {
+
+ /**
+ * Retrieve a {@link TaskExecution} by its id.
+ *
+ * @param executionId the task execution id
+ * @return the {@link TaskExecution} with this id, or null if not found
+ */
+ public TaskExecution getTaskExecution(Long executionId);
+
+
+ /**
+ * Retrieve a collection of taskExecutions that have the task name provided.
+ *
+ * @param taskName the name of the task
+ * @return the set of running executions for tasks with the specified name
+ */
+ public Set findRunningTaskExecutions(String taskName);
+
+ /**
+ * Retrieve a list of available task names.
+ *
+ * @return the set of task names that have been executed
+ */
+ public List getTaskNames();
+
+ /**
+ * Get number of executions for a taskName.
+ *
+ * @param taskName the name of the task to be searched
+ * @return the number of running tasks that have the taskname specified
+ */
+ public long getTaskExecutionCount(String taskName);
+
+ /**
+ * Get a collection/page of executions
+ *
+ * @param taskName the name of the task to be searched
+ * @param start the position of the first execution to return
+ * @param count the number of executions to return
+ * @return list of task executions
+ */
+ public List getTaskExecutionsByName(String taskName, int start, int count);
+
+
+}
diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/TaskRepository.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/TaskRepository.java
new file mode 100644
index 00000000..f416c8eb
--- /dev/null
+++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/TaskRepository.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.task.repository;
+
+/**
+ * TaskRepository interface offers methods that create and update task execution
+ * information. The interface will support the following methods:
+ *
+ * @author Glenn Renfro
+ */
+public interface TaskRepository {
+
+ /**
+ * Notifies the repository that a taskExecution needs to be updated.
+ *
+ * @param taskExecution taskExecution to be updated
+ */
+ public void update(TaskExecution taskExecution);
+
+ /**
+ * Notifies the repository that a taskExecution needs to be created.
+ *
+ * @param taskExecution taskExecution to be recorded
+ */
+ public void createTaskExecution(TaskExecution taskExecution);
+}