You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pp...@apache.org on 2020/11/27 11:21:03 UTC
[camel-quarkus] 01/03: OptaPlanner native support fixes #1721
This is an automated email from the ASF dual-hosted git repository.
ppalaga pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit ee56a0606144cc5989186931dca7dab2a1e856d5
Author: Zineb Bendhiba <be...@gmail.com>
AuthorDate: Fri Sep 11 15:56:35 2020 +0200
OptaPlanner native support fixes #1721
---
.../pages/reference/extensions/optaplanner.adoc | 8 +-
.../partials/reference/components/optaplanner.adoc | 6 +-
extensions-jvm/pom.xml | 1 -
.../optaplanner/deployment/pom.xml | 16 +++
.../deployment/OptaplannerProcessor.java | 14 ---
{extensions-jvm => extensions}/optaplanner/pom.xml | 1 -
.../optaplanner/runtime/pom.xml | 30 ++++++
.../main/resources/META-INF/quarkus-extension.yaml | 3 +-
extensions/pom.xml | 1 +
.../optaplanner}/pom.xml | 74 ++++++++++++-
.../quarkus/component/optaplanner/it/MyBean.java | 48 +++++++++
.../optaplanner/it/OptaplannerResource.java | 89 ++++++++++++++++
.../quarkus/component/optaplanner/it/Routes.java | 39 +++----
.../optaplanner/it/bootstrap/DataGenerator.java | 95 +++++++++++++++++
.../component/optaplanner/it/domain/Lesson.java | 100 +++++++++++++++++
.../component/optaplanner/it/domain/Room.java | 61 +++++++++++
.../component/optaplanner/it/domain/TimeTable.java | 72 +++++++++++++
.../component/optaplanner/it/domain/Timeslot.java | 77 ++++++++++++++
.../it/solver/TimeTableConstraintProvider.java | 118 +++++++++++++++++++++
.../src/main/resources/application.properties | 32 ++++++
.../component/optaplanner/it/OptaplannerIT.java | 16 +--
.../component/optaplanner/it/OptaplannerTest.java | 31 +++++-
integration-tests/pom.xml | 1 +
pom.xml | 2 +
poms/bom/pom.xml | 10 ++
tooling/scripts/test-categories.yaml | 1 +
26 files changed, 877 insertions(+), 69 deletions(-)
diff --git a/docs/modules/ROOT/pages/reference/extensions/optaplanner.adoc b/docs/modules/ROOT/pages/reference/extensions/optaplanner.adoc
index bc9def7..d4fa4d3 100644
--- a/docs/modules/ROOT/pages/reference/extensions/optaplanner.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/optaplanner.adoc
@@ -2,15 +2,15 @@
// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
= OptaPlanner
:cq-artifact-id: camel-quarkus-optaplanner
-:cq-native-supported: false
-:cq-status: Preview
+:cq-native-supported: true
+:cq-status: Stable
:cq-description: Solve planning problems with OptaPlanner.
:cq-deprecated: false
:cq-jvm-since: 1.1.0
-:cq-native-since: n/a
+:cq-native-since: 1.2.0
[.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.1.0## [.badge-key]##Native##[.badge-unsupported]##unsupported##
+[.badge-key]##JVM since##[.badge-supported]##1.1.0## [.badge-key]##Native since##[.badge-supported]##1.2.0##
Solve planning problems with OptaPlanner.
diff --git a/docs/modules/ROOT/partials/reference/components/optaplanner.adoc b/docs/modules/ROOT/partials/reference/components/optaplanner.adoc
index e5a1a6b..4e31fd7 100644
--- a/docs/modules/ROOT/partials/reference/components/optaplanner.adoc
+++ b/docs/modules/ROOT/partials/reference/components/optaplanner.adoc
@@ -2,11 +2,11 @@
// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
:cq-artifact-id: camel-quarkus-optaplanner
:cq-artifact-id-base: optaplanner
-:cq-native-supported: false
-:cq-status: Preview
+:cq-native-supported: true
+:cq-status: Stable
:cq-deprecated: false
:cq-jvm-since: 1.1.0
-:cq-native-since: n/a
+:cq-native-since: 1.2.0
:cq-camel-part-name: optaplanner
:cq-camel-part-title: OptaPlanner
:cq-camel-part-description: Solve planning problems with OptaPlanner.
diff --git a/extensions-jvm/pom.xml b/extensions-jvm/pom.xml
index d13fcc5..dbb2244 100644
--- a/extensions-jvm/pom.xml
+++ b/extensions-jvm/pom.xml
@@ -108,7 +108,6 @@
<module>nitrite</module>
<module>ognl</module>
<module>openstack</module>
- <module>optaplanner</module>
<module>printer</module>
<module>pubnub</module>
<module>pulsar</module>
diff --git a/extensions-jvm/optaplanner/deployment/pom.xml b/extensions/optaplanner/deployment/pom.xml
similarity index 81%
rename from extensions-jvm/optaplanner/deployment/pom.xml
rename to extensions/optaplanner/deployment/pom.xml
index 1b047be..d2bed0b 100644
--- a/extensions-jvm/optaplanner/deployment/pom.xml
+++ b/extensions/optaplanner/deployment/pom.xml
@@ -29,6 +29,18 @@
<artifactId>camel-quarkus-optaplanner-deployment</artifactId>
<name>Camel Quarkus :: OptaPlanner :: Deployment</name>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.optaplanner</groupId>
+ <artifactId>optaplanner-quarkus-deployment</artifactId>
+ <version>${optaplanner.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
<dependencies>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
@@ -38,6 +50,10 @@
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-optaplanner</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.optaplanner</groupId>
+ <artifactId>optaplanner-quarkus-deployment</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git a/extensions-jvm/optaplanner/deployment/src/main/java/org/apache/camel/quarkus/component/optaplanner/deployment/OptaplannerProcessor.java b/extensions/optaplanner/deployment/src/main/java/org/apache/camel/quarkus/component/optaplanner/deployment/OptaplannerProcessor.java
similarity index 68%
rename from extensions-jvm/optaplanner/deployment/src/main/java/org/apache/camel/quarkus/component/optaplanner/deployment/OptaplannerProcessor.java
rename to extensions/optaplanner/deployment/src/main/java/org/apache/camel/quarkus/component/optaplanner/deployment/OptaplannerProcessor.java
index d07ab81..3956d43 100644
--- a/extensions-jvm/optaplanner/deployment/src/main/java/org/apache/camel/quarkus/component/optaplanner/deployment/OptaplannerProcessor.java
+++ b/extensions/optaplanner/deployment/src/main/java/org/apache/camel/quarkus/component/optaplanner/deployment/OptaplannerProcessor.java
@@ -17,11 +17,7 @@
package org.apache.camel.quarkus.component.optaplanner.deployment;
import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.pkg.steps.NativeBuild;
-import org.apache.camel.quarkus.core.JvmOnlyRecorder;
import org.jboss.logging.Logger;
class OptaplannerProcessor {
@@ -33,14 +29,4 @@ class OptaplannerProcessor {
FeatureBuildItem feature() {
return new FeatureBuildItem(FEATURE);
}
-
- /**
- * Remove this once this extension starts supporting the native mode.
- */
- @BuildStep(onlyIf = NativeBuild.class)
- @Record(value = ExecutionTime.RUNTIME_INIT)
- void warnJvmInNative(JvmOnlyRecorder recorder) {
- JvmOnlyRecorder.warnJvmInNative(LOG, FEATURE); // warn at build time
- recorder.warnJvmInNative(FEATURE); // warn at runtime
- }
}
diff --git a/extensions-jvm/optaplanner/pom.xml b/extensions/optaplanner/pom.xml
similarity index 97%
rename from extensions-jvm/optaplanner/pom.xml
rename to extensions/optaplanner/pom.xml
index fa0bff5..0e1dede 100644
--- a/extensions-jvm/optaplanner/pom.xml
+++ b/extensions/optaplanner/pom.xml
@@ -33,6 +33,5 @@
<modules>
<module>deployment</module>
<module>runtime</module>
- <module>integration-test</module>
</modules>
</project>
diff --git a/extensions-jvm/optaplanner/runtime/pom.xml b/extensions/optaplanner/runtime/pom.xml
similarity index 77%
rename from extensions-jvm/optaplanner/runtime/pom.xml
rename to extensions/optaplanner/runtime/pom.xml
index ac8340b..5c5fdda 100644
--- a/extensions-jvm/optaplanner/runtime/pom.xml
+++ b/extensions/optaplanner/runtime/pom.xml
@@ -32,6 +32,7 @@
<properties>
<camel.quarkus.jvmSince>1.1.0</camel.quarkus.jvmSince>
+ <camel.quarkus.nativeSince>1.2.0</camel.quarkus.nativeSince>
</properties>
<dependencyManagement>
@@ -43,6 +44,20 @@
<type>pom</type>
<scope>import</scope>
</dependency>
+ <dependency>
+ <groupId>org.optaplanner</groupId>
+ <artifactId>optaplanner-quarkus</artifactId>
+ <version>${optaplanner.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mvel</groupId>
+ <artifactId>mvel2</artifactId>
+ <version>${mvel2.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
</dependencies>
</dependencyManagement>
@@ -55,6 +70,21 @@
<groupId>org.apache.camel</groupId>
<artifactId>camel-optaplanner</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.optaplanner</groupId>
+ <artifactId>optaplanner-quarkus</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.mvel</groupId>
+ <artifactId>mvel2</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <!-- delete mvel2 dependency when optaplanner 7.45.0.Final is released-->
+ <dependency>
+ <groupId>org.mvel</groupId>
+ <artifactId>mvel2</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git a/extensions-jvm/optaplanner/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/optaplanner/runtime/src/main/resources/META-INF/quarkus-extension.yaml
similarity index 97%
rename from extensions-jvm/optaplanner/runtime/src/main/resources/META-INF/quarkus-extension.yaml
rename to extensions/optaplanner/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index 343577a..8951b1f 100644
--- a/extensions-jvm/optaplanner/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ b/extensions/optaplanner/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -24,9 +24,8 @@
name: "Camel OptaPlanner"
description: "Solve planning problems with OptaPlanner"
metadata:
- unlisted: true
guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/optaplanner.html"
categories:
- "integration"
status:
- - "preview"
+ - "stable"
diff --git a/extensions/pom.xml b/extensions/pom.xml
index 689c85e..7d7172f 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -164,6 +164,7 @@
<module>olingo4</module>
<module>openapi-java</module>
<module>opentracing</module>
+ <module>optaplanner</module>
<module>paho</module>
<module>pdf</module>
<module>pg-replication-slot</module>
diff --git a/extensions-jvm/optaplanner/integration-test/pom.xml b/integration-tests/optaplanner/pom.xml
similarity index 54%
rename from extensions-jvm/optaplanner/integration-test/pom.xml
rename to integration-tests/optaplanner/pom.xml
index 4b9af27..8b510b3 100644
--- a/extensions-jvm/optaplanner/integration-test/pom.xml
+++ b/integration-tests/optaplanner/pom.xml
@@ -21,13 +21,12 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-build-parent-it</artifactId>
+ <artifactId>camel-quarkus-integration-tests</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath>../../../poms/build-parent-it/pom.xml</relativePath>
</parent>
- <artifactId>camel-quarkus-optaplanner-integration-test</artifactId>
- <name>Camel Quarkus :: OptaPlanner :: Integration Test</name>
+ <artifactId>camel-quarkus-integration-test-optaplanner</artifactId>
+ <name>Camel Quarkus :: Integration Tests :: OptaPlanner</name>
<description>Integration tests for Camel Quarkus OptaPlanner extension</description>
<dependencyManagement>
@@ -51,6 +50,18 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-resteasy-jackson</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-direct</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-bean</artifactId>
+ </dependency>
<!-- test dependencies -->
<dependency>
@@ -67,6 +78,32 @@
<!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-bean-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-direct-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-optaplanner-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
@@ -80,4 +117,33 @@
</dependency>
</dependencies>
+ <profiles>
+ <profile>
+ <id>native</id>
+ <activation>
+ <property>
+ <name>native</name>
+ </property>
+ </activation>
+ <properties>
+ <quarkus.package.type>native</quarkus.package.type>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
</project>
diff --git a/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/MyBean.java b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/MyBean.java
new file mode 100644
index 0000000..185cda0
--- /dev/null
+++ b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/MyBean.java
@@ -0,0 +1,48 @@
+/*
+ * 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.quarkus.component.optaplanner.it;
+
+import javax.enterprise.context.ApplicationScoped;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.optaplanner.OptaPlannerConstants;
+import org.apache.camel.quarkus.component.optaplanner.it.domain.TimeTable;
+
+@RegisterForReflection
+@ApplicationScoped
+public class MyBean {
+
+ public TimeTable bestSolution;
+
+ public TimeTable getBestSolution() {
+ return bestSolution;
+ }
+
+ public void setBestSolution(TimeTable bestSolution) {
+ this.bestSolution = bestSolution;
+ }
+
+ public void updateBestSolution(Exchange exchange) {
+ if (exchange != null) {
+ TimeTable newBestSolution = exchange.getMessage().getHeader(OptaPlannerConstants.BEST_SOLUTION, TimeTable.class);
+ if (newBestSolution != null) {
+ this.bestSolution = newBestSolution;
+ }
+ }
+ }
+}
diff --git a/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerResource.java b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerResource.java
new file mode 100644
index 0000000..70f5f9c
--- /dev/null
+++ b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerResource.java
@@ -0,0 +1,89 @@
+/*
+ * 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.quarkus.component.optaplanner.it;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.optaplanner.OptaPlannerConstants;
+import org.apache.camel.quarkus.component.optaplanner.it.bootstrap.DataGenerator;
+import org.apache.camel.quarkus.component.optaplanner.it.domain.TimeTable;
+import org.jboss.logging.Logger;
+import org.optaplanner.core.api.solver.SolverManager;
+import org.optaplanner.core.api.solver.SolverStatus;
+
+@Path("/optaplanner")
+@ApplicationScoped
+@Produces(MediaType.APPLICATION_JSON)
+public class OptaplannerResource {
+
+ private static final Logger LOG = Logger.getLogger(OptaplannerResource.class);
+
+ public static final Long SINGLETON_TIME_TABLE_ID = 1L;
+
+ @Inject
+ SolverManager<TimeTable, Long> solverManager;
+
+ @Inject
+ ProducerTemplate producerTemplate;
+
+ @Inject
+ MyBean bean;
+
+ @GET
+ @Path("solveSync")
+ public TimeTable solveSync() {
+ if (SolverStatus.NOT_SOLVING == solverManager.getSolverStatus(SINGLETON_TIME_TABLE_ID)) {
+ TimeTable finalSolution = producerTemplate.requestBodyAndHeader(
+ "direct:solveSync", DataGenerator.timeTable,
+ OptaPlannerConstants.SOLVER_MANAGER, solverManager, TimeTable.class);
+ return finalSolution;
+ }
+ return DataGenerator.timeTable;
+ }
+
+ @GET
+ @Path("solveAsync")
+ public TimeTable solveAsync() throws ExecutionException, InterruptedException {
+ // reset best Solution
+ bean.setBestSolution(null);
+ if (SolverStatus.NOT_SOLVING == solverManager.getSolverStatus(SINGLETON_TIME_TABLE_ID)) {
+ CompletableFuture<TimeTable> response = producerTemplate.asyncRequestBodyAndHeader(
+ "direct:solveAsync", DataGenerator.timeTable, OptaPlannerConstants.SOLVER_MANAGER,
+ solverManager, TimeTable.class);
+
+ TimeTable finalSolution = response.get();
+ return finalSolution;
+ }
+ return DataGenerator.timeTable;
+ }
+
+ @GET
+ @Path("newBestSolution")
+ public TimeTable getNewBestSolution() {
+ return bean.getBestSolution();
+ }
+
+}
diff --git a/extensions-jvm/optaplanner/integration-test/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerResource.java b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/Routes.java
similarity index 50%
rename from extensions-jvm/optaplanner/integration-test/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerResource.java
rename to integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/Routes.java
index 8c7ae86..8f82b9e 100644
--- a/extensions-jvm/optaplanner/integration-test/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerResource.java
+++ b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/Routes.java
@@ -18,34 +18,27 @@ package org.apache.camel.quarkus.component.optaplanner.it;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.camel.CamelContext;
-import org.jboss.logging.Logger;
+import org.apache.camel.builder.RouteBuilder;
-@Path("/optaplanner")
@ApplicationScoped
-public class OptaplannerResource {
+public class Routes extends RouteBuilder {
+ @Inject
+ MyBean bean;
- private static final Logger LOG = Logger.getLogger(OptaplannerResource.class);
+ @Override
+ public void configure() throws Exception {
- private static final String COMPONENT_OPTAPLANNER = "optaplanner";
- @Inject
- CamelContext context;
+ // async producer
+ from("direct:solveAsync").to("optaplanner:anything?useSolverManager=true&async=true&problemId="
+ + OptaplannerResource.SINGLETON_TIME_TABLE_ID);
+
+ // async consumer
+ from("optaplanner:anything?useSolverManager=true&problemId=" + OptaplannerResource.SINGLETON_TIME_TABLE_ID)
+ .bean(bean, "updateBestSolution");
- @Path("/load/component/optaplanner")
- @GET
- @Produces(MediaType.TEXT_PLAIN)
- public Response loadComponentOptaplanner() throws Exception {
- /* This is an autogenerated test */
- if (context.getComponent(COMPONENT_OPTAPLANNER) != null) {
- return Response.ok().build();
- }
- LOG.warnf("Could not load [%s] from the Camel context", COMPONENT_OPTAPLANNER);
- return Response.status(500, COMPONENT_OPTAPLANNER + " could not be loaded from the Camel context").build();
+ // sync producer
+ from("direct:solveSync")
+ .to("optaplanner:anything?useSolverManager=true&problemId=" + OptaplannerResource.SINGLETON_TIME_TABLE_ID);
}
}
diff --git a/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/bootstrap/DataGenerator.java b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/bootstrap/DataGenerator.java
new file mode 100644
index 0000000..7538aeb
--- /dev/null
+++ b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/bootstrap/DataGenerator.java
@@ -0,0 +1,95 @@
+/*
+ * 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.quarkus.component.optaplanner.it.bootstrap;
+
+import java.time.DayOfWeek;
+import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+
+import io.quarkus.runtime.StartupEvent;
+import org.apache.camel.quarkus.component.optaplanner.it.domain.Lesson;
+import org.apache.camel.quarkus.component.optaplanner.it.domain.Room;
+import org.apache.camel.quarkus.component.optaplanner.it.domain.TimeTable;
+import org.apache.camel.quarkus.component.optaplanner.it.domain.Timeslot;
+
+/**
+ * adapted from optaplanner quarkus quickstart :
+ * https://github.com/quarkusio/quarkus-quickstarts/blob/master/optaplanner-quickstart/src/main/java/org/acme/optaplanner/bootstrap/DemoDataGenerator.java
+ */
+@ApplicationScoped
+public class DataGenerator {
+
+ public static List<Timeslot> timeslotList;
+
+ public static List<Room> roomList;
+
+ public static List<Lesson> lessonList;
+
+ public static TimeTable timeTable;
+
+ public void generateDemoData(@Observes StartupEvent startupEvent) {
+ timeslotList = new ArrayList<>(10);
+ timeslotList.add(new Timeslot(DayOfWeek.MONDAY, LocalTime.of(8, 30), LocalTime.of(9, 30)));
+ timeslotList.add(new Timeslot(DayOfWeek.MONDAY, LocalTime.of(9, 30), LocalTime.of(10, 30)));
+ timeslotList.add(new Timeslot(DayOfWeek.MONDAY, LocalTime.of(10, 30), LocalTime.of(11, 30)));
+ timeslotList.add(new Timeslot(DayOfWeek.MONDAY, LocalTime.of(13, 30), LocalTime.of(14, 30)));
+ timeslotList.add(new Timeslot(DayOfWeek.MONDAY, LocalTime.of(14, 30), LocalTime.of(15, 30)));
+ timeslotList.add(new Timeslot(DayOfWeek.TUESDAY, LocalTime.of(8, 30), LocalTime.of(9, 30)));
+ timeslotList.add(new Timeslot(DayOfWeek.TUESDAY, LocalTime.of(9, 30), LocalTime.of(10, 30)));
+ timeslotList.add(new Timeslot(DayOfWeek.TUESDAY, LocalTime.of(10, 30), LocalTime.of(11, 30)));
+ timeslotList.add(new Timeslot(DayOfWeek.TUESDAY, LocalTime.of(13, 30), LocalTime.of(14, 30)));
+ timeslotList.add(new Timeslot(DayOfWeek.TUESDAY, LocalTime.of(14, 30), LocalTime.of(15, 30)));
+
+ roomList = new ArrayList<>(3);
+ roomList.add(new Room("Room A"));
+ roomList.add(new Room("Room B"));
+ roomList.add(new Room("Room C"));
+
+ lessonList = new ArrayList<>();
+ lessonList.add(new Lesson("Math", "A. Turing", "9th grade"));
+ lessonList.add(new Lesson("Math", "A. Turing", "9th grade"));
+ lessonList.add(new Lesson("Physics", "M. Curie", "9th grade"));
+ lessonList.add(new Lesson("Chemistry", "M. Curie", "9th grade"));
+ lessonList.add(new Lesson("Biology", "C. Darwin", "9th grade"));
+ lessonList.add(new Lesson("History", "I. Jones", "9th grade"));
+ lessonList.add(new Lesson("English", "I. Jones", "9th grade"));
+ lessonList.add(new Lesson("English", "I. Jones", "9th grade"));
+ lessonList.add(new Lesson("Spanish", "P. Cruz", "9th grade"));
+ lessonList.add(new Lesson("Spanish", "P. Cruz", "9th grade"));
+
+ lessonList.add(new Lesson("Math", "A. Turing", "10th grade"));
+ lessonList.add(new Lesson("Math", "A. Turing", "10th grade"));
+ lessonList.add(new Lesson("Math", "A. Turing", "10th grade"));
+ lessonList.add(new Lesson("Physics", "M. Curie", "10th grade"));
+ lessonList.add(new Lesson("Chemistry", "M. Curie", "10th grade"));
+ lessonList.add(new Lesson("French", "M. Curie", "10th grade"));
+ lessonList.add(new Lesson("Geography", "C. Darwin", "10th grade"));
+ lessonList.add(new Lesson("History", "I. Jones", "10th grade"));
+ lessonList.add(new Lesson("English", "P. Cruz", "10th grade"));
+ lessonList.add(new Lesson("Spanish", "P. Cruz", "10th grade"));
+
+ timeTable = new TimeTable(
+ DataGenerator.timeslotList,
+ DataGenerator.roomList,
+ DataGenerator.lessonList);
+ }
+
+}
diff --git a/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/domain/Lesson.java b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/domain/Lesson.java
new file mode 100644
index 0000000..fb7b977
--- /dev/null
+++ b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/domain/Lesson.java
@@ -0,0 +1,100 @@
+/*
+ * 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.quarkus.component.optaplanner.it.domain;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+import org.optaplanner.core.api.domain.entity.PlanningEntity;
+import org.optaplanner.core.api.domain.lookup.PlanningId;
+import org.optaplanner.core.api.domain.variable.PlanningVariable;
+
+/**
+ * adapted from optaplanner quarkus quickstart :
+ * https://github.com/quarkusio/quarkus-quickstarts/blob/master/optaplanner-quickstart/src/main/java/org/acme/optaplanner/domain/Lesson.java
+ */
+@PlanningEntity
+public class Lesson {
+
+ @PlanningId
+ @NotNull
+ private Long id;
+
+ @NotBlank
+ private String subject;
+ @NotBlank
+ private String teacher;
+ @NotBlank
+ private String studentGroup;
+
+ @PlanningVariable(valueRangeProviderRefs = "timeslotRange")
+ private Timeslot timeslot;
+ @PlanningVariable(valueRangeProviderRefs = "roomRange")
+ private Room room;
+
+ private static AtomicLong increment = new AtomicLong(1);
+
+ public Lesson() {
+ }
+
+ public Lesson(String subject, String teacher, String studentGroup) {
+ this.id = increment.getAndIncrement();
+ this.subject = subject.trim();
+ this.teacher = teacher.trim();
+ this.studentGroup = studentGroup.trim();
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getSubject() {
+ return subject;
+ }
+
+ public String getTeacher() {
+ return teacher;
+ }
+
+ public String getStudentGroup() {
+ return studentGroup;
+ }
+
+ public Timeslot getTimeslot() {
+ return timeslot;
+ }
+
+ public void setTimeslot(Timeslot timeslot) {
+ this.timeslot = timeslot;
+ }
+
+ public Room getRoom() {
+ return room;
+ }
+
+ public void setRoom(Room room) {
+ this.room = room;
+ }
+
+ @Override
+ public String toString() {
+ return subject + "(" + id + ")";
+ }
+
+}
diff --git a/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/domain/Room.java b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/domain/Room.java
new file mode 100644
index 0000000..bd93b2d
--- /dev/null
+++ b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/domain/Room.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.optaplanner.it.domain;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+import org.optaplanner.core.api.domain.lookup.PlanningId;
+
+/**
+ * adapted from optaplanner quarkus quickstart :
+ * https://github.com/quarkusio/quarkus-quickstarts/blob/master/optaplanner-quickstart/src/main/java/org/acme/optaplanner/domain/Room.java
+ */
+public class Room {
+
+ @PlanningId
+ @NotNull
+ private Long id;
+
+ @NotBlank
+ private String name;
+ private static AtomicLong increment = new AtomicLong(1);
+
+ public Room() {
+ }
+
+ public Room(String name) {
+ this.id = increment.getAndIncrement();
+ this.name = name.trim();
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+}
diff --git a/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/domain/TimeTable.java b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/domain/TimeTable.java
new file mode 100644
index 0000000..8fe3800
--- /dev/null
+++ b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/domain/TimeTable.java
@@ -0,0 +1,72 @@
+/*
+ * 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.quarkus.component.optaplanner.it.domain;
+
+import java.util.List;
+
+import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty;
+import org.optaplanner.core.api.domain.solution.PlanningScore;
+import org.optaplanner.core.api.domain.solution.PlanningSolution;
+import org.optaplanner.core.api.domain.solution.drools.ProblemFactCollectionProperty;
+import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider;
+import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore;
+
+/**
+ * adapted from optaplanner quarkus quickstart :
+ * https://github.com/quarkusio/quarkus-quickstarts/blob/master/optaplanner-quickstart/src/main/java/org/acme/optaplanner/domain/Timeslot.java
+ */
+@PlanningSolution
+public class TimeTable {
+
+ @ProblemFactCollectionProperty
+ @ValueRangeProvider(id = "timeslotRange")
+ private List<Timeslot> timeslotList;
+ @ProblemFactCollectionProperty
+ @ValueRangeProvider(id = "roomRange")
+ private List<Room> roomList;
+ @PlanningEntityCollectionProperty
+ private List<Lesson> lessonList;
+
+ @PlanningScore
+ private HardSoftScore score;
+
+ public TimeTable() {
+ }
+
+ public TimeTable(List<Timeslot> timeslotList, List<Room> roomList, List<Lesson> lessonList) {
+ this.timeslotList = timeslotList;
+ this.roomList = roomList;
+ this.lessonList = lessonList;
+ }
+
+ public List<Timeslot> getTimeslotList() {
+ return timeslotList;
+ }
+
+ public List<Room> getRoomList() {
+ return roomList;
+ }
+
+ public List<Lesson> getLessonList() {
+ return lessonList;
+ }
+
+ public HardSoftScore getScore() {
+ return score;
+ }
+
+}
diff --git a/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/domain/Timeslot.java b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/domain/Timeslot.java
new file mode 100644
index 0000000..57fc50f
--- /dev/null
+++ b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/domain/Timeslot.java
@@ -0,0 +1,77 @@
+/*
+ * 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.quarkus.component.optaplanner.it.domain;
+
+import java.time.DayOfWeek;
+import java.time.LocalTime;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.validation.constraints.NotNull;
+
+import org.optaplanner.core.api.domain.lookup.PlanningId;
+
+/**
+ * adapted from optaplanner quarkus quickstart :
+ * https://github.com/quarkusio/quarkus-quickstarts/blob/master/optaplanner-quickstart/src/main/java/org/acme/optaplanner/domain/TimeTable.java
+ */
+public class Timeslot {
+
+ @PlanningId
+ @NotNull
+ private Long id;
+
+ @NotNull
+ private DayOfWeek dayOfWeek;
+ @NotNull
+ private LocalTime startTime;
+ @NotNull
+ private LocalTime endTime;
+
+ private static AtomicLong increment = new AtomicLong(1);
+
+ public Timeslot() {
+ }
+
+ public Timeslot(DayOfWeek dayOfWeek, LocalTime startTime, LocalTime endTime) {
+ this.id = increment.getAndIncrement();
+ this.dayOfWeek = dayOfWeek;
+ this.startTime = startTime;
+ this.endTime = endTime;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public DayOfWeek getDayOfWeek() {
+ return dayOfWeek;
+ }
+
+ public LocalTime getStartTime() {
+ return startTime;
+ }
+
+ public LocalTime getEndTime() {
+ return endTime;
+ }
+
+ @Override
+ public String toString() {
+ return dayOfWeek + " " + startTime;
+ }
+
+}
diff --git a/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/solver/TimeTableConstraintProvider.java b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/solver/TimeTableConstraintProvider.java
new file mode 100644
index 0000000..b15c6c0
--- /dev/null
+++ b/integration-tests/optaplanner/src/main/java/org/apache/camel/quarkus/component/optaplanner/it/solver/TimeTableConstraintProvider.java
@@ -0,0 +1,118 @@
+/*
+ * 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.quarkus.component.optaplanner.it.solver;
+
+import java.time.Duration;
+
+import org.apache.camel.quarkus.component.optaplanner.it.domain.Lesson;
+import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore;
+import org.optaplanner.core.api.score.stream.Constraint;
+import org.optaplanner.core.api.score.stream.ConstraintFactory;
+import org.optaplanner.core.api.score.stream.ConstraintProvider;
+import org.optaplanner.core.api.score.stream.Joiners;
+
+/**
+ * adapted from optaplanner quarkus quickstart :
+ * https://github.com/quarkusio/quarkus-quickstarts/blob/master/optaplanner-quickstart/src/main/java/org/acme/optaplanner/solver/TimeTableConstraintProvider.java
+ */
+public class TimeTableConstraintProvider implements ConstraintProvider {
+
+ @Override
+ public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
+ return new Constraint[] {
+ // Hard constraints
+ roomConflict(constraintFactory),
+ teacherConflict(constraintFactory),
+ studentGroupConflict(constraintFactory),
+ // Soft constraints
+ teacherRoomStability(constraintFactory),
+ teacherTimeEfficiency(constraintFactory),
+ studentGroupSubjectVariety(constraintFactory)
+ };
+ }
+
+ private Constraint roomConflict(ConstraintFactory constraintFactory) {
+ // A room can accommodate at most one lesson at the same time.
+ return constraintFactory
+ // Select each pair of 2 different lessons ...
+ .fromUniquePair(Lesson.class,
+ // ... in the same timeslot ...
+ Joiners.equal(Lesson::getTimeslot),
+ // ... in the same room ...
+ Joiners.equal(Lesson::getRoom))
+ // ... and penalize each pair with a hard weight.
+ .penalize("Room conflict", HardSoftScore.ONE_HARD);
+ }
+
+ private Constraint teacherConflict(ConstraintFactory constraintFactory) {
+ // A teacher can teach at most one lesson at the same time.
+ return constraintFactory
+ .fromUniquePair(Lesson.class,
+ Joiners.equal(Lesson::getTimeslot),
+ Joiners.equal(Lesson::getTeacher))
+ .penalize("Teacher conflict", HardSoftScore.ONE_HARD);
+ }
+
+ private Constraint studentGroupConflict(ConstraintFactory constraintFactory) {
+ // A student can attend at most one lesson at the same time.
+ return constraintFactory
+ .fromUniquePair(Lesson.class,
+ Joiners.equal(Lesson::getTimeslot),
+ Joiners.equal(Lesson::getStudentGroup))
+ .penalize("Student group conflict", HardSoftScore.ONE_HARD);
+ }
+
+ private Constraint teacherRoomStability(ConstraintFactory constraintFactory) {
+ // A teacher prefers to teach in a single room.
+ return constraintFactory
+ .fromUniquePair(Lesson.class,
+ Joiners.equal(Lesson::getTeacher))
+ .filter((lesson1, lesson2) -> lesson1.getRoom() != lesson2.getRoom())
+ .penalize("Teacher room stability", HardSoftScore.ONE_SOFT);
+ }
+
+ private Constraint teacherTimeEfficiency(ConstraintFactory constraintFactory) {
+ // A teacher prefers to teach sequential lessons and dislikes gaps between lessons.
+ return constraintFactory
+ .from(Lesson.class)
+ .join(Lesson.class, Joiners.equal(Lesson::getTeacher),
+ Joiners.equal((lesson) -> lesson.getTimeslot().getDayOfWeek()))
+ .filter((lesson1, lesson2) -> {
+ Duration between = Duration.between(lesson1.getTimeslot().getEndTime(),
+ lesson2.getTimeslot().getStartTime());
+ return !between.isNegative() && between.compareTo(Duration.ofMinutes(30)) <= 0;
+ })
+ .reward("Teacher time efficiency", HardSoftScore.ONE_SOFT);
+ }
+
+ private Constraint studentGroupSubjectVariety(ConstraintFactory constraintFactory) {
+ // A student group dislikes sequential lessons on the same subject.
+ return constraintFactory
+ .from(Lesson.class)
+ .join(Lesson.class,
+ Joiners.equal(Lesson::getSubject),
+ Joiners.equal(Lesson::getStudentGroup),
+ Joiners.equal((lesson) -> lesson.getTimeslot().getDayOfWeek()))
+ .filter((lesson1, lesson2) -> {
+ Duration between = Duration.between(lesson1.getTimeslot().getEndTime(),
+ lesson2.getTimeslot().getStartTime());
+ return !between.isNegative() && between.compareTo(Duration.ofMinutes(30)) <= 0;
+ })
+ .penalize("Student group subject variety", HardSoftScore.ONE_SOFT);
+ }
+
+}
diff --git a/integration-tests/optaplanner/src/main/resources/application.properties b/integration-tests/optaplanner/src/main/resources/application.properties
new file mode 100644
index 0000000..4156b41
--- /dev/null
+++ b/integration-tests/optaplanner/src/main/resources/application.properties
@@ -0,0 +1,32 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+########################
+# OptaPlanner properties
+# adapted from optaplanner quarkus quickstart : https://github.com/quarkusio/quarkus-quickstarts/blob/master/optaplanner-quickstart/src/main/resources/application.properties
+########################
+
+# The solver runs for 30 seconds. To run for 5 minutes use "5m" and for 2 hours use "2h".
+quarkus.optaplanner.solver.termination.spent-limit=30s
+
+########################
+# Test overrides
+########################
+
+# Effectively disable this termination in favor of the best-score-limit
+%test.quarkus.optaplanner.solver.termination.spent-limit=1h
+%test.quarkus.optaplanner.solver.termination.best-score-limit=0hard/*soft
diff --git a/extensions-jvm/optaplanner/integration-test/src/test/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerTest.java b/integration-tests/optaplanner/src/test/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerIT.java
similarity index 69%
copy from extensions-jvm/optaplanner/integration-test/src/test/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerTest.java
copy to integration-tests/optaplanner/src/test/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerIT.java
index ff99e1e..81cc65d 100644
--- a/extensions-jvm/optaplanner/integration-test/src/test/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerTest.java
+++ b/integration-tests/optaplanner/src/test/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerIT.java
@@ -16,19 +16,9 @@
*/
package org.apache.camel.quarkus.component.optaplanner.it;
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
+import io.quarkus.test.junit.NativeImageTest;
-@QuarkusTest
-class OptaplannerTest {
-
- @Test
- public void loadComponentOptaplanner() {
- /* A simple autogenerated test */
- RestAssured.get("/optaplanner/load/component/optaplanner")
- .then()
- .statusCode(200);
- }
+@NativeImageTest
+class OptaplannerIT extends OptaplannerTest {
}
diff --git a/extensions-jvm/optaplanner/integration-test/src/test/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerTest.java b/integration-tests/optaplanner/src/test/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerTest.java
similarity index 52%
rename from extensions-jvm/optaplanner/integration-test/src/test/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerTest.java
rename to integration-tests/optaplanner/src/test/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerTest.java
index ff99e1e..de30a7e 100644
--- a/extensions-jvm/optaplanner/integration-test/src/test/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerTest.java
+++ b/integration-tests/optaplanner/src/test/java/org/apache/camel/quarkus/component/optaplanner/it/OptaplannerTest.java
@@ -20,15 +20,38 @@ import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
+import static org.hamcrest.Matchers.notNullValue;
+
@QuarkusTest
class OptaplannerTest {
@Test
- public void loadComponentOptaplanner() {
- /* A simple autogenerated test */
- RestAssured.get("/optaplanner/load/component/optaplanner")
+ public void solveSync() {
+ RestAssured.given()
+ .get("/optaplanner/solveSync")
+ .then()
+ .statusCode(200)
+ .body("lessonList[0].timeslot", notNullValue(null))
+ .body("lessonList[0].room", notNullValue(null));
+ }
+
+ @Test
+ public void solveASyncWithConsumer() {
+ // solve async
+ RestAssured.given()
+ .get("/optaplanner/solveAsync")
+ .then()
+ .statusCode(200)
+ .body("lessonList[0].timeslot", notNullValue(null))
+ .body("lessonList[0].room", notNullValue(null));
+
+ // test consumer data
+ RestAssured.given()
+ .get("/optaplanner/newBestSolution")
.then()
- .statusCode(200);
+ .statusCode(200)
+ .body("lessonList[0].timeslot", notNullValue(null))
+ .body("lessonList[0].room", notNullValue(null));
}
}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 834e5e2..b0303c7 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -138,6 +138,7 @@
<module>olingo4</module>
<module>openapi-java</module>
<module>opentracing</module>
+ <module>optaplanner</module>
<module>pdf</module>
<module>pg-replication-slot</module>
<module>pgevent</module>
diff --git a/pom.xml b/pom.xml
index 08cf44a..c9f9042 100644
--- a/pom.xml
+++ b/pom.xml
@@ -87,6 +87,7 @@
<okhttp.version>3.14.6</okhttp.version><!-- keep in sync with okio -->
<okio.version>1.17.2</okio.version><!-- keep in sync with okhttp -->
<opencensus-api.version>0.26.0</opencensus-api.version><!-- Mess in pubsub transitive deps vs google cloud deps -->
+ <optaplanner.version>7.46.0.Final</optaplanner.version>
<quarkus.version>1.10.1.Final</quarkus.version>
<quarkus-qpid-jms.version>0.21.0</quarkus-qpid-jms.version>
<protobuf.version>3.11.1</protobuf.version>
@@ -116,6 +117,7 @@
<istack-commons-runtime.version>3.0.10</istack-commons-runtime.version>
<jakarta.mail.version>1.6.5</jakarta.mail.version>
<mock-javamail.version>1.9</mock-javamail.version>
+ <mvel2.version>2.4.8.Final</mvel2.version>
<pdfbox.version>2.0.21</pdfbox.version>
<slf4j-log4j12.version>1.7.30</slf4j-log4j12.version><!-- Mess in the transitive dependencies of hbase-testing-util -->
<sshd.version>2.3.0</sshd.version>
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index f12e70a..6435c1d 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -1530,6 +1530,16 @@
<groupId>org.apache.camel</groupId>
<artifactId>camel-optaplanner</artifactId>
<version>${camel.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.optaplanner</groupId>
+ <artifactId>optaplanner-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.optaplanner</groupId>
+ <artifactId>optaplanner-persistence-common</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
diff --git a/tooling/scripts/test-categories.yaml b/tooling/scripts/test-categories.yaml
index 5327b7c..b0e8ee7 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -92,6 +92,7 @@ xml-json-olingo4:
- weather
- geocoder
- lumberjack
+ - optaplanner
dozer-social:
- crypto
- dozer