This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 3ae018ff09d CAMEL-22309: camel-spring-batch - Should auto wire job
launcher and registry
3ae018ff09d is described below
commit 3ae018ff09d8f3f9035eb363451bef563f223e1d
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Jul 31 19:50:20 2025 +0200
CAMEL-22309: camel-spring-batch - Should auto wire job launcher and registry
---
.../camel/catalog/components/spring-batch.json | 7 +-
.../batch/SpringBatchComponentConfigurer.java | 5 +
.../camel/component/spring/batch/spring-batch.json | 7 +-
.../spring/batch/SpringBatchComponent.java | 19 +--
.../spring/batch/SpringBatchConstants.java | 5 +
.../spring/batch/SpringBatchEndpoint.java | 71 ++---------
.../spring/batch/SpringBatchProducer.java | 6 +-
.../batch/SpringBatchEndpointDynamicTest.java | 142 +++++++++++++++++++++
.../spring/batch/SpringBatchEndpointTest.java | 90 +------------
.../spring/batch/SpringBatchJobLauncherIT.java | 9 --
.../batch/springBatchtestJobLauncherContext.xml | 4 -
.../ROOT/pages/camel-4x-upgrade-guide-4_14.adoc | 4 +
.../dsl/SpringBatchEndpointBuilderFactory.java | 36 ++++++
13 files changed, 222 insertions(+), 183 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-batch.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-batch.json
index 2955ce584fb..dc6e55c424e 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-batch.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-batch.json
@@ -24,11 +24,14 @@
"remote": false
},
"componentProperties": {
- "jobLauncher": { "index": 0, "kind": "property", "displayName": "Job
Launcher", "group": "producer", "label": "", "required": false, "type":
"object", "javaType": "org.springframework.batch.core.launch.JobLauncher",
"deprecated": false, "autowired": false, "secret": false, "description":
"Explicitly specifies a JobLauncher to be used." },
- "jobRegistry": { "index": 1, "kind": "property", "displayName": "Job
Registry", "group": "producer", "label": "", "required": false, "type":
"object", "javaType":
"org.springframework.batch.core.configuration.JobRegistry", "deprecated":
false, "autowired": false, "secret": false, "description": "Explicitly
specifies a JobRegistry to be used." },
+ "jobLauncher": { "index": 0, "kind": "property", "displayName": "Job
Launcher", "group": "producer", "label": "", "required": false, "type":
"object", "javaType": "org.springframework.batch.core.launch.JobLauncher",
"deprecated": false, "autowired": true, "secret": false, "description":
"Explicitly specifies a JobLauncher to be used." },
+ "jobRegistry": { "index": 1, "kind": "property", "displayName": "Job
Registry", "group": "producer", "label": "", "required": false, "type":
"object", "javaType":
"org.springframework.batch.core.configuration.JobRegistry", "deprecated":
false, "autowired": true, "secret": false, "description": "Explicitly specifies
a JobRegistry to be used." },
"lazyStartProducer": { "index": 2, "kind": "property", "displayName":
"Lazy Start Producer", "group": "producer", "label": "producer", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "defaultValue": false, "description":
"Whether the producer should be started lazy (on the first message). By
starting lazy you can use this to allow CamelContext and routes to startup in
situations where a producer may otherwise fail [...]
"autowiredEnabled": { "index": 3, "kind": "property", "displayName":
"Autowired Enabled", "group": "advanced", "label": "advanced", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "defaultValue": true, "description":
"Whether autowiring is enabled. This is used for automatic autowiring options
(the option must be marked as autowired) by looking up in the registry to find
if there is a single instance of matching t [...]
},
+ "headers": {
+ "CamelSpringBatchJobName": { "index": 0, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "The name of the Batch Job to use", "constantName":
"org.apache.camel.component.spring.batch.SpringBatchConstants#JOB_NAME" }
+ },
"properties": {
"jobName": { "index": 0, "kind": "path", "displayName": "Job Name",
"group": "producer", "label": "", "required": true, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "The name of the Spring
Batch job located in the registry." },
"jobFromHeader": { "index": 1, "kind": "parameter", "displayName": "Job
From Header", "group": "producer", "label": "", "required": false, "type":
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "description": "Explicitly defines if
the jobName should be taken from the headers instead of the URI." },
diff --git
a/components/camel-spring-parent/camel-spring-batch/src/generated/java/org/apache/camel/component/spring/batch/SpringBatchComponentConfigurer.java
b/components/camel-spring-parent/camel-spring-batch/src/generated/java/org/apache/camel/component/spring/batch/SpringBatchComponentConfigurer.java
index 9fd44c4bcab..9e924b2962d 100644
---
a/components/camel-spring-parent/camel-spring-batch/src/generated/java/org/apache/camel/component/spring/batch/SpringBatchComponentConfigurer.java
+++
b/components/camel-spring-parent/camel-spring-batch/src/generated/java/org/apache/camel/component/spring/batch/SpringBatchComponentConfigurer.java
@@ -35,6 +35,11 @@ public class SpringBatchComponentConfigurer extends
PropertyConfigurerSupport im
}
}
+ @Override
+ public String[] getAutowiredNames() {
+ return new String[]{"jobLauncher", "jobRegistry"};
+ }
+
@Override
public Class<?> getOptionType(String name, boolean ignoreCase) {
switch (ignoreCase ? name.toLowerCase() : name) {
diff --git
a/components/camel-spring-parent/camel-spring-batch/src/generated/resources/META-INF/org/apache/camel/component/spring/batch/spring-batch.json
b/components/camel-spring-parent/camel-spring-batch/src/generated/resources/META-INF/org/apache/camel/component/spring/batch/spring-batch.json
index 2955ce584fb..dc6e55c424e 100644
---
a/components/camel-spring-parent/camel-spring-batch/src/generated/resources/META-INF/org/apache/camel/component/spring/batch/spring-batch.json
+++
b/components/camel-spring-parent/camel-spring-batch/src/generated/resources/META-INF/org/apache/camel/component/spring/batch/spring-batch.json
@@ -24,11 +24,14 @@
"remote": false
},
"componentProperties": {
- "jobLauncher": { "index": 0, "kind": "property", "displayName": "Job
Launcher", "group": "producer", "label": "", "required": false, "type":
"object", "javaType": "org.springframework.batch.core.launch.JobLauncher",
"deprecated": false, "autowired": false, "secret": false, "description":
"Explicitly specifies a JobLauncher to be used." },
- "jobRegistry": { "index": 1, "kind": "property", "displayName": "Job
Registry", "group": "producer", "label": "", "required": false, "type":
"object", "javaType":
"org.springframework.batch.core.configuration.JobRegistry", "deprecated":
false, "autowired": false, "secret": false, "description": "Explicitly
specifies a JobRegistry to be used." },
+ "jobLauncher": { "index": 0, "kind": "property", "displayName": "Job
Launcher", "group": "producer", "label": "", "required": false, "type":
"object", "javaType": "org.springframework.batch.core.launch.JobLauncher",
"deprecated": false, "autowired": true, "secret": false, "description":
"Explicitly specifies a JobLauncher to be used." },
+ "jobRegistry": { "index": 1, "kind": "property", "displayName": "Job
Registry", "group": "producer", "label": "", "required": false, "type":
"object", "javaType":
"org.springframework.batch.core.configuration.JobRegistry", "deprecated":
false, "autowired": true, "secret": false, "description": "Explicitly specifies
a JobRegistry to be used." },
"lazyStartProducer": { "index": 2, "kind": "property", "displayName":
"Lazy Start Producer", "group": "producer", "label": "producer", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "defaultValue": false, "description":
"Whether the producer should be started lazy (on the first message). By
starting lazy you can use this to allow CamelContext and routes to startup in
situations where a producer may otherwise fail [...]
"autowiredEnabled": { "index": 3, "kind": "property", "displayName":
"Autowired Enabled", "group": "advanced", "label": "advanced", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "defaultValue": true, "description":
"Whether autowiring is enabled. This is used for automatic autowiring options
(the option must be marked as autowired) by looking up in the registry to find
if there is a single instance of matching t [...]
},
+ "headers": {
+ "CamelSpringBatchJobName": { "index": 0, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "The name of the Batch Job to use", "constantName":
"org.apache.camel.component.spring.batch.SpringBatchConstants#JOB_NAME" }
+ },
"properties": {
"jobName": { "index": 0, "kind": "path", "displayName": "Job Name",
"group": "producer", "label": "", "required": true, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "The name of the Spring
Batch job located in the registry." },
"jobFromHeader": { "index": 1, "kind": "parameter", "displayName": "Job
From Header", "group": "producer", "label": "", "required": false, "type":
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "description": "Explicitly defines if
the jobName should be taken from the headers instead of the URI." },
diff --git
a/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchComponent.java
b/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchComponent.java
index 1a0c84022aa..edda605605c 100644
---
a/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchComponent.java
+++
b/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchComponent.java
@@ -28,14 +28,9 @@ import org.springframework.batch.core.launch.JobLauncher;
@Component("spring-batch")
public class SpringBatchComponent extends DefaultComponent {
- private static final String DEFAULT_JOB_LAUNCHER_REF_NAME = "jobLauncher";
-
- private JobLauncher defaultResolvedJobLauncher;
- private Map<String, JobLauncher> allResolvedJobLaunchers;
-
- @Metadata
+ @Metadata(autowired = true)
private JobLauncher jobLauncher;
- @Metadata
+ @Metadata(autowired = true)
private JobRegistry jobRegistry;
public SpringBatchComponent() {
@@ -44,8 +39,7 @@ public class SpringBatchComponent extends DefaultComponent {
@Override
protected Endpoint createEndpoint(String uri, String remaining,
Map<String, Object> parameters) throws Exception {
SpringBatchEndpoint endpoint = new SpringBatchEndpoint(
- uri, this, jobLauncher, defaultResolvedJobLauncher,
- allResolvedJobLaunchers, remaining, jobRegistry);
+ uri, this, jobLauncher, remaining, jobRegistry);
setProperties(endpoint, parameters);
return endpoint;
}
@@ -53,9 +47,10 @@ public class SpringBatchComponent extends DefaultComponent {
@Override
protected void doInit() throws Exception {
super.doInit();
- defaultResolvedJobLauncher
- =
getCamelContext().getRegistry().lookupByNameAndType(DEFAULT_JOB_LAUNCHER_REF_NAME,
JobLauncher.class);
- allResolvedJobLaunchers =
getCamelContext().getRegistry().findByTypeWithName(JobLauncher.class);
+ if (jobLauncher == null) {
+ jobLauncher = getCamelContext().getRegistry()
+
.lookupByNameAndType(SpringBatchConstants.DEFAULT_JOB_LAUNCHER_REF_NAME,
JobLauncher.class);
+ }
}
public JobLauncher getJobLauncher() {
diff --git
a/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchConstants.java
b/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchConstants.java
index 07e4e46a7e7..a3876601947 100644
---
a/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchConstants.java
+++
b/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchConstants.java
@@ -16,11 +16,16 @@
*/
package org.apache.camel.component.spring.batch;
+import org.apache.camel.spi.Metadata;
+
/**
* Constants.
*/
public final class SpringBatchConstants {
+ public static final String DEFAULT_JOB_LAUNCHER_REF_NAME = "jobLauncher";
+
+ @Metadata(description = "The name of the Batch Job to use", javaType =
"String")
public static final String JOB_NAME = "CamelSpringBatchJobName";
private SpringBatchConstants() {
diff --git
a/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchEndpoint.java
b/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchEndpoint.java
index 345e60f558f..34f54554fc4 100644
---
a/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchEndpoint.java
+++
b/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchEndpoint.java
@@ -16,8 +16,6 @@
*/
package org.apache.camel.component.spring.batch;
-import java.util.Map;
-
import org.apache.camel.Category;
import org.apache.camel.Component;
import org.apache.camel.Consumer;
@@ -37,40 +35,26 @@ import org.springframework.batch.core.launch.JobLauncher;
* Send messages to Spring Batch for further processing.
*/
@UriEndpoint(firstVersion = "2.10.0", scheme = "spring-batch", title = "Spring
Batch", syntax = "spring-batch:jobName",
- remote = false, producerOnly = true, category = {
Category.WORKFLOW })
+ remote = false, producerOnly = true, headersClass =
SpringBatchConstants.class, category = { Category.WORKFLOW })
public class SpringBatchEndpoint extends DefaultEndpoint {
@UriPath
@Metadata(required = true)
private String jobName;
-
@UriParam
private boolean jobFromHeader;
-
- /**
- * @deprecated will be removed in Camel 3.0 use jobLauncher instead
- */
- @Deprecated
- private String jobLauncherRef;
-
@UriParam
private JobLauncher jobLauncher;
-
- private JobLauncher defaultResolvedJobLauncher;
- private Map<String, JobLauncher> allResolvedJobLaunchers;
- private Job job;
-
@UriParam
private JobRegistry jobRegistry;
+ private Job job;
+
public SpringBatchEndpoint(String endpointUri, Component component,
- JobLauncher jobLauncher, JobLauncher
defaultResolvedJobLauncher,
- Map<String, JobLauncher>
allResolvedJobLaunchers, String jobName,
- JobRegistry jobRegistry) {
+ JobLauncher jobLauncher,
+ String jobName, JobRegistry jobRegistry) {
super(endpointUri, component);
this.jobLauncher = jobLauncher;
- this.defaultResolvedJobLauncher = defaultResolvedJobLauncher;
- this.allResolvedJobLaunchers = allResolvedJobLaunchers;
this.jobName = jobName;
this.jobRegistry = jobRegistry;
}
@@ -91,42 +75,20 @@ public class SpringBatchEndpoint extends DefaultEndpoint {
}
@Override
- protected void doInit() throws Exception {
- super.doInit();
+ protected void doStart() throws Exception {
+ super.doStart();
if (jobLauncher == null) {
- jobLauncher = resolveJobLauncher();
+ jobLauncher =
CamelContextHelper.mandatoryFindSingleByType(getCamelContext(),
JobLauncher.class);
}
if (job == null && jobName != null && !jobFromHeader) {
if (jobRegistry != null) {
job = jobRegistry.getJob(jobName);
- } else {
- job = CamelContextHelper.mandatoryLookup(getCamelContext(),
jobName, Job.class);
}
- }
- }
-
- private JobLauncher resolveJobLauncher() {
- if (jobLauncherRef != null) {
- JobLauncher jobLauncher =
getCamelContext().getRegistry().lookupByNameAndType(jobLauncherRef,
JobLauncher.class);
- if (jobLauncher == null) {
- throw new IllegalStateException(
- String.format("No JobLauncher named %s found in the
registry.", jobLauncherRef));
+ if (job == null) {
+ job = CamelContextHelper.mandatoryLookup(getCamelContext(),
jobName, Job.class);
}
- return jobLauncher;
- }
-
- if (defaultResolvedJobLauncher != null) {
- return defaultResolvedJobLauncher;
}
-
- if (allResolvedJobLaunchers.size() == 1) {
- return allResolvedJobLaunchers.values().iterator().next();
- } else if (allResolvedJobLaunchers.size() > 1) {
- throw new IllegalStateException("Expected single jobLauncher
instance. Found: " + allResolvedJobLaunchers.size());
- }
-
- throw new IllegalStateException("Cannot find Spring Batch
JobLauncher.");
}
public String getJobName() {
@@ -140,19 +102,6 @@ public class SpringBatchEndpoint extends DefaultEndpoint {
this.jobName = jobName;
}
- @Deprecated
- public String getJobLauncherRef() {
- return jobLauncherRef;
- }
-
- /**
- * Explicitly specifies a JobLauncher to be used looked up from the
registry.
- */
- @Deprecated
- public void setJobLauncherRef(String jobLauncherRef) {
- this.jobLauncherRef = jobLauncherRef;
- }
-
public JobLauncher getJobLauncher() {
return jobLauncher;
}
diff --git
a/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchProducer.java
b/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchProducer.java
index 9cab4e55894..1598269accd 100644
---
a/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchProducer.java
+++
b/components/camel-spring-parent/camel-spring-batch/src/main/java/org/apache/camel/component/spring/batch/SpringBatchProducer.java
@@ -40,9 +40,7 @@ public class SpringBatchProducer extends DefaultProducer {
private static final Logger LOG =
LoggerFactory.getLogger(SpringBatchProducer.class);
private final JobLauncher jobLauncher;
-
private final Job job;
-
private final JobRegistry jobRegistry;
public SpringBatchProducer(SpringBatchEndpoint endpoint, JobLauncher
jobLauncher, Job job, JobRegistry jobRegistry) {
@@ -54,7 +52,6 @@ public class SpringBatchProducer extends DefaultProducer {
@Override
public void process(Exchange exchange) throws Exception {
-
JobParameters jobParameters =
prepareJobParameters(exchange.getIn().getHeaders());
String messageJobName =
jobParameters.getString(SpringBatchConstants.JOB_NAME);
@@ -63,7 +60,8 @@ public class SpringBatchProducer extends DefaultProducer {
if (messageJobName != null) {
if (jobRegistry != null) {
job2run = jobRegistry.getJob(messageJobName);
- } else {
+ }
+ if (job2run == null) {
job2run =
CamelContextHelper.mandatoryLookup(getEndpoint().getCamelContext(),
messageJobName, Job.class);
}
}
diff --git
a/components/camel-spring-parent/camel-spring-batch/src/test/java/org/apache/camel/component/spring/batch/SpringBatchEndpointDynamicTest.java
b/components/camel-spring-parent/camel-spring-batch/src/test/java/org/apache/camel/component/spring/batch/SpringBatchEndpointDynamicTest.java
new file mode 100644
index 00000000000..443c2310de5
--- /dev/null
+++
b/components/camel-spring-parent/camel-spring-batch/src/test/java/org/apache/camel/component/spring/batch/SpringBatchEndpointDynamicTest.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.component.spring.batch;
+
+import java.time.Instant;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.spi.Registry;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+import org.springframework.batch.core.Job;
+import org.springframework.batch.core.configuration.JobRegistry;
+import org.springframework.batch.core.launch.JobLauncher;
+
+import static org.apache.camel.test.junit5.TestSupport.header;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@MockitoSettings(strictness = Strictness.LENIENT)
+public class SpringBatchEndpointDynamicTest extends CamelTestSupport {
+
+ // Fixtures
+ @Mock
+ JobLauncher jobLauncher;
+
+ @Mock
+ JobRegistry jobRegistry;
+
+ @Mock
+ Job dynamicMockjob;
+
+ // Camel fixtures
+ @EndpointInject("mock:test")
+ MockEndpoint mockEndpoint;
+
+ @EndpointInject("mock:error")
+ MockEndpoint errorEndpoint;
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+
from("direct:dynamic").to("spring-batch:fake?jobFromHeader=true").errorHandler(deadLetterChannel("mock:error"))
+ .to("mock:test");
+
from("direct:dynamicWithJobRegistry").to("spring-batch:fake?jobFromHeader=true&jobRegistry=#jobRegistry")
+
.errorHandler(deadLetterChannel("mock:error")).to("mock:test");
+ }
+ };
+ }
+
+ @Override
+ protected void bindToRegistry(Registry registry) {
+ registry.bind("jobLauncher", jobLauncher);
+ registry.bind("dynamicMockjob", dynamicMockjob);
+ registry.bind("jobRegistry", jobRegistry);
+ }
+
+ // Tests
+ @Test
+ public void dynamicJobFailsIfHeaderNotPressent() throws Exception {
+
+ mockEndpoint.expectedMessageCount(0);
+ errorEndpoint.expectedMessageCount(1);
+
+ //dynamic job should fail as header is not present and the job is
dynamic
+ sendBody("direct:dyanmic?block=false", "Start the job, please.");
+ mockEndpoint.assertIsSatisfied();
+ mockEndpoint.assertIsSatisfied();
+ }
+
+ @Test
+ public void dynamicJobFailsIfHeaderWithInvalidJobName() throws Exception {
+
+ mockEndpoint.expectedMessageCount(0);
+ errorEndpoint.expectedMessageCount(1);
+
+ //dynamic job should fail as header is present but the job does not
exist
+
header(SpringBatchConstants.JOB_NAME).append("thisJobDoesNotExsistAtAll" +
Date.from(Instant.now()));
+ sendBody("direct:dyanmic?block=false", "Start the job, please.");
+
+ mockEndpoint.assertIsSatisfied();
+ mockEndpoint.assertIsSatisfied();
+ }
+
+ @Test
+ public void dynamicJobWorksIfHeaderPressentWithValidJob() throws Exception
{
+
+ mockEndpoint.expectedMessageCount(1);
+ errorEndpoint.expectedMessageCount(0);
+
+ final Map<String, Object> headers = new HashMap<>();
+ headers.put(SpringBatchConstants.JOB_NAME, "dynamicMockjob");
+
+ sendBody("direct:dynamic?block=false", "Start the job, please.",
headers);
+
+ mockEndpoint.assertIsSatisfied();
+ errorEndpoint.assertIsSatisfied();
+ }
+
+ @Test
+ public void
dynamicJobWorksIfHeaderPresentWithValidJobLocatedInJobRegistry() throws
Exception {
+ mockEndpoint.expectedMessageCount(1);
+ errorEndpoint.expectedMessageCount(0);
+
+ Job mockJob = mock(Job.class);
+
when(jobRegistry.getJob(eq("dyanmicMockJobFromJobRegistry"))).thenReturn(mockJob);
+
+ final Map<String, Object> headers = new HashMap<>();
+ headers.put(SpringBatchConstants.JOB_NAME,
"dyanmicMockJobFromJobRegistry");
+ headers.put("jobRegistry", "#jobRegistry");
+
+ sendBody("direct:dynamicWithJobRegistry", "Start the job, please.",
headers);
+
+ mockEndpoint.assertIsSatisfied();
+ errorEndpoint.assertIsSatisfied();
+ }
+
+}
diff --git
a/components/camel-spring-parent/camel-spring-batch/src/test/java/org/apache/camel/component/spring/batch/SpringBatchEndpointTest.java
b/components/camel-spring-parent/camel-spring-batch/src/test/java/org/apache/camel/component/spring/batch/SpringBatchEndpointTest.java
index 52508a003bf..7b14d5b61d9 100644
---
a/components/camel-spring-parent/camel-spring-batch/src/test/java/org/apache/camel/component/spring/batch/SpringBatchEndpointTest.java
+++
b/components/camel-spring-parent/camel-spring-batch/src/test/java/org/apache/camel/component/spring/batch/SpringBatchEndpointTest.java
@@ -16,14 +16,10 @@
*/
package org.apache.camel.component.spring.batch;
-import java.time.Instant;
import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
import org.apache.camel.CamelContext;
import org.apache.camel.EndpointInject;
-import org.apache.camel.FailedToCreateRouteException;
import org.apache.camel.FailedToStartRouteException;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
@@ -43,7 +39,6 @@ import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.launch.JobLauncher;
-import static org.apache.camel.test.junit5.TestSupport.header;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -85,10 +80,6 @@ public class SpringBatchEndpointTest extends
CamelTestSupport {
@Override
public void configure() throws Exception {
from("direct:start").to("spring-batch:mockJob").to("mock:test");
-
from("direct:dynamic").to("spring-batch:fake?jobFromHeader=true").errorHandler(deadLetterChannel("mock:error"))
- .to("mock:test");
-
from("direct:dynamicWithJobRegistry").to("spring-batch:fake?jobFromHeader=true&jobRegistry=#jobRegistry")
-
.errorHandler(deadLetterChannel("mock:error")).to("mock:test");
}
};
}
@@ -103,65 +94,6 @@ public class SpringBatchEndpointTest extends
CamelTestSupport {
}
// Tests
- @Test
- public void dynamicJobFailsIfHeaderNotPressent() throws Exception {
-
- mockEndpoint.expectedMessageCount(0);
- errorEndpoint.expectedMessageCount(1);
-
- //dynamic job should fail as header is not present and the job is
dynamic
- sendBody("direct:dyanmic?block=false", "Start the job, please.");
- mockEndpoint.assertIsSatisfied();
- mockEndpoint.assertIsSatisfied();
- }
-
- @Test
- public void dynamicJobFailsIfHeaderWithInvalidJobName() throws Exception {
-
- mockEndpoint.expectedMessageCount(0);
- errorEndpoint.expectedMessageCount(1);
-
- //dynamic job should fail as header is present but the job does not
exist
-
header(SpringBatchConstants.JOB_NAME).append("thisJobDoesNotExsistAtAll" +
Date.from(Instant.now()));
- sendBody("direct:dyanmic?block=false", "Start the job, please.");
-
- mockEndpoint.assertIsSatisfied();
- mockEndpoint.assertIsSatisfied();
- }
-
- @Test
- public void dynamicJobWorksIfHeaderPressentWithValidJob() throws Exception
{
-
- mockEndpoint.expectedMessageCount(1);
- errorEndpoint.expectedMessageCount(0);
-
- final Map<String, Object> headers = new HashMap<>();
- headers.put(SpringBatchConstants.JOB_NAME, "dynamicMockjob");
-
- sendBody("direct:dynamic?block=false", "Start the job, please.",
headers);
-
- mockEndpoint.assertIsSatisfied();
- errorEndpoint.assertIsSatisfied();
- }
-
- @Test
- public void
dynamicJobWorksIfHeaderPresentWithValidJobLocatedInJobRegistry() throws
Exception {
-
- mockEndpoint.expectedMessageCount(1);
- errorEndpoint.expectedMessageCount(0);
-
- Job mockJob = mock(Job.class);
-
when(jobRegistry.getJob(eq("dyanmicMockJobFromJobRegistry"))).thenReturn(mockJob);
-
- final Map<String, Object> headers = new HashMap<>();
- headers.put(SpringBatchConstants.JOB_NAME,
"dyanmicMockJobFromJobRegistry");
- headers.put("jobRegistry", "#jobRegistry");
-
- sendBody("direct:dynamicWithJobRegistry", "Start the job, please.",
headers);
-
- mockEndpoint.assertIsSatisfied();
- errorEndpoint.assertIsSatisfied();
- }
@Test
public void shouldInjectJobToEndpoint() throws IllegalAccessException {
@@ -305,27 +237,7 @@ public class SpringBatchEndpointTest extends
CamelTestSupport {
});
// When
- assertThrows(FailedToCreateRouteException.class,
- () -> camelContext.start());
- }
-
- @Test
- public void shouldFailWhenThereIsMoreThanOneJobLauncher() throws Exception
{
- // Given
- SimpleRegistry registry = new SimpleRegistry();
- registry.bind("mockJob", job);
- registry.bind("launcher1", jobLauncher);
- registry.bind("launcher2", jobLauncher);
- CamelContext camelContext = new DefaultCamelContext(registry);
- camelContext.addRoutes(new RouteBuilder() {
- @Override
- public void configure() throws Exception {
- from("direct:start").to("spring-batch:mockJob");
- }
- });
-
- // When
- assertThrows(FailedToCreateRouteException.class,
+ assertThrows(FailedToStartRouteException.class,
() -> camelContext.start());
}
diff --git
a/components/camel-spring-parent/camel-spring-batch/src/test/java/org/apache/camel/component/spring/batch/SpringBatchJobLauncherIT.java
b/components/camel-spring-parent/camel-spring-batch/src/test/java/org/apache/camel/component/spring/batch/SpringBatchJobLauncherIT.java
index 6123e4bbf5a..d7a9a3687b9 100644
---
a/components/camel-spring-parent/camel-spring-batch/src/test/java/org/apache/camel/component/spring/batch/SpringBatchJobLauncherIT.java
+++
b/components/camel-spring-parent/camel-spring-batch/src/test/java/org/apache/camel/component/spring/batch/SpringBatchJobLauncherIT.java
@@ -53,15 +53,6 @@ public class SpringBatchJobLauncherIT extends
CamelSpringTestSupport {
outputEndpoint.assertIsSatisfied();
}
- @Test
- public void testJobLauncherRef() throws InterruptedException {
- outputEndpoint.expectedBodiesReceived("Echo foo", "Echo bar", "Echo
baz");
-
- template.sendBody("direct:start-jobLauncherRef", "Start batch!");
-
- outputEndpoint.assertIsSatisfied();
- }
-
@Override
protected AbstractApplicationContext createApplicationContext() {
return new ClassPathXmlApplicationContext(
diff --git
a/components/camel-spring-parent/camel-spring-batch/src/test/resources/org/apache/camel/component/spring/batch/springBatchtestJobLauncherContext.xml
b/components/camel-spring-parent/camel-spring-batch/src/test/resources/org/apache/camel/component/spring/batch/springBatchtestJobLauncherContext.xml
index ab19b1bb2cb..43bb137488a 100644
---
a/components/camel-spring-parent/camel-spring-batch/src/test/resources/org/apache/camel/component/spring/batch/springBatchtestJobLauncherContext.xml
+++
b/components/camel-spring-parent/camel-spring-batch/src/test/resources/org/apache/camel/component/spring/batch/springBatchtestJobLauncherContext.xml
@@ -42,10 +42,6 @@
<!-- Camel infrastructure -->
<camel:camelContext id="camel">
- <camel:route>
- <camel:from uri="direct:start-jobLauncherRef"/>
- <camel:to uri="spring-batch:echoJob?jobLauncherRef=jobLauncher"/>
- </camel:route>
<camel:route>
<camel:from uri="direct:start-jobLauncher"/>
<camel:to uri="spring-batch:echoJob?jobLauncher=#jobLauncher"/>
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_14.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_14.adoc
index da0fb875900..1ce75daf702 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_14.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_14.adoc
@@ -88,3 +88,7 @@ The ids parameter for camel-weather has been defined as
String instead of List<S
The addresses, privateFor and Topics parameters for camel-web3j have been
defined as String instead of List<String>. For the migration users will need
to, eventually, define addresses, privateFor or topics as a comma separated
list of addresses, privateFor or topics instead of a List instance. For more
information the related issue is CAMEL-17339.
+=== camel-spring-batch
+
+The `jobLauncher` and 'jobRegistry' is now autowired on the component if there
is a single instance pre-configured in the application.
+This avoids having to wire this into the Camel component or endpoints.
diff --git
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SpringBatchEndpointBuilderFactory.java
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SpringBatchEndpointBuilderFactory.java
index 308b7659955..d176e950913 100644
---
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SpringBatchEndpointBuilderFactory.java
+++
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SpringBatchEndpointBuilderFactory.java
@@ -199,6 +199,19 @@ public interface SpringBatchEndpointBuilderFactory {
}
public interface SpringBatchBuilders {
+ /**
+ * Spring Batch (camel-spring-batch)
+ * Send messages to Spring Batch for further processing.
+ *
+ * Category: workflow
+ * Since: 2.10
+ * Maven coordinates: org.apache.camel:camel-spring-batch
+ *
+ * @return the dsl builder for the headers' name.
+ */
+ default SpringBatchHeaderNameBuilder springBatch() {
+ return SpringBatchHeaderNameBuilder.INSTANCE;
+ }
/**
* Spring Batch (camel-spring-batch)
* Send messages to Spring Batch for further processing.
@@ -241,6 +254,29 @@ public interface SpringBatchEndpointBuilderFactory {
}
}
+ /**
+ * The builder of headers' name for the Spring Batch component.
+ */
+ public static class SpringBatchHeaderNameBuilder {
+ /**
+ * The internal instance of the builder used to access to all the
+ * methods representing the name of headers.
+ */
+ private static final SpringBatchHeaderNameBuilder INSTANCE = new
SpringBatchHeaderNameBuilder();
+
+ /**
+ * The name of the Batch Job to use.
+ *
+ * The option is a: {@code String} type.
+ *
+ * Group: producer
+ *
+ * @return the name of the header {@code SpringBatchJobName}.
+ */
+ public String springBatchJobName() {
+ return "CamelSpringBatchJobName";
+ }
+ }
static SpringBatchEndpointBuilder endpointBuilder(String componentName,
String path) {
class SpringBatchEndpointBuilderImpl extends AbstractEndpointBuilder
implements SpringBatchEndpointBuilder, AdvancedSpringBatchEndpointBuilder {
public SpringBatchEndpointBuilderImpl(String path) {