camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bibr...@apache.org
Subject camel git commit: Added consumer, producer with event listeners, async and daemon solving features
Date Fri, 21 Aug 2015 01:10:25 GMT
Repository: camel
Updated Branches:
  refs/heads/master 32d75e290 -> cba859770


Added consumer, producer with event listeners, async and daemon solving features


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/cba85977
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/cba85977
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/cba85977

Branch: refs/heads/master
Commit: cba859770c005dea2bb217e672adf40de682e416
Parents: 32d75e2
Author: Bilgin Ibryam <bibryam@apache.org>
Authored: Fri Aug 21 02:09:43 2015 +0100
Committer: Bilgin Ibryam <bibryam@apache.org>
Committed: Fri Aug 21 02:09:43 2015 +0100

----------------------------------------------------------------------
 .../optaplanner/OptaPlannerComponent.java       |  12 +-
 .../optaplanner/OptaPlannerConfiguration.java   |  83 +++++++++++++
 .../optaplanner/OptaPlannerConstants.java       |  28 +++++
 .../optaplanner/OptaPlannerConsumer.java        |  75 +++++++++++
 .../optaplanner/OptaPlannerEndpoint.java        |  80 +++++++-----
 .../optaplanner/OptaPlannerProducer.java        | 124 +++++++++++++++++++
 .../optaplanner/OptaPlannerAsyncSolverTest.java |  63 ++++++++++
 .../optaplanner/OptaPlannerConsumerTest.java    |  70 +++++++++++
 .../OptaPlannerDaemonSolverTest.java            |  96 ++++++++++++++
 .../optaplanner/OptaPlannerSyncSolverTest.java  |  55 ++++++++
 .../component/optaplanner/OptaPlannerTest.java  |  55 --------
 .../optaplanner/daemonSolverConfig.xml          |  55 ++++++++
 .../component/optaplanner/solverConfig.xml      |   2 +-
 13 files changed, 704 insertions(+), 94 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/cba85977/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerComponent.java
b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerComponent.java
index cb59460..b188d39 100644
--- a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerComponent.java
+++ b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerComponent.java
@@ -20,7 +20,6 @@ import java.util.Map;
 
 import org.apache.camel.Endpoint;
 import org.apache.camel.impl.UriEndpointComponent;
-import org.optaplanner.core.api.solver.SolverFactory;
 
 /**
  * OptaPlanner component for Camel
@@ -32,13 +31,10 @@ public class OptaPlannerComponent extends UriEndpointComponent {
     }
 
     protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object>
parameters) throws Exception {
-        SolverFactory solverFactory = SolverFactory.createFromXmlResource(remaining);
-
-        OptaPlannerEndpoint endpoint = new OptaPlannerEndpoint(uri, this, remaining);
-        endpoint.setSolverFactory(solverFactory);
-        setProperties(endpoint, parameters);
-
-        return endpoint;
+        OptaPlannerConfiguration configuration = new OptaPlannerConfiguration();
+        configuration.setConfigFile(remaining);
+        setProperties(configuration, parameters);
+        return new OptaPlannerEndpoint(uri, this, configuration);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/cba85977/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConfiguration.java
b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConfiguration.java
new file mode 100644
index 0000000..0e70c77
--- /dev/null
+++ b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConfiguration.java
@@ -0,0 +1,83 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.optaplanner;
+
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.apache.camel.spi.UriPath;
+
+@UriParams
+public class OptaPlannerConfiguration {
+
+    /**
+     * Specifies the solverId to user for the solver instance key
+     */
+    @UriParam(label = "common", defaultValue = "DEFAULT_SOLVER")
+    private String solverId = OptaPlannerConstants.DEFAULT_SOLVER_ID;
+
+    /**
+     * Specifies the location to the solver file
+     */
+    @UriPath
+    @Metadata(required = "true")
+    private String configFile;
+
+    /**
+     * Specifies the thread pool size to use when async is true
+     */
+    @UriParam(label = "producer", defaultValue = "10")
+    private int threadPoolSize = 10;
+
+    /**
+     * Specifies to perform operations in async mode
+     */
+    @UriParam(label = "producer", defaultValue = "false")
+    private boolean async;
+
+    public String getSolverId() {
+        return solverId;
+    }
+
+    public void setSolverId(String solverId) {
+        this.solverId = solverId;
+    }
+
+    public void setConfigFile(String configFile) {
+        this.configFile = configFile;
+    }
+
+    public String getConfigFile() {
+        return configFile;
+    }
+
+    public int getThreadPoolSize() {
+        return threadPoolSize;
+    }
+
+    public void setThreadPoolSize(int threadPoolSize) {
+        this.threadPoolSize = threadPoolSize;
+    }
+
+    public boolean isAsync() {
+        return async;
+    }
+
+    public void setAsync(boolean async) {
+        this.async = async;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/cba85977/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConstants.java
----------------------------------------------------------------------
diff --git a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConstants.java
b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConstants.java
new file mode 100644
index 0000000..986a161
--- /dev/null
+++ b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConstants.java
@@ -0,0 +1,28 @@
+/**
+ * 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;
+
+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_FACT_PROCESSED = "CamelOptaPlannerIsFactProcessed";
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/cba85977/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConsumer.java
----------------------------------------------------------------------
diff --git a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConsumer.java
b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConsumer.java
new file mode 100644
index 0000000..0e10a79
--- /dev/null
+++ b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerConsumer.java
@@ -0,0 +1,75 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.optaplanner;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.impl.DefaultConsumer;
+import org.optaplanner.core.api.solver.Solver;
+import org.optaplanner.core.api.solver.event.BestSolutionChangedEvent;
+import org.optaplanner.core.api.solver.event.SolverEventListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * OptaPlanner component for Camel
+ */
+public class OptaPlannerConsumer extends DefaultConsumer {
+    private static final transient Logger LOGGER = LoggerFactory.getLogger(OptaPlannerConsumer.class);
+    private final OptaPlannerEndpoint endpoint;
+    private final OptaPlannerConfiguration configuration;
+    private final SolverEventListener listener;
+
+    public OptaPlannerConsumer(OptaPlannerEndpoint endpoint, Processor processor, OptaPlannerConfiguration
configuration) {
+        super(endpoint, processor);
+        this.endpoint = endpoint;
+        this.configuration = configuration;
+        listener = new SolverEventListener() {
+            @Override
+            public void bestSolutionChanged(BestSolutionChangedEvent event) {
+                if (event.isEveryProblemFactChangeProcessed() && event.isNewBestSolutionInitialized())
{
+                    processEvent(event);
+                }
+            }
+        };
+    }
+
+    public void processEvent(BestSolutionChangedEvent event) {
+        Exchange exchange = getEndpoint().createExchange();
+        exchange.getOut().setHeader(OptaPlannerConstants.BEST_SOLUTION, event.getNewBestSolution());
+        try {
+            getProcessor().process(exchange);
+        } catch (Exception e) {
+            LOGGER.error("Error processing event ", e);
+        }
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        Solver solver = endpoint.getOrCreateSolver(configuration.getSolverId());
+        solver.addEventListener(listener);
+        super.doStart();
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        Solver solver = endpoint.getOrCreateSolver(configuration.getSolverId());
+        solver.removeEventListener(listener);
+        super.doStop();
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/camel/blob/cba85977/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerEndpoint.java
----------------------------------------------------------------------
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 3eade1b..8424530 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
@@ -16,63 +16,83 @@
  */
 package org.apache.camel.component.optaplanner;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.apache.camel.Component;
-import org.apache.camel.Exchange;
-import org.apache.camel.ExchangePattern;
-import org.apache.camel.component.ResourceEndpoint;
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.impl.DefaultEndpoint;
 import org.apache.camel.spi.UriEndpoint;
-import org.apache.camel.util.ObjectHelper;
-import org.optaplanner.core.api.domain.solution.Solution;
+import org.apache.camel.spi.UriParam;
 import org.optaplanner.core.api.solver.Solver;
 import org.optaplanner.core.api.solver.SolverFactory;
 
 /**
  * OptaPlanner endpoint for Camel
  */
-@UriEndpoint(scheme = "optaplanner", title = "OptaPlanner", syntax = "optaplanner:resourceUri",
producerOnly = true, label = "engine,planning")
-public class OptaPlannerEndpoint extends ResourceEndpoint {
+@UriEndpoint(scheme = "optaplanner", title = "OptaPlanner", syntax = "optaplanner:resourceUri",
label = "engine,planning")
+public class OptaPlannerEndpoint extends DefaultEndpoint {
+    protected static final Map<String, Solver> SOLVERS = new HashMap<String, Solver>();
 
+    @UriParam
+    private OptaPlannerConfiguration configuration;
     private SolverFactory solverFactory;
 
     public OptaPlannerEndpoint() {
     }
 
-    public OptaPlannerEndpoint(String uri, Component component, String resourceUri) {
-        super(uri, component, resourceUri);
+    public OptaPlannerEndpoint(String uri, Component component, OptaPlannerConfiguration
configuration) {
+        super(uri, component);
+        this.configuration = configuration;
+        solverFactory = SolverFactory.createFromXmlResource(configuration.getConfigFile());
     }
 
-    public SolverFactory getSolverFactory() {
-        return solverFactory;
+    protected Solver getOrCreateSolver(String solverId) throws Exception {
+        synchronized (SOLVERS) {
+            Solver solver = SOLVERS.get(solverId);
+            if (solver == null) {
+                solver = createSolver();
+                SOLVERS.put(solverId, solver);
+            }
+            return solver;
+        }
     }
 
-    public void setSolverFactory(SolverFactory solverFactory) {
-        this.solverFactory = solverFactory;
+    protected Solver createSolver() {
+        return solverFactory.buildSolver();
     }
 
-    @Override
-    public ExchangePattern getExchangePattern() {
-        return ExchangePattern.InOut;
+    protected Solver getSolver(String solverId) {
+        synchronized (SOLVERS) {
+            return SOLVERS.get(solverId);
+        }
     }
 
     @Override
-    protected String createEndpointUri() {
-        return "optaplanner:" + getResourceUri();
+    public Producer createProducer() throws Exception {
+        return new OptaPlannerProducer(this, configuration);
     }
 
     @Override
-    protected void onExchange(Exchange exchange) throws Exception {
-        ObjectHelper.notNull(solverFactory, "solverFactory");
-        Solver solver = solverFactory.buildSolver();
-
-        Solution planningProblem = exchange.getIn().getMandatoryBody(Solution.class);
-
-        solver.solve(planningProblem);
-        Solution bestSolution = solver.getBestSolution();
+    public Consumer createConsumer(Processor processor) throws Exception {
+        return new OptaPlannerConsumer(this, processor, configuration);
+    }
 
-        exchange.getOut().setBody(bestSolution);
-        // propagate headers and attachments
-        exchange.getOut().setHeaders(exchange.getIn().getHeaders());
-        exchange.getOut().setAttachments(exchange.getIn().getAttachments());
+    @Override
+    public boolean isSingleton() {
+        return true;
     }
 
+    @Override
+    protected void doStop() throws Exception {
+        synchronized (SOLVERS) {
+            for (Solver solver : SOLVERS.values()) {
+                solver.terminateEarly();
+                SOLVERS.remove(solver);
+            }
+        }
+        super.doStop();
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/cba85977/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerProducer.java
b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerProducer.java
new file mode 100644
index 0000000..c862cd7
--- /dev/null
+++ b/components/camel-optaplanner/src/main/java/org/apache/camel/component/optaplanner/OptaPlannerProducer.java
@@ -0,0 +1,124 @@
+/**
+ * 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.ExecutorService;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.impl.DefaultProducer;
+import org.optaplanner.core.api.domain.solution.Solution;
+import org.optaplanner.core.api.solver.Solver;
+import org.optaplanner.core.impl.solver.ProblemFactChange;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OptaPlannerProducer extends DefaultProducer {
+    private static final transient Logger LOGGER = LoggerFactory.getLogger(OptaPlannerProducer.class);
+    private ExecutorService executor;
+    private final OptaPlannerEndpoint endpoint;
+    private final OptaPlannerConfiguration configuration;
+
+    public OptaPlannerProducer(OptaPlannerEndpoint endpoint, OptaPlannerConfiguration configuration)
{
+        super(endpoint);
+        this.endpoint = endpoint;
+        this.configuration = configuration;
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        if (configuration.isAsync()) {
+            executor = endpoint.getCamelContext().getExecutorServiceManager().newFixedThreadPool(
+                    this, endpoint.getEndpointUri(), configuration.getThreadPoolSize());
+        }
+        super.doStart();
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        if (executor != null) {
+            endpoint.getCamelContext().getExecutorServiceManager().shutdown(executor);
+            executor = null;
+        }
+        super.doStop();
+    }
+
+    @Override
+    public synchronized void process(Exchange exchange) throws Exception {
+        final Object body = exchange.getIn().getMandatoryBody();
+        final String solverId = getSolverId(exchange);
+
+        if (body instanceof Solution) {
+            if (isAsync(exchange)) {
+                LOGGER.debug("Asynchronously solving problem: [{}] with id [{}]", body, solverId);
+                final Solver solver = endpoint.getOrCreateSolver(solverId);
+                executor.submit(new Runnable() {
+                    @Override
+                    public void run() {
+                        solver.solve((Solution)body);
+                    }
+                });
+            } else {
+                LOGGER.debug("Synchronously solving problem: [{}] with id [{}]", body, solverId);
+                Solver solver = endpoint.getSolver(solverId);
+                if (solver == null) {
+                    solver = endpoint.createSolver();
+                }
+                solver.solve((Solution) body);
+                populateResult(exchange, solver);
+            }
+        } else if (body instanceof ProblemFactChange) {
+            LOGGER.debug("Adding ProblemFactChange to solver: [{}] with id [{}]", body, solverId);
+            Solver solver = endpoint.getOrCreateSolver(solverId);
+            solver.addProblemFactChange((ProblemFactChange)body);
+            if (!isAsync(exchange)) {
+                while (!solver.isEveryProblemFactChangeProcessed()) {
+                    Thread.currentThread().sleep(100);
+                }
+            }
+            populateResult(exchange, solver);
+        } else {
+            LOGGER.debug("Retrieving best score for solver: [{}]", solverId);
+            Solver solver = endpoint.getSolver(solverId);
+            if (solver == null) {
+                throw new RuntimeException("Solver not found: " + solverId);
+            }
+            populateResult(exchange, solver);
+        }
+    }
+
+    private void populateResult(Exchange exchange, Solver solver) {
+        exchange.getIn().setBody(solver.getBestSolution());
+        exchange.getIn().setHeader(OptaPlannerConstants.TIME_SPENT, solver.getTimeMillisSpent());
+        exchange.getIn().setHeader(OptaPlannerConstants.IS_FACT_PROCESSED, solver.isEveryProblemFactChangeProcessed());
+        exchange.getIn().setHeader(OptaPlannerConstants.IS_TERMINATE_EARLY, solver.isTerminateEarly());
+        exchange.getIn().setHeader(OptaPlannerConstants.IS_SOLVING, solver.isSolving());
+    }
+
+    private String getSolverId(Exchange exchange) throws Exception {
+        String solverId = exchange.getIn().getHeader(OptaPlannerConstants.SOLVER_ID, String.class);
+        if (solverId == null) {
+            solverId = configuration.getSolverId();
+        }
+        LOGGER.debug("SolverId: [{}]", solverId);
+        return solverId;
+    }
+
+    private boolean isAsync(Exchange exchange) {
+        Boolean isAsync = exchange.getIn().getHeader(OptaPlannerConstants.IS_ASYNC, Boolean.class);
+        return isAsync != null ? isAsync : configuration.isAsync();
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/cba85977/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerAsyncSolverTest.java
----------------------------------------------------------------------
diff --git a/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerAsyncSolverTest.java
b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerAsyncSolverTest.java
new file mode 100644
index 0000000..cdbafe7
--- /dev/null
+++ b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerAsyncSolverTest.java
@@ -0,0 +1,63 @@
+/**
+ * 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.junit4.CamelTestSupport;
+import org.junit.Test;
+import org.optaplanner.examples.cloudbalancing.domain.CloudBalance;
+import org.optaplanner.examples.cloudbalancing.persistence.CloudBalancingGenerator;
+
+/**
+ * OptaPlanner unit test with Camel
+ */
+public class OptaPlannerAsyncSolverTest extends CamelTestSupport {
+
+    @Test
+    public void testAsynchronousProblemSolving() 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());
+
+        template.requestBody("direct:in", planningProblem);
+        getMockEndpoint("mock:result").assertIsSatisfied();
+
+        CloudBalance bestSolution = (CloudBalance) template.requestBody("direct:in", "foo");
+
+        assertEquals(4, bestSolution.getComputerList().size());
+        assertEquals(12, bestSolution.getProcessList().size());
+        assertNotNull(bestSolution.getScore());
+        assertTrue(bestSolution.getScore().isFeasible());
+        assertNotNull(bestSolution.getProcessList().get(0).getComputer());
+    }
+
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:in").
+                        to("optaplanner:org/apache/camel/component/optaplanner/solverConfig.xml?async=true");
+
+                from("optaplanner:org/apache/camel/component/optaplanner/solverConfig.xml").
+                        to("log:com.mycompany.order?showAll=true&multiline=true").
+                        to("mock:result");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/cba85977/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerConsumerTest.java
----------------------------------------------------------------------
diff --git a/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerConsumerTest.java
b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerConsumerTest.java
new file mode 100644
index 0000000..2e86201
--- /dev/null
+++ b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerConsumerTest.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.optaplanner;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.apache.commons.lang.ObjectUtils;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.optaplanner.core.impl.score.director.ScoreDirector;
+import org.optaplanner.core.impl.solver.ProblemFactChange;
+import org.optaplanner.examples.cloudbalancing.domain.CloudBalance;
+import org.optaplanner.examples.cloudbalancing.domain.CloudComputer;
+import org.optaplanner.examples.cloudbalancing.domain.CloudProcess;
+import org.optaplanner.examples.cloudbalancing.persistence.CloudBalancingGenerator;
+
+/**
+ * OptaPlanner unit test with Camel
+ */
+public class OptaPlannerConsumerTest 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());
+
+        CloudBalance bestSolution = (CloudBalance) template.requestBody("direct:in", planningProblem);
+
+        assertEquals(4, bestSolution.getComputerList().size());
+        assertEquals(12, bestSolution.getProcessList().size());
+        assertNotNull(bestSolution.getScore());
+        assertTrue(bestSolution.getScore().isFeasible());
+        assertNotNull(bestSolution.getProcessList().get(0).getComputer());
+    }
+
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:in").
+                        to("optaplanner:org/apache/camel/component/optaplanner/solverConfig.xml");
+
+                from("optaplanner:org/apache/camel/component/optaplanner/solverConfig.xml").
+                        to("log:com.mycompany.order?showAll=true&multiline=true").
+                        to("mock:result");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/cba85977/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerDaemonSolverTest.java
----------------------------------------------------------------------
diff --git a/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerDaemonSolverTest.java
b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerDaemonSolverTest.java
new file mode 100644
index 0000000..596fd16
--- /dev/null
+++ b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerDaemonSolverTest.java
@@ -0,0 +1,96 @@
+/**
+ * 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.ArrayList;
+import java.util.Iterator;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.apache.commons.lang.ObjectUtils;
+import org.junit.Test;
+import org.optaplanner.core.impl.score.director.ScoreDirector;
+import org.optaplanner.core.impl.solver.ProblemFactChange;
+import org.optaplanner.examples.cloudbalancing.domain.CloudBalance;
+import org.optaplanner.examples.cloudbalancing.domain.CloudComputer;
+import org.optaplanner.examples.cloudbalancing.domain.CloudProcess;
+import org.optaplanner.examples.cloudbalancing.persistence.CloudBalancingGenerator;
+
+/**
+ * OptaPlanner unit test with Camel
+ */
+public class OptaPlannerDaemonSolverTest extends CamelTestSupport {
+
+    @Test
+    public void testAsynchronousProblemSolving() 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());
+
+        template.requestBody("direct:in", planningProblem);
+        getMockEndpoint("mock:result").assertIsSatisfied();
+        getMockEndpoint("mock:result").reset();
+        getMockEndpoint("mock:result").setExpectedCount(1);
+
+        template.requestBody("direct:in", new ProblemFactChange() {
+            @Override
+            public void doChange(ScoreDirector scoreDirector) {
+                CloudBalance cloudBalance = (CloudBalance) scoreDirector.getWorkingSolution();
+                CloudComputer computer = null;
+                for (CloudProcess process : cloudBalance.getProcessList()) {
+                    computer = process.getComputer();
+                    if (ObjectUtils.equals(process.getComputer(), computer)) {
+                        scoreDirector.beforeVariableChanged(process, "computer");
+                        process.setComputer(null);
+                        scoreDirector.afterVariableChanged(process, "computer");
+                    }
+                }
+                cloudBalance.setComputerList(new ArrayList<CloudComputer>(cloudBalance.getComputerList()));
+                for (Iterator<CloudComputer> it = cloudBalance.getComputerList().iterator();
it.hasNext();) {
+                    CloudComputer workingComputer = it.next();
+                    if (ObjectUtils.equals(workingComputer, computer)) {
+                        scoreDirector.beforeProblemFactRemoved(workingComputer);
+                        it.remove(); // remove from list
+                        scoreDirector.beforeProblemFactRemoved(workingComputer);
+                        break;
+                    }
+                }
+            }
+        });
+
+        getMockEndpoint("mock:result").assertIsSatisfied();
+        CloudBalance bestSolution = (CloudBalance) template.requestBody("direct:in", "foo");
+
+        assertEquals(3, bestSolution.getComputerList().size());
+    }
+
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:in").
+                        to("optaplanner:org/apache/camel/component/optaplanner/daemonSolverConfig.xml?async=true");
+
+                from("optaplanner:org/apache/camel/component/optaplanner/daemonSolverConfig.xml").
+                        to("log:com.mycompany.order?showAll=true&multiline=true").
+                        to("mock:result");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/cba85977/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerSyncSolverTest.java
----------------------------------------------------------------------
diff --git a/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerSyncSolverTest.java
b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerSyncSolverTest.java
new file mode 100644
index 0000000..ed2e7c6
--- /dev/null
+++ b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerSyncSolverTest.java
@@ -0,0 +1,55 @@
+/**
+ * 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.junit4.CamelTestSupport;
+import org.junit.Test;
+import org.optaplanner.examples.cloudbalancing.domain.CloudBalance;
+import org.optaplanner.examples.cloudbalancing.persistence.CloudBalancingGenerator;
+
+/**
+ * OptaPlanner unit test with Camel
+ */
+public class OptaPlannerSyncSolverTest 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());
+
+        CloudBalance bestSolution = (CloudBalance) template.requestBody("direct:in", planningProblem);
+
+        assertEquals(4, bestSolution.getComputerList().size());
+        assertEquals(12, bestSolution.getProcessList().size());
+        assertNotNull(bestSolution.getScore());
+        assertTrue(bestSolution.getScore().isFeasible());
+        assertNotNull(bestSolution.getProcessList().get(0).getComputer());
+    }
+
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:in").
+                        to("optaplanner:org/apache/camel/component/optaplanner/solverConfig.xml");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/cba85977/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerTest.java
----------------------------------------------------------------------
diff --git a/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerTest.java
b/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerTest.java
deleted file mode 100644
index 5a7fd15..0000000
--- a/components/camel-optaplanner/src/test/java/org/apache/camel/component/optaplanner/OptaPlannerTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * 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.junit4.CamelTestSupport;
-import org.junit.Test;
-import org.optaplanner.examples.cloudbalancing.domain.CloudBalance;
-import org.optaplanner.examples.cloudbalancing.persistence.CloudBalancingGenerator;
-
-/**
- * OptaPlanner unit test with Camel
- */
-public class OptaPlannerTest extends CamelTestSupport {
-
-    @Test
-    public void testCloudBalance4computers12processes() throws Exception {
-        CloudBalancingGenerator generator = new CloudBalancingGenerator(true);
-        final CloudBalance planningProblem = generator.createCloudBalance(4, 12);
-        assertNull(planningProblem.getScore());
-        assertNull(planningProblem.getProcessList().get(0).getComputer());
-
-        CloudBalance bestSolution = (CloudBalance) template.requestBody("direct:in", planningProblem);
-
-        assertEquals(4, bestSolution.getComputerList().size());
-        assertEquals(12, bestSolution.getProcessList().size());
-        assertNotNull(bestSolution.getScore());
-        assertTrue(bestSolution.getScore().isFeasible());
-        assertNotNull(bestSolution.getProcessList().get(0).getComputer());
-    }
-
-    protected RouteBuilder createRouteBuilder() {
-        return new RouteBuilder() {
-            public void configure() {
-                from("direct:in").
-                        to("optaplanner:org/apache/camel/component/optaplanner/solverConfig.xml");
-            }
-        };
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/cba85977/components/camel-optaplanner/src/test/resources/org/apache/camel/component/optaplanner/daemonSolverConfig.xml
----------------------------------------------------------------------
diff --git a/components/camel-optaplanner/src/test/resources/org/apache/camel/component/optaplanner/daemonSolverConfig.xml
b/components/camel-optaplanner/src/test/resources/org/apache/camel/component/optaplanner/daemonSolverConfig.xml
new file mode 100644
index 0000000..45e60f3
--- /dev/null
+++ b/components/camel-optaplanner/src/test/resources/org/apache/camel/component/optaplanner/daemonSolverConfig.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<solver>
+
+  <!-- Run in daemon mode -->
+  <daemon>true</daemon>
+
+  <!--<environmentMode>FAST_ASSERT</environmentMode>-->
+
+  <!-- Domain model configuration -->
+  <solutionClass>org.optaplanner.examples.cloudbalancing.domain.CloudBalance</solutionClass>
+  <entityClass>org.optaplanner.examples.cloudbalancing.domain.CloudProcess</entityClass>
+
+  <!-- Score configuration -->
+  <scoreDirectorFactory>
+    <scoreDefinitionType>HARD_SOFT</scoreDefinitionType>
+    <scoreDrl>org/optaplanner/examples/cloudbalancing/solver/cloudBalancingScoreRules.drl</scoreDrl>
+  </scoreDirectorFactory>
+
+  <!-- Optimization algorithms configuration -->
+  <termination>
+    <terminationCompositionStyle>AND</terminationCompositionStyle>
+    <secondsSpentLimit>2</secondsSpentLimit>
+    <bestScoreFeasible>true</bestScoreFeasible>
+  </termination>
+  <constructionHeuristic>
+    <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType>
+    <forager>
+      <pickEarlyType>FIRST_NON_DETERIORATING_SCORE</pickEarlyType>
+    </forager>
+  </constructionHeuristic>
+  <localSearch>
+    <acceptor>
+      <entityTabuSize>7</entityTabuSize>
+    </acceptor>
+    <forager>
+      <acceptedCountLimit>1000</acceptedCountLimit>
+    </forager>
+  </localSearch>
+</solver>

http://git-wip-us.apache.org/repos/asf/camel/blob/cba85977/components/camel-optaplanner/src/test/resources/org/apache/camel/component/optaplanner/solverConfig.xml
----------------------------------------------------------------------
diff --git a/components/camel-optaplanner/src/test/resources/org/apache/camel/component/optaplanner/solverConfig.xml
b/components/camel-optaplanner/src/test/resources/org/apache/camel/component/optaplanner/solverConfig.xml
index 6ecf1a6..68f3e5b 100644
--- a/components/camel-optaplanner/src/test/resources/org/apache/camel/component/optaplanner/solverConfig.xml
+++ b/components/camel-optaplanner/src/test/resources/org/apache/camel/component/optaplanner/solverConfig.xml
@@ -31,7 +31,7 @@
   <!-- Optimization algorithms configuration -->
   <termination>
     <terminationCompositionStyle>AND</terminationCompositionStyle>
-    <secondsSpentLimit>10</secondsSpentLimit>
+    <secondsSpentLimit>2</secondsSpentLimit>
     <bestScoreFeasible>true</bestScoreFeasible>
   </termination>
   <constructionHeuristic>


Mime
View raw message