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 2020/09/19 05:44:55 UTC

[camel] branch master updated: CAMEL-15531 - adding SolverManager (#4240)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 5cda624  CAMEL-15531 - adding SolverManager (#4240)
5cda624 is described below

commit 5cda624e8a116f43e8618209e7287019ce114c98
Author: Zineb BENDHIBA <be...@gmail.com>
AuthorDate: Sat Sep 19 07:44:38 2020 +0200

    CAMEL-15531 - adding SolverManager (#4240)
---
 .../camel/catalog/components/optaplanner.json      |   4 +-
 .../camel/catalog/docs/optaplanner-component.adoc  |   6 +-
 .../optaplanner/OptaPlannerEndpointConfigurer.java |  10 ++
 .../camel/component/optaplanner/optaplanner.json   |   4 +-
 .../src/main/docs/optaplanner-component.adoc       |   6 +-
 .../optaplanner/OptaPlannerConfiguration.java      |  34 ++++-
 .../optaplanner/OptaPlannerConstants.java          |   1 +
 .../component/optaplanner/OptaPlannerConsumer.java |  59 +++++--
 .../component/optaplanner/OptaPlannerEndpoint.java |  31 +++-
 .../component/optaplanner/OptaPlannerProducer.java | 100 +++++++++++-
 ...Constants.java => OptaplannerEventSupport.java} |  29 ++--
 ...onstants.java => OptaplannerSolutionEvent.java} |  24 +--
 ....java => OptaplannerSolutionEventListener.java} |  14 +-
 .../OptaplannerSolverManagerAsyncTest.java         |  80 ++++++++++
 .../optaplanner/OptaplannerSolverManagerTest.java  |  67 ++++++++
 .../builder/endpoint/StaticEndpointBuilders.java   |  12 +-
 .../dsl/OptaPlannerEndpointBuilderFactory.java     | 170 ++++++++++++++++++++-
 .../modules/ROOT/pages/optaplanner-component.adoc  |   6 +-
 18 files changed, 591 insertions(+), 66 deletions(-)

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
index c1b0c21..faf03fb 100644
--- 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
@@ -28,8 +28,10 @@
     "basicPropertyBinding": { "kind": "property", "displayName": "Basic Property Binding", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": true, "secret": false, "defaultValue": false, "description": "Whether the component should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities" }
   },
   "properties": {
-    "configFile": { "kind": "path", "displayName": "Config File", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "secret": false, "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "Specifies the location to the solver file" },
+    "configFile": { "kind": "path", "displayName": "Config File", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "secret": false, "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "Specifies the location to the solver file. If useSolverManager=FALSE, Camel uses this file and create the Solver. If useS [...]
+    "problemId": { "kind": "parameter", "displayName": "Problem Id", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": 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, "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" },
+    "useSolverManager": { "kind": "parameter", "displayName": "Use Solver Manager", "group": "common", "label": "common", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": "false", "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "use SolverManager instead of XML file config. Use this mode on Quarkus app." },
     "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": 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 message and handled b [...]
     "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, "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 consumer will deal with [...]
     "exchangePattern": { "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", "InOptionalOut" ], "deprecated": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/optaplanner-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/optaplanner-component.adoc
index a9037d3..8b438ea 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/optaplanner-component.adoc
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/optaplanner-component.adoc
@@ -78,17 +78,19 @@ with the following path and query parameters:
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
-| *configFile* | *Required* Specifies the location to the solver file |  | String
+| *configFile* | *Required* Specifies the location to the solver file. If useSolverManager=FALSE, Camel uses this file and create the Solver. If useSolverManager=TRUE and SolverManager is set in the header {OptaPlannerConstants.SOLVER_MANAGER} : this file is ignored by Camel usage of SolverManager. SolverManager can be injected by DI in Quarkus or Spring. |  | String
 |===
 
 
-=== Query Parameters (9 parameters):
+=== Query Parameters (11 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
+| *problemId* (common) | In case of using SolverManager : the problem id | 1L | Long
 | *solverId* (common) | Specifies the solverId to user for the solver instance key | DEFAULT_SOLVER | String
+| *useSolverManager* (common) | use SolverManager instead of XML file config. Use this mode on Quarkus app. | false | boolean
 | *bridgeErrorHandler* (consumer) | 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. | false | boolean
 | *exceptionHandler* (consumer) | 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. |  | ExceptionHandler
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. There are 3 enums and the value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern
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
index 8474a1f..434798c 100644
--- 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
@@ -30,11 +30,15 @@ public class OptaPlannerEndpointConfigurer extends PropertyConfigurerSupport imp
         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 "synchronous": target.setSynchronous(property(camelContext, boolean.class, value)); return true;
         case "threadpoolsize":
         case "threadPoolSize": target.getConfiguration().setThreadPoolSize(property(camelContext, int.class, value)); return true;
+        case "usesolvermanager":
+        case "useSolverManager": target.getConfiguration().setUseSolverManager(property(camelContext, boolean.class, value)); return true;
         default: return false;
         }
     }
@@ -48,9 +52,11 @@ public class OptaPlannerEndpointConfigurer extends PropertyConfigurerSupport imp
         answer.put("exceptionHandler", org.apache.camel.spi.ExceptionHandler.class);
         answer.put("exchangePattern", org.apache.camel.ExchangePattern.class);
         answer.put("lazyStartProducer", boolean.class);
+        answer.put("problemId", java.lang.Long.class);
         answer.put("solverId", java.lang.String.class);
         answer.put("synchronous", boolean.class);
         answer.put("threadPoolSize", int.class);
+        answer.put("useSolverManager", boolean.class);
         return answer;
     }
 
@@ -69,11 +75,15 @@ public class OptaPlannerEndpointConfigurer extends PropertyConfigurerSupport imp
         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 "synchronous": return target.isSynchronous();
         case "threadpoolsize":
         case "threadPoolSize": return target.getConfiguration().getThreadPoolSize();
+        case "usesolvermanager":
+        case "useSolverManager": return target.getConfiguration().isUseSolverManager();
         default: return null;
         }
     }
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
index c1b0c21..faf03fb 100644
--- 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
@@ -28,8 +28,10 @@
     "basicPropertyBinding": { "kind": "property", "displayName": "Basic Property Binding", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": true, "secret": false, "defaultValue": false, "description": "Whether the component should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities" }
   },
   "properties": {
-    "configFile": { "kind": "path", "displayName": "Config File", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "secret": false, "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "Specifies the location to the solver file" },
+    "configFile": { "kind": "path", "displayName": "Config File", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "secret": false, "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "Specifies the location to the solver file. If useSolverManager=FALSE, Camel uses this file and create the Solver. If useS [...]
+    "problemId": { "kind": "parameter", "displayName": "Problem Id", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": 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, "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" },
+    "useSolverManager": { "kind": "parameter", "displayName": "Use Solver Manager", "group": "common", "label": "common", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": "false", "configurationClass": "org.apache.camel.component.optaplanner.OptaPlannerConfiguration", "configurationField": "configuration", "description": "use SolverManager instead of XML file config. Use this mode on Quarkus app." },
     "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": 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 message and handled b [...]
     "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, "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 consumer will deal with [...]
     "exchangePattern": { "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", "InOptionalOut" ], "deprecated": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
diff --git a/components/camel-optaplanner/src/main/docs/optaplanner-component.adoc b/components/camel-optaplanner/src/main/docs/optaplanner-component.adoc
index a9037d3..8b438ea 100644
--- a/components/camel-optaplanner/src/main/docs/optaplanner-component.adoc
+++ b/components/camel-optaplanner/src/main/docs/optaplanner-component.adoc
@@ -78,17 +78,19 @@ with the following path and query parameters:
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
-| *configFile* | *Required* Specifies the location to the solver file |  | String
+| *configFile* | *Required* Specifies the location to the solver file. If useSolverManager=FALSE, Camel uses this file and create the Solver. If useSolverManager=TRUE and SolverManager is set in the header {OptaPlannerConstants.SOLVER_MANAGER} : this file is ignored by Camel usage of SolverManager. SolverManager can be injected by DI in Quarkus or Spring. |  | String
 |===
 
 
-=== Query Parameters (9 parameters):
+=== Query Parameters (11 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
+| *problemId* (common) | In case of using SolverManager : the problem id | 1L | Long
 | *solverId* (common) | Specifies the solverId to user for the solver instance key | DEFAULT_SOLVER | String
+| *useSolverManager* (common) | use SolverManager instead of XML file config. Use this mode on Quarkus app. | false | boolean
 | *bridgeErrorHandler* (consumer) | 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. | false | boolean
 | *exceptionHandler* (consumer) | 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. |  | ExceptionHandler
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. There are 3 enums and the value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern
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
index 1f95ef2..47026ef 100644
--- 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
@@ -33,13 +33,19 @@ public class OptaPlannerConfiguration {
     private int threadPoolSize = 10;
     @UriParam(label = "producer")
     private boolean async;
+    @UriParam(label = "common", defaultValue = "1L")
+    private Long problemId = 1L;
+    @UriParam(label = "common", defaultValue = "false")
+    private boolean useSolverManager;
 
     public String getConfigFile() {
         return configFile;
     }
 
     /**
-     * Specifies the location to the solver file
+     * Specifies the location to the solver file. If useSolverManager=FALSE, Camel uses this file and create the Solver.
+     * If useSolverManager=TRUE and SolverManager is set in the header {OptaPlannerConstants.SOLVER_MANAGER} : this file
+     * is ignored by Camel + usage of SolverManager. SolverManager can be injected by DI in Quarkus or Spring.
      */
     public void setConfigFile(String configFile) {
         this.configFile = configFile;
@@ -77,4 +83,30 @@ public class OptaPlannerConfiguration {
     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 boolean isUseSolverManager() {
+        return useSolverManager;
+    }
+
+    /**
+     * use SolverManager instead of XML file config. Use this mode on Quarkus app.
+     *
+     * @param useSolverManager
+     */
+    public void setUseSolverManager(boolean useSolverManager) {
+        this.useSolverManager = useSolverManager;
+    }
 }
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
index 1768ca7..40ee6d4 100644
--- 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
@@ -25,5 +25,6 @@ public interface OptaPlannerConstants {
     String IS_SOLVING = "CamelOptaPlannerIsSolving";
     String IS_TERMINATE_EARLY = "CamelOptaPlannerIsTerminateEarly";
     String IS_EVERY_PROBLEM_FACT_CHANGE_PROCESSED = "CamelOptaPlannerIsEveryProblemFactChangeProcessed";
+    String SOLVER_MANAGER = "CamelOptaPlannerSolverManager";
     long IS_EVERY_PROBLEM_FACT_CHANGE_DELAY = 100;
 }
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
index 3a29a47..3ea6ccf 100644
--- 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
@@ -32,25 +32,45 @@ public class OptaPlannerConsumer extends DefaultConsumer {
     private static final transient Logger LOG = LoggerFactory.getLogger(OptaPlannerConsumer.class);
     private final OptaPlannerEndpoint endpoint;
     private final OptaPlannerConfiguration configuration;
-    private final SolverEventListener<Object> listener;
+    private SolverEventListener<Object> solverListener;
+    private OptaplannerSolutionEventListener solverJobListener;
 
     public OptaPlannerConsumer(OptaPlannerEndpoint endpoint, Processor processor, OptaPlannerConfiguration configuration) {
         super(endpoint, processor);
         this.endpoint = endpoint;
         this.configuration = configuration;
-        listener = new SolverEventListener<Object>() {
-            @Override
-            public void bestSolutionChanged(BestSolutionChangedEvent<Object> event) {
-                if (event.isEveryProblemFactChangeProcessed() && event.getNewBestScore().isSolutionInitialized()) {
-                    processEvent(event);
+        if (!configuration.isUseSolverManager()) {
+            solverListener = new SolverEventListener<Object>() {
+                @Override
+                public void bestSolutionChanged(BestSolutionChangedEvent<Object> event) {
+                    if (event.isEveryProblemFactChangeProcessed() && event.getNewBestScore().isSolutionInitialized()) {
+                        processEvent(event);
+                    }
                 }
-            }
-        };
+            };
+        } else {
+            solverJobListener = new OptaplannerSolutionEventListener() {
+                @Override
+                public void bestSolutionChanged(OptaplannerSolutionEvent event) {
+                    processSolverJobEvent(event);
+                }
+            };
+        }
     }
 
     public void processEvent(BestSolutionChangedEvent<Object> event) {
         Exchange exchange = getEndpoint().createExchange();
-        exchange.getOut().setHeader(OptaPlannerConstants.BEST_SOLUTION, event.getNewBestSolution());
+        exchange.getMessage().setHeader(OptaPlannerConstants.BEST_SOLUTION, event.getNewBestSolution());
+        try {
+            getProcessor().process(exchange);
+        } catch (Exception e) {
+            LOG.error("Error processing event ", e);
+        }
+    }
+
+    public void processSolverJobEvent(OptaplannerSolutionEvent event) {
+        Exchange exchange = getEndpoint().createExchange();
+        exchange.getMessage().setHeader(OptaPlannerConstants.BEST_SOLUTION, event.getBestSolution());
         try {
             getProcessor().process(exchange);
         } catch (Exception e) {
@@ -60,15 +80,28 @@ public class OptaPlannerConsumer extends DefaultConsumer {
 
     @Override
     protected void doStart() throws Exception {
-        Solver<Object> solver = endpoint.getOrCreateSolver(configuration.getSolverId());
-        solver.addEventListener(listener);
+        // usage of XML file and getting the solver created
+        if (!configuration.isUseSolverManager()) {
+            Solver<Object> solver = endpoint.getOrCreateSolver(configuration.getSolverId());
+            solver.addEventListener(solverListener);
+        } else {
+            final Long problemId = configuration.getProblemId();
+            endpoint.addSolutionEventListener(problemId, solverJobListener);
+        }
         super.doStart();
     }
 
     @Override
     protected void doStop() throws Exception {
-        Solver<Object> solver = endpoint.getOrCreateSolver(configuration.getSolverId());
-        solver.removeEventListener(listener);
+        // usage of XML file and getting the solver created
+        if (!configuration.isUseSolverManager()) {
+            Solver<Object> solver = endpoint.getOrCreateSolver(configuration.getSolverId());
+            solver.removeEventListener(solverListener);
+        } else {
+            // usage of problem Id created async with Optaplanner producer
+            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
index 64ca7d2..7f72aa7 100644
--- 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
@@ -17,7 +17,9 @@
 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;
@@ -37,6 +39,7 @@ import org.optaplanner.core.api.solver.SolverFactory;
              category = { Category.ENGINE, Category.PLANNING })
 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;
 
@@ -64,6 +67,8 @@ public class OptaPlannerEndpoint extends DefaultEndpoint {
     }
 
     protected Solver<Object> createSolver() {
+        ClassLoader classLoader = getCamelContext().getApplicationContextClassLoader();
+        solverFactory = SolverFactory.createFromXmlResource(configuration.getConfigFile(), classLoader);
         return solverFactory.buildSolver();
     }
 
@@ -88,9 +93,6 @@ public class OptaPlannerEndpoint extends DefaultEndpoint {
     @Override
     protected void doStart() throws Exception {
         super.doStart();
-
-        ClassLoader classLoader = getCamelContext().getApplicationContextClassLoader();
-        solverFactory = SolverFactory.createFromXmlResource(configuration.getConfigFile(), classLoader);
     }
 
     @Override
@@ -103,4 +105,27 @@ public class OptaPlannerEndpoint extends DefaultEndpoint {
         }
         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.size() == 0) {
+            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
index 305c3c0..1d39609 100644
--- 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
@@ -16,18 +16,22 @@
  */
 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.DefaultProducer;
+import org.apache.camel.support.DefaultAsyncProducer;
 import org.optaplanner.core.api.domain.solution.PlanningSolution;
 import org.optaplanner.core.api.domain.solution.Solution;
 import org.optaplanner.core.api.solver.Solver;
+import org.optaplanner.core.api.solver.SolverJob;
+import org.optaplanner.core.api.solver.SolverManager;
 import org.optaplanner.core.impl.solver.ProblemFactChange;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class OptaPlannerProducer extends DefaultProducer {
+public class OptaPlannerProducer extends DefaultAsyncProducer {
 
     private static final transient Logger LOGGER = LoggerFactory.getLogger(OptaPlannerProducer.class);
 
@@ -59,12 +63,37 @@ public class OptaPlannerProducer extends DefaultProducer {
         super.doStop();
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public synchronized void process(Exchange exchange) throws Exception {
-        final Object body = exchange.getIn().getMandatoryBody();
-        final String solverId = getSolverId(exchange);
+    public boolean process(Exchange exchange, AsyncCallback callback) {
+        try {
+            final Object body = exchange.getIn().getMandatoryBody();
+
+            // using Solver Manager :: Optaplanner creates the Solver under the hood
+            if (endpoint.getConfiguration().isUseSolverManager()) {
+                return processWithSolverManager(exchange, body, callback);
+            } else {
+                // using XML File ==> Camel creates the Solver itself and uses some deprecated methods
+                // upgrade this code to use SolverManager instead. Generate SolverManager from XML plus some new config params
+                // postponed for optaplanner 8.0.x release for 2 reasons :
+                // 1. ProblemFactChange support in SolverManager is work in progress (JIRA : https://issues.redhat.com/browse/PLANNER-2141)
+                // 2. Waiting for end of support of Solution in Optaplanner planned for version 8.0.0
+                processWithXmlFile(exchange, body);
+            }
+        } catch (Exception e) {
+            exchange.setException(e);
+        }
+        callback.done(true);
+        return true;
+    }
 
+    /**
+     *
+     * @param  exchange
+     * @param  body
+     * @throws Exception
+     */
+    private void processWithXmlFile(Exchange exchange, Object body) throws Exception {
+        final String solverId = getSolverId(exchange);
         /*
          * Keep for backward compatibility untill optaplanner version 8.0.0 not
          * released After that the code '|| body instanceof Solution' need to be
@@ -80,7 +109,7 @@ public class OptaPlannerProducer extends DefaultProducer {
                         try {
                             solver.solve(body);
                         } catch (Throwable e) {
-                            LOGGER.error("Asynchronously solving failed for solverId ({})", solverId, e);
+                            exchange.setException(new Exception("Asynchronously solving failed for solverId " + solverId, e));
                         }
                     }
                 });
@@ -113,6 +142,58 @@ public class OptaPlannerProducer extends DefaultProducer {
         }
     }
 
+    /**
+     * Using SolverManager
+     *
+     * @param  exchange
+     * @param  body
+     * @throws Exception
+     */
+    private boolean processWithSolverManager(Exchange exchange, Object body, AsyncCallback callback)
+            throws Exception {
+        final SolverManager solverManager = getSolverManager(exchange);
+
+        if (body.getClass().isAnnotationPresent(PlanningSolution.class)) {
+            LOGGER.debug("Asynchronously solving problem: [{}] with id [{}]", body);
+            Long problemId = endpoint.getConfiguration().getProblemId();
+            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
+                        populateResultWithSolverManager(exchange, solverJob);
+                    } catch (Throwable e) {
+                        exchange.setException(e);
+                        e.printStackTrace();
+                    } finally {
+                        callback.done(false);
+                    }
+                });
+                return false;
+            } else {
+                // no need for a consumer for sync call
+                SolverJob solverJob = solverManager.solve(problemId, body);
+                // wait for result
+                populateResultWithSolverManager(exchange, solverJob);
+            }
+        } else {
+            exchange.setException(new Exception("Unsuported type. Body must be of Type PlanningSolution"));
+        }
+        // synchronous or wrong type of body
+        callback.done(true);
+        return true;
+    }
+
+    private void populateResultWithSolverManager(Exchange exchange, SolverJob solverJob)
+            throws InterruptedException, ExecutionException {
+        exchange.getIn().setBody(solverJob.getFinalBestSolution());
+        exchange.getIn().setHeader(OptaPlannerConstants.IS_SOLVING, false);
+    }
+
     private void populateResult(Exchange exchange, Solver<Object> solver) {
         exchange.getIn().setBody(solver.getBestSolution());
         exchange.getIn().setHeader(OptaPlannerConstants.TIME_SPENT, solver.getTimeMillisSpent());
@@ -135,4 +216,9 @@ public class OptaPlannerProducer extends DefaultProducer {
         Boolean isAsync = exchange.getIn().getHeader(OptaPlannerConstants.IS_ASYNC, Boolean.class);
         return isAsync != null ? isAsync : configuration.isAsync();
     }
+
+    private SolverManager getSolverManager(Exchange exchange) {
+        return exchange.getIn().getHeader(OptaPlannerConstants.SOLVER_MANAGER, SolverManager.class);
+    }
+
 }
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/OptaplannerEventSupport.java
similarity index 53%
copy from components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConstants.java
copy to components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaplannerEventSupport.java
index 1768ca7..5181ae0 100644
--- 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/OptaplannerEventSupport.java
@@ -16,14 +16,23 @@
  */
 package org.apache.camel.component.optaplanner;
 
-public interface OptaPlannerConstants {
-    String DEFAULT_SOLVER_ID = "DEFAULT_SOLVER";
-    String SOLVER_ID = "CamelOptaPlannerSolverId";
-    String IS_ASYNC = "CamelOptaPlannerIsAsync";
-    String BEST_SOLUTION = "CamelOptaPlannerBestSolution";
-    String TIME_SPENT = "CamelOptaPlannerTimeSpent";
-    String IS_SOLVING = "CamelOptaPlannerIsSolving";
-    String IS_TERMINATE_EARLY = "CamelOptaPlannerIsTerminateEarly";
-    String IS_EVERY_PROBLEM_FACT_CHANGE_PROCESSED = "CamelOptaPlannerIsEveryProblemFactChangeProcessed";
-    long IS_EVERY_PROBLEM_FACT_CHANGE_DELAY = 100;
+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/OptaPlannerConstants.java b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaplannerSolutionEvent.java
similarity index 59%
copy from components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConstants.java
copy to components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaplannerSolutionEvent.java
index 1768ca7..9f86c8d 100644
--- 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/OptaplannerSolutionEvent.java
@@ -16,14 +16,18 @@
  */
 package org.apache.camel.component.optaplanner;
 
-public interface OptaPlannerConstants {
-    String DEFAULT_SOLVER_ID = "DEFAULT_SOLVER";
-    String SOLVER_ID = "CamelOptaPlannerSolverId";
-    String IS_ASYNC = "CamelOptaPlannerIsAsync";
-    String BEST_SOLUTION = "CamelOptaPlannerBestSolution";
-    String TIME_SPENT = "CamelOptaPlannerTimeSpent";
-    String IS_SOLVING = "CamelOptaPlannerIsSolving";
-    String IS_TERMINATE_EARLY = "CamelOptaPlannerIsTerminateEarly";
-    String IS_EVERY_PROBLEM_FACT_CHANGE_PROCESSED = "CamelOptaPlannerIsEveryProblemFactChangeProcessed";
-    long IS_EVERY_PROBLEM_FACT_CHANGE_DELAY = 100;
+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/OptaPlannerConstants.java b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaplannerSolutionEventListener.java
similarity index 59%
copy from components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConstants.java
copy to components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaplannerSolutionEventListener.java
index 1768ca7..5b93cde 100644
--- 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/OptaplannerSolutionEventListener.java
@@ -16,14 +16,8 @@
  */
 package org.apache.camel.component.optaplanner;
 
-public interface OptaPlannerConstants {
-    String DEFAULT_SOLVER_ID = "DEFAULT_SOLVER";
-    String SOLVER_ID = "CamelOptaPlannerSolverId";
-    String IS_ASYNC = "CamelOptaPlannerIsAsync";
-    String BEST_SOLUTION = "CamelOptaPlannerBestSolution";
-    String TIME_SPENT = "CamelOptaPlannerTimeSpent";
-    String IS_SOLVING = "CamelOptaPlannerIsSolving";
-    String IS_TERMINATE_EARLY = "CamelOptaPlannerIsTerminateEarly";
-    String IS_EVERY_PROBLEM_FACT_CHANGE_PROCESSED = "CamelOptaPlannerIsEveryProblemFactChangeProcessed";
-    long IS_EVERY_PROBLEM_FACT_CHANGE_DELAY = 100;
+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/OptaplannerSolverManagerAsyncTest.java b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaplannerSolverManagerAsyncTest.java
new file mode 100644
index 0000000..c97867b
--- /dev/null
+++ b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaplannerSolverManagerAsyncTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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 org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit5.CamelTestSupport;
+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 {
+
+    @Test
+    public void testAsyncProblemSolving() throws Exception {
+        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());
+
+        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);
+
+        // 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());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:in").to("optaplanner:doesntmatter?useSolverManager=true&async=true");
+
+                from("optaplanner:doesntmatter?useSolverManager=true")
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaplannerSolverManagerTest.java b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaplannerSolverManagerTest.java
new file mode 100644
index 0000000..cc6faf1
--- /dev/null
+++ b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaplannerSolverManagerTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.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 OptaplannerSolverManagerTest extends CamelTestSupport {
+
+    @Test
+    public void testSynchronousProblemSolving() throws Exception {
+        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());
+
+        CloudBalance bestSolution = template.requestBodyAndHeader("direct:in", planningProblem,
+                OptaPlannerConstants.SOLVER_MANAGER, solverManager, 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:doesntmatter?useSolverManager=true&problemId=" + 1L);
+            }
+        };
+    }
+}
diff --git a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
index be18290..b0f198f 100644
--- a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
+++ b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
@@ -11389,7 +11389,11 @@ public class StaticEndpointBuilders {
      * Syntax: <code>optaplanner:configFile</code>
      * 
      * Path parameter: configFile (required)
-     * Specifies the location to the solver file
+     * Specifies the location to the solver file. If useSolverManager=FALSE,
+     * Camel uses this file and create the Solver. If useSolverManager=TRUE and
+     * SolverManager is set in the header {OptaPlannerConstants.SOLVER_MANAGER}
+     * : this file is ignored by Camel usage of SolverManager. SolverManager can
+     * be injected by DI in Quarkus or Spring.
      * 
      * @param path configFile
      */
@@ -11408,7 +11412,11 @@ public class StaticEndpointBuilders {
      * Syntax: <code>optaplanner:configFile</code>
      * 
      * Path parameter: configFile (required)
-     * Specifies the location to the solver file
+     * Specifies the location to the solver file. If useSolverManager=FALSE,
+     * Camel uses this file and create the Solver. If useSolverManager=TRUE and
+     * SolverManager is set in the header {OptaPlannerConstants.SOLVER_MANAGER}
+     * : this file is ignored by Camel usage of SolverManager. SolverManager can
+     * be injected by DI in Quarkus or Spring.
      * 
      * @param componentName to use a custom component name for the endpoint
      * instead of the default name
diff --git a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OptaPlannerEndpointBuilderFactory.java b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OptaPlannerEndpointBuilderFactory.java
index 3220c30..79ffb7e 100644
--- a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OptaPlannerEndpointBuilderFactory.java
+++ b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OptaPlannerEndpointBuilderFactory.java
@@ -42,6 +42,30 @@ public interface OptaPlannerEndpointBuilderFactory {
             return (AdvancedOptaPlannerEndpointConsumerBuilder) this;
         }
         /**
+         * In case of using SolverManager : the problem id.
+         * 
+         * The option is a: <code>java.lang.Long</code> type.
+         * 
+         * Default: 1L
+         * Group: common
+         */
+        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 <code>java.lang.Long</code> type.
+         * 
+         * Default: 1L
+         * Group: common
+         */
+        default OptaPlannerEndpointConsumerBuilder problemId(String problemId) {
+            doSetProperty("problemId", problemId);
+            return this;
+        }
+        /**
          * Specifies the solverId to user for the solver instance key.
          * 
          * The option is a: <code>java.lang.String</code> type.
@@ -54,6 +78,34 @@ public interface OptaPlannerEndpointBuilderFactory {
             return this;
         }
         /**
+         * use SolverManager instead of XML file config. Use this mode on
+         * Quarkus app.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: common
+         */
+        default OptaPlannerEndpointConsumerBuilder useSolverManager(
+                boolean useSolverManager) {
+            doSetProperty("useSolverManager", useSolverManager);
+            return this;
+        }
+        /**
+         * use SolverManager instead of XML file config. Use this mode on
+         * Quarkus app.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: common
+         */
+        default OptaPlannerEndpointConsumerBuilder useSolverManager(
+                String useSolverManager) {
+            doSetProperty("useSolverManager", useSolverManager);
+            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
@@ -227,6 +279,30 @@ public interface OptaPlannerEndpointBuilderFactory {
             return (AdvancedOptaPlannerEndpointProducerBuilder) this;
         }
         /**
+         * In case of using SolverManager : the problem id.
+         * 
+         * The option is a: <code>java.lang.Long</code> type.
+         * 
+         * Default: 1L
+         * Group: common
+         */
+        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 <code>java.lang.Long</code> type.
+         * 
+         * Default: 1L
+         * Group: common
+         */
+        default OptaPlannerEndpointProducerBuilder problemId(String problemId) {
+            doSetProperty("problemId", problemId);
+            return this;
+        }
+        /**
          * Specifies the solverId to user for the solver instance key.
          * 
          * The option is a: <code>java.lang.String</code> type.
@@ -239,6 +315,34 @@ public interface OptaPlannerEndpointBuilderFactory {
             return this;
         }
         /**
+         * use SolverManager instead of XML file config. Use this mode on
+         * Quarkus app.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: common
+         */
+        default OptaPlannerEndpointProducerBuilder useSolverManager(
+                boolean useSolverManager) {
+            doSetProperty("useSolverManager", useSolverManager);
+            return this;
+        }
+        /**
+         * use SolverManager instead of XML file config. Use this mode on
+         * Quarkus app.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: common
+         */
+        default OptaPlannerEndpointProducerBuilder useSolverManager(
+                String useSolverManager) {
+            doSetProperty("useSolverManager", useSolverManager);
+            return this;
+        }
+        /**
          * Specifies to perform operations in async mode.
          * 
          * The option is a: <code>boolean</code> type.
@@ -410,6 +514,30 @@ public interface OptaPlannerEndpointBuilderFactory {
             return (AdvancedOptaPlannerEndpointBuilder) this;
         }
         /**
+         * In case of using SolverManager : the problem id.
+         * 
+         * The option is a: <code>java.lang.Long</code> type.
+         * 
+         * Default: 1L
+         * Group: common
+         */
+        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 <code>java.lang.Long</code> type.
+         * 
+         * Default: 1L
+         * Group: common
+         */
+        default OptaPlannerEndpointBuilder problemId(String problemId) {
+            doSetProperty("problemId", problemId);
+            return this;
+        }
+        /**
          * Specifies the solverId to user for the solver instance key.
          * 
          * The option is a: <code>java.lang.String</code> type.
@@ -421,6 +549,34 @@ public interface OptaPlannerEndpointBuilderFactory {
             doSetProperty("solverId", solverId);
             return this;
         }
+        /**
+         * use SolverManager instead of XML file config. Use this mode on
+         * Quarkus app.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: common
+         */
+        default OptaPlannerEndpointBuilder useSolverManager(
+                boolean useSolverManager) {
+            doSetProperty("useSolverManager", useSolverManager);
+            return this;
+        }
+        /**
+         * use SolverManager instead of XML file config. Use this mode on
+         * Quarkus app.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: common
+         */
+        default OptaPlannerEndpointBuilder useSolverManager(
+                String useSolverManager) {
+            doSetProperty("useSolverManager", useSolverManager);
+            return this;
+        }
     }
 
     /**
@@ -503,7 +659,12 @@ public interface OptaPlannerEndpointBuilderFactory {
          * Syntax: <code>optaplanner:configFile</code>
          * 
          * Path parameter: configFile (required)
-         * Specifies the location to the solver file
+         * Specifies the location to the solver file. If useSolverManager=FALSE,
+         * Camel uses this file and create the Solver. If useSolverManager=TRUE
+         * and SolverManager is set in the header
+         * {OptaPlannerConstants.SOLVER_MANAGER} : this file is ignored by Camel
+         * usage of SolverManager. SolverManager can be injected by DI in
+         * Quarkus or Spring.
          * 
          * @param path configFile
          */
@@ -521,7 +682,12 @@ public interface OptaPlannerEndpointBuilderFactory {
          * Syntax: <code>optaplanner:configFile</code>
          * 
          * Path parameter: configFile (required)
-         * Specifies the location to the solver file
+         * Specifies the location to the solver file. If useSolverManager=FALSE,
+         * Camel uses this file and create the Solver. If useSolverManager=TRUE
+         * and SolverManager is set in the header
+         * {OptaPlannerConstants.SOLVER_MANAGER} : this file is ignored by Camel
+         * usage of SolverManager. SolverManager can be injected by DI in
+         * Quarkus or Spring.
          * 
          * @param componentName to use a custom component name for the endpoint
          * instead of the default name
diff --git a/docs/components/modules/ROOT/pages/optaplanner-component.adoc b/docs/components/modules/ROOT/pages/optaplanner-component.adoc
index 6e116dd..b10efd3 100644
--- a/docs/components/modules/ROOT/pages/optaplanner-component.adoc
+++ b/docs/components/modules/ROOT/pages/optaplanner-component.adoc
@@ -80,17 +80,19 @@ with the following path and query parameters:
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
-| *configFile* | *Required* Specifies the location to the solver file |  | String
+| *configFile* | *Required* Specifies the location to the solver file. If useSolverManager=FALSE, Camel uses this file and create the Solver. If useSolverManager=TRUE and SolverManager is set in the header {OptaPlannerConstants.SOLVER_MANAGER} : this file is ignored by Camel usage of SolverManager. SolverManager can be injected by DI in Quarkus or Spring. |  | String
 |===
 
 
-=== Query Parameters (9 parameters):
+=== Query Parameters (11 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
+| *problemId* (common) | In case of using SolverManager : the problem id | 1L | Long
 | *solverId* (common) | Specifies the solverId to user for the solver instance key | DEFAULT_SOLVER | String
+| *useSolverManager* (common) | use SolverManager instead of XML file config. Use this mode on Quarkus app. | false | boolean
 | *bridgeErrorHandler* (consumer) | 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. | false | boolean
 | *exceptionHandler* (consumer) | 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. |  | ExceptionHandler
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. There are 3 enums and the value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern