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 <[email protected]>
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