/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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.drools.compiler.integrationtests;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.Test;
import org.kie.internal.KnowledgeBase;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderConfiguration;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.io.ResourceFactory;
import org.kie.api.io.Resource;
import org.kie.api.io.ResourceType;
public class ParallelCompilationTest {
private static final int PARALLEL_THREADS = 5;
private static final ExecutorService executor = Executors.newFixedThreadPool(PARALLEL_THREADS);
private static final String DRL_FILE = "parallel_compilation.drl";
private List<User> users;
@Test(timeout=10000)
public void testConcurrentRuleAdditions() throws Exception {
parallelExecute(BuildExecutor.getSolvers());
}
private void parallelExecute(Collection<Callable<KnowledgeBase>> solvers) throws Exception {
CompletionService<KnowledgeBase> ecs = new ExecutorCompletionService<KnowledgeBase>(executor);
for (Callable<KnowledgeBase> s : solvers) {
ecs.submit(s);
}
for (int i = 0; i < PARALLEL_THREADS; ++i) {
KnowledgeBase kbase = ecs.take().get();
}
}
public static class BuildExecutor implements Callable<KnowledgeBase> {
public KnowledgeBase call() throws Exception {
final Reader source = new InputStreamReader(ParallelCompilationTest.class.getResourceAsStream(DRL_FILE));
final Properties props = new Properties();
props.setProperty("drools.dialect.java.compiler", "JANINO");
props.setProperty("drools.dialect.java.compiler.lnglevel", "1.6");
KnowledgeBase result;
final KnowledgeBuilderConfiguration configuration = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(props, ParallelCompilationTest.class.getClass().getClassLoader());
final KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder(configuration);
Thread.sleep(Math.round(Math.random()*250));
Resource newReaderResource = ResourceFactory.newReaderResource(source);
//synchronized (RuleUtil.class)
{
builder.add(newReaderResource, ResourceType.DRL);
}
result = builder.newKnowledgeBase();
return result;
}
public static Collection<Callable<KnowledgeBase>> getSolvers() {
Collection<Callable<KnowledgeBase>> solvers = new ArrayList<Callable<KnowledgeBase>>();
for (int i = 0; i < PARALLEL_THREADS; ++i) {
solvers.add(new BuildExecutor());
}
return solvers;
}
}
public static class User {
private int age;
private boolean risky;
private Gender gender;
private String name;
public enum Gender { MALE, FEMALE, OTHER}
public User(int age, Gender gender, String name) {
this.age = age;
this.gender = gender;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isRisky() {
return risky;
}
public void setRisky(boolean risky) {
this.risky = risky;
}
}
}