Remove the static configuration of Micrometer's observation registry
Resolves #4222
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.batch.core.configuration.annotation;
|
||||
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.batch.core.job.AbstractJob;
|
||||
import org.springframework.batch.core.step.AbstractStep;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
|
||||
/**
|
||||
* Bean post processor that configures observable batch artifacts (jobs and steps) with
|
||||
* Micrometer's observation registry.
|
||||
*
|
||||
* @author Mahmoud Ben Hassine
|
||||
* @since 5.0
|
||||
*/
|
||||
public class BatchObservabilityBeanPostProcessor implements BeanFactoryPostProcessor, BeanPostProcessor {
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(BatchObservabilityBeanPostProcessor.class);
|
||||
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
try {
|
||||
if (bean instanceof AbstractJob || bean instanceof AbstractStep) {
|
||||
ObservationRegistry observationRegistry = this.beanFactory.getBean(ObservationRegistry.class);
|
||||
if (bean instanceof AbstractJob) {
|
||||
((AbstractJob) bean).setObservationRegistry(observationRegistry);
|
||||
}
|
||||
if (bean instanceof AbstractStep) {
|
||||
((AbstractStep) bean).setObservationRegistry(observationRegistry);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException e) {
|
||||
LOGGER.info("No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP");
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -151,7 +151,8 @@ import org.springframework.context.annotation.Import;
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Import({ BatchRegistrar.class, ScopeConfiguration.class, AutomaticJobRegistrarBeanPostProcessor.class })
|
||||
@Import({ BatchRegistrar.class, ScopeConfiguration.class, AutomaticJobRegistrarBeanPostProcessor.class,
|
||||
BatchObservabilityBeanPostProcessor.class })
|
||||
public @interface EnableBatchProcessing {
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.stream.Collectors;
|
||||
import io.micrometer.core.instrument.LongTaskTimer;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -87,6 +88,8 @@ public abstract class AbstractJob implements Job, StepLocator, BeanNameAware, In
|
||||
|
||||
private StepHandler stepHandler;
|
||||
|
||||
private ObservationRegistry observationRegistry = ObservationRegistry.NOOP;
|
||||
|
||||
private BatchJobObservationConvention observationConvention = new DefaultBatchJobObservationConvention();
|
||||
|
||||
/**
|
||||
@@ -289,7 +292,8 @@ public abstract class AbstractJob implements Job, StepLocator, BeanNameAware, In
|
||||
BatchMetrics.METRICS_PREFIX + activeJobMeterName + ".name", execution.getJobInstance().getJobName()));
|
||||
LongTaskTimer.Sample longTaskTimerSample = longTaskTimer.start();
|
||||
Observation observation = BatchMetrics
|
||||
.createObservation(BatchJobObservation.BATCH_JOB_OBSERVATION.getName(), new BatchJobContext(execution))
|
||||
.createObservation(BatchJobObservation.BATCH_JOB_OBSERVATION.getName(), new BatchJobContext(execution),
|
||||
this.observationRegistry)
|
||||
.contextualName(execution.getJobInstance().getJobName())
|
||||
.observationConvention(this.observationConvention).start();
|
||||
try (Observation.Scope scope = observation.openScope()) {
|
||||
@@ -439,6 +443,10 @@ public abstract class AbstractJob implements Job, StepLocator, BeanNameAware, In
|
||||
this.observationConvention = observationConvention;
|
||||
}
|
||||
|
||||
public void setObservationRegistry(ObservationRegistry observationRegistry) {
|
||||
this.observationRegistry = observationRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ClassUtils.getShortName(getClass()) + ": [name=" + name + "]";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2020 the original author or authors.
|
||||
* Copyright 2006-2022 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.
|
||||
@@ -22,8 +22,10 @@ import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecutionListener;
|
||||
import org.springframework.batch.core.JobParametersIncrementer;
|
||||
@@ -99,6 +101,18 @@ public abstract class JobBuilderHelper<B extends JobBuilderHelper<B>> {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the observation registry for the job.
|
||||
* @param observationRegistry the observation registry (optional)
|
||||
* @return this to enable fluent chaining
|
||||
*/
|
||||
public B observationRegistry(ObservationRegistry observationRegistry) {
|
||||
properties.observationRegistry = observationRegistry;
|
||||
@SuppressWarnings("unchecked")
|
||||
B result = (B) this;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers objects using the annotation based listener configuration.
|
||||
* @param listener the object that has a method configured with listener annotation
|
||||
@@ -170,6 +184,10 @@ public abstract class JobBuilderHelper<B extends JobBuilderHelper<B>> {
|
||||
if (jobParametersValidator != null) {
|
||||
job.setJobParametersValidator(jobParametersValidator);
|
||||
}
|
||||
ObservationRegistry observationRegistry = properties.getObservationRegistry();
|
||||
if (observationRegistry != null) {
|
||||
job.setObservationRegistry(observationRegistry);
|
||||
}
|
||||
|
||||
Boolean restartable = properties.getRestartable();
|
||||
if (restartable != null) {
|
||||
@@ -193,6 +211,8 @@ public abstract class JobBuilderHelper<B extends JobBuilderHelper<B>> {
|
||||
|
||||
private JobRepository jobRepository;
|
||||
|
||||
private ObservationRegistry observationRegistry;
|
||||
|
||||
private JobParametersIncrementer jobParametersIncrementer;
|
||||
|
||||
private JobParametersValidator jobParametersValidator;
|
||||
@@ -204,6 +224,7 @@ public abstract class JobBuilderHelper<B extends JobBuilderHelper<B>> {
|
||||
this.name = properties.name;
|
||||
this.restartable = properties.restartable;
|
||||
this.jobRepository = properties.jobRepository;
|
||||
this.observationRegistry = properties.observationRegistry;
|
||||
this.jobExecutionListeners = new LinkedHashSet<>(properties.jobExecutionListeners);
|
||||
this.jobParametersIncrementer = properties.jobParametersIncrementer;
|
||||
this.jobParametersValidator = properties.jobParametersValidator;
|
||||
@@ -233,6 +254,14 @@ public abstract class JobBuilderHelper<B extends JobBuilderHelper<B>> {
|
||||
this.jobRepository = jobRepository;
|
||||
}
|
||||
|
||||
public ObservationRegistry getObservationRegistry() {
|
||||
return observationRegistry;
|
||||
}
|
||||
|
||||
public void setObservationRegistry(ObservationRegistry observationRegistry) {
|
||||
this.observationRegistry = observationRegistry;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -54,18 +54,6 @@ public final class BatchMetrics {
|
||||
|
||||
public static final String STATUS_FAILURE = "FAILURE";
|
||||
|
||||
/**
|
||||
* Global {@link ObservationRegistry}. A {@link DefaultMeterObservationHandler} is
|
||||
* attached to create a {@link Timer} for every finished {@link Observation}.
|
||||
*/
|
||||
public static ObservationRegistry observationRegistry;
|
||||
|
||||
static {
|
||||
observationRegistry = ObservationRegistry.create();
|
||||
observationRegistry.observationConfig()
|
||||
.observationHandler(new DefaultMeterObservationHandler(Metrics.globalRegistry));
|
||||
}
|
||||
|
||||
private BatchMetrics() {
|
||||
}
|
||||
|
||||
@@ -94,7 +82,8 @@ public final class BatchMetrics {
|
||||
* @return a new observation instance
|
||||
* @since 5.0
|
||||
*/
|
||||
public static Observation createObservation(String name, BatchJobContext context) {
|
||||
public static Observation createObservation(String name, BatchJobContext context,
|
||||
ObservationRegistry observationRegistry) {
|
||||
return Observation.createNotStarted(name, context, observationRegistry);
|
||||
}
|
||||
|
||||
@@ -110,7 +99,8 @@ public final class BatchMetrics {
|
||||
* @return a new observation instance
|
||||
* @since 5.0
|
||||
*/
|
||||
public static Observation createObservation(String name, BatchStepContext context) {
|
||||
public static Observation createObservation(String name, BatchStepContext context,
|
||||
ObservationRegistry observationRegistry) {
|
||||
return Observation.createNotStarted(name, context, observationRegistry);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -75,6 +76,8 @@ public abstract class AbstractStep implements Step, InitializingBean, BeanNameAw
|
||||
|
||||
private JobRepository jobRepository;
|
||||
|
||||
private ObservationRegistry observationRegistry = ObservationRegistry.NOOP;
|
||||
|
||||
private BatchStepObservationConvention observationConvention = new DefaultBatchStepObservationConvention();
|
||||
|
||||
/**
|
||||
@@ -203,7 +206,7 @@ public abstract class AbstractStep implements Step, InitializingBean, BeanNameAw
|
||||
stepExecution.setStatus(BatchStatus.STARTED);
|
||||
Observation observation = BatchMetrics
|
||||
.createObservation(BatchStepObservation.BATCH_STEP_OBSERVATION.getName(),
|
||||
new BatchStepContext(stepExecution))
|
||||
new BatchStepContext(stepExecution), this.observationRegistry)
|
||||
.contextualName(stepExecution.getStepName()).observationConvention(this.observationConvention).start();
|
||||
getJobRepository().update(stepExecution);
|
||||
|
||||
@@ -424,4 +427,8 @@ public abstract class AbstractStep implements Step, InitializingBean, BeanNameAw
|
||||
this.observationConvention = observationConvention;
|
||||
}
|
||||
|
||||
public void setObservationRegistry(ObservationRegistry observationRegistry) {
|
||||
this.observationRegistry = observationRegistry;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,8 +15,16 @@
|
||||
*/
|
||||
package org.springframework.batch.core.step.builder;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecutionListener;
|
||||
import org.springframework.batch.core.annotation.AfterStep;
|
||||
@@ -24,15 +32,7 @@ import org.springframework.batch.core.annotation.BeforeStep;
|
||||
import org.springframework.batch.core.listener.StepListenerFactoryBean;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.step.AbstractStep;
|
||||
import org.springframework.batch.core.step.tasklet.TaskletStep;
|
||||
import org.springframework.batch.support.ReflectionUtils;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A base class and utility for other step builders providing access to common properties
|
||||
@@ -68,6 +68,11 @@ public abstract class StepBuilderHelper<B extends StepBuilderHelper<B>> {
|
||||
return self();
|
||||
}
|
||||
|
||||
public B observationRegistry(ObservationRegistry observationRegistry) {
|
||||
properties.observationRegistry = observationRegistry;
|
||||
return self();
|
||||
}
|
||||
|
||||
public B startLimit(int startLimit) {
|
||||
properties.startLimit = startLimit;
|
||||
return self();
|
||||
@@ -123,6 +128,11 @@ public abstract class StepBuilderHelper<B extends StepBuilderHelper<B>> {
|
||||
AbstractStep step = (AbstractStep) target;
|
||||
step.setJobRepository(properties.getJobRepository());
|
||||
|
||||
ObservationRegistry observationRegistry = properties.getObservationRegistry();
|
||||
if (observationRegistry != null) {
|
||||
step.setObservationRegistry(observationRegistry);
|
||||
}
|
||||
|
||||
Boolean allowStartIfComplete = properties.allowStartIfComplete;
|
||||
if (allowStartIfComplete != null) {
|
||||
step.setAllowStartIfComplete(allowStartIfComplete);
|
||||
@@ -149,6 +159,8 @@ public abstract class StepBuilderHelper<B extends StepBuilderHelper<B>> {
|
||||
|
||||
private JobRepository jobRepository;
|
||||
|
||||
private ObservationRegistry observationRegistry = ObservationRegistry.NOOP;
|
||||
|
||||
public CommonStepProperties() {
|
||||
}
|
||||
|
||||
@@ -157,6 +169,7 @@ public abstract class StepBuilderHelper<B extends StepBuilderHelper<B>> {
|
||||
this.startLimit = properties.startLimit;
|
||||
this.allowStartIfComplete = properties.allowStartIfComplete;
|
||||
this.jobRepository = properties.jobRepository;
|
||||
this.observationRegistry = properties.observationRegistry;
|
||||
this.stepExecutionListeners = new ArrayList<>(properties.stepExecutionListeners);
|
||||
}
|
||||
|
||||
@@ -168,6 +181,14 @@ public abstract class StepBuilderHelper<B extends StepBuilderHelper<B>> {
|
||||
this.jobRepository = jobRepository;
|
||||
}
|
||||
|
||||
public ObservationRegistry getObservationRegistry() {
|
||||
return observationRegistry;
|
||||
}
|
||||
|
||||
public void setObservationRegistry(ObservationRegistry observationRegistry) {
|
||||
this.observationRegistry = observationRegistry;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.batch.core.step.factory;
|
||||
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.core.ChunkListener;
|
||||
@@ -84,6 +85,8 @@ public class SimpleStepFactoryBean<T, S> implements FactoryBean<Step>, BeanNameA
|
||||
|
||||
protected JobRepository jobRepository;
|
||||
|
||||
protected ObservationRegistry observationRegistry = ObservationRegistry.NOOP;
|
||||
|
||||
private boolean singleton = true;
|
||||
|
||||
private ItemStream[] streams = new ItemStream[0];
|
||||
@@ -270,6 +273,15 @@ public class SimpleStepFactoryBean<T, S> implements FactoryBean<Step>, BeanNameA
|
||||
this.jobRepository = jobRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for {@link ObservationRegistry}.
|
||||
* @param observationRegistry is an optional dependency (defaults to
|
||||
* {@link ObservationRegistry#NOOP}).
|
||||
*/
|
||||
public void setObservationRegistry(ObservationRegistry observationRegistry) {
|
||||
this.observationRegistry = observationRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the {@link PlatformTransactionManager}.
|
||||
* @param transactionManager the transaction manager to set
|
||||
@@ -469,6 +481,7 @@ public class SimpleStepFactoryBean<T, S> implements FactoryBean<Step>, BeanNameA
|
||||
builder.transactionManager(transactionManager);
|
||||
builder.transactionAttribute(getTransactionAttribute());
|
||||
builder.repository(jobRepository);
|
||||
builder.observationRegistry(observationRegistry);
|
||||
builder.startLimit(startLimit);
|
||||
builder.allowStartIfComplete(allowStartIfComplete);
|
||||
builder.chunk(commitInterval);
|
||||
|
||||
@@ -26,7 +26,9 @@ import java.util.List;
|
||||
import io.micrometer.core.instrument.Metrics;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import io.micrometer.core.instrument.Tags;
|
||||
import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler;
|
||||
import io.micrometer.core.tck.MeterRegistryAssert;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -34,7 +36,6 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobExecutionException;
|
||||
import org.springframework.batch.core.JobExecutionListener;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobInterruptedException;
|
||||
@@ -49,9 +50,9 @@ import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
|
||||
import org.springframework.batch.core.step.StepSupport;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.jdbc.support.JdbcTransactionManager;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.support.JdbcTransactionManager;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
@@ -111,6 +112,11 @@ class SimpleJobTests {
|
||||
job = new SimpleJob();
|
||||
job.setJobRepository(jobRepository);
|
||||
|
||||
ObservationRegistry observationRegistry = ObservationRegistry.create();
|
||||
observationRegistry.observationConfig()
|
||||
.observationHandler(new DefaultMeterObservationHandler(Metrics.globalRegistry));
|
||||
job.setObservationRegistry(observationRegistry);
|
||||
|
||||
step1 = new StubStep("TestStep1", jobRepository);
|
||||
step1.setCallback(new Runnable() {
|
||||
@Override
|
||||
|
||||
@@ -17,7 +17,6 @@ package org.springframework.batch.core.observability;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -26,6 +25,8 @@ import javax.sql.DataSource;
|
||||
|
||||
import io.micrometer.core.instrument.Meter;
|
||||
import io.micrometer.core.instrument.Metrics;
|
||||
import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
@@ -215,46 +216,43 @@ class BatchMetricsTests {
|
||||
|
||||
@Configuration
|
||||
@EnableBatchProcessing
|
||||
@Import(DataSoourceConfiguration.class)
|
||||
static class MyJobConfiguration {
|
||||
|
||||
private PlatformTransactionManager transactionManager;
|
||||
|
||||
public MyJobConfiguration(PlatformTransactionManager transactionManager) {
|
||||
this.transactionManager = transactionManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Step step1(JobRepository jobRepository) {
|
||||
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
|
||||
return new StepBuilder("step1", jobRepository)
|
||||
.tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED, this.transactionManager).build();
|
||||
.tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED, transactionManager).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Step step2(JobRepository jobRepository) {
|
||||
return new StepBuilder("step2", jobRepository).<Integer, Integer>chunk(2, this.transactionManager)
|
||||
public Step step2(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
|
||||
return new StepBuilder("step2", jobRepository).<Integer, Integer>chunk(2, transactionManager)
|
||||
.reader(new ListItemReader<>(Arrays.asList(1, 2, 3, 4, 5)))
|
||||
.writer(items -> items.forEach(System.out::println)).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Step step3(JobRepository jobRepository) {
|
||||
return new StepBuilder("step3", jobRepository).<Integer, Integer>chunk(2, this.transactionManager)
|
||||
public Step step3(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
|
||||
return new StepBuilder("step3", jobRepository).<Integer, Integer>chunk(2, transactionManager)
|
||||
.reader(new ListItemReader<>(Arrays.asList(6, 7, 8, 9, 10)))
|
||||
.writer(items -> items.forEach(System.out::println)).faultTolerant().skip(Exception.class)
|
||||
.skipLimit(3).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Job job(JobRepository jobRepository) {
|
||||
return new JobBuilder("job", jobRepository).start(step1(jobRepository)).next(step2(jobRepository))
|
||||
.next(step3(jobRepository)).build();
|
||||
public Job job(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
|
||||
return new JobBuilder("job", jobRepository).start(step1(jobRepository, transactionManager))
|
||||
.next(step2(jobRepository, transactionManager)).next(step3(jobRepository, transactionManager))
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class DataSoourceConfiguration {
|
||||
@Bean
|
||||
public ObservationRegistry observationRegistry() {
|
||||
ObservationRegistry observationRegistry = ObservationRegistry.create();
|
||||
observationRegistry.observationConfig()
|
||||
.observationHandler(new DefaultMeterObservationHandler(Metrics.globalRegistry));
|
||||
return observationRegistry;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
|
||||
@@ -21,7 +21,9 @@ import java.util.List;
|
||||
import io.micrometer.core.instrument.Metrics;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import io.micrometer.core.instrument.Tags;
|
||||
import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler;
|
||||
import io.micrometer.core.tck.MeterRegistryAssert;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -190,6 +192,12 @@ class NonAbstractStepTests {
|
||||
@Test
|
||||
void testExecute() throws Exception {
|
||||
tested.setStepExecutionListeners(new StepExecutionListener[] { listener1, listener2 });
|
||||
|
||||
ObservationRegistry observationRegistry = ObservationRegistry.create();
|
||||
observationRegistry.observationConfig()
|
||||
.observationHandler(new DefaultMeterObservationHandler(Metrics.globalRegistry));
|
||||
tested.setObservationRegistry(observationRegistry);
|
||||
|
||||
tested.execute(execution);
|
||||
|
||||
int i = 0;
|
||||
|
||||
@@ -15,8 +15,11 @@
|
||||
*/
|
||||
package org.springframework.batch.test.observability;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Metrics;
|
||||
import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler;
|
||||
import io.micrometer.core.tck.MeterRegistryAssert;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import io.micrometer.tracing.test.SampleTestRunner;
|
||||
@@ -28,13 +31,20 @@ import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.observability.BatchMetrics;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.job.builder.JobBuilder;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.step.builder.StepBuilder;
|
||||
import org.springframework.batch.repeat.RepeatStatus;
|
||||
import org.springframework.batch.test.JobLauncherTestUtils;
|
||||
import org.springframework.batch.test.SpringBatchTestJUnit5Tests;
|
||||
import org.springframework.batch.test.context.SpringBatchTest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import org.springframework.jdbc.support.JdbcTransactionManager;
|
||||
|
||||
import static io.micrometer.tracing.test.simple.SpansAssert.assertThat;
|
||||
|
||||
@@ -44,6 +54,9 @@ class ObservabilitySampleStepTests extends SampleTestRunner {
|
||||
@Autowired
|
||||
private JobLauncherTestUtils jobLauncherTestUtils;
|
||||
|
||||
@Autowired
|
||||
private ObservationRegistry observationRegistry;
|
||||
|
||||
ObservabilitySampleStepTests() {
|
||||
super(SampleRunnerConfig.builder().build());
|
||||
}
|
||||
@@ -55,7 +68,7 @@ class ObservabilitySampleStepTests extends SampleTestRunner {
|
||||
|
||||
@Override
|
||||
protected ObservationRegistry createObservationRegistry() {
|
||||
return BatchMetrics.observationRegistry;
|
||||
return this.observationRegistry;
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
@@ -91,9 +104,40 @@ class ObservabilitySampleStepTests extends SampleTestRunner {
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import(SpringBatchTestJUnit5Tests.JobConfiguration.class)
|
||||
@EnableBatchProcessing
|
||||
static class TestConfig {
|
||||
|
||||
@Bean
|
||||
public ObservationRegistry observationRegistry() {
|
||||
ObservationRegistry observationRegistry = ObservationRegistry.create();
|
||||
observationRegistry.observationConfig()
|
||||
.observationHandler(new DefaultMeterObservationHandler(Metrics.globalRegistry));
|
||||
return observationRegistry;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Step step(JobRepository jobRepository, JdbcTransactionManager transactionManager) {
|
||||
return new StepBuilder("step", jobRepository)
|
||||
.tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED, transactionManager).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Job job(JobRepository jobRepository, Step step) {
|
||||
return new JobBuilder("job", jobRepository).start(step).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL)
|
||||
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
|
||||
.addScript("/org/springframework/batch/core/schema-hsqldb.sql").build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JdbcTransactionManager transactionManager(DataSource dataSource) {
|
||||
return new JdbcTransactionManager(dataSource);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user