Instrument spring-batch: & Spring Batch XML tests
ADD
instrumentation/spring/spring-batch-3.0/javaagent/src/test/groovy/JavaxBatchConfigTrait.groovy
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import java.util.concurrent.atomic.AtomicInteger
+import javax.batch.operations.JobOperator
+import javax.batch.runtime.BatchRuntime
+import org.springframework.batch.core.JobParameter
+
+trait JavaxBatchConfigTrait {
+ static JobOperator jobOperator
+ static AtomicInteger counter = new AtomicInteger()
+
+ def setupSpec() {
+ jobOperator = BatchRuntime.jobOperator
+ }
+
+ // just for consistency with ApplicationConfigTrait
+ def cleanupSpec() {
+ additionalCleanup()
+ }
+
+ def additionalCleanup() {}
+
+ def runJob(String jobName, Map<String, JobParameter> params) {
+ def jobParams = new Properties()
+ params.forEach({k, v ->
+ jobParams.setProperty(k, v.toString())
+ })
+ // each job instance with the same name needs to be unique
+ jobParams.setProperty("uniqueJobIdCounter", counter.getAndIncrement().toString())
+ jobOperator.start(jobName, jobParams)
+ }
+}
\ No newline at end of file

MODIFY
instrumentation/spring/spring-batch-3.0/javaagent/src/test/groovy/SpringBatchTest.groovy
instrumentation/spring/spring-batch-3.0/javaagent/src/test/groovy/SpringBatchTest.groovy
@@ -13,6 +13,7 @@ import io.opentelemetry.instrumentation.test.AgentTestRunner
import org.springframework.batch.core.JobParameter
import org.springframework.context.ConfigurableApplicationContext
import org.springframework.context.annotation.AnnotationConfigApplicationContext
+import org.springframework.context.support.ClassPathXmlApplicationContext
abstract class SpringBatchTest extends AgentTestRunner {
@@ -78,3 +79,28 @@ class JavaConfigBatchJobTest extends SpringBatchTest implements ApplicationConfi
new AnnotationConfigApplicationContext(SpringBatchApplication)
}
}
+
+class XmlConfigBatchJobTest extends SpringBatchTest implements ApplicationConfigTrait {
+ static final Config PREVIOUS_CONFIG = updateConfig {
+ it.setProperty("otel.instrumentation.spring-batch.enabled", "true")
+ }
+
+ def additionalCleanup() {
+ setConfig(PREVIOUS_CONFIG)
+ }
+
+ @Override
+ ConfigurableApplicationContext createApplicationContext() {
+ new ClassPathXmlApplicationContext("spring-batch.xml")
+ }
+}
+
+class JsrConfigBatchJobTest extends SpringBatchTest implements JavaxBatchConfigTrait {
+ static final Config PREVIOUS_CONFIG = updateConfig {
+ it.setProperty("otel.instrumentation.spring-batch.enabled", "true")
+ }
+
+ def additionalCleanup() {
+ setConfig(PREVIOUS_CONFIG)
+ }
+}

ADD
instrumentation/spring/spring-batch-3.0/javaagent/src/test/groovy/jsr/TestBatchlet.groovy
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package jsr
+
+import javax.batch.api.BatchProperty
+import javax.batch.api.Batchlet
+import javax.inject.Inject
+
+class TestBatchlet implements Batchlet {
+ @Inject
+ @BatchProperty(name = "fail")
+ String fail
+
+ @Override
+ String process() throws Exception {
+ if (fail != null && Integer.valueOf(fail) == 1) {
+ throw new RuntimeException("fail")
+ }
+ return "FINISHED"
+ }
+
+ @Override
+ void stop() throws Exception {
+ }
+}

ADD
instrumentation/spring/spring-batch-3.0/javaagent/src/test/groovy/jsr/TestItemProcessor.groovy
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package jsr
+
+import javax.batch.api.chunk.ItemProcessor
+
+class TestItemProcessor implements ItemProcessor {
+ @Override
+ Object processItem(Object item) throws Exception {
+ Integer.parseInt(item as String)
+ }
+}
\ No newline at end of file

ADD
instrumentation/spring/spring-batch-3.0/javaagent/src/test/groovy/jsr/TestItemReader.groovy
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package jsr
+
+import java.util.stream.Collectors
+import java.util.stream.IntStream
+import javax.batch.api.chunk.ItemReader
+
+class TestItemReader implements ItemReader {
+ private final List<String> items = IntStream.range(0, 13).mapToObj(String.&valueOf).collect(Collectors.toList())
+ private Iterator<String> itemsIt
+
+ @Override
+ void open(Serializable serializable) throws Exception {
+ itemsIt = items.iterator()
+ }
+
+ @Override
+ void close() throws Exception {
+ itemsIt = null
+ }
+
+ @Override
+ Object readItem() throws Exception {
+ if (itemsIt == null) {
+ return null
+ }
+ return itemsIt.hasNext() ? itemsIt.next() : null
+ }
+
+ @Override
+ Serializable checkpointInfo() throws Exception {
+ return null
+ }
+}
\ No newline at end of file

ADD
instrumentation/spring/spring-batch-3.0/javaagent/src/test/groovy/jsr/TestItemWriter.groovy
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package jsr
+
+import javax.batch.api.chunk.ItemWriter
+
+class TestItemWriter implements ItemWriter {
+ final List<Integer> items = new ArrayList()
+
+ @Override
+ void open(Serializable checkpoint) throws Exception {
+ }
+
+ @Override
+ void close() throws Exception {
+ }
+
+ @Override
+ void writeItems(List<Object> items) throws Exception {
+ for (item in items) {
+ this.items.add(item as Integer)
+ }
+ }
+
+ @Override
+ Serializable checkpointInfo() throws Exception {
+ return null
+ }
+}
\ No newline at end of file

ADD
instrumentation/spring/spring-batch-3.0/javaagent/src/test/resources/META-INF/batch-jobs/itemsAndTaskletJob.xml
+<?xml version="1.0" encoding="UTF-8"?>
+<job id="itemsAndTaskletJob" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
+ <step id="itemStep">
+ <chunk item-count="5">
+ <reader ref="jsr.TestItemReader"/>
+ <processor ref="jsr.TestItemProcessor"/>
+ <writer ref="jsr.TestItemWriter"/>
+ </chunk>
+ <next on="*" to="taskletStep"/>
+ </step>
+ <step id="taskletStep">
+ <batchlet ref="jsr.TestBatchlet"/>
+ </step>
+</job>
\ No newline at end of file

ADD
instrumentation/spring/spring-batch-3.0/javaagent/src/test/resources/META-INF/batch-jobs/taskletJob.xml
+<?xml version="1.0" encoding="UTF-8"?>
+<job id="taskletJob" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
+ <step id="step">
+ <batchlet ref="jsr.TestBatchlet">
+ <properties>
+ <property name="fail" value="#{jobParameters['fail']}"/>
+ </properties>
+ </batchlet>
+ </step>
+</job>
\ No newline at end of file

ADD
instrumentation/spring/spring-batch-3.0/javaagent/src/test/resources/baseContext.xml
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <bean id="jobRepository"
+ class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
+ <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
+ <property name="jobRepository" ref="jobRepository"/>
+ </bean>
+ <bean id="jobParametersConverter"
+ class="org.springframework.batch.core.converter.DefaultJobParametersConverter"/>
+ <bean id="jobExplorer"
+ class="org.springframework.batch.core.explore.support.MapJobExplorerFactoryBean">
+ <property name="repositoryFactory" ref="&amp;jobRepository"/>
+ </bean>
+ <bean id="transactionManager"
+ class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
+</beans>

ADD
instrumentation/spring/spring-batch-3.0/javaagent/src/test/resources/jsrBaseContext.xml
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
+ <import resource="baseContext.xml"/>
+</beans>
\ No newline at end of file

ADD
instrumentation/spring/spring-batch-3.0/javaagent/src/test/resources/spring-batch.xml
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:b="http://www.springframework.org/schema/batch"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd">
+ <import resource="baseContext.xml"/>
+
+ <b:job id="taskletJob">
+ <b:step id="step">
+ <b:tasklet ref="testTasklet"/>
+ </b:step>
+ </b:job>
+
+ <b:job id="itemsAndTaskletJob">
+ <b:step id="itemStep">
+ <b:tasklet>
+ <b:chunk commit-interval="5" reader="itemReader" processor="itemProcessor"
+ writer="itemWriter"/>
+ </b:tasklet>
+ <b:next on="*" to="taskletStep"/>
+ </b:step>
+ <b:step id="taskletStep">
+ <b:tasklet ref="testTasklet"/>
+ </b:step>
+ </b:job>
+
+ <bean id="itemReader" class="springbatch.TestItemReader"/>
+ <bean id="itemProcessor" class="springbatch.TestItemProcessor"/>
+ <bean id="itemWriter" class="springbatch.TestItemWriter"/>
+ <bean id="testTasklet" class="springbatch.TestTasklet"/>
+</beans>
\ No newline at end of file

Instrument spring-batch: JSR-352 & Spring Batch XML tests (#1852)