You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/04/26 04:42:33 UTC

[camel] branch main updated: CAMEL-19230: Bring back Optaplanner and upgrade Optaplannet to 9.37.0.Final (#9931)

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 cf9d7335861 CAMEL-19230: Bring back Optaplanner and upgrade Optaplannet to 9.37.0.Final (#9931)
cf9d7335861 is described below

commit cf9d7335861a18194e0c12bd958a1c4f6663044d
Author: Zineb BENDHIBA <be...@gmail.com>
AuthorDate: Wed Apr 26 06:42:27 2023 +0200

    CAMEL-19230: Bring back Optaplanner and upgrade Optaplannet to 9.37.0.Final (#9931)
---
 bom/camel-bom/pom.xml                              |   5 +
 camel-dependencies/pom.xml                         |   2 +-
 catalog/camel-allcomponents/pom.xml                |   5 +
 .../org/apache/camel/catalog/components.properties |   1 +
 .../camel/catalog/components/optaplanner.json      |  49 ++
 components/camel-optaplanner/pom.xml               |  97 +++
 .../OptaPlannerComponentConfigurer.java            |  61 ++
 .../optaplanner/OptaPlannerEndpointConfigurer.java | 100 +++
 .../optaplanner/OptaPlannerEndpointUriFactory.java |  78 +++
 .../services/org/apache/camel/component.properties |   7 +
 .../org/apache/camel/component/optaplanner         |   2 +
 .../apache/camel/configurer/optaplanner-component  |   2 +
 .../apache/camel/configurer/optaplanner-endpoint   |   2 +
 .../apache/camel/urifactory/optaplanner-endpoint   |   2 +
 .../camel/component/optaplanner/optaplanner.json   |  49 ++
 .../src/main/docs/optaplanner-component.adoc       |  95 +++
 .../optaplanner/OptaPlannerComponent.java          |  53 ++
 .../optaplanner/OptaPlannerConfiguration.java      | 125 ++++
 .../optaplanner/OptaPlannerConstants.java          |  36 +
 .../component/optaplanner/OptaPlannerConsumer.java |  70 ++
 .../component/optaplanner/OptaPlannerEndpoint.java | 126 ++++
 .../component/optaplanner/OptaPlannerProducer.java | 154 +++++
 .../optaplanner/OptaplannerEventSupport.java       |  38 ++
 .../optaplanner/OptaplannerSolutionEvent.java      |  33 +
 .../OptaplannerSolutionEventListener.java          |  23 +
 .../OptaPlannerAsyncConfigFileTest.java            |  74 ++
 .../optaplanner/OptaPlannerProblemChangeTest.java  |  98 +++
 .../optaplanner/OptaPlannerSyncConfigFileTest.java |  61 ++
 .../OptaplannerSolverManagerAsyncTest.java         | 109 +++
 .../OptaplannerSolverManagerSyncTest.java          |  87 +++
 .../src/test/resources/log4j2.properties           |  32 +
 .../camel/component/optaplanner/solverConfig.xml   |  38 ++
 components/pom.xml                                 |   1 +
 .../org/apache/camel/main/components.properties    |   1 +
 .../modules/ROOT/examples/json/optaplanner.json    |   1 +
 docs/components/modules/ROOT/nav.adoc              |   1 +
 .../modules/ROOT/pages/optaplanner-component.adoc  |   1 +
 .../ROOT/pages/camel-4-migration-guide.adoc        |  28 +-
 .../component/ComponentsBuilderFactory.java        |  13 +
 .../dsl/OptaplannerComponentBuilderFactory.java    | 144 ++++
 .../src/generated/resources/metadata.json          |  22 +
 .../builder/endpoint/EndpointBuilderFactory.java   |   1 +
 .../camel/builder/endpoint/EndpointBuilders.java   |   1 +
 .../builder/endpoint/StaticEndpointBuilders.java   |  43 ++
 .../dsl/OptaPlannerEndpointBuilderFactory.java     | 758 +++++++++++++++++++++
 .../camel-component-known-dependencies.properties  |   1 +
 parent/pom.xml                                     |   7 +-
 47 files changed, 2734 insertions(+), 3 deletions(-)

diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index e8d98c70c89..4c648cfb9e2 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -1462,6 +1462,11 @@
         <artifactId>camel-opentelemetry</artifactId>
         <version>${project.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-optaplanner</artifactId>
+        <version>${project.version}</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId>
         <artifactId>camel-paho</artifactId>
diff --git a/camel-dependencies/pom.xml b/camel-dependencies/pom.xml
index 3c56824bb2c..9d1f9a8517a 100644
--- a/camel-dependencies/pom.xml
+++ b/camel-dependencies/pom.xml
@@ -403,7 +403,7 @@
         <openstack4j-version>3.10</openstack4j-version>
         <opentelemetry-version>1.23.1</opentelemetry-version>
         <opentelemetry-alpha-version>${opentelemetry-version}-alpha</opentelemetry-alpha-version>
-        <optaplanner-version>8.32.0.Final</optaplanner-version>
+        <optaplanner-version>9.37.0.Final</optaplanner-version>
         <os-maven-plugin-version>1.7.0</os-maven-plugin-version>
         <paho-version>1.2.5</paho-version>
         <partial-build-plugin-version>2.7</partial-build-plugin-version>
diff --git a/catalog/camel-allcomponents/pom.xml b/catalog/camel-allcomponents/pom.xml
index 27523a90ad0..ad0caf2c730 100644
--- a/catalog/camel-allcomponents/pom.xml
+++ b/catalog/camel-allcomponents/pom.xml
@@ -1258,6 +1258,11 @@
             <artifactId>camel-opentelemetry</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-optaplanner</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-paho</artifactId>
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components.properties b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components.properties
index 6b677801d0c..a035d5e429a 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components.properties
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components.properties
@@ -231,6 +231,7 @@ openstack-keystone
 openstack-neutron
 openstack-nova
 openstack-swift
+optaplanner
 paho
 paho-mqtt5
 pdf
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/optaplanner.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/optaplanner.json
new file mode 100644
index 00000000000..48264df76d8
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/optaplanner.json
@@ -0,0 +1,49 @@
+{
+  "component": {
+    "kind": "component",
+    "name": "optaplanner",
+    "title": "OptaPlanner",
+    "description": "Solve planning problems with OptaPlanner.",
+    "deprecated": false,
+    "firstVersion": "2.13.0",
+    "label": "engine,planning",
+    "javaType": "org.apache.camel.component.optaplanner.OptaPlannerComponent",
+    "supportLevel": "Stable",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-optaplanner",
+    "version": "4.0.0-SNAPSHOT",
+    "scheme": "optaplanner",
+    "extendsScheme": "",
+    "syntax": "optaplanner:problemName",
+    "async": false,
+    "api": false,
+    "consumerOnly": false,
+    "producerOnly": false,
+    "lenientProperties": false
+  },
+  "componentProperties": {
+    "bridgeErrorHandler": { "kind": "property", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a me [...]
+    "lazyStartProducer": { "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 during star [...]
+    "autowiredEnabled": { "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 type, which t [...]
+  },
+  "headers": {
+    "CamelOptaPlannerSolverId": { "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Specifies the solverId to use.", "constantName": "org.apache.camel.component.optaplanner.OptaPlannerConstants#SOLVER_ID" },
+    "CamelOptaPlannerIsAsync": { "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Specify whether to use another thread for submitting Solution instances rather than blocking the current thread.", "constantName": "org.apache.camel.component.optaplanner.OptaPlannerConstants#IS_ASYNC" },
+    "CamelOptaPlannerBestSolution": { "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "Object", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The best planning solution.", "constantName": "org.apache.camel.component.optaplanner.OptaPlannerConstants#BEST_SOLUTION" },
+    "CamelOptaPlannerIsSolving": { "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Is solving.", "constantName": "org.apache.camel.component.optaplanner.OptaPlannerConstants#IS_SOLVING" },
+    "CamelOptaPlannerSolverManager": { "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "org.optaplanner.core.api.solver.SolverManager", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Solver Manager.", "constantName": "org.apache.camel.component.optaplanner.OptaPlannerConstants#SOLVER_MANAGER" }
+  },
+  "properties": {
+    "problemName": { "kind": "path", "displayName": "Problem Name", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "Problem name" },
+    "problemId": { "kind": "parameter", "displayName": "Problem Id", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1L", "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "In case of using SolverManager : the problem id" },
+    "solverId": { "kind": "parameter", "displayName": "Solver Id", "group": "common", "label": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "DEFAULT_SOLVER", "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "Specifies the solverId to user for the solver instance key" },
+    "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now [...]
+    "exceptionHandler": { "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the con [...]
+    "exchangePattern": { "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
+    "async": { "kind": "parameter", "displayName": "Async", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "Specifies to perform operations in async mode" },
+    "threadPoolSize": { "kind": "parameter", "displayName": "Thread Pool Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 10, "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "Specifies the thread pool size to use when async is true" },
+    "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "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 other [...]
+    "configFile": { "kind": "parameter", "displayName": "Config File", "group": "configFile", "label": "configFile", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "If SolverManager is absent from the header {OptaPlannerConstants.SOLVER_MANAGER} : A SolverManager will  [...]
+    "solverManager": { "kind": "parameter", "displayName": "Solver Manager", "group": "solverManager", "label": "solverManager", "required": false, "type": "object", "javaType": "org.optaplanner.core.api.solver.SolverManager", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "SolverManager" }
+  }
+}
diff --git a/components/camel-optaplanner/pom.xml b/components/camel-optaplanner/pom.xml
new file mode 100644
index 00000000000..c90a1cb7bb5
--- /dev/null
+++ b/components/camel-optaplanner/pom.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>components</artifactId>
+        <version>4.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-optaplanner</artifactId>
+    <packaging>jar</packaging>
+    <name>Camel :: OptaPlanner</name>
+    <description>Camel OptaPlanner support</description>
+
+    <properties>
+        <camel.surefire.forkTimeout>1800</camel.surefire.forkTimeout>
+    </properties>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-support</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.optaplanner</groupId>
+            <artifactId>optaplanner-core</artifactId>
+            <version>${optaplanner-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.optaplanner</groupId>
+            <artifactId>optaplanner-persistence-common</artifactId>
+            <version>${optaplanner-version}</version>
+        </dependency>
+
+        <!-- testing -->
+        <dependency>
+            <groupId>org.optaplanner</groupId>
+            <artifactId>optaplanner-examples</artifactId>
+            <version>${optaplanner-version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>ch.qos.logback</groupId>
+                    <artifactId>logback-classic</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.logging.log4j</groupId>
+                    <artifactId>log4j-to-slf4j</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+            <version>${log4j2-version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-spring-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <version>${awaitility-version}</version>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+</project>
diff --git a/components/camel-optaplanner/src/generated/java/org/apache/camel/component/optaplanner/OptaPlannerComponentConfigurer.java b/components/camel-optaplanner/src/generated/java/org/apache/camel/component/optaplanner/OptaPlannerComponentConfigurer.java
new file mode 100644
index 00000000000..ec5d7584e5d
--- /dev/null
+++ b/components/camel-optaplanner/src/generated/java/org/apache/camel/component/optaplanner/OptaPlannerComponentConfigurer.java
@@ -0,0 +1,61 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.optaplanner;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.support.component.PropertyConfigurerSupport;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class OptaPlannerComponentConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        OptaPlannerComponent target = (OptaPlannerComponent) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "autowiredenabled":
+        case "autowiredEnabled": target.setAutowiredEnabled(property(camelContext, boolean.class, value)); return true;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
+        case "lazystartproducer":
+        case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "autowiredenabled":
+        case "autowiredEnabled": return boolean.class;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return boolean.class;
+        case "lazystartproducer":
+        case "lazyStartProducer": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        OptaPlannerComponent target = (OptaPlannerComponent) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "autowiredenabled":
+        case "autowiredEnabled": return target.isAutowiredEnabled();
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return target.isBridgeErrorHandler();
+        case "lazystartproducer":
+        case "lazyStartProducer": return target.isLazyStartProducer();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-optaplanner/src/generated/java/org/apache/camel/component/optaplanner/OptaPlannerEndpointConfigurer.java b/components/camel-optaplanner/src/generated/java/org/apache/camel/component/optaplanner/OptaPlannerEndpointConfigurer.java
new file mode 100644
index 00000000000..fcd7ea710fd
--- /dev/null
+++ b/components/camel-optaplanner/src/generated/java/org/apache/camel/component/optaplanner/OptaPlannerEndpointConfigurer.java
@@ -0,0 +1,100 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.optaplanner;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.support.component.PropertyConfigurerSupport;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class OptaPlannerEndpointConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        OptaPlannerEndpoint target = (OptaPlannerEndpoint) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "async": target.getConfiguration().setAsync(property(camelContext, boolean.class, value)); return true;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
+        case "configfile":
+        case "configFile": target.getConfiguration().setConfigFile(property(camelContext, java.lang.String.class, value)); return true;
+        case "exceptionhandler":
+        case "exceptionHandler": target.setExceptionHandler(property(camelContext, org.apache.camel.spi.ExceptionHandler.class, value)); return true;
+        case "exchangepattern":
+        case "exchangePattern": target.setExchangePattern(property(camelContext, org.apache.camel.ExchangePattern.class, value)); return true;
+        case "lazystartproducer":
+        case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
+        case "problemid":
+        case "problemId": target.getConfiguration().setProblemId(property(camelContext, java.lang.Long.class, value)); return true;
+        case "solverid":
+        case "solverId": target.getConfiguration().setSolverId(property(camelContext, java.lang.String.class, value)); return true;
+        case "solvermanager":
+        case "solverManager": target.getConfiguration().setSolverManager(property(camelContext, org.optaplanner.core.api.solver.SolverManager.class, value)); return true;
+        case "threadpoolsize":
+        case "threadPoolSize": target.getConfiguration().setThreadPoolSize(property(camelContext, int.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "async": return boolean.class;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return boolean.class;
+        case "configfile":
+        case "configFile": return java.lang.String.class;
+        case "exceptionhandler":
+        case "exceptionHandler": return org.apache.camel.spi.ExceptionHandler.class;
+        case "exchangepattern":
+        case "exchangePattern": return org.apache.camel.ExchangePattern.class;
+        case "lazystartproducer":
+        case "lazyStartProducer": return boolean.class;
+        case "problemid":
+        case "problemId": return java.lang.Long.class;
+        case "solverid":
+        case "solverId": return java.lang.String.class;
+        case "solvermanager":
+        case "solverManager": return org.optaplanner.core.api.solver.SolverManager.class;
+        case "threadpoolsize":
+        case "threadPoolSize": return int.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        OptaPlannerEndpoint target = (OptaPlannerEndpoint) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "async": return target.getConfiguration().isAsync();
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return target.isBridgeErrorHandler();
+        case "configfile":
+        case "configFile": return target.getConfiguration().getConfigFile();
+        case "exceptionhandler":
+        case "exceptionHandler": return target.getExceptionHandler();
+        case "exchangepattern":
+        case "exchangePattern": return target.getExchangePattern();
+        case "lazystartproducer":
+        case "lazyStartProducer": return target.isLazyStartProducer();
+        case "problemid":
+        case "problemId": return target.getConfiguration().getProblemId();
+        case "solverid":
+        case "solverId": return target.getConfiguration().getSolverId();
+        case "solvermanager":
+        case "solverManager": return target.getConfiguration().getSolverManager();
+        case "threadpoolsize":
+        case "threadPoolSize": return target.getConfiguration().getThreadPoolSize();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-optaplanner/src/generated/java/org/apache/camel/component/optaplanner/OptaPlannerEndpointUriFactory.java b/components/camel-optaplanner/src/generated/java/org/apache/camel/component/optaplanner/OptaPlannerEndpointUriFactory.java
new file mode 100644
index 00000000000..06f295582b9
--- /dev/null
+++ b/components/camel-optaplanner/src/generated/java/org/apache/camel/component/optaplanner/OptaPlannerEndpointUriFactory.java
@@ -0,0 +1,78 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.optaplanner;
+
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.camel.spi.EndpointUriFactory;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+public class OptaPlannerEndpointUriFactory extends org.apache.camel.support.component.EndpointUriFactorySupport implements EndpointUriFactory {
+
+    private static final String BASE = ":problemName";
+
+    private static final Set<String> PROPERTY_NAMES;
+    private static final Set<String> SECRET_PROPERTY_NAMES;
+    private static final Set<String> MULTI_VALUE_PREFIXES;
+    static {
+        Set<String> props = new HashSet<>(11);
+        props.add("async");
+        props.add("bridgeErrorHandler");
+        props.add("configFile");
+        props.add("exceptionHandler");
+        props.add("exchangePattern");
+        props.add("lazyStartProducer");
+        props.add("problemId");
+        props.add("problemName");
+        props.add("solverId");
+        props.add("solverManager");
+        props.add("threadPoolSize");
+        PROPERTY_NAMES = Collections.unmodifiableSet(props);
+        SECRET_PROPERTY_NAMES = Collections.emptySet();
+        MULTI_VALUE_PREFIXES = Collections.emptySet();
+    }
+
+    @Override
+    public boolean isEnabled(String scheme) {
+        return "optaplanner".equals(scheme);
+    }
+
+    @Override
+    public String buildUri(String scheme, Map<String, Object> properties, boolean encode) throws URISyntaxException {
+        String syntax = scheme + BASE;
+        String uri = syntax;
+
+        Map<String, Object> copy = new HashMap<>(properties);
+
+        uri = buildPathParameter(syntax, uri, "problemName", null, true, copy);
+        uri = buildQueryParameters(uri, copy, encode);
+        return uri;
+    }
+
+    @Override
+    public Set<String> propertyNames() {
+        return PROPERTY_NAMES;
+    }
+
+    @Override
+    public Set<String> secretPropertyNames() {
+        return SECRET_PROPERTY_NAMES;
+    }
+
+    @Override
+    public Set<String> multiValuePrefixes() {
+        return MULTI_VALUE_PREFIXES;
+    }
+
+    @Override
+    public boolean isLenientProperties() {
+        return false;
+    }
+}
+
diff --git a/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/component.properties b/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/component.properties
new file mode 100644
index 00000000000..b93732f322a
--- /dev/null
+++ b/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/component.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+components=optaplanner
+groupId=org.apache.camel
+artifactId=camel-optaplanner
+version=4.0.0-SNAPSHOT
+projectName=Camel :: OptaPlanner
+projectDescription=Camel OptaPlanner support
diff --git a/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/component/optaplanner b/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/component/optaplanner
new file mode 100644
index 00000000000..609d8cd9953
--- /dev/null
+++ b/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/component/optaplanner
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.optaplanner.OptaPlannerComponent
diff --git a/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/configurer/optaplanner-component b/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/configurer/optaplanner-component
new file mode 100644
index 00000000000..229a33f2104
--- /dev/null
+++ b/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/configurer/optaplanner-component
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.optaplanner.OptaPlannerComponentConfigurer
diff --git a/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/configurer/optaplanner-endpoint b/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/configurer/optaplanner-endpoint
new file mode 100644
index 00000000000..18d76c2b80f
--- /dev/null
+++ b/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/configurer/optaplanner-endpoint
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.optaplanner.OptaPlannerEndpointConfigurer
diff --git a/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/urifactory/optaplanner-endpoint b/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/urifactory/optaplanner-endpoint
new file mode 100644
index 00000000000..b32aafdae9a
--- /dev/null
+++ b/components/camel-optaplanner/src/generated/resources/META-INF/services/org/apache/camel/urifactory/optaplanner-endpoint
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.optaplanner.OptaPlannerEndpointUriFactory
diff --git a/components/camel-optaplanner/src/generated/resources/org/apache/camel/component/optaplanner/optaplanner.json b/components/camel-optaplanner/src/generated/resources/org/apache/camel/component/optaplanner/optaplanner.json
new file mode 100644
index 00000000000..48264df76d8
--- /dev/null
+++ b/components/camel-optaplanner/src/generated/resources/org/apache/camel/component/optaplanner/optaplanner.json
@@ -0,0 +1,49 @@
+{
+  "component": {
+    "kind": "component",
+    "name": "optaplanner",
+    "title": "OptaPlanner",
+    "description": "Solve planning problems with OptaPlanner.",
+    "deprecated": false,
+    "firstVersion": "2.13.0",
+    "label": "engine,planning",
+    "javaType": "org.apache.camel.component.optaplanner.OptaPlannerComponent",
+    "supportLevel": "Stable",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-optaplanner",
+    "version": "4.0.0-SNAPSHOT",
+    "scheme": "optaplanner",
+    "extendsScheme": "",
+    "syntax": "optaplanner:problemName",
+    "async": false,
+    "api": false,
+    "consumerOnly": false,
+    "producerOnly": false,
+    "lenientProperties": false
+  },
+  "componentProperties": {
+    "bridgeErrorHandler": { "kind": "property", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a me [...]
+    "lazyStartProducer": { "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 during star [...]
+    "autowiredEnabled": { "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 type, which t [...]
+  },
+  "headers": {
+    "CamelOptaPlannerSolverId": { "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Specifies the solverId to use.", "constantName": "org.apache.camel.component.optaplanner.OptaPlannerConstants#SOLVER_ID" },
+    "CamelOptaPlannerIsAsync": { "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Specify whether to use another thread for submitting Solution instances rather than blocking the current thread.", "constantName": "org.apache.camel.component.optaplanner.OptaPlannerConstants#IS_ASYNC" },
+    "CamelOptaPlannerBestSolution": { "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "Object", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The best planning solution.", "constantName": "org.apache.camel.component.optaplanner.OptaPlannerConstants#BEST_SOLUTION" },
+    "CamelOptaPlannerIsSolving": { "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Is solving.", "constantName": "org.apache.camel.component.optaplanner.OptaPlannerConstants#IS_SOLVING" },
+    "CamelOptaPlannerSolverManager": { "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "org.optaplanner.core.api.solver.SolverManager", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Solver Manager.", "constantName": "org.apache.camel.component.optaplanner.OptaPlannerConstants#SOLVER_MANAGER" }
+  },
+  "properties": {
+    "problemName": { "kind": "path", "displayName": "Problem Name", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "Problem name" },
+    "problemId": { "kind": "parameter", "displayName": "Problem Id", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1L", "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "In case of using SolverManager : the problem id" },
+    "solverId": { "kind": "parameter", "displayName": "Solver Id", "group": "common", "label": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "DEFAULT_SOLVER", "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "Specifies the solverId to user for the solver instance key" },
+    "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now [...]
+    "exceptionHandler": { "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the con [...]
+    "exchangePattern": { "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
+    "async": { "kind": "parameter", "displayName": "Async", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "Specifies to perform operations in async mode" },
+    "threadPoolSize": { "kind": "parameter", "displayName": "Thread Pool Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 10, "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "Specifies the thread pool size to use when async is true" },
+    "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "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 other [...]
+    "configFile": { "kind": "parameter", "displayName": "Config File", "group": "configFile", "label": "configFile", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "If SolverManager is absent from the header {OptaPlannerConstants.SOLVER_MANAGER} : A SolverManager will  [...]
+    "solverManager": { "kind": "parameter", "displayName": "Solver Manager", "group": "solverManager", "label": "solverManager", "required": false, "type": "object", "javaType": "org.optaplanner.core.api.solver.SolverManager", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "SolverManager" }
+  }
+}
diff --git a/components/camel-optaplanner/src/main/docs/optaplanner-component.adoc b/components/camel-optaplanner/src/main/docs/optaplanner-component.adoc
new file mode 100644
index 00000000000..a9cf18b04fe
--- /dev/null
+++ b/components/camel-optaplanner/src/main/docs/optaplanner-component.adoc
@@ -0,0 +1,95 @@
+= OptaPlanner Component
+:doctitle: OptaPlanner
+:shortname: optaplanner
+:artifactid: camel-optaplanner
+:description: Solve planning problems with OptaPlanner.
+:since: 2.13
+:supportlevel: Stable
+:component-header: Both producer and consumer are supported
+//Manually maintained attributes
+:camel-spring-boot-name: optaplanner
+
+*Since Camel {since}*
+
+*{component-header}*
+
+The Optaplanner component solves the planning problem contained in a
+message with http://www.optaplanner.org/[OptaPlanner]. +
+ For example: feed it an unsolved Vehicle Routing problem and it solves
+it.
+
+The component supports consumer listening for SloverManager results and
+producer for processing Solution and ProblemChange.
+
+Maven users will need to add the following dependency to their `pom.xml`
+for this component:
+
+[source,xml]
+------------------------------------------------------------------------------------
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-optaplanner</artifactId>
+    <version>x.x.x</version><!-- use the same version as your Camel core version -->
+</dependency>
+------------------------------------------------------------------------------------
+
+== URI format
+
+----------------------------------
+optaplanner:problemName[?options]
+----------------------------------
+
+You can append query options to the URI in the following format,
+`?option=value&option=value&...`
+
+// component-configure options: START
+
+// component-configure options: END
+
+// component options: START
+include::partial$component-configure-options.adoc[]
+include::partial$component-endpoint-options.adoc[]
+// component options: END
+
+// endpoint options: START
+
+// endpoint options: END
+
+// component headers: START
+include::partial$component-endpoint-headers.adoc[]
+// component headers: END
+
+== Message Body
+
+Camel takes the planning problem for the IN body, solves it and returns
+it on the OUT body. The IN body object supports the following use cases:
+
+* If the body contains the PlanningSolution annotation, then it will be solved using the
+solver identified by solverId and either synchronously or asynchronously.
+* If the body is instance of ProblemChange, then it will trigger
+addProblemFactChange.
+* If the body is none of the above types, then the producer will return
+the best result from the solver identified by solverId
+
+
+=== Samples
+
+Solve a planning problem that's on the ActiveMQ queue with OptaPlanner, passing the SolverManager:
+
+[source,java]
+--------------------------------------------------
+from("activemq:My.Queue").
+  .to("optaplanner:problemName?solverManager=#solverManager");
+--------------------------------------------------
+
+Expose OptaPlanner as a REST service, passing the Solver configuration file:
+
+[source,java]
+-------------------------------------------------------
+from("cxfrs:bean:rsServer?bindingStyle=SimpleConsumer")
+  .to("optaplanner:problemName?configFile=/org/foo/barSolverConfig.xml");
+-------------------------------------------------------
+
+
+
+include::spring-boot:partial$starter.adoc[]
diff --git a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerComponent.java b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerComponent.java
new file mode 100644
index 00000000000..9359be8d771
--- /dev/null
+++ b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerComponent.java
@@ -0,0 +1,53 @@
+/*
+ * 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.optaplanner;
+
+import java.util.Map;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.spi.annotations.Component;
+import org.apache.camel.support.DefaultComponent;
+import org.apache.camel.util.ObjectHelper;
+import org.kie.api.KieServices;
+
+/**
+ * OptaPlanner component for Camel
+ */
+@Component("optaplanner")
+public class OptaPlannerComponent extends DefaultComponent {
+
+    @Override
+    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+        OptaPlannerConfiguration configuration = new OptaPlannerConfiguration();
+        configuration.setConfigFile(remaining);
+
+        // [CAMEL-11889] Kie assumes that the TCCL can load its services
+        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+        try {
+            Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+            KieServices kieServices = KieServices.Factory.get();
+            ObjectHelper.notNull(kieServices, "KieServices");
+        } finally {
+            Thread.currentThread().setContextClassLoader(tccl);
+        }
+
+        OptaPlannerEndpoint answer = new OptaPlannerEndpoint(uri, this, configuration);
+        setProperties(answer, parameters);
+        return answer;
+    }
+
+}
diff --git a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConfiguration.java b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConfiguration.java
new file mode 100644
index 00000000000..19a0522dd4f
--- /dev/null
+++ b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConfiguration.java
@@ -0,0 +1,125 @@
+/*
+ * 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.optaplanner;
+
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.apache.camel.spi.UriPath;
+import org.optaplanner.core.api.solver.SolverManager;
+
+@UriParams
+public class OptaPlannerConfiguration {
+
+    @UriPath
+    @Metadata(required = true)
+    private String problemName;
+    @UriParam(label = "common", defaultValue = "DEFAULT_SOLVER")
+    private String solverId = OptaPlannerConstants.DEFAULT_SOLVER_ID;
+    @UriParam(label = "producer", defaultValue = "10")
+    private int threadPoolSize = 10;
+    @UriParam(label = "producer")
+    private boolean async;
+    @UriParam(label = "common", defaultValue = "1L")
+    private Long problemId = 1L;
+    @UriParam(label = "configFile")
+    private String configFile;
+    @UriParam(label = "solverManager")
+    private SolverManager solverManager;
+
+    public String getConfigFile() {
+        return configFile;
+    }
+
+    /**
+     * If SolverManager is absent from the header {OptaPlannerConstants.SOLVER_MANAGER} : A SolverManager will be
+     * created using this Optaplanner config file.
+     */
+    public void setConfigFile(String configFile) {
+        this.configFile = configFile;
+    }
+
+    public String getSolverId() {
+        return solverId;
+    }
+
+    /**
+     * Problem name
+     */
+    public String getProblemName() {
+        return problemName;
+    }
+
+    public void setProblemName(String problemName) {
+        this.problemName = problemName;
+    }
+
+    /**
+     * Specifies the solverId to user for the solver instance key
+     */
+    public void setSolverId(String solverId) {
+        this.solverId = solverId;
+    }
+
+    public int getThreadPoolSize() {
+        return threadPoolSize;
+    }
+
+    /**
+     * Specifies the thread pool size to use when async is true
+     */
+    public void setThreadPoolSize(int threadPoolSize) {
+        this.threadPoolSize = threadPoolSize;
+    }
+
+    public boolean isAsync() {
+        return async;
+    }
+
+    /**
+     * Specifies to perform operations in async mode
+     */
+    public void setAsync(boolean async) {
+        this.async = async;
+    }
+
+    public Long getProblemId() {
+        return problemId;
+    }
+
+    /**
+     * In case of using SolverManager : the problem id
+     *
+     * @param problemId
+     */
+    public void setProblemId(Long problemId) {
+        this.problemId = problemId;
+    }
+
+    public SolverManager getSolverManager() {
+        return solverManager;
+    }
+
+    /**
+     * SolverManager
+     *
+     * @param solverManager
+     */
+    public void setSolverManager(SolverManager solverManager) {
+        this.solverManager = solverManager;
+    }
+}
diff --git a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConstants.java b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConstants.java
new file mode 100644
index 00000000000..d9c8ca376f5
--- /dev/null
+++ b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConstants.java
@@ -0,0 +1,36 @@
+/*
+ * 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.optaplanner;
+
+import org.apache.camel.spi.Metadata;
+
+public interface OptaPlannerConstants {
+    String DEFAULT_SOLVER_ID = "DEFAULT_SOLVER";
+    @Metadata(label = "producer", description = "Specifies the solverId to use.", javaType = "String")
+    String SOLVER_ID = "CamelOptaPlannerSolverId";
+    @Metadata(label = "producer", description = "Specify whether to use another thread for submitting Solution instances\n" +
+                                                "rather than blocking the current thread.",
+              javaType = "Boolean")
+    String IS_ASYNC = "CamelOptaPlannerIsAsync";
+    @Metadata(label = "consumer", description = "The best planning solution.", javaType = "Object")
+    String BEST_SOLUTION = "CamelOptaPlannerBestSolution";
+    @Metadata(label = "producer", description = "Is solving.", javaType = "Boolean")
+    String IS_SOLVING = "CamelOptaPlannerIsSolving";
+    @Metadata(label = "producer", description = "The Solver Manager.",
+              javaType = "org.optaplanner.core.api.solver.SolverManager")
+    String SOLVER_MANAGER = "CamelOptaPlannerSolverManager";
+}
diff --git a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConsumer.java b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConsumer.java
new file mode 100644
index 00000000000..e98c00d5942
--- /dev/null
+++ b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConsumer.java
@@ -0,0 +1,70 @@
+/*
+ * 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.optaplanner;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.support.DefaultConsumer;
+
+/**
+ * OptaPlanner component for Camel
+ */
+public class OptaPlannerConsumer extends DefaultConsumer {
+    private final OptaPlannerEndpoint endpoint;
+    private final OptaPlannerConfiguration configuration;
+    private OptaplannerSolutionEventListener solverJobListener;
+
+    public OptaPlannerConsumer(OptaPlannerEndpoint endpoint, Processor processor, OptaPlannerConfiguration configuration) {
+        super(endpoint, processor);
+        this.endpoint = endpoint;
+        this.configuration = configuration;
+
+        solverJobListener = new OptaplannerSolutionEventListener() {
+            @Override
+            public void bestSolutionChanged(OptaplannerSolutionEvent event) {
+                processSolverJobEvent(event);
+            }
+        };
+    }
+
+    public void processSolverJobEvent(OptaplannerSolutionEvent event) {
+        Exchange exchange = createExchange(true);
+        exchange.getMessage().setHeader(OptaPlannerConstants.BEST_SOLUTION, event.getBestSolution());
+        try {
+            getProcessor().process(exchange);
+        } catch (Exception e) {
+            getExceptionHandler().handleException(e);
+        }
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+
+        final Long problemId = configuration.getProblemId();
+        endpoint.addSolutionEventListener(problemId, solverJobListener);
+
+        super.doStart();
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        final Long problemId = configuration.getProblemId();
+        endpoint.removeSolutionEventListener(problemId, solverJobListener);
+
+        super.doStop();
+    }
+}
diff --git a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerEndpoint.java b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerEndpoint.java
new file mode 100644
index 00000000000..1aef344f581
--- /dev/null
+++ b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerEndpoint.java
@@ -0,0 +1,126 @@
+/*
+ * 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.optaplanner;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.camel.Category;
+import org.apache.camel.Component;
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.support.DefaultEndpoint;
+import org.optaplanner.core.api.solver.Solver;
+import org.optaplanner.core.api.solver.SolverFactory;
+
+/**
+ * Solve planning problems with OptaPlanner.
+ */
+@UriEndpoint(firstVersion = "2.13.0", scheme = "optaplanner", title = "OptaPlanner", syntax = "optaplanner:problemName",
+             category = { Category.ENGINE, Category.PLANNING }, headersClass = OptaPlannerConstants.class)
+public class OptaPlannerEndpoint extends DefaultEndpoint {
+    private static final Map<String, Solver<Object>> SOLVERS = new HashMap<>();
+    private static final Map<Long, Set<OptaplannerSolutionEventListener>> SOLUTION_LISTENER = new HashMap();
+
+    private SolverFactory<Object> solverFactory;
+
+    @UriParam
+    private OptaPlannerConfiguration configuration;
+
+    public OptaPlannerEndpoint(String uri, Component component, OptaPlannerConfiguration configuration) {
+        super(uri, component);
+        this.configuration = configuration;
+    }
+
+    public OptaPlannerConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    protected Solver<Object> getOrCreateSolver(String solverId) {
+        synchronized (SOLVERS) {
+            return SOLVERS.computeIfAbsent(solverId, k -> createSolver());
+        }
+    }
+
+    protected Solver<Object> createSolver() {
+        ClassLoader classLoader = getCamelContext().getApplicationContextClassLoader();
+        solverFactory = SolverFactory.createFromXmlResource(configuration.getConfigFile(), classLoader);
+        return solverFactory.buildSolver();
+    }
+
+    protected Solver<Object> getSolver(String solverId) {
+        synchronized (SOLVERS) {
+            return SOLVERS.get(solverId);
+        }
+    }
+
+    @Override
+    public Producer createProducer() {
+        return new OptaPlannerProducer(this, configuration);
+    }
+
+    @Override
+    public Consumer createConsumer(Processor processor) throws Exception {
+        OptaPlannerConsumer consumer = new OptaPlannerConsumer(this, processor, configuration);
+        configureConsumer(consumer);
+        return consumer;
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        synchronized (SOLVERS) {
+            for (Map.Entry<String, Solver<Object>> solver : SOLVERS.entrySet()) {
+                solver.getValue().terminateEarly();
+                SOLVERS.remove(solver.getKey());
+            }
+        }
+        super.doStop();
+    }
+
+    protected Set<OptaplannerSolutionEventListener> getSolutionEventListeners(Long problemId) {
+        return SOLUTION_LISTENER.get(problemId);
+    }
+
+    protected synchronized void addSolutionEventListener(Long problemId, OptaplannerSolutionEventListener listener) {
+        Set<OptaplannerSolutionEventListener> listeners = SOLUTION_LISTENER.get(problemId);
+        if (listeners == null) {
+            listeners = new HashSet<>();
+            listeners.add(listener);
+            SOLUTION_LISTENER.put(problemId, listeners);
+        } else {
+            listeners.add(listener);
+        }
+    }
+
+    protected synchronized void removeSolutionEventListener(Long problemId, OptaplannerSolutionEventListener listener) {
+        Set<OptaplannerSolutionEventListener> listeners = SOLUTION_LISTENER.get(problemId);
+        listeners.remove(listener);
+        if (listeners.isEmpty()) {
+            SOLUTION_LISTENER.remove(problemId);
+        }
+    }
+}
diff --git a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerProducer.java b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerProducer.java
new file mode 100644
index 00000000000..50f2f8d333e
--- /dev/null
+++ b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerProducer.java
@@ -0,0 +1,154 @@
+/*
+ * 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.optaplanner;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Exchange;
+import org.apache.camel.support.DefaultAsyncProducer;
+import org.optaplanner.core.api.solver.SolverFactory;
+import org.optaplanner.core.api.solver.SolverJob;
+import org.optaplanner.core.api.solver.SolverManager;
+import org.optaplanner.core.api.solver.change.ProblemChange;
+import org.optaplanner.core.config.solver.SolverConfig;
+import org.optaplanner.core.config.solver.SolverManagerConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OptaPlannerProducer extends DefaultAsyncProducer {
+
+    private static final transient Logger LOGGER = LoggerFactory.getLogger(OptaPlannerProducer.class);
+
+    private ExecutorService executor;
+    private final OptaPlannerEndpoint endpoint;
+    private final OptaPlannerConfiguration configuration;
+
+    public OptaPlannerProducer(OptaPlannerEndpoint endpoint, OptaPlannerConfiguration configuration) {
+        super(endpoint);
+        this.endpoint = endpoint;
+        this.configuration = configuration;
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        if (configuration.isAsync()) {
+            executor = endpoint.getCamelContext().getExecutorServiceManager().newFixedThreadPool(this,
+                    endpoint.getEndpointUri(), configuration.getThreadPoolSize());
+        }
+        super.doStart();
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        if (executor != null) {
+            endpoint.getCamelContext().getExecutorServiceManager().shutdown(executor);
+            executor = null;
+        }
+        super.doStop();
+    }
+
+    @Override
+    public boolean process(Exchange exchange, AsyncCallback callback) {
+        try {
+            final Object body = exchange.getIn().getMandatoryBody();
+            // using Solver Manager :: Optaplanner creates the Solver under the hood
+            final SolverManager solverManager = getSolverManager(exchange);
+            final String solverId = getSolverId(exchange);
+
+            Long problemId = endpoint.getConfiguration().getProblemId();
+            LOGGER.debug("Asynchronously solving problem: [{}] with id [{}]", body, problemId);
+
+            if (body instanceof ProblemChange<?>) {
+                solverManager.addProblemChange(problemId, (ProblemChange) body);
+            } else if (isAsync(exchange)) {
+                executor.submit(() -> {
+                    try {
+                        // create a consumer for best solution
+                        OptaplannerEventSupport eventSupport = new OptaplannerEventSupport(endpoint, problemId);
+                        // start solving :: Solver Job is a thread
+                        SolverJob solverJob
+                                = solverManager.solveAndListen(problemId, t -> body, eventSupport::updateBestSolution);
+
+                        // wait for result
+                        populateResult(exchange, solverJob);
+                    } catch (Exception e) {
+                        exchange.setException(e);
+                    } finally {
+                        callback.done(false);
+                    }
+                });
+                return false;
+            } else {
+                // no need for a consumer for sync call
+                SolverJob solverJob = solverManager.solve(problemId, body);
+                // wait for result
+                populateResult(exchange, solverJob);
+            }
+
+            // synchronous or wrong type of body
+            callback.done(true);
+            return true;
+        } catch (Exception e) {
+            exchange.setException(e);
+        }
+        callback.done(true);
+        return true;
+    }
+
+    private void populateResult(Exchange exchange, SolverJob<?, ?> solverJob)
+            throws InterruptedException, ExecutionException {
+        exchange.getIn().setBody(solverJob.getFinalBestSolution());
+        exchange.getIn().setHeader(OptaPlannerConstants.IS_SOLVING, false);
+    }
+
+    private String getSolverId(Exchange exchange) {
+        String solverId = exchange.getIn().getHeader(OptaPlannerConstants.SOLVER_ID, String.class);
+        if (solverId == null) {
+            solverId = configuration.getSolverId();
+        }
+        LOGGER.debug("SolverId: [{}]", solverId);
+        return solverId;
+    }
+
+    private boolean isAsync(Exchange exchange) {
+        Boolean isAsync = exchange.getIn().getHeader(OptaPlannerConstants.IS_ASYNC, Boolean.class);
+        return isAsync != null ? isAsync : configuration.isAsync();
+    }
+
+    private SolverManager<?, Long> getSolverManager(Exchange exchange) {
+        // prioritize the solverManager from configuration
+        if (configuration.getSolverManager() != null) {
+            return configuration.getSolverManager();
+        }
+        // if no Solver Manager, check on headers
+        var solverManager = exchange.getIn().getHeader(OptaPlannerConstants.SOLVER_MANAGER, SolverManager.class);
+        // if no SolverManager, check if configFile exists and create one based on it
+        if (solverManager == null) {
+            if (configuration.getConfigFile() == null) {
+                return null;
+            }
+            SolverConfig solverConfig
+                    = SolverConfig.createFromXmlResource(configuration.getConfigFile());
+            SolverFactory<?> solverFactory = SolverFactory.create(solverConfig);
+            solverManager = SolverManager.create(solverFactory, new SolverManagerConfig());
+        }
+        return solverManager;
+    }
+
+}
diff --git a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaplannerEventSupport.java b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaplannerEventSupport.java
new file mode 100644
index 00000000000..5181ae0973d
--- /dev/null
+++ b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaplannerEventSupport.java
@@ -0,0 +1,38 @@
+/*
+ * 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.optaplanner;
+
+import java.util.Set;
+
+public class OptaplannerEventSupport {
+
+    private OptaPlannerEndpoint optaPlannerEndpoint;
+    private Long problemId;
+
+    public OptaplannerEventSupport(OptaPlannerEndpoint optaPlannerEndpoint, Long problemId) {
+        this.optaPlannerEndpoint = optaPlannerEndpoint;
+        this.problemId = problemId;
+    }
+
+    protected void updateBestSolution(Object newBestSolution) {
+        OptaplannerSolutionEvent event = new OptaplannerSolutionEvent(newBestSolution);
+        Set<OptaplannerSolutionEventListener> listeners = optaPlannerEndpoint.getSolutionEventListeners(problemId);
+        if (listeners != null) {
+            listeners.stream().forEachOrdered(l -> l.bestSolutionChanged(event));
+        }
+    }
+}
diff --git a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaplannerSolutionEvent.java b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaplannerSolutionEvent.java
new file mode 100644
index 00000000000..9f86c8d0e1e
--- /dev/null
+++ b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaplannerSolutionEvent.java
@@ -0,0 +1,33 @@
+/*
+ * 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.optaplanner;
+
+import java.util.EventObject;
+
+public class OptaplannerSolutionEvent extends EventObject {
+
+    private Object bestSolution;
+
+    public OptaplannerSolutionEvent(Object bestSolution) {
+        super(bestSolution);
+        this.bestSolution = bestSolution;
+    }
+
+    public Object getBestSolution() {
+        return this.bestSolution;
+    }
+}
diff --git a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaplannerSolutionEventListener.java b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaplannerSolutionEventListener.java
new file mode 100644
index 00000000000..5b93cdec4e2
--- /dev/null
+++ b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaplannerSolutionEventListener.java
@@ -0,0 +1,23 @@
+/*
+ * 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.optaplanner;
+
+import java.util.EventListener;
+
+public interface OptaplannerSolutionEventListener extends EventListener {
+    void bestSolutionChanged(OptaplannerSolutionEvent event);
+}
diff --git a/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerAsyncConfigFileTest.java b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerAsyncConfigFileTest.java
new file mode 100644
index 00000000000..c192362d5de
--- /dev/null
+++ b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerAsyncConfigFileTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.optaplanner;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.optaplanner.examples.cloudbalancing.domain.CloudBalance;
+import org.optaplanner.examples.cloudbalancing.persistence.CloudBalancingGenerator;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * OptaPlanner unit test with Camel
+ */
+public class OptaPlannerAsyncConfigFileTest extends CamelTestSupport {
+
+    @Test
+    public void testAsynchronousProblemSolving() throws Exception {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
+        mockEndpoint.setExpectedCount(1);
+        CloudBalancingGenerator generator = new CloudBalancingGenerator(true);
+        final CloudBalance planningProblem = generator.createCloudBalance(4, 12);
+        assertNull(planningProblem.getScore());
+        assertNull(planningProblem.getProcessList().get(0).getComputer());
+
+        template.requestBody("direct:in", planningProblem);
+
+        // consumer
+        getMockEndpoint("mock:result").assertIsSatisfied();
+        Exchange exchange = mockEndpoint.getReceivedExchanges().get(0);
+
+        CloudBalance bestSolution = exchange.getMessage().getHeader(OptaPlannerConstants.BEST_SOLUTION, CloudBalance.class);
+
+        assertEquals(4, bestSolution.getComputerList().size());
+        assertEquals(12, bestSolution.getProcessList().size());
+        assertNotNull(bestSolution.getScore());
+        assertTrue(bestSolution.getScore().isFeasible());
+        assertNotNull(bestSolution.getProcessList().get(0).getComputer());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:in")
+                        .to("optaplanner:myName?configFile=org/apache/camel/component/optaplanner/solverConfig.xml&async=true");
+
+                from("optaplanner:myName?configFile=org/apache/camel/component/optaplanner/solverConfig.xml")
+                        .to("mock:result");
+            }
+        };
+    }
+
+}
diff --git a/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerProblemChangeTest.java b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerProblemChangeTest.java
new file mode 100644
index 00000000000..08d51826584
--- /dev/null
+++ b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerProblemChangeTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.optaplanner;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.Test;
+import org.optaplanner.core.api.solver.SolverFactory;
+import org.optaplanner.core.api.solver.SolverManager;
+import org.optaplanner.core.config.solver.SolverConfig;
+import org.optaplanner.core.config.solver.SolverManagerConfig;
+import org.optaplanner.examples.cloudbalancing.domain.CloudBalance;
+import org.optaplanner.examples.cloudbalancing.domain.CloudComputer;
+import org.optaplanner.examples.cloudbalancing.persistence.CloudBalancingGenerator;
+import org.optaplanner.examples.cloudbalancing.swingui.realtime.DeleteComputerProblemChange;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.optaplanner.core.api.solver.SolverStatus.NOT_SOLVING;
+
+/**
+ * OptaPlanner unit test with Camel
+ */
+public class OptaPlannerProblemChangeTest extends CamelTestSupport {
+
+    @Test
+    public void testAsynchronousProblemSolving() throws Exception {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
+
+        CloudBalancingGenerator generator = new CloudBalancingGenerator(true);
+        final CloudBalance planningProblem = generator.createCloudBalance(4, 12);
+        assertNull(planningProblem.getScore());
+        assertNull(planningProblem.getProcessList().get(0).getComputer());
+
+        ClassLoader classLoader = this.context().getApplicationContextClassLoader();
+        SolverConfig solverConfig
+                = SolverConfig.createFromXmlResource("org/apache/camel/component/optaplanner/solverConfig.xml", classLoader);
+        SolverFactory solverFactory = SolverFactory.create(solverConfig);
+        SolverManager solverManager = SolverManager.create(solverFactory, new SolverManagerConfig());
+
+        CompletableFuture<CloudBalance> solution = template.asyncRequestBodyAndHeader("direct:in", planningProblem,
+                OptaPlannerConstants.SOLVER_MANAGER, solverManager,
+                CloudBalance.class);
+
+        CloudComputer firstComputer = planningProblem.getComputerList().get(0);
+        assertNotNull(firstComputer);
+
+        // wait for Solver to be at least scheduled or started
+        Awaitility.with()
+                .pollInterval(10, TimeUnit.MILLISECONDS).atMost(1000, TimeUnit.MILLISECONDS)
+                .until(() -> !NOT_SOLVING.equals(solverManager.getSolverStatus(1L)));
+
+        // update the Problem
+        template.requestBodyAndHeader("direct:in", new DeleteComputerProblemChange(firstComputer),
+                OptaPlannerConstants.SOLVER_MANAGER, solverManager);
+        mockEndpoint.assertIsSatisfied();
+
+        // wait for the solution
+        CloudBalance bestSolution = solution.get();
+        // check the solution has been changed
+        assertEquals(3, bestSolution.getComputerList().size());
+        assertEquals(12, bestSolution.getProcessList().size());
+        assertNotNull(bestSolution.getScore());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:in").to("optaplanner:cloudBalance?async=true");
+
+                from("optaplanner:cloudBalance")
+                        .to("mock:result");
+            }
+        };
+    }
+
+}
diff --git a/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerSyncConfigFileTest.java b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerSyncConfigFileTest.java
new file mode 100644
index 00000000000..d85f45ef822
--- /dev/null
+++ b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerSyncConfigFileTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.optaplanner;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.optaplanner.examples.cloudbalancing.domain.CloudBalance;
+import org.optaplanner.examples.cloudbalancing.persistence.CloudBalancingGenerator;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * OptaPlanner unit test with Camel
+ */
+public class OptaPlannerSyncConfigFileTest extends CamelTestSupport {
+
+    @Test
+    public void testSynchronousProblemSolving() {
+        CloudBalancingGenerator generator = new CloudBalancingGenerator(true);
+        final CloudBalance planningProblem = generator.createCloudBalance(4, 12);
+        assertNull(planningProblem.getScore());
+        assertNull(planningProblem.getProcessList().get(0).getComputer());
+
+        CloudBalance bestSolution = (CloudBalance) template.requestBody("direct:in", planningProblem);
+
+        assertEquals(4, bestSolution.getComputerList().size());
+        assertEquals(12, bestSolution.getProcessList().size());
+        assertNotNull(bestSolution.getScore());
+        assertTrue(bestSolution.getScore().isFeasible());
+        assertNotNull(bestSolution.getProcessList().get(0).getComputer());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:in")
+                        .to("optaplanner:problemName?configFile=org/apache/camel/component/optaplanner/solverConfig.xml");
+            }
+        };
+    }
+
+}
diff --git a/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaplannerSolverManagerAsyncTest.java b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaplannerSolverManagerAsyncTest.java
new file mode 100644
index 00000000000..22e6ead9947
--- /dev/null
+++ b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaplannerSolverManagerAsyncTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.optaplanner;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.optaplanner.core.api.solver.SolverFactory;
+import org.optaplanner.core.api.solver.SolverManager;
+import org.optaplanner.core.config.solver.SolverConfig;
+import org.optaplanner.core.config.solver.SolverManagerConfig;
+import org.optaplanner.examples.cloudbalancing.domain.CloudBalance;
+import org.optaplanner.examples.cloudbalancing.persistence.CloudBalancingGenerator;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class OptaplannerSolverManagerAsyncTest extends CamelTestSupport {
+
+    private static SolverManager solverManager;
+
+    @BeforeEach
+    public void beforeEach() {
+        ClassLoader classLoader = this.context().getApplicationContextClassLoader();
+        SolverConfig solverConfig
+                = SolverConfig.createFromXmlResource("org/apache/camel/component/optaplanner/solverConfig.xml", classLoader);
+        SolverFactory solverFactory = SolverFactory.create(solverConfig);
+        solverManager = SolverManager.create(solverFactory, new SolverManagerConfig());
+    }
+
+    @Test
+    public void testWithSolverManagerInHeader() throws Exception {
+        final CloudBalance planningProblem = getCloudBalance();
+
+        CompletableFuture<CloudBalance> solution
+                = template.asyncRequestBodyAndHeader("optaplanner:doesntmatter?async=true", planningProblem,
+                        OptaPlannerConstants.SOLVER_MANAGER, solverManager,
+                        CloudBalance.class);
+
+        assertResults(solution);
+    }
+
+    @Test
+    public void testWithSolverManagerBinded() throws Exception {
+        final CloudBalance planningProblem = getCloudBalance();
+
+        this.context.getRegistry().bind("mySolverManager", solverManager);
+
+        CompletableFuture<CloudBalance> solution = template.asyncRequestBody(
+                "optaplanner:doesntmatter?async=true&solverManager=#mySolverManager", planningProblem,
+                CloudBalance.class);
+
+        assertResults(solution);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+
+                from("optaplanner:doesntmatter")
+                        .to("mock:result");
+            }
+        };
+    }
+
+    private void assertResults(CompletableFuture<CloudBalance> solution) throws InterruptedException, ExecutionException {
+        // consumer
+        getMockEndpoint("mock:result").assertIsSatisfied();
+
+        // producer
+        CloudBalance bestSolution = solution.get();
+        assertEquals(4, bestSolution.getComputerList().size());
+        assertEquals(12, bestSolution.getProcessList().size());
+        assertNotNull(bestSolution.getScore());
+        assertTrue(bestSolution.getScore().isFeasible());
+        assertNotNull(bestSolution.getProcessList().get(0).getComputer());
+    }
+
+    private CloudBalance getCloudBalance() {
+        getMockEndpoint("mock:result").setExpectedCount(1);
+
+        CloudBalancingGenerator generator = new CloudBalancingGenerator(true);
+        final CloudBalance planningProblem = generator.createCloudBalance(4, 12);
+        assertNull(planningProblem.getScore());
+        assertNull(planningProblem.getProcessList().get(0).getComputer());
+        return planningProblem;
+    }
+}
diff --git a/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaplannerSolverManagerSyncTest.java b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaplannerSolverManagerSyncTest.java
new file mode 100644
index 00000000000..7fbd54c9a60
--- /dev/null
+++ b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaplannerSolverManagerSyncTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.optaplanner;
+
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.optaplanner.core.api.solver.SolverFactory;
+import org.optaplanner.core.api.solver.SolverManager;
+import org.optaplanner.core.config.solver.SolverConfig;
+import org.optaplanner.core.config.solver.SolverManagerConfig;
+import org.optaplanner.examples.cloudbalancing.domain.CloudBalance;
+import org.optaplanner.examples.cloudbalancing.persistence.CloudBalancingGenerator;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class OptaplannerSolverManagerSyncTest extends CamelTestSupport {
+
+    private static SolverManager solverManager;
+
+    @BeforeEach
+    public void beforeEach() {
+        ClassLoader classLoader = this.context().getApplicationContextClassLoader();
+        SolverConfig solverConfig
+                = SolverConfig.createFromXmlResource("org/apache/camel/component/optaplanner/solverConfig.xml", classLoader);
+        SolverFactory solverFactory = SolverFactory.create(solverConfig);
+        solverManager = SolverManager.create(solverFactory, new SolverManagerConfig());
+    }
+
+    @Test
+    public void testWithSolverManagerInHeader() throws InterruptedException {
+
+        final CloudBalance planningProblem = getCloudBalance();
+
+        CloudBalance bestSolution = template.requestBodyAndHeader("optaplanner:doesntmatter", planningProblem,
+                OptaPlannerConstants.SOLVER_MANAGER, solverManager, CloudBalance.class);
+
+        assertResults(bestSolution);
+    }
+
+    @Test
+    public void testWithSolverManagerBinded() throws InterruptedException {
+        final CloudBalance planningProblem = getCloudBalance();
+
+        this.context.getRegistry().bind("mySolverManager", solverManager);
+
+        CloudBalance bestSolution
+                = template.requestBody("optaplanner:doesntmatter?solverManager=#mySolverManager", planningProblem,
+                        CloudBalance.class);
+
+        assertResults(bestSolution);
+    }
+
+    private CloudBalance getCloudBalance() {
+        CloudBalancingGenerator generator = new CloudBalancingGenerator(true);
+        final CloudBalance planningProblem = generator.createCloudBalance(4, 12);
+        assertNull(planningProblem.getScore());
+        assertNull(planningProblem.getProcessList().get(0).getComputer());
+        return planningProblem;
+    }
+
+    private void assertResults(CloudBalance bestSolution) throws InterruptedException {
+        assertEquals(4, bestSolution.getComputerList().size());
+        assertEquals(12, bestSolution.getProcessList().size());
+        assertNotNull(bestSolution.getScore());
+        assertTrue(bestSolution.getScore().isFeasible());
+        assertNotNull(bestSolution.getProcessList().get(0).getComputer());
+    }
+
+}
diff --git a/components/camel-optaplanner/src/test/resources/log4j2.properties b/components/camel-optaplanner/src/test/resources/log4j2.properties
new file mode 100644
index 00000000000..c9570579495
--- /dev/null
+++ b/components/camel-optaplanner/src/test/resources/log4j2.properties
@@ -0,0 +1,32 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+appender.out.type = File
+appender.out.name = out
+appender.out.fileName = target/camel-optaplanner-test.log
+appender.out.layout.type = PatternLayout
+appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+appender.stdout.type = Console
+appender.stdout.name = stdout
+appender.stdout.layout.type = PatternLayout
+appender.stdout.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+logger.spring.name = org.apache.activemq.spring
+logger.spring.level = WARN
+logger.optaplanner.name = org.apache.camel.component.optaplanner
+logger.optaplanner.level = DEBUG
+rootLogger.level = INFO
+rootLogger.appenderRef.out.ref = out
diff --git a/components/camel-optaplanner/src/test/resources/org/apache/camel/component/optaplanner/solverConfig.xml b/components/camel-optaplanner/src/test/resources/org/apache/camel/component/optaplanner/solverConfig.xml
new file mode 100644
index 00000000000..a32c7f2cc25
--- /dev/null
+++ b/components/camel-optaplanner/src/test/resources/org/apache/camel/component/optaplanner/solverConfig.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<solver xmlns="https://www.optaplanner.org/xsd/solver" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="https://www.optaplanner.org/xsd/solver https://www.optaplanner.org/xsd/solver/solver.xsd">
+
+  <!-- Domain model configuration -->
+  <solutionClass>org.optaplanner.examples.cloudbalancing.domain.CloudBalance</solutionClass>
+  <entityClass>org.optaplanner.examples.cloudbalancing.domain.CloudProcess</entityClass>
+
+  <!-- Score configuration -->
+  <scoreDirectorFactory>
+    <constraintProviderClass>org.optaplanner.examples.cloudbalancing.score.CloudBalancingConstraintProvider</constraintProviderClass>
+    <initializingScoreTrend>ONLY_DOWN</initializingScoreTrend>
+  </scoreDirectorFactory>
+
+  <!-- Optimization algorithms configuration -->
+  <termination>
+    <minutesSpentLimit>2</minutesSpentLimit>
+  </termination>
+
+</solver>
diff --git a/components/pom.xml b/components/pom.xml
index 0e518dd6f24..8bdd8df1dd7 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -287,6 +287,7 @@
         <module>camel-stringtemplate</module>
         <module>camel-stitch</module>
         <module>camel-openapi-java</module>
+        <module>camel-optaplanner</module>
         <module>camel-syslog</module>
         <module>camel-tarfile</module>
         <module>camel-telegram</module>
diff --git a/core/camel-main/src/generated/resources/org/apache/camel/main/components.properties b/core/camel-main/src/generated/resources/org/apache/camel/main/components.properties
index 6b677801d0c..a035d5e429a 100644
--- a/core/camel-main/src/generated/resources/org/apache/camel/main/components.properties
+++ b/core/camel-main/src/generated/resources/org/apache/camel/main/components.properties
@@ -231,6 +231,7 @@ openstack-keystone
 openstack-neutron
 openstack-nova
 openstack-swift
+optaplanner
 paho
 paho-mqtt5
 pdf
diff --git a/docs/components/modules/ROOT/examples/json/optaplanner.json b/docs/components/modules/ROOT/examples/json/optaplanner.json
new file mode 120000
index 00000000000..ab94d880576
--- /dev/null
+++ b/docs/components/modules/ROOT/examples/json/optaplanner.json
@@ -0,0 +1 @@
+../../../../../../components/camel-optaplanner/src/generated/resources/org/apache/camel/component/optaplanner/optaplanner.json
\ No newline at end of file
diff --git a/docs/components/modules/ROOT/nav.adoc b/docs/components/modules/ROOT/nav.adoc
index 30c645f6fba..1d8fb609550 100644
--- a/docs/components/modules/ROOT/nav.adoc
+++ b/docs/components/modules/ROOT/nav.adoc
@@ -238,6 +238,7 @@
 *** xref:openstack-neutron-component.adoc[OpenStack Neutron]
 *** xref:openstack-nova-component.adoc[OpenStack Nova]
 *** xref:openstack-swift-component.adoc[OpenStack Swift]
+** xref:optaplanner-component.adoc[OptaPlanner]
 ** xref:paho-component.adoc[Paho]
 ** xref:paho-mqtt5-component.adoc[Paho MQTT 5]
 ** xref:pdf-component.adoc[PDF]
diff --git a/docs/components/modules/ROOT/pages/optaplanner-component.adoc b/docs/components/modules/ROOT/pages/optaplanner-component.adoc
new file mode 120000
index 00000000000..0a28adc9842
--- /dev/null
+++ b/docs/components/modules/ROOT/pages/optaplanner-component.adoc
@@ -0,0 +1 @@
+../../../../../components/camel-optaplanner/src/main/docs/optaplanner-component.adoc
\ No newline at end of file
diff --git a/docs/user-manual/modules/ROOT/pages/camel-4-migration-guide.adoc b/docs/user-manual/modules/ROOT/pages/camel-4-migration-guide.adoc
index ff561ef12d4..270cc60e83b 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4-migration-guide.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4-migration-guide.adoc
@@ -37,7 +37,6 @@ The following components has been removed:
 | camel-microprofile-metrics           | camel-micrometer, camel-opentelemetry
 | camel-milo                           | none
 | camel-opentracing                    | camel-micrometer, camel-opentelemetry
-| camel-optaplanner                    | none
 | camel-rabbitmq                       | spring-rabbitmq-component
 | camel-rest-swagger                   | camel-openapi-rest
 | camel-restdsl-swagger-plugin         | camel-restdsl-openapi-plugin
@@ -252,3 +251,30 @@ Then calling _myservice_ would before require to include the context-path, such
 Now the context-path is not in use, and the endpoint can be called with `http://localhost:8080/myservice`.
 
 NOTE: The `platform-http-starter` can also be used with Rest DSL.
+
+== camel-optaplanner
+The `camel-optaplanner` component has been change to use `SolverManager`. If you were using `SoverManager` in Camel 3, you don't need anymore the boolean useSolverManager in the Route.
+Deprecated `ProblemFactChange` has been replaced by `ProblemChange`.
+
+The new URI path is :
+[source,java]
+----
+from("optaplanner:myProblemName")
+  .to("...")
+----
+
+You can pass the Optaplanner SolverManager in 2 ways:
+- as #parameter
+- as header
+
+When running `camel-optaplanner` on Spring Boot or Quarkus, it is preferrable to use the Spring Boot or Quarkus way of creating the SolverManager.
+
+It is possible to migrate legacy Camel Optaplanner Routes, by putting the XML config file, as show in the code below. Camel Optaplanner will handle creating the SolverManager for those legacy Routes:
+[source,java]
+----
+from("optaplanner:myProblemName?configFile=PATH/TO/CONFIG.FILE.xml")
+  .to("...")
+----
+
+Solver Daemon solutions should be migrated to use SolverManager.
+
diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java
index 281f9d03dbf..57af8c3c262 100644
--- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java
+++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java
@@ -3138,6 +3138,19 @@ public interface ComponentsBuilderFactory {
     static org.apache.camel.builder.component.dsl.OpenstackSwiftComponentBuilderFactory.OpenstackSwiftComponentBuilder openstackSwift() {
         return org.apache.camel.builder.component.dsl.OpenstackSwiftComponentBuilderFactory.openstackSwift();
     }
+    /**
+     * OptaPlanner (camel-optaplanner)
+     * Solve planning problems with OptaPlanner.
+     * 
+     * Category: engine,planning
+     * Since: 2.13
+     * Maven coordinates: org.apache.camel:camel-optaplanner
+     * 
+     * @return the dsl builder
+     */
+    static org.apache.camel.builder.component.dsl.OptaplannerComponentBuilderFactory.OptaplannerComponentBuilder optaplanner() {
+        return org.apache.camel.builder.component.dsl.OptaplannerComponentBuilderFactory.optaplanner();
+    }
     /**
      * Paho (camel-paho)
      * Communicate with MQTT message brokers using Eclipse Paho MQTT Client.
diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/OptaplannerComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/OptaplannerComponentBuilderFactory.java
new file mode 100644
index 00000000000..ddd31fb42f0
--- /dev/null
+++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/OptaplannerComponentBuilderFactory.java
@@ -0,0 +1,144 @@
+/*
+ * 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.builder.component.dsl;
+
+import javax.annotation.processing.Generated;
+import org.apache.camel.Component;
+import org.apache.camel.builder.component.AbstractComponentBuilder;
+import org.apache.camel.builder.component.ComponentBuilder;
+import org.apache.camel.component.optaplanner.OptaPlannerComponent;
+
+/**
+ * Solve planning problems with OptaPlanner.
+ * 
+ * Generated by camel-package-maven-plugin - do not edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.ComponentDslMojo")
+public interface OptaplannerComponentBuilderFactory {
+
+    /**
+     * OptaPlanner (camel-optaplanner)
+     * Solve planning problems with OptaPlanner.
+     * 
+     * Category: engine,planning
+     * Since: 2.13
+     * Maven coordinates: org.apache.camel:camel-optaplanner
+     * 
+     * @return the dsl builder
+     */
+    static OptaplannerComponentBuilder optaplanner() {
+        return new OptaplannerComponentBuilderImpl();
+    }
+
+    /**
+     * Builder for the OptaPlanner component.
+     */
+    interface OptaplannerComponentBuilder
+            extends
+                ComponentBuilder<OptaPlannerComponent> {
+        /**
+         * Allows for bridging the consumer to the Camel routing Error Handler,
+         * which mean any exceptions occurred while the consumer is trying to
+         * pickup incoming messages, or the likes, will now be processed as a
+         * message and handled by the routing Error Handler. By default the
+         * consumer will use the org.apache.camel.spi.ExceptionHandler to deal
+         * with exceptions, that will be logged at WARN or ERROR level and
+         * ignored.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: consumer
+         * 
+         * @param bridgeErrorHandler the value to set
+         * @return the dsl builder
+         */
+        default OptaplannerComponentBuilder bridgeErrorHandler(
+                boolean bridgeErrorHandler) {
+            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
+            return this;
+        }
+        /**
+         * 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 during
+         * starting and cause the route to fail being started. By deferring this
+         * startup to be lazy then the startup failure can be handled during
+         * routing messages via Camel's routing error handlers. Beware that when
+         * the first message is processed then creating and starting the
+         * producer may take a little time and prolong the total processing time
+         * of the processing.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: producer
+         * 
+         * @param lazyStartProducer the value to set
+         * @return the dsl builder
+         */
+        default OptaplannerComponentBuilder lazyStartProducer(
+                boolean lazyStartProducer) {
+            doSetProperty("lazyStartProducer", lazyStartProducer);
+            return this;
+        }
+        /**
+         * 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 type,
+         * which then gets configured on the component. This can be used for
+         * automatic configuring JDBC data sources, JMS connection factories,
+         * AWS Clients, etc.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: true
+         * Group: advanced
+         * 
+         * @param autowiredEnabled the value to set
+         * @return the dsl builder
+         */
+        default OptaplannerComponentBuilder autowiredEnabled(
+                boolean autowiredEnabled) {
+            doSetProperty("autowiredEnabled", autowiredEnabled);
+            return this;
+        }
+    }
+
+    class OptaplannerComponentBuilderImpl
+            extends
+                AbstractComponentBuilder<OptaPlannerComponent>
+            implements
+                OptaplannerComponentBuilder {
+        @Override
+        protected OptaPlannerComponent buildConcreteComponent() {
+            return new OptaPlannerComponent();
+        }
+        @Override
+        protected boolean setPropertyOnComponent(
+                Component component,
+                String name,
+                Object value) {
+            switch (name) {
+            case "bridgeErrorHandler": ((OptaPlannerComponent) component).setBridgeErrorHandler((boolean) value); return true;
+            case "lazyStartProducer": ((OptaPlannerComponent) component).setLazyStartProducer((boolean) value); return true;
+            case "autowiredEnabled": ((OptaPlannerComponent) component).setAutowiredEnabled((boolean) value); return true;
+            default: return false;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/dsl/camel-componentdsl/src/generated/resources/metadata.json b/dsl/camel-componentdsl/src/generated/resources/metadata.json
index fbc55a05887..fa22f2ab897 100644
--- a/dsl/camel-componentdsl/src/generated/resources/metadata.json
+++ b/dsl/camel-componentdsl/src/generated/resources/metadata.json
@@ -5164,6 +5164,28 @@
     "producerOnly": true,
     "lenientProperties": false
   },
+  "OptaplannerComponentBuilderFactory": {
+    "kind": "component",
+    "name": "optaplanner",
+    "title": "OptaPlanner",
+    "description": "Solve planning problems with OptaPlanner.",
+    "deprecated": false,
+    "firstVersion": "2.13.0",
+    "label": "engine,planning",
+    "javaType": "org.apache.camel.component.optaplanner.OptaPlannerComponent",
+    "supportLevel": "Stable",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-optaplanner",
+    "version": "4.0.0-SNAPSHOT",
+    "scheme": "optaplanner",
+    "extendsScheme": "",
+    "syntax": "optaplanner:problemName",
+    "async": false,
+    "api": false,
+    "consumerOnly": false,
+    "producerOnly": false,
+    "lenientProperties": false
+  },
   "PahoComponentBuilderFactory": {
     "kind": "component",
     "name": "paho",
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java
index e154c638553..43a47b7cf3b 100644
--- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java
@@ -245,6 +245,7 @@ public interface EndpointBuilderFactory
             org.apache.camel.builder.endpoint.dsl.OpenshiftBuildConfigsEndpointBuilderFactory.OpenshiftBuildConfigsBuilders,
             org.apache.camel.builder.endpoint.dsl.OpenshiftBuildsEndpointBuilderFactory.OpenshiftBuildsBuilders,
             org.apache.camel.builder.endpoint.dsl.OpenshiftDeploymentConfigsEndpointBuilderFactory.OpenshiftDeploymentConfigsBuilders,
+            org.apache.camel.builder.endpoint.dsl.OptaPlannerEndpointBuilderFactory.OptaPlannerBuilders,
             org.apache.camel.builder.endpoint.dsl.PahoEndpointBuilderFactory.PahoBuilders,
             org.apache.camel.builder.endpoint.dsl.PahoMqtt5EndpointBuilderFactory.PahoMqtt5Builders,
             org.apache.camel.builder.endpoint.dsl.PdfEndpointBuilderFactory.PdfBuilders,
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilders.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilders.java
index 34215632160..14225958e2d 100644
--- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilders.java
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilders.java
@@ -242,6 +242,7 @@ public interface EndpointBuilders
             org.apache.camel.builder.endpoint.dsl.OpenshiftBuildConfigsEndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.OpenshiftBuildsEndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.OpenshiftDeploymentConfigsEndpointBuilderFactory,
+            org.apache.camel.builder.endpoint.dsl.OptaPlannerEndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.PahoEndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.PahoMqtt5EndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.PdfEndpointBuilderFactory,
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
index e8d0401a87a..079270d8f31 100644
--- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
@@ -10840,6 +10840,49 @@ public class StaticEndpointBuilders {
             String path) {
         return org.apache.camel.builder.endpoint.dsl.SwiftEndpointBuilderFactory.endpointBuilder(componentName, path);
     }
+    /**
+     * OptaPlanner (camel-optaplanner)
+     * Solve planning problems with OptaPlanner.
+     * 
+     * Category: engine,planning
+     * Since: 2.13
+     * Maven coordinates: org.apache.camel:camel-optaplanner
+     * 
+     * Syntax: <code>optaplanner:problemName</code>
+     * 
+     * Path parameter: problemName (required)
+     * Problem name
+     * 
+     * @param path problemName
+     * @return the dsl builder
+     */
+    public static org.apache.camel.builder.endpoint.dsl.OptaPlannerEndpointBuilderFactory.OptaPlannerEndpointBuilder optaplanner(
+            String path) {
+        return org.apache.camel.builder.endpoint.dsl.OptaPlannerEndpointBuilderFactory.endpointBuilder("optaplanner", path);
+    }
+    /**
+     * OptaPlanner (camel-optaplanner)
+     * Solve planning problems with OptaPlanner.
+     * 
+     * Category: engine,planning
+     * Since: 2.13
+     * Maven coordinates: org.apache.camel:camel-optaplanner
+     * 
+     * Syntax: <code>optaplanner:problemName</code>
+     * 
+     * Path parameter: problemName (required)
+     * Problem name
+     * 
+     * @param componentName to use a custom component name for the endpoint
+     * instead of the default name
+     * @param path problemName
+     * @return the dsl builder
+     */
+    public static org.apache.camel.builder.endpoint.dsl.OptaPlannerEndpointBuilderFactory.OptaPlannerEndpointBuilder optaplanner(
+            String componentName,
+            String path) {
+        return org.apache.camel.builder.endpoint.dsl.OptaPlannerEndpointBuilderFactory.endpointBuilder(componentName, path);
+    }
     /**
      * Paho (camel-paho)
      * Communicate with MQTT message brokers using Eclipse Paho MQTT Client.
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OptaPlannerEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OptaPlannerEndpointBuilderFactory.java
new file mode 100644
index 00000000000..11ec2c798e4
--- /dev/null
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OptaPlannerEndpointBuilderFactory.java
@@ -0,0 +1,758 @@
+/*
+ * 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.builder.endpoint.dsl;
+
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.function.*;
+import java.util.stream.*;
+import javax.annotation.processing.Generated;
+import org.apache.camel.builder.EndpointConsumerBuilder;
+import org.apache.camel.builder.EndpointProducerBuilder;
+import org.apache.camel.builder.endpoint.AbstractEndpointBuilder;
+
+/**
+ * Solve planning problems with OptaPlanner.
+ * 
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
+public interface OptaPlannerEndpointBuilderFactory {
+
+
+    /**
+     * Builder for endpoint consumers for the OptaPlanner component.
+     */
+    public interface OptaPlannerEndpointConsumerBuilder
+            extends
+                EndpointConsumerBuilder {
+        default AdvancedOptaPlannerEndpointConsumerBuilder advanced() {
+            return (AdvancedOptaPlannerEndpointConsumerBuilder) this;
+        }
+        /**
+         * In case of using SolverManager : the problem id.
+         * 
+         * The option is a: &lt;code&gt;java.lang.Long&lt;/code&gt; type.
+         * 
+         * Default: 1L
+         * Group: common
+         * 
+         * @param problemId the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointConsumerBuilder problemId(Long problemId) {
+            doSetProperty("problemId", problemId);
+            return this;
+        }
+        /**
+         * In case of using SolverManager : the problem id.
+         * 
+         * The option will be converted to a
+         * &lt;code&gt;java.lang.Long&lt;/code&gt; type.
+         * 
+         * Default: 1L
+         * Group: common
+         * 
+         * @param problemId the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointConsumerBuilder problemId(String problemId) {
+            doSetProperty("problemId", problemId);
+            return this;
+        }
+        /**
+         * Specifies the solverId to user for the solver instance key.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Default: DEFAULT_SOLVER
+         * Group: common
+         * 
+         * @param solverId the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointConsumerBuilder solverId(String solverId) {
+            doSetProperty("solverId", solverId);
+            return this;
+        }
+        /**
+         * If SolverManager is absent from the header
+         * {OptaPlannerConstants.SOLVER_MANAGER} : A SolverManager will be
+         * created using this Optaplanner config file.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: configFile
+         * 
+         * @param configFile the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointConsumerBuilder configFile(String configFile) {
+            doSetProperty("configFile", configFile);
+            return this;
+        }
+        /**
+         * SolverManager.
+         * 
+         * The option is a:
+         * &lt;code&gt;org.optaplanner.core.api.solver.SolverManager&lt;/code&gt; type.
+         * 
+         * Group: solverManager
+         * 
+         * @param solverManager the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointConsumerBuilder solverManager(
+                org.optaplanner.core.api.solver.SolverManager solverManager) {
+            doSetProperty("solverManager", solverManager);
+            return this;
+        }
+        /**
+         * SolverManager.
+         * 
+         * The option will be converted to a
+         * &lt;code&gt;org.optaplanner.core.api.solver.SolverManager&lt;/code&gt; type.
+         * 
+         * Group: solverManager
+         * 
+         * @param solverManager the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointConsumerBuilder solverManager(
+                String solverManager) {
+            doSetProperty("solverManager", solverManager);
+            return this;
+        }
+    }
+
+    /**
+     * Advanced builder for endpoint consumers for the OptaPlanner component.
+     */
+    public interface AdvancedOptaPlannerEndpointConsumerBuilder
+            extends
+                EndpointConsumerBuilder {
+        default OptaPlannerEndpointConsumerBuilder basic() {
+            return (OptaPlannerEndpointConsumerBuilder) this;
+        }
+        /**
+         * Allows for bridging the consumer to the Camel routing Error Handler,
+         * which mean any exceptions occurred while the consumer is trying to
+         * pickup incoming messages, or the likes, will now be processed as a
+         * message and handled by the routing Error Handler. By default the
+         * consumer will use the org.apache.camel.spi.ExceptionHandler to deal
+         * with exceptions, that will be logged at WARN or ERROR level and
+         * ignored.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: consumer (advanced)
+         * 
+         * @param bridgeErrorHandler the value to set
+         * @return the dsl builder
+         */
+        default AdvancedOptaPlannerEndpointConsumerBuilder bridgeErrorHandler(
+                boolean bridgeErrorHandler) {
+            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
+            return this;
+        }
+        /**
+         * Allows for bridging the consumer to the Camel routing Error Handler,
+         * which mean any exceptions occurred while the consumer is trying to
+         * pickup incoming messages, or the likes, will now be processed as a
+         * message and handled by the routing Error Handler. By default the
+         * consumer will use the org.apache.camel.spi.ExceptionHandler to deal
+         * with exceptions, that will be logged at WARN or ERROR level and
+         * ignored.
+         * 
+         * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
+         * type.
+         * 
+         * Default: false
+         * Group: consumer (advanced)
+         * 
+         * @param bridgeErrorHandler the value to set
+         * @return the dsl builder
+         */
+        default AdvancedOptaPlannerEndpointConsumerBuilder bridgeErrorHandler(
+                String bridgeErrorHandler) {
+            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
+            return this;
+        }
+        /**
+         * To let the consumer use a custom ExceptionHandler. Notice if the
+         * option bridgeErrorHandler is enabled then this option is not in use.
+         * By default the consumer will deal with exceptions, that will be
+         * logged at WARN or ERROR level and ignored.
+         * 
+         * The option is a:
+         * &lt;code&gt;org.apache.camel.spi.ExceptionHandler&lt;/code&gt; type.
+         * 
+         * Group: consumer (advanced)
+         * 
+         * @param exceptionHandler the value to set
+         * @return the dsl builder
+         */
+        default AdvancedOptaPlannerEndpointConsumerBuilder exceptionHandler(
+                org.apache.camel.spi.ExceptionHandler exceptionHandler) {
+            doSetProperty("exceptionHandler", exceptionHandler);
+            return this;
+        }
+        /**
+         * To let the consumer use a custom ExceptionHandler. Notice if the
+         * option bridgeErrorHandler is enabled then this option is not in use.
+         * By default the consumer will deal with exceptions, that will be
+         * logged at WARN or ERROR level and ignored.
+         * 
+         * The option will be converted to a
+         * &lt;code&gt;org.apache.camel.spi.ExceptionHandler&lt;/code&gt; type.
+         * 
+         * Group: consumer (advanced)
+         * 
+         * @param exceptionHandler the value to set
+         * @return the dsl builder
+         */
+        default AdvancedOptaPlannerEndpointConsumerBuilder exceptionHandler(
+                String exceptionHandler) {
+            doSetProperty("exceptionHandler", exceptionHandler);
+            return this;
+        }
+        /**
+         * Sets the exchange pattern when the consumer creates an exchange.
+         * 
+         * The option is a:
+         * &lt;code&gt;org.apache.camel.ExchangePattern&lt;/code&gt; type.
+         * 
+         * Group: consumer (advanced)
+         * 
+         * @param exchangePattern the value to set
+         * @return the dsl builder
+         */
+        default AdvancedOptaPlannerEndpointConsumerBuilder exchangePattern(
+                org.apache.camel.ExchangePattern exchangePattern) {
+            doSetProperty("exchangePattern", exchangePattern);
+            return this;
+        }
+        /**
+         * Sets the exchange pattern when the consumer creates an exchange.
+         * 
+         * The option will be converted to a
+         * &lt;code&gt;org.apache.camel.ExchangePattern&lt;/code&gt; type.
+         * 
+         * Group: consumer (advanced)
+         * 
+         * @param exchangePattern the value to set
+         * @return the dsl builder
+         */
+        default AdvancedOptaPlannerEndpointConsumerBuilder exchangePattern(
+                String exchangePattern) {
+            doSetProperty("exchangePattern", exchangePattern);
+            return this;
+        }
+    }
+
+    /**
+     * Builder for endpoint producers for the OptaPlanner component.
+     */
+    public interface OptaPlannerEndpointProducerBuilder
+            extends
+                EndpointProducerBuilder {
+        default AdvancedOptaPlannerEndpointProducerBuilder advanced() {
+            return (AdvancedOptaPlannerEndpointProducerBuilder) this;
+        }
+        /**
+         * In case of using SolverManager : the problem id.
+         * 
+         * The option is a: &lt;code&gt;java.lang.Long&lt;/code&gt; type.
+         * 
+         * Default: 1L
+         * Group: common
+         * 
+         * @param problemId the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointProducerBuilder problemId(Long problemId) {
+            doSetProperty("problemId", problemId);
+            return this;
+        }
+        /**
+         * In case of using SolverManager : the problem id.
+         * 
+         * The option will be converted to a
+         * &lt;code&gt;java.lang.Long&lt;/code&gt; type.
+         * 
+         * Default: 1L
+         * Group: common
+         * 
+         * @param problemId the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointProducerBuilder problemId(String problemId) {
+            doSetProperty("problemId", problemId);
+            return this;
+        }
+        /**
+         * Specifies the solverId to user for the solver instance key.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Default: DEFAULT_SOLVER
+         * Group: common
+         * 
+         * @param solverId the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointProducerBuilder solverId(String solverId) {
+            doSetProperty("solverId", solverId);
+            return this;
+        }
+        /**
+         * Specifies to perform operations in async mode.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: producer
+         * 
+         * @param async the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointProducerBuilder async(boolean async) {
+            doSetProperty("async", async);
+            return this;
+        }
+        /**
+         * Specifies to perform operations in async mode.
+         * 
+         * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
+         * type.
+         * 
+         * Default: false
+         * Group: producer
+         * 
+         * @param async the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointProducerBuilder async(String async) {
+            doSetProperty("async", async);
+            return this;
+        }
+        /**
+         * Specifies the thread pool size to use when async is true.
+         * 
+         * The option is a: &lt;code&gt;int&lt;/code&gt; type.
+         * 
+         * Default: 10
+         * Group: producer
+         * 
+         * @param threadPoolSize the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointProducerBuilder threadPoolSize(
+                int threadPoolSize) {
+            doSetProperty("threadPoolSize", threadPoolSize);
+            return this;
+        }
+        /**
+         * Specifies the thread pool size to use when async is true.
+         * 
+         * The option will be converted to a &lt;code&gt;int&lt;/code&gt; type.
+         * 
+         * Default: 10
+         * Group: producer
+         * 
+         * @param threadPoolSize the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointProducerBuilder threadPoolSize(
+                String threadPoolSize) {
+            doSetProperty("threadPoolSize", threadPoolSize);
+            return this;
+        }
+        /**
+         * If SolverManager is absent from the header
+         * {OptaPlannerConstants.SOLVER_MANAGER} : A SolverManager will be
+         * created using this Optaplanner config file.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: configFile
+         * 
+         * @param configFile the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointProducerBuilder configFile(String configFile) {
+            doSetProperty("configFile", configFile);
+            return this;
+        }
+        /**
+         * SolverManager.
+         * 
+         * The option is a:
+         * &lt;code&gt;org.optaplanner.core.api.solver.SolverManager&lt;/code&gt; type.
+         * 
+         * Group: solverManager
+         * 
+         * @param solverManager the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointProducerBuilder solverManager(
+                org.optaplanner.core.api.solver.SolverManager solverManager) {
+            doSetProperty("solverManager", solverManager);
+            return this;
+        }
+        /**
+         * SolverManager.
+         * 
+         * The option will be converted to a
+         * &lt;code&gt;org.optaplanner.core.api.solver.SolverManager&lt;/code&gt; type.
+         * 
+         * Group: solverManager
+         * 
+         * @param solverManager the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointProducerBuilder solverManager(
+                String solverManager) {
+            doSetProperty("solverManager", solverManager);
+            return this;
+        }
+    }
+
+    /**
+     * Advanced builder for endpoint producers for the OptaPlanner component.
+     */
+    public interface AdvancedOptaPlannerEndpointProducerBuilder
+            extends
+                EndpointProducerBuilder {
+        default OptaPlannerEndpointProducerBuilder basic() {
+            return (OptaPlannerEndpointProducerBuilder) this;
+        }
+        /**
+         * 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 during
+         * starting and cause the route to fail being started. By deferring this
+         * startup to be lazy then the startup failure can be handled during
+         * routing messages via Camel's routing error handlers. Beware that when
+         * the first message is processed then creating and starting the
+         * producer may take a little time and prolong the total processing time
+         * of the processing.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: producer (advanced)
+         * 
+         * @param lazyStartProducer the value to set
+         * @return the dsl builder
+         */
+        default AdvancedOptaPlannerEndpointProducerBuilder lazyStartProducer(
+                boolean lazyStartProducer) {
+            doSetProperty("lazyStartProducer", lazyStartProducer);
+            return this;
+        }
+        /**
+         * 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 during
+         * starting and cause the route to fail being started. By deferring this
+         * startup to be lazy then the startup failure can be handled during
+         * routing messages via Camel's routing error handlers. Beware that when
+         * the first message is processed then creating and starting the
+         * producer may take a little time and prolong the total processing time
+         * of the processing.
+         * 
+         * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
+         * type.
+         * 
+         * Default: false
+         * Group: producer (advanced)
+         * 
+         * @param lazyStartProducer the value to set
+         * @return the dsl builder
+         */
+        default AdvancedOptaPlannerEndpointProducerBuilder lazyStartProducer(
+                String lazyStartProducer) {
+            doSetProperty("lazyStartProducer", lazyStartProducer);
+            return this;
+        }
+    }
+
+    /**
+     * Builder for endpoint for the OptaPlanner component.
+     */
+    public interface OptaPlannerEndpointBuilder
+            extends
+                OptaPlannerEndpointConsumerBuilder,
+                OptaPlannerEndpointProducerBuilder {
+        default AdvancedOptaPlannerEndpointBuilder advanced() {
+            return (AdvancedOptaPlannerEndpointBuilder) this;
+        }
+        /**
+         * In case of using SolverManager : the problem id.
+         * 
+         * The option is a: &lt;code&gt;java.lang.Long&lt;/code&gt; type.
+         * 
+         * Default: 1L
+         * Group: common
+         * 
+         * @param problemId the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointBuilder problemId(Long problemId) {
+            doSetProperty("problemId", problemId);
+            return this;
+        }
+        /**
+         * In case of using SolverManager : the problem id.
+         * 
+         * The option will be converted to a
+         * &lt;code&gt;java.lang.Long&lt;/code&gt; type.
+         * 
+         * Default: 1L
+         * Group: common
+         * 
+         * @param problemId the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointBuilder problemId(String problemId) {
+            doSetProperty("problemId", problemId);
+            return this;
+        }
+        /**
+         * Specifies the solverId to user for the solver instance key.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Default: DEFAULT_SOLVER
+         * Group: common
+         * 
+         * @param solverId the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointBuilder solverId(String solverId) {
+            doSetProperty("solverId", solverId);
+            return this;
+        }
+        /**
+         * If SolverManager is absent from the header
+         * {OptaPlannerConstants.SOLVER_MANAGER} : A SolverManager will be
+         * created using this Optaplanner config file.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: configFile
+         * 
+         * @param configFile the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointBuilder configFile(String configFile) {
+            doSetProperty("configFile", configFile);
+            return this;
+        }
+        /**
+         * SolverManager.
+         * 
+         * The option is a:
+         * &lt;code&gt;org.optaplanner.core.api.solver.SolverManager&lt;/code&gt; type.
+         * 
+         * Group: solverManager
+         * 
+         * @param solverManager the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointBuilder solverManager(
+                org.optaplanner.core.api.solver.SolverManager solverManager) {
+            doSetProperty("solverManager", solverManager);
+            return this;
+        }
+        /**
+         * SolverManager.
+         * 
+         * The option will be converted to a
+         * &lt;code&gt;org.optaplanner.core.api.solver.SolverManager&lt;/code&gt; type.
+         * 
+         * Group: solverManager
+         * 
+         * @param solverManager the value to set
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointBuilder solverManager(String solverManager) {
+            doSetProperty("solverManager", solverManager);
+            return this;
+        }
+    }
+
+    /**
+     * Advanced builder for endpoint for the OptaPlanner component.
+     */
+    public interface AdvancedOptaPlannerEndpointBuilder
+            extends
+                AdvancedOptaPlannerEndpointConsumerBuilder,
+                AdvancedOptaPlannerEndpointProducerBuilder {
+        default OptaPlannerEndpointBuilder basic() {
+            return (OptaPlannerEndpointBuilder) this;
+        }
+    }
+
+    public interface OptaPlannerBuilders {
+        /**
+         * OptaPlanner (camel-optaplanner)
+         * Solve planning problems with OptaPlanner.
+         * 
+         * Category: engine,planning
+         * Since: 2.13
+         * Maven coordinates: org.apache.camel:camel-optaplanner
+         * 
+         * @return the dsl builder for the headers' name.
+         */
+        default OptaPlannerHeaderNameBuilder optaplanner() {
+            return OptaPlannerHeaderNameBuilder.INSTANCE;
+        }
+        /**
+         * OptaPlanner (camel-optaplanner)
+         * Solve planning problems with OptaPlanner.
+         * 
+         * Category: engine,planning
+         * Since: 2.13
+         * Maven coordinates: org.apache.camel:camel-optaplanner
+         * 
+         * Syntax: <code>optaplanner:problemName</code>
+         * 
+         * Path parameter: problemName (required)
+         * Problem name
+         * 
+         * @param path problemName
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointBuilder optaplanner(String path) {
+            return OptaPlannerEndpointBuilderFactory.endpointBuilder("optaplanner", path);
+        }
+        /**
+         * OptaPlanner (camel-optaplanner)
+         * Solve planning problems with OptaPlanner.
+         * 
+         * Category: engine,planning
+         * Since: 2.13
+         * Maven coordinates: org.apache.camel:camel-optaplanner
+         * 
+         * Syntax: <code>optaplanner:problemName</code>
+         * 
+         * Path parameter: problemName (required)
+         * Problem name
+         * 
+         * @param componentName to use a custom component name for the endpoint
+         * instead of the default name
+         * @param path problemName
+         * @return the dsl builder
+         */
+        default OptaPlannerEndpointBuilder optaplanner(
+                String componentName,
+                String path) {
+            return OptaPlannerEndpointBuilderFactory.endpointBuilder(componentName, path);
+        }
+    }
+
+    /**
+     * The builder of headers' name for the OptaPlanner component.
+     */
+    public static class OptaPlannerHeaderNameBuilder {
+        /**
+         * The internal instance of the builder used to access to all the
+         * methods representing the name of headers.
+         */
+        private static final OptaPlannerHeaderNameBuilder INSTANCE = new OptaPlannerHeaderNameBuilder();
+
+        /**
+         * Specifies the solverId to use.
+         * 
+         * The option is a: {@code String} type.
+         * 
+         * Group: producer
+         * 
+         * @return the name of the header {@code OptaPlannerSolverId}.
+         */
+        public String optaPlannerSolverId() {
+            return "OptaPlannerSolverId";
+        }
+
+        /**
+         * Specify whether to use another thread for submitting Solution
+         * instances rather than blocking the current thread.
+         * 
+         * The option is a: {@code Boolean} type.
+         * 
+         * Group: producer
+         * 
+         * @return the name of the header {@code OptaPlannerIsAsync}.
+         */
+        public String optaPlannerIsAsync() {
+            return "OptaPlannerIsAsync";
+        }
+
+        /**
+         * The best planning solution.
+         * 
+         * The option is a: {@code Object} type.
+         * 
+         * Group: consumer
+         * 
+         * @return the name of the header {@code OptaPlannerBestSolution}.
+         */
+        public String optaPlannerBestSolution() {
+            return "OptaPlannerBestSolution";
+        }
+
+        /**
+         * Is solving.
+         * 
+         * The option is a: {@code Boolean} type.
+         * 
+         * Group: producer
+         * 
+         * @return the name of the header {@code OptaPlannerIsSolving}.
+         */
+        public String optaPlannerIsSolving() {
+            return "OptaPlannerIsSolving";
+        }
+
+        /**
+         * The Solver Manager.
+         * 
+         * The option is a: {@code
+         * org.optaplanner.core.api.solver.SolverManager} type.
+         * 
+         * Group: producer
+         * 
+         * @return the name of the header {@code OptaPlannerSolverManager}.
+         */
+        public String optaPlannerSolverManager() {
+            return "OptaPlannerSolverManager";
+        }
+    }
+    static OptaPlannerEndpointBuilder endpointBuilder(
+            String componentName,
+            String path) {
+        class OptaPlannerEndpointBuilderImpl extends AbstractEndpointBuilder implements OptaPlannerEndpointBuilder, AdvancedOptaPlannerEndpointBuilder {
+            public OptaPlannerEndpointBuilderImpl(String path) {
+                super(componentName, path);
+            }
+        }
+        return new OptaPlannerEndpointBuilderImpl(path);
+    }
+}
\ No newline at end of file
diff --git a/dsl/camel-kamelet-main/src/generated/resources/camel-component-known-dependencies.properties b/dsl/camel-kamelet-main/src/generated/resources/camel-component-known-dependencies.properties
index e5a4bc54baf..c5bd8096c24 100644
--- a/dsl/camel-kamelet-main/src/generated/resources/camel-component-known-dependencies.properties
+++ b/dsl/camel-kamelet-main/src/generated/resources/camel-component-known-dependencies.properties
@@ -242,6 +242,7 @@ org.apache.camel.component.openstack.keystone.KeystoneComponent=camel:openstack
 org.apache.camel.component.openstack.neutron.NeutronComponent=camel:openstack
 org.apache.camel.component.openstack.nova.NovaComponent=camel:openstack
 org.apache.camel.component.openstack.swift.SwiftComponent=camel:openstack
+org.apache.camel.component.optaplanner.OptaPlannerComponent=camel:optaplanner
 org.apache.camel.component.paho.PahoComponent=camel:paho
 org.apache.camel.component.paho.mqtt5.PahoMqtt5Component=camel:paho-mqtt5
 org.apache.camel.component.pdf.PdfComponent=camel:pdf
diff --git a/parent/pom.xml b/parent/pom.xml
index 95b788ca8e0..e72dae2a78d 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -398,7 +398,7 @@
         <openstack4j-version>3.10</openstack4j-version>
         <opentelemetry-version>1.23.1</opentelemetry-version>
         <opentelemetry-alpha-version>${opentelemetry-version}-alpha</opentelemetry-alpha-version>
-        <optaplanner-version>8.32.0.Final</optaplanner-version>
+        <optaplanner-version>9.37.0.Final</optaplanner-version>
         <os-maven-plugin-version>1.7.0</os-maven-plugin-version>
         <paho-version>1.2.5</paho-version>
         <partial-build-plugin-version>2.7</partial-build-plugin-version>
@@ -1888,6 +1888,11 @@
                 <artifactId>camel-opentelemetry</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.camel</groupId>
+                <artifactId>camel-optaplanner</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.apache.camel</groupId>
                 <artifactId>camel-paho</artifactId>