diff --git a/batch-simple-jc/.gitignore b/batch-simple-jc/.gitignore new file mode 100644 index 0000000..86bc7e8 --- /dev/null +++ b/batch-simple-jc/.gitignore @@ -0,0 +1,4 @@ +/build/ +/*.iml +/bin +target diff --git a/batch-simple-jc/README.md b/batch-simple-jc/README.md new file mode 100644 index 0000000..95b0aac --- /dev/null +++ b/batch-simple-jc/README.md @@ -0,0 +1,132 @@ +Spring XD Simple Batch Sample +============================= + +In this *Hello World* example for *Spring XD* you will create a minimal code-based Job. This Job does no processing, only printing out `Hello Spring XD!` as well as any Job parameters that were passed into the Job so as to focus only on the mechanics of the compilation and copying of artifacts into the Spring XD installation directory. + +## Requirements + +In order for the sample to run you will need to have installed: + +* Spring XD 1.1.0.RELEASE or higher ([Instructions](https://github.com/SpringSource/spring-xd/wiki/Getting-Started)) + +## Code Tour + +The processing actions that are part of a Step in a batch Job are pluggable. The plug-in point for a Step is known as a [Tasklet](http://static.springsource.org/spring-batch/apidocs/org/springframework/batch/core/step/tasklet/Tasklet.html). In this example we create a tasklet by implementing the Tasklet interface. Take a look at the [source code](https://github.com/spring-projects/spring-xd-samples/blob/master/batch-simple/src/main/java/org/springframework/springxd/samples/batch/HelloSpringXDTasklet.java) as well as its incorporation into a [Job definition](https://github.com/spring-projects/spring-xd-samples/blob/master/batch-simple/src/main/resources/spring-module.xml) inside an XML file. Note that the XML file must contain a single Job. + +## Building with Maven + +Build the sample simply by executing: + + $ mvn clean package + +The project's [pom][] declares `spring-xd-module-parent` as its parent. This adds the dependencies needed to compile and test the module and also configures the [Spring Boot Maven Plugin][] to package the module as an uber-jar, packaging any dependencies that are not already provided by the Spring XD container. In this case there are no additional dependencies so the artifact is built as a common jar. See the [Modules][] section in the Spring XD Reference for more details on module packaging. + +## Building with Gradle + + $./gradlew clean bootRepackage + +The project's [build.gradle][] applies the `spring-xd-module` plugin, providing analagous build and packaging support for gradle. This plugin also applies the [Spring Boot Gradle Plugin][] as well as the [propdeps plugin][]. + + +## Running the Sample + +Now your sample is ready to be executed. Start your *Spring XD* singlenode server: + + xd/bin>$ ./xd-singlenode + + _____ __ _______ + / ___| (-) \ \ / / _ \ + \ `--. _ __ _ __ _ _ __ __ _ \ V /| | | | + `--. \ '_ \| '__| | '_ \ / _` | / ^ \| | | | + /\__/ / |_) | | | | | | | (_| | / / \ \ |/ / + \____/| .__/|_| |_|_| |_|\__, | \/ \/___/ + | | __/ | + |_| |___/ + 1.1.0.BUILD-SNAPSHOT eXtreme Data + + + Started container : SingleNodeApplication + Documentation: https://github.com/SpringSource/spring-xd/wiki + ... + +Now start the *Spring XD Shell* in a separate window: + + shell/bin>$ ./xd-shell + + _____ __ _______ + / ___| (-) \ \ / / _ \ + \ `--. _ __ _ __ _ _ __ __ _ \ V /| | | | + `--. \ '_ \| '__| | '_ \ / _` | / ^ \| | | | + /\__/ / |_) | | | | | | | (_| | / / \ \ |/ / + \____/| .__/|_| |_|_| |_|\__, | \/ \/___/ + | | __/ | + |_| |___/ + eXtreme Data + 1.1.0.BUILD-SNAPSHOT | Admin Server Target: http://localhost:9393 + Welcome to the Spring XD shell. For assistance hit TAB or type "help". + xd:> + +First install the module using the `module upload` command: + + xd:>module upload --type job --name myjob --file [path-to]/springxd-batch-simple-jc-1.0.0.BUILD-SNAPSHOT.jar + +You will now create a new Batch Job Stream using the *Spring XD Shell*: + + xd:>job create --name helloSpringXD --definition "myjob --message=SpringXD" + +The UI is located on the machine where xd-singlenode is running and will show you the jobs that can be deployed. The UI is located at: + +* **http://localhost:9393/admin-ui** + +Alternatively, you can deploy it using the command line + + xd:>job deploy helloSpringXD + +And then launch the job + + xd:>job launch helloSpringXD + +You should see a message in the log output from the XD container: + + Hello Spring XD! + The following 1 Job Parameter(s) is/are present: + Parameter name: random; isIdentifying: true; type: STRING; value: 0.07119643877192872 + +You can also experiment with Job parameters: + + job launch helloSpringXD --params {"myStringParameter":"foobar","-secondParam(long)":"123456"} + + Hello SpringXD + The following 3 Job Parameter(s) is/are present: + Parameter name: secondParam; isIdentifying: false; type: LONG; value: 123456 + Parameter name: myStringParameter; isIdentifying: true; type: STRING; value: foobar + Parameter name: random; isIdentifying: true; type: STRING; value: 0.06893349621991496 + 12:04:18,384 INFO http-nio-9393-exec-5 support.SimpleJobLauncher:135 - Job: [FlowJob: [name=helloSpringXD.job]] completed with the following parameters: [{secondParam=123456, myStringParameter=foobar, random=0.06893349621991496}] and the following status: [COMPLETED] + +## Throwing Exceptions + +You can trigger an exception by providing a parameter named `throwError` with a String value of `true`. + +## Adding Variables to the Step Execution Context + +Any parameters that start with `context` will be added to the Step Execution Context. +E.g. if you add a parameter named `contextHello` with a String value of `World`, +the variable `contextHello` will be added to the Step Execution Context. You can +verify the context using the **Admin UI** and drilling to the Step Execution Details +via the *Executions* tab. + +## Job Repository + +In this example the state of the Job execution is stored in an HSQLDB database embedded inside the single node server. Please refer to the Spring XD documentation if you would like to store this data in another database. + +## To run batch job with multiple steps + +Follow the instructions in the module's [xml] configuration to have batch job with multiple steps + +[xml]: https://github.com/spring-projects/spring-xd-samples/blob/master/batch-simple/src/main/resources/config/spring-module.xml +[pom]: https://github.com/spring-projects/spring-xd-samples/blob/master/batch-simple/pom.xml +[build.gradle]: https://github.com/spring-projects/spring-xd-samples/blob/master/batch-simple/build.gradle +[Spring Boot Maven Plugin]: http://docs.spring.io/spring-boot/docs/current/reference/html/build-tool-plugins-maven-plugin.html +[Spring Boot Gradle Plugin]: http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/html/build-tool-plugins-gradle-plugin.html +[propdeps plugin]: https://github.com/spring-projects/gradle-plugins/tree/master/propdeps-plugin +[Modules]: http://docs.spring.io/spring-xd/docs/current/reference/html/#modules diff --git a/batch-simple-jc/build.gradle b/batch-simple-jc/build.gradle new file mode 100644 index 0000000..848cd14 --- /dev/null +++ b/batch-simple-jc/build.gradle @@ -0,0 +1,16 @@ +/* +NOTE: This configuration is convenient for maintaining shared configuration across multiple projects in the samples repo. +If copying this example, it may be simpler to declare the +required configuration inline. +*/ +buildscript { + apply from: '../sample-modules-parent/buildscript.gradle', + to: buildscript +} +apply from: '../sample-modules-parent/build.gradle' +apply plugin: 'spring-xd-module' + +description = "Batch Simple Example using Java Configuration" + +sourceCompatibility = 1.6 +targetCompatibility = 1.6 diff --git a/batch-simple-jc/gradle/wrapper/gradle-wrapper.jar b/batch-simple-jc/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..3d0dee6 Binary files /dev/null and b/batch-simple-jc/gradle/wrapper/gradle-wrapper.jar differ diff --git a/batch-simple-jc/gradle/wrapper/gradle-wrapper.properties b/batch-simple-jc/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..15bdcb3 --- /dev/null +++ b/batch-simple-jc/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sun Jan 25 13:12:53 EST 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-1.12-bin.zip diff --git a/batch-simple-jc/gradlew b/batch-simple-jc/gradlew new file mode 100644 index 0000000..91a7e26 --- /dev/null +++ b/batch-simple-jc/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/batch-simple-jc/gradlew.bat b/batch-simple-jc/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/batch-simple-jc/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/batch-simple-jc/pom.xml b/batch-simple-jc/pom.xml new file mode 100644 index 0000000..cb8f31c --- /dev/null +++ b/batch-simple-jc/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + org.springframework.xd.samples + springxd-batch-simple-jc + 1.0.0.BUILD-SNAPSHOT + Spring XD Sample - Batch Simple Example using Java Configuration + jar + + + + + + 2.2.1 + + + + org.springframework.xd.samples + sample-modules-parent + 1.0.0.BUILD-SNAPSHOT + ../sample-modules-parent + + diff --git a/batch-simple-jc/settings.gradle b/batch-simple-jc/settings.gradle new file mode 100644 index 0000000..06d2829 --- /dev/null +++ b/batch-simple-jc/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'batch-simple-jc' diff --git a/batch-simple-jc/src/main/java/org/springframework/springxd/samples/batch/HelloSpringXDConfiguration.java b/batch-simple-jc/src/main/java/org/springframework/springxd/samples/batch/HelloSpringXDConfiguration.java new file mode 100644 index 0000000..9a63d64 --- /dev/null +++ b/batch-simple-jc/src/main/java/org/springframework/springxd/samples/batch/HelloSpringXDConfiguration.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015 wz07. + * + * 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.springxd.samples.batch; + +import org.springframework.batch.core.Job; +import org.springframework.batch.core.Step; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.support.RunIdIncrementer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Java Configuration for Batch Job + * @author Sathish Kumar Thiyagarajan + */ +@Configuration +@EnableBatchProcessing +public class HelloSpringXDConfiguration { + + @Autowired + private HelloSpringXDTasklet helloSpringXDTasklet; + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory stepBuilderFactory) { + Step step1 = stepBuilderFactory.get("helloSpringXDStep") + .tasklet(helloSpringXDTasklet) + .build(); + return jobs.get("helloSpringXDJob") + .incrementer(new RunIdIncrementer()) + .flow(step1) + .end() + .build(); + } + +} diff --git a/batch-simple-jc/src/main/java/org/springframework/springxd/samples/batch/HelloSpringXDOptionsMetadata.java b/batch-simple-jc/src/main/java/org/springframework/springxd/samples/batch/HelloSpringXDOptionsMetadata.java new file mode 100644 index 0000000..a317f90 --- /dev/null +++ b/batch-simple-jc/src/main/java/org/springframework/springxd/samples/batch/HelloSpringXDOptionsMetadata.java @@ -0,0 +1,48 @@ +/* + * Copyright 2015 WZ07. + * + * 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.springxd.samples.batch; + +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.NotNull; + +import org.springframework.xd.module.options.spi.ModuleOption; + +/** + * An example class to describe and validate module options. + * + * Note the @ModuleOption annotation on the setters and the javax.validation + * annotations on the getters. + * @author Sathish Kumar Thiyagarajan + */ +public class HelloSpringXDOptionsMetadata { + + private String message; + + @NotNull + public String getMessage() { + return message; + } + + @ModuleOption("the message") + public void setMessage(String message) { + this.message = message; + } + + @AssertTrue(message = "message cannot be empty") + public boolean messageCannotBeTheEmpty() { + return (message != null && message.trim().length() !=0); + } +} diff --git a/batch-simple-jc/src/main/java/org/springframework/springxd/samples/batch/HelloSpringXDTasklet.java b/batch-simple-jc/src/main/java/org/springframework/springxd/samples/batch/HelloSpringXDTasklet.java new file mode 100644 index 0000000..3fdad3c --- /dev/null +++ b/batch-simple-jc/src/main/java/org/springframework/springxd/samples/batch/HelloSpringXDTasklet.java @@ -0,0 +1,109 @@ +/* + * Copyright 2013-2014 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.springxd.samples.batch; + +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.JobParameter; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.StepContribution; +import org.springframework.batch.core.StepExecution; +import org.springframework.batch.core.StepExecutionListener; +import org.springframework.batch.core.scope.context.ChunkContext; +import org.springframework.batch.core.step.tasklet.Tasklet; +import org.springframework.batch.item.ExecutionContext; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * Hello Tasklet + * This will display hello message with message input provided by HelloSpringXDOptionsMetadata + * @author Sathish Kumar Thiyagarajan + */ +@Component +public class HelloSpringXDTasklet implements Tasklet, StepExecutionListener { + + private volatile AtomicInteger counter = new AtomicInteger(0); + + @Value("${message}") + private String message; + + /** + * + */ + public HelloSpringXDTasklet() { + super(); + } + + public RepeatStatus execute(StepContribution contribution, + ChunkContext chunkContext) throws Exception { + + final JobParameters jobParameters = chunkContext.getStepContext().getStepExecution().getJobParameters(); + final ExecutionContext stepExecutionContext = chunkContext.getStepContext().getStepExecution().getExecutionContext(); + + System.out.println("Hello " + message); + + if (jobParameters != null && !jobParameters.isEmpty()) { + + final Set> parameterEntries = jobParameters.getParameters().entrySet(); + + System.out.println(String.format("The following %s Job Parameter(s) is/are present:", parameterEntries.size())); + + for (Entry jobParameterEntry : parameterEntries) { + System.out.println(String.format( + "Parameter name: %s; isIdentifying: %s; type: %s; value: %s", + jobParameterEntry.getKey(), + jobParameterEntry.getValue().isIdentifying(), + jobParameterEntry.getValue().getType().toString(), + jobParameterEntry.getValue().getValue())); + + if (jobParameterEntry.getKey().startsWith("context")) { + stepExecutionContext.put(jobParameterEntry.getKey(), jobParameterEntry.getValue().getValue()); + } + } + + if (jobParameters.getString("throwError") != null + && Boolean.TRUE.toString().equalsIgnoreCase(jobParameters.getString("throwError"))) { + + if (this.counter.compareAndSet(3, 0)) { + System.out.println("Counter reset to 0. Execution will succeed."); + } else { + this.counter.incrementAndGet(); + throw new IllegalStateException("Exception triggered by user."); + } + + } + } + return RepeatStatus.FINISHED; + } + + @Override + public void beforeStep(StepExecution stepExecution) { + } + + @Override + public ExitStatus afterStep(StepExecution stepExecution) { + // To make the job execution fail, set the step execution to fail + // and return failed ExitStatus + // stepExecution.setStatus(BatchStatus.FAILED); + // return ExitStatus.FAILED; + return ExitStatus.COMPLETED; + } +} diff --git a/batch-simple-jc/src/main/resources/config/spring-module.properties b/batch-simple-jc/src/main/resources/config/spring-module.properties new file mode 100644 index 0000000..0280d10 --- /dev/null +++ b/batch-simple-jc/src/main/resources/config/spring-module.properties @@ -0,0 +1,2 @@ +options_class=org.springframework.springxd.samples.batch.HelloSpringXDOptionsMetadata +base_packages=org.springframework.springxd.samples.batch \ No newline at end of file diff --git a/batch-simple-jc/src/main/resources/log4j.properties b/batch-simple-jc/src/main/resources/log4j.properties new file mode 100644 index 0000000..b3573b3 --- /dev/null +++ b/batch-simple-jc/src/main/resources/log4j.properties @@ -0,0 +1,6 @@ +log4j.rootLogger=WARN, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n + diff --git a/pom.xml b/pom.xml index efda299..698a634 100644 --- a/pom.xml +++ b/pom.xml @@ -11,6 +11,7 @@ batch-notifications batch-pig batch-simple + batch-simple-jc batch-wordcount groovy-script-sink payload-conversion