use of org.kie.internal.runtime.StatefulKnowledgeSession in project drools by kiegroup.
the class ReloadSessionTest method reloadKnowledgeSessionTest.
@Test
public void reloadKnowledgeSessionTest() {
// Initialize drools environment stuff
Environment env = createEnvironment();
KieBase kbase = initializeKnowledgeBase(simpleRule);
StatefulKnowledgeSession commandKSession = JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env);
assertTrue("There should be NO facts present in a new (empty) knowledge session.", commandKSession.getFactHandles().isEmpty());
// Persist a facthandle to the database
Integer integerFact = (new Random()).nextInt(Integer.MAX_VALUE - 1) + 1;
commandKSession.insert(integerFact);
// At this point in the code, the fact has been persisted to the database
// (within a transaction via the PersistableRunner)
Collection<FactHandle> factHandles = commandKSession.getFactHandles();
assertTrue("At least one fact should have been inserted by the ksession.insert() method above.", !factHandles.isEmpty());
FactHandle origFactHandle = factHandles.iterator().next();
assertTrue("The stored fact should contain the same number as the value inserted (but does not).", Integer.parseInt(((DefaultFactHandle) origFactHandle).getObject().toString()) == integerFact.intValue());
// Save the sessionInfo id in order to retrieve it later
long sessionInfoId = commandKSession.getIdentifier();
// Clean up the session, environment, etc.
PersistenceContextManager pcm = (PersistenceContextManager) commandKSession.getEnvironment().get(EnvironmentName.PERSISTENCE_CONTEXT_MANAGER);
commandKSession.dispose();
pcm.dispose();
emf.close();
// Reload session from the database
emf = Persistence.createEntityManagerFactory(DROOLS_PERSISTENCE_UNIT_NAME);
context.put(ENTITY_MANAGER_FACTORY, emf);
env = createEnvironment();
// Re-initialize the knowledge session:
StatefulKnowledgeSession newCommandKSession = JPAKnowledgeService.loadStatefulKnowledgeSession(sessionInfoId, kbase, null, env);
// Test that the session has been successfully reinitialized
factHandles = newCommandKSession.getFactHandles();
assertTrue("At least one fact should have been persisted by the ksession.insert above.", !factHandles.isEmpty() && factHandles.size() == 1);
FactHandle retrievedFactHandle = factHandles.iterator().next();
assertTrue("If the retrieved and original FactHandle object are the same, then the knowledge session has NOT been reloaded!", origFactHandle != retrievedFactHandle);
assertTrue("The retrieved fact should contain the same info as the original (but does not).", Integer.parseInt(((DefaultFactHandle) retrievedFactHandle).getObject().toString()) == integerFact.intValue());
// Test to see if the (retrieved) facts can be processed
ArrayList<Object> list = new ArrayList<Object>();
newCommandKSession.setGlobal("list", list);
newCommandKSession.fireAllRules();
assertEquals(1, list.size());
}
use of org.kie.internal.runtime.StatefulKnowledgeSession in project drools by kiegroup.
the class TransactionTestCommand method execute.
public Void execute(Context context) {
em.joinTransaction();
em.persist(mainObject);
if (subObject != null) {
KieSession ksession = ((RegistryContext) context).lookup(KieSession.class);
// THe following 3 lines are the important ones! (See below for an explanation)
InternalKnowledgeBase cleanKBase = KnowledgeBaseFactory.newKnowledgeBase();
cleanKBase.addPackages(ksession.getKieBase().getKiePackages());
StatefulKnowledgeSession commandKSession = JPAKnowledgeService.newStatefulKnowledgeSession(cleanKBase, null, initializeEnvironment());
/**
* Here's what's going on:
* If the PersistableRunner (SSCS) & JtaTransactionManager (JTM) were _not_ aware of transactions,
* -> then inserting the mainObject _before_ having inserted the subObject
* would cause the operation/persist to fail and the transaction to fail.
* - This is because the mainObject contains a foreign key referring to the subObject.
*
* However, the SSCS & JTM check whether or not they're owners of the transaction
* when starting and when committing the transaction they use.
* -> So that when we insert the mainObject here (via a _new_ CommandBasedStatefulKnowledgeSession),
* it does _not_ mess with the transaction state and the operation succeeds.
*/
TransactionTestCommand transactionTestSubCommand = new TransactionTestCommand(this.subObject, getPersistenceEnvironment());
commandKSession.execute(transactionTestSubCommand);
}
return null;
}
use of org.kie.internal.runtime.StatefulKnowledgeSession in project drools by kiegroup.
the class JpaOptLockPersistentStatefulSessionTest method testOptimisticLockInterceptorMaxRetry.
@Test
public void testOptimisticLockInterceptorMaxRetry() {
String str = "";
str += "package org.kie.test\n";
str += "rule rule1\n";
str += "when\n";
str += " Integer(intValue == 1)\n";
str += "then\n";
str += "end\n";
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newByteArrayResource(str.getBytes()), ResourceType.DRL);
final InternalKnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
if (kbuilder.hasErrors()) {
fail(kbuilder.getErrors().toString());
}
kbase.addPackages(kbuilder.getKnowledgePackages());
final AtomicInteger attempts = new AtomicInteger(0);
final StatefulKnowledgeSession ksession1 = JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env);
PersistableRunner sscs1 = (PersistableRunner) ((CommandBasedStatefulKnowledgeSession) ksession1).getRunner();
OptimisticLockRetryInterceptor interceptor1 = new OptimisticLockRetryInterceptor();
sscs1.addInterceptor(interceptor1);
ksession1.addEventListener(new DefaultRuleRuntimeEventListener() {
public void objectInserted(ObjectInsertedEvent event) {
attempts.incrementAndGet();
try {
ksession1latch = new CountDownLatch(1);
ksession2latch.countDown();
// Wait for ksession2 to commit so ksesison1 will hit OptimisticLockException
ksession1latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
final long ksessionId = ksession1.getIdentifier();
StatefulKnowledgeSession ksession2 = JPAKnowledgeService.loadStatefulKnowledgeSession(ksessionId, kbase, null, createEnvironment(context));
PersistableRunner sscs2 = (PersistableRunner) ((CommandBasedStatefulKnowledgeSession) ksession2).getRunner();
OptimisticLockRetryInterceptor interceptor2 = new OptimisticLockRetryInterceptor();
sscs2.addInterceptor(interceptor2);
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(() -> {
try {
ksession1.insert(1);
} catch (Exception e) {
e.printStackTrace();
} finally {
ksession1.dispose();
isKsession1finished = true;
ksession2latch.countDown();
}
});
try {
while (!isKsession1finished) {
try {
ksession2latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
ksession2latch = new CountDownLatch(1);
ksession2.insert(2);
ksession1latch.countDown();
}
} finally {
ksession2.dispose();
executor.shutdown();
}
try {
executor.awaitTermination(300, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
assertEquals(4, attempts.get());
}
use of org.kie.internal.runtime.StatefulKnowledgeSession in project jbpm by kiegroup.
the class JbpmSerializationHelper method getSerialisedStatefulKnowledgeSession.
public static StatefulKnowledgeSession getSerialisedStatefulKnowledgeSession(StatefulKnowledgeSession ksession, ObjectMarshallingStrategy[] strategies, boolean dispose) throws Exception {
Marshaller marshaller = MarshallerFactory.newMarshaller(ksession.getKieBase(), strategies);
final byte[] b1 = serializeKnowledgeSession(marshaller, ksession);
StatefulKnowledgeSession ksession2 = deserializeKnowledgeSession(marshaller, b1);
final byte[] b2 = serializeKnowledgeSession(marshaller, ksession2);
// bytes should be the same.
if (!areByteArraysEqual(b1, b2)) {
// throw new IllegalArgumentException( "byte streams for serialisation test are not equal" );
}
((StatefulKnowledgeSessionImpl) ksession2).setGlobalResolver(((StatefulKnowledgeSessionImpl) ksession).getGlobalResolver());
if (dispose) {
ksession.dispose();
}
return ksession2;
}
use of org.kie.internal.runtime.StatefulKnowledgeSession in project jbpm by kiegroup.
the class JbpmSerializationHelper method deserializeKnowledgeSession.
public static StatefulKnowledgeSession deserializeKnowledgeSession(Marshaller marshaller, byte[] serializedKsession) throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(serializedKsession);
StatefulKnowledgeSession deserializedKsession = (StatefulKnowledgeSession) marshaller.unmarshall(bais, SessionConfiguration.newInstance(), EnvironmentFactory.newEnvironment());
bais.close();
return deserializedKsession;
}
Aggregations