Package org.drools.compiler.integrationtests

Source Code of org.drools.compiler.integrationtests.MTEntryPointsTest

package org.drools.compiler.integrationtests;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.drools.core.time.SessionPseudoClock;
import org.junit.After;
import org.junit.Test;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;

import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.kie.api.builder.model.KieModuleModel;
import org.kie.api.io.Resource;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.conf.ClockTypeOption;
import org.kie.api.runtime.rule.EntryPoint;

/**
* Tests inserting events into KIE Session from multiple threads using one and
* two entry points.
*
* BZ-967599
*/
public class MTEntryPointsTest {

    private KieSession kieSession;

    @Before
    public void initSession() {
        String str = "package org.jboss.brms\n" +
                     "\n" +
                     "import org.drools.compiler.integrationtests.MTEntryPointsTest.MessageEvent\n" +
                     "\n" +
                     "declare MessageEvent\n" +
                     "    @role( event )\n" +
                     "end\n" +
                     "\n" +
                     "rule \"sum of last event from first entry point\"\n" +
                     "    when\n" +
                     "\t    accumulate (\n" +
                     "\t        MessageEvent ($value : value) over window:length(1) from entry-point \"FirstStream\",\n" +
                     "\t        $sum : sum($value)\n" +
                     "\t    )\n" +
                     "    then\n" +
                     "end\n" +
                     "\n" +
                     "rule \"sum of last event from both entry points\"\n" +
                     "    when\n" +
                     "        accumulate (\n" +
                     "            MessageEvent ($value1 : value) over window:length(1) from entry-point \"FirstStream\",\n" +
                     "            $thirdSum1 : sum($value1)\n" +
                     "        )\n" +
                     "        accumulate (\n" +
                     "            MessageEvent ($value2 : value) over window:length(1) from entry-point \"SecondStream\",\n" +
                     "            $thirdSum2 : sum($value2)\n" +
                     "        )\n" +
                     "    then\n" +
                     "end\n" +
                     "\n";

        KieServices ks = KieServices.Factory.get();
        KieFileSystem kfs = ks.newKieFileSystem().write( "src/main/resources/r1.drl", str );

        KieModuleModel kmoduleModel = ks.newKieModuleModel();
        kmoduleModel.newKieBaseModel("defaultKieBase")
                    .addPackage("*")
                    .newKieSessionModel("defaultKieSession")
                    .setDefault(true)
                    .setClockType(ClockTypeOption.get("pseudo"));
        kfs.writeKModuleXML(kmoduleModel.toXML());

        KieBuilder builder = ks.newKieBuilder(kfs).buildAll();
        assertEquals(0, builder.getResults().getMessages().size());
        ks.getRepository().addKieModule(builder.getKieModule());

        this.kieSession = ks.newKieContainer(ks.getRepository()
                                               .getDefaultReleaseId()).newKieSession();
    }

    @After
    public void cleanup() {
        if (this.kieSession != null) {
            this.kieSession.dispose();
        }
    }

    /**
     * Inserts events using multiple threads into one EntryPoint. The insert
     * operation is synchronized on corresponding SessionEntryPoint instance.
     */
    @Test
    public void testOneEntryPoint() throws Exception {
        final EntryPoint firstThreadEntryPoint = kieSession.getEntryPoint("FirstStream");

        int numInsertersInEachEntryPoint = 10;
        int numThreadPoolCapacity = numInsertersInEachEntryPoint;

        ExecutorService executorService = Executors.newFixedThreadPool(numThreadPoolCapacity);
        List<Future<?>> futures = new ArrayList<Future<?>>();

        for (int i = 0; i < numInsertersInEachEntryPoint; i++) {
            // future for exception watching
            Future<?> futureForFirstThread = executorService.submit(
                    new TestInserter(kieSession, firstThreadEntryPoint));
            futures.add(futureForFirstThread);
        }

        try {
            for (Future<?> f : futures) {
                f.get(30, TimeUnit.SECONDS);
            }
        } catch (ExecutionException ex) {
            throw ex;
        }
    }

    /**
     * Inserts events using multiple threads into two EntryPoints. The insert
     * operation is synchronized on corresponding SessionEntryPoint instance.
     */
    @Test
    public void testTwoEntryPoints() throws Exception {

        final EntryPoint firstThreadEntryPoint = kieSession.getEntryPoint("FirstStream");
        final EntryPoint secondThreadEntryPoint = kieSession.getEntryPoint("SecondStream");

        int numInsertersInEachEntryPoint = 10;
        int numThreadPoolCapacity = numInsertersInEachEntryPoint * 2;

        ExecutorService executorService = Executors.newFixedThreadPool(numThreadPoolCapacity);
        List<Future<?>> futures = new ArrayList<Future<?>>();

        for (int i = 0; i < numInsertersInEachEntryPoint; i++) {
            // working only with first stream, future for exception watching
            Future<?> futureForFirstThread = executorService.submit(new TestInserter(kieSession,
                                                                                     firstThreadEntryPoint));
            futures.add(futureForFirstThread);

            // working only with second stream, future for exception watching
            Future<?> futureForSecondThread = executorService.submit(new TestInserter(kieSession,
                                                                                      secondThreadEntryPoint));
            futures.add(futureForSecondThread);
        }

        try {
            for (Future<?> f : futures) {
                f.get(30, TimeUnit.SECONDS);
            }
        } catch (ExecutionException ex) {
            throw ex;
        }
    }

    /**
     * Inserts 10 test events into specified EntryPoint and advances pseudo-clock
     * time by a fixed amount.
     *
     * Insert operation is synchronized on given SessionEntryPoint instance.
     */
    public static class TestInserter implements Runnable {

        private final EntryPoint entryPoint;
        private final KieSession kieSession;

        public TestInserter(final KieSession kieSession, final EntryPoint entryPoint) {
            this.kieSession = kieSession;
            this.entryPoint = entryPoint;
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                synchronized (entryPoint) {
                    entryPoint.insert(new MessageEvent(i));
                }
                advanceTime(100);
            }
        }

        private void advanceTime(long millis) {
            SessionPseudoClock pseudoClock = kieSession.getSessionClock();
            pseudoClock.advanceTime(millis, TimeUnit.MILLISECONDS);
        }
    }

    /**
     * Immutable event used in the test.
     */
    public static class MessageEvent {
        private int value;

        public MessageEvent(final int value) {
            this.value = value;
        }

        public int getValue() {
            return this.value;
        }
    }
}
TOP

Related Classes of org.drools.compiler.integrationtests.MTEntryPointsTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.