You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/07/23 20:04:50 UTC
[isis] branch master updated: ISIS-2573: remove
TransactionService#nextTransaction()
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 7e730cb ISIS-2573: remove TransactionService#nextTransaction()
7e730cb is described below
commit 7e730cbf8ddc2fd29f687facf50f11a099899325
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Jul 23 22:04:33 2021 +0200
ISIS-2573: remove TransactionService#nextTransaction()
also fixes most publishing tests
---
.../applib/services/xactn/TransactionService.java | 13 +-
.../transaction/TransactionServiceSpring.java | 96 +++++++-------
.../publishing/jpa/JpaPropertyPublishingTest.java | 1 +
.../publishing/PublishingTestFactoryAbstract.java | 105 +++++++++------
.../publishing/PublishingTestFactoryJdo.java | 145 +++++++--------------
.../publishing/PublishingTestFactoryJpa.java | 142 +++++++-------------
6 files changed, 223 insertions(+), 279 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService.java b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService.java
index f232e25..8fa2cc5 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService.java
@@ -62,9 +62,14 @@ public interface TransactionService extends TransactionalProcessor {
*/
void flushTransaction();
- /**
- * Commits the current thread's transaction (if there is one), and in any case begins a new one.
- */
- void nextTransaction();
+
+ //XXX we removed the entire method, because of following subtlety with JpaTransactionManager's commit
+ // If the transaction wasn't a new one, omit the commit for proper participation in
+ // the surrounding transaction. If a previous transaction has been suspended to be
+ // able to create a new one, resume the previous transaction after committing the new one.
+// /**
+// * Commits the current thread's transaction (if there is one), and in any case begins a new one.
+// */
+// void nextTransaction();
}
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/transaction/TransactionServiceSpring.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/transaction/TransactionServiceSpring.java
index 9825ae7..904c984 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/transaction/TransactionServiceSpring.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/transaction/TransactionServiceSpring.java
@@ -70,7 +70,7 @@ import lombok.extern.log4j.Log4j2;
public class TransactionServiceSpring
implements
TransactionService,
- TransactionBoundaryAware {
+ TransactionBoundaryAware {
private final Can<PlatformTransactionManager> platformTransactionManagers;
private final InteractionLayerTracker interactionLayerTracker;
@@ -95,7 +95,7 @@ implements
// -- SPRING INTEGRATION
@Override
- public <T> Result<T> callTransactional(TransactionDefinition def, Callable<T> callable) {
+ public <T> Result<T> callTransactional(final TransactionDefinition def, final Callable<T> callable) {
val txManager = transactionManagerForElseFail(def);
@@ -128,45 +128,49 @@ implements
return result;
}
- @Override
- public void nextTransaction() {
-
- val txManager = singletonTransactionManagerElseFail();
-
- try {
-
- val txTemplate = new TransactionTemplate(txManager);
- txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
-
- // either reuse existing or create new
- val txStatus = txManager.getTransaction(txTemplate);
- if(txStatus.isNewTransaction()) {
- // we have created a new transaction, so we are done
- return;
- }
- // we are reusing an exiting transaction, so end it and create a new one afterwards
- if(txStatus.isRollbackOnly()) {
- txManager.rollback(txStatus);
- } else {
- txManager.commit(txStatus);
- }
-
- // begin a new transaction
- txManager.getTransaction(txTemplate);
-
- } catch (RuntimeException ex) {
-
- val translatedEx = translateExceptionIfPossible(ex, txManager);
-
- if(translatedEx instanceof RuntimeException) {
- throw ex;
- }
-
- throw new RuntimeException(ex);
-
- }
-
- }
+// @Override
+// public void nextTransaction() {
+//
+// val txManager = singletonTransactionManagerElseFail();
+//
+// try {
+//
+// val txTemplate = new TransactionTemplate(txManager);
+// txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
+//
+// // either reuse existing or create new
+// val txStatus = txManager.getTransaction(txTemplate);
+// if(txStatus.isNewTransaction()) {
+// // we have created a new transaction, so we are done
+// return;
+// }
+// // we are reusing an exiting transaction, so end it and create a new one afterwards
+// if(txStatus.isRollbackOnly()) {
+// txManager.rollback(txStatus);
+// } else {
+// //XXX we removed the entire method, because of following subtlety
+ // If the transaction wasn't a new one, omit the commit for proper participation in
+// // the surrounding transaction. If a previous transaction has been suspended to be
+// // able to create a new one, resume the previous transaction after committing the new one.
+// txManager.commit(txStatus);
+// }
+//
+// // begin a new transaction
+// txManager.getTransaction(txTemplate);
+//
+// } catch (RuntimeException ex) {
+//
+// val translatedEx = translateExceptionIfPossible(ex, txManager);
+//
+// if(translatedEx instanceof RuntimeException) {
+// throw ex;
+// }
+//
+// throw new RuntimeException(ex);
+//
+// }
+//
+// }
@Override
public void flushTransaction() {
@@ -230,25 +234,25 @@ implements
/** INTERACTION BEGIN BOUNDARY */
@Override
- public void beforeEnteringTransactionalBoundary(Interaction interaction) {
+ public void beforeEnteringTransactionalBoundary(final Interaction interaction) {
txCounter.get().reset();
}
/** TRANSACTION END BOUNDARY */
@EventListener(TransactionAfterCompletionEvent.class)
- public void onTransactionEnded(TransactionAfterCompletionEvent event) {
+ public void onTransactionEnded(final TransactionAfterCompletionEvent event) {
txCounter.get().increment();
}
/** INTERACTION END BOUNDARY */
@Override
- public void afterLeavingTransactionalBoundary(Interaction interaction) {
+ public void afterLeavingTransactionalBoundary(final Interaction interaction) {
txCounter.remove(); //XXX not tested yet: can we be certain that no txCounter.get() is called afterwards?
}
// -- HELPER
- private PlatformTransactionManager transactionManagerForElseFail(TransactionDefinition def) {
+ private PlatformTransactionManager transactionManagerForElseFail(final TransactionDefinition def) {
if(def instanceof TransactionTemplate) {
val txManager = ((TransactionTemplate)def).getTransactionManager();
if(txManager!=null) {
@@ -291,7 +295,7 @@ implements
}
- private Throwable translateExceptionIfPossible(Throwable ex, PlatformTransactionManager txManager) {
+ private Throwable translateExceptionIfPossible(final Throwable ex, final PlatformTransactionManager txManager) {
if(ex instanceof DataAccessException) {
return ex; // nothing to do, already translated
diff --git a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/jpa/JpaPropertyPublishingTest.java b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/jpa/JpaPropertyPublishingTest.java
index dc33e86..40d26f1 100644
--- a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/jpa/JpaPropertyPublishingTest.java
+++ b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/jpa/JpaPropertyPublishingTest.java
@@ -50,6 +50,7 @@ import lombok.val;
//XrayEnable.class
},
properties = {
+ "logging.level.org.springframework.orm.jpa.*=DEBUG",
"logging.level.org.apache.isis.applib.services.publishing.log.*=DEBUG",
"logging.level.org.apache.isis.testdomain.util.rest.KVStoreForTesting=DEBUG",
"logging.level.org.apache.isis.core.transaction.changetracking.EntityChangeTrackerDefault=DEBUG",
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryAbstract.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryAbstract.java
index 5bbc386..51b28d8 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryAbstract.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryAbstract.java
@@ -39,10 +39,11 @@ import org.apache.isis.applib.services.xactn.TransactionService;
import org.apache.isis.applib.services.xactn.TransactionState;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.assertions._Assert;
+import org.apache.isis.commons.internal.debug._Probe;
import org.apache.isis.commons.internal.debug.xray.XrayUi;
import org.apache.isis.core.security.util.XrayUtil;
+import org.apache.isis.core.transaction.events.TransactionAfterCompletionEvent;
import org.apache.isis.core.transaction.events.TransactionBeforeCompletionEvent;
-import org.apache.isis.testdomain.publishing.PublishingTestFactoryAbstract.PublishingTestContext.TraceLog;
import lombok.Getter;
import lombok.NonNull;
@@ -63,6 +64,13 @@ public abstract class PublishingTestFactoryAbstract {
@Value(staticConstructor = "of")
public static class PublishingTestContext {
+ public static PublishingTestContext of(
+ final Runnable given,
+ final Consumer<VerificationStage> verifier,
+ final VerificationStage completionStage) {
+ return PublishingTestContext.of(new TraceLog(), given, verifier, completionStage);
+ }
+
public static class TraceLog {
private final StringBuilder buffer = new StringBuilder();
@Getter private boolean debug = true;
@@ -80,6 +88,7 @@ public abstract class PublishingTestFactoryAbstract {
private final @NonNull TraceLog traceLog;
private final @NonNull Runnable given;
private final @NonNull Consumer<VerificationStage> verifier;
+ private final @NonNull VerificationStage transactionCompletionStage;
public void runGiven() {
traceLog.log("2.1 about to run given");
@@ -94,17 +103,9 @@ public abstract class PublishingTestFactoryAbstract {
/**
* @param preCommitListener - shared instance
*/
- public void bind(final PreCommitListener preCommitListener) {
- traceLog.log("1. bind to pre-commit events");
- preCommitListener.bind(verifier);
- }
-
- /**
- * @param preCommitListener - shared instance
- */
- public void unbind(final PreCommitListener preCommitListener) {
- traceLog.log("3. unbind from pre-commit events");
- preCommitListener.unbind(verifier);
+ public void bind(final CommitListener preCommitListener) {
+ traceLog.log("1. bind to commit events");
+ preCommitListener.bind(this);
}
public void changeProperty(final Runnable runnable) {
@@ -113,6 +114,11 @@ public abstract class PublishingTestFactoryAbstract {
traceLog.log("2.4 book's name has changed");
}
+ public void runPostCommitVerify() {
+ traceLog.log("4. post commit verify %s", transactionCompletionStage);
+ runVerify(transactionCompletionStage);
+ }
+
}
@FunctionalInterface
@@ -121,31 +127,43 @@ public abstract class PublishingTestFactoryAbstract {
}
@Service
- public static class PreCommitListener {
+ public static class CommitListener {
- private Consumer<VerificationStage> verifier;
-// @Setter private TraceLog traceLog;
+ private PublishingTestContext testContext;
- /** TRANSACTION END BOUNDARY */
+ /** TRANSACTION END BOUNDARY (PRE) */
@EventListener(TransactionBeforeCompletionEvent.class)
public void onPreCommit(final TransactionBeforeCompletionEvent event) {
-// if(traceLog!=null) {
-// traceLog.log("=== TRANSACTION END BOUNDARY");
-// }
- if(verifier!=null) {
- verifier.accept(VerificationStage.PRE_COMMIT);
+ _Probe.errOut("=== TRANSACTION before completion");
+ if(testContext!=null) {
+ testContext.getTraceLog().log("3. pre-commit event is occurring");
+ testContext.runVerify(VerificationStage.PRE_COMMIT);
}
}
- public void bind(final Consumer<VerificationStage> verifier) {
- _Assert.assertNull(this.verifier, "PreCommitListener is already bound to a verifier.");
- this.verifier = verifier;
+ /** TRANSACTION END BOUNDARY (POST)*/
+ @EventListener(TransactionAfterCompletionEvent.class)
+ public void onPreCommit(final TransactionAfterCompletionEvent event) {
+ _Probe.errOut("=== TRANSACTION after completion");
+ if(testContext!=null) {
+ try {
+ testContext.runPostCommitVerify();
+ } finally {
+ unbind(testContext);
+ }
+ }
}
- public void unbind(final Consumer<VerificationStage> verifier) {
- _Assert.assertEquals(this.verifier, verifier, "PreCommitListener is not bound to the verifier, "
+ public void bind(final PublishingTestContext testContext) {
+ _Assert.assertNull(this.testContext, "PreCommitListener is already bound to a testContext.");
+ this.testContext = testContext;
+ }
+
+ public void unbind(final PublishingTestContext testContext) {
+ _Assert.assertEquals(this.testContext, testContext, "PreCommitListener is not bound to the testContext, "
+ "which it receives a request to unbind from.");
- this.verifier = null;
+ this.testContext.getTraceLog().log("5. unbind from commit events");
+ this.testContext = null;
}
}
@@ -161,30 +179,32 @@ public abstract class PublishingTestFactoryAbstract {
final Runnable given,
final Consumer<VerificationStage> verifier) {
+ _Probe.errOut("GENERATE TESTS");
+
val dynamicTests = Can.<DynamicTest>of(
publishingTest("Programmatic Execution",
- given, verifier,
+ PublishingTestContext.of(given, verifier, VerificationStage.POST_COMMIT_WHEN_PROGRAMMATIC),
VerificationStage.POST_INTERACTION_WHEN_PROGRAMMATIC,
this::programmaticExecution),
publishingTest("Interaction Api Execution",
- given, verifier,
+ PublishingTestContext.of(given, verifier, VerificationStage.POST_COMMIT),
VerificationStage.POST_INTERACTION,
this::interactionApiExecution),
publishingTest("Wrapper Sync Execution w/o Rules",
- given, verifier,
+ PublishingTestContext.of(given, verifier, VerificationStage.POST_COMMIT),
VerificationStage.POST_INTERACTION,
this::wrapperSyncExecutionNoRules),
publishingTest("Wrapper Sync Execution w/ Rules (expected to fail w/ DisabledException)",
- given, verifier,
+ PublishingTestContext.of(given, verifier, VerificationStage.FAILURE_CASE),
VerificationStage.POST_INTERACTION,
this::wrapperSyncExecutionWithFailure),
publishingTest("Wrapper Async Execution w/o Rules",
- given, verifier,
+ PublishingTestContext.of(given, verifier, VerificationStage.POST_COMMIT),
VerificationStage.POST_INTERACTION,
this::wrapperAsyncExecutionNoRules),
publishingTest("Wrapper Async Execution w/ Rules (expected to fail w/ DisabledException)",
- given, verifier,
+ PublishingTestContext.of(given, verifier, VerificationStage.FAILURE_CASE),
VerificationStage.POST_INTERACTION,
this::wrapperAsyncExecutionWithFailure)
);
@@ -198,6 +218,8 @@ public abstract class PublishingTestFactoryAbstract {
}
+ protected abstract void setupEntity(PublishingTestContext context);
+
protected abstract boolean programmaticExecution(PublishingTestContext context);
protected abstract boolean interactionApiExecution(PublishingTestContext context);
@@ -215,8 +237,7 @@ public abstract class PublishingTestFactoryAbstract {
private final DynamicTest publishingTest(
final String displayName,
- final Runnable given,
- final Consumer<VerificationStage> verifier,
+ final PublishingTestContext testContext,
final VerificationStage onSuccess,
final PublishingTestRunner testRunner) {
@@ -227,12 +248,20 @@ public abstract class PublishingTestFactoryAbstract {
assertFalse(getInteractionService().isInInteraction());
assert_no_initial_tx_context();
- val traceLog = new TraceLog();
+ getInteractionService().runAnonymous(()->{
+ val currentInteraction = getInteractionService().currentInteraction();
+ xrayEnterInteraction(currentInteraction);
+ setupEntity(testContext);
+ xrayExitInteraction();
+ });
+
+ assertFalse(getInteractionService().isInInteraction());
+ assert_no_initial_tx_context();
final boolean isSuccesfulRun = getInteractionService().callAnonymous(()->{
val currentInteraction = getInteractionService().currentInteraction();
xrayEnterInteraction(currentInteraction);
- val result = testRunner.run(PublishingTestContext.of(traceLog, given, verifier));
+ val result = testRunner.run(testContext);
xrayExitInteraction();
return result;
});
@@ -240,7 +269,7 @@ public abstract class PublishingTestFactoryAbstract {
getInteractionService().closeInteractionLayers();
if(isSuccesfulRun) {
- verifier.accept(onSuccess);
+ testContext.runVerify(onSuccess);
}
});
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJdo.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJdo.java
index 77dab90..df2f20d 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJdo.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJdo.java
@@ -30,7 +30,6 @@ import javax.jdo.PersistenceManagerFactory;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Propagation;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
@@ -52,7 +51,7 @@ import org.apache.isis.testdomain.jdo.JdoTestDomainPersona;
import org.apache.isis.testdomain.jdo.entities.JdoBook;
import org.apache.isis.testdomain.jdo.entities.JdoInventory;
import org.apache.isis.testdomain.jdo.entities.JdoProduct;
-import org.apache.isis.testdomain.publishing.PublishingTestFactoryAbstract.PreCommitListener;
+import org.apache.isis.testdomain.publishing.PublishingTestFactoryAbstract.CommitListener;
import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts;
import static org.apache.isis.applib.services.wrapper.control.AsyncControl.returningVoid;
@@ -60,11 +59,12 @@ import static org.apache.isis.applib.services.wrapper.control.AsyncControl.retur
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
import lombok.val;
@Component
@Import({
- PreCommitListener.class
+ CommitListener.class
})
@RequiredArgsConstructor(onConstructor_ = {@Inject})
public class PublishingTestFactoryJdo
@@ -74,7 +74,7 @@ extends PublishingTestFactoryAbstract {
private final WrapperFactory wrapper;
private final ObjectManager objectManager;
private final FixtureScripts fixtureScripts;
- private final PreCommitListener preCommitListener;
+ private final CommitListener preCommitListener;
@Getter(onMethod_ = {@Override}, value = AccessLevel.PROTECTED)
private final InteractionService interactionService;
@@ -85,18 +85,27 @@ extends PublishingTestFactoryAbstract {
@Named("transaction-aware-pmf-proxy")
private final PersistenceManagerFactory pmf;
+ // -- TEST SETUP
+
+ @Override
+ protected void setupEntity(final PublishingTestContext context) {
+ // given
+ setupBookForJdo();
+ }
+
// -- TESTS - PROGRAMMATIC
@Override
protected boolean programmaticExecution(
final PublishingTestContext context) {
- // given
- setupBookForJdo();
-
context.bind(preCommitListener);
- withBookDoTransactional(book->{
+ // This test does not trigger command or execution publishing, however it does trigger
+ // entity-change-publishing.
+
+
+ withBookDo(book->{
context.runGiven();
@@ -107,14 +116,6 @@ extends PublishingTestFactoryAbstract {
});
- context.unbind(preCommitListener);
-
- // This test does not trigger command or execution publishing, however it does trigger
- // entity-change-publishing.
-
- // then
- context.runVerify(VerificationStage.POST_COMMIT_WHEN_PROGRAMMATIC);
-
return true;
}
@@ -124,16 +125,13 @@ extends PublishingTestFactoryAbstract {
protected boolean interactionApiExecution(
final PublishingTestContext context) {
- // given
- setupBookForJdo();
+ context.bind(preCommitListener);
// when
- withBookDoTransactional(book->{
+ withBookDo(book->{
context.runGiven();
- context.bind(preCommitListener);
-
// when
context.changeProperty(()->{
@@ -149,11 +147,6 @@ extends PublishingTestFactoryAbstract {
});
- context.unbind(preCommitListener);
-
- // then
- context.runVerify(VerificationStage.POST_COMMIT);
-
return true;
}
@@ -163,27 +156,19 @@ extends PublishingTestFactoryAbstract {
protected boolean wrapperSyncExecutionNoRules(
final PublishingTestContext context) {
- // given
- setupBookForJdo();
+ context.bind(preCommitListener);
// when
- withBookDoTransactional(book->{
+ withBookDo(book->{
context.runGiven();
- context.bind(preCommitListener);
-
// when - running synchronous
val syncControl = SyncControl.control().withSkipRules(); // don't enforce rules
context.changeProperty(()->wrapper.wrap(book, syncControl).setName("Book #2"));
- context.unbind(preCommitListener);
-
});
- // then
- context.runVerify(VerificationStage.POST_COMMIT);
-
return true;
}
@@ -191,16 +176,13 @@ extends PublishingTestFactoryAbstract {
protected boolean wrapperSyncExecutionWithFailure(
final PublishingTestContext context) {
- // given
- setupBookForJdo();
+ context.bind(preCommitListener);
// when
- withBookDoTransactional(book->{
+ withBookDo(book->{
context.runGiven();
- context.bind(preCommitListener);
-
// when - running synchronous
val syncControl = SyncControl.control().withCheckRules(); // enforce rules
@@ -208,14 +190,8 @@ extends PublishingTestFactoryAbstract {
wrapper.wrap(book, syncControl).setName("Book #2"); // should fail with DisabledException
});
- context.unbind(preCommitListener);
-
});
-
- // then
- context.runVerify(VerificationStage.FAILURE_CASE);
-
return false;
}
@@ -225,17 +201,18 @@ extends PublishingTestFactoryAbstract {
protected boolean wrapperAsyncExecutionNoRules(
final PublishingTestContext context) throws InterruptedException, ExecutionException, TimeoutException {
+ context.bind(preCommitListener);
+
// given
- setupBookForJdo();
val asyncControl = returningVoid().withSkipRules(); // don't enforce rules
// when
- withBookDoTransactional(book->{
+ withBookDo(book->{
context.runGiven();
- context.bind(preCommitListener);
+
// when - running asynchronous
wrapper.asyncWrap(book, asyncControl)
@@ -245,11 +222,6 @@ extends PublishingTestFactoryAbstract {
asyncControl.getFuture().get(10, TimeUnit.SECONDS);
- context.unbind(preCommitListener);
-
- // then
- context.runVerify(VerificationStage.POST_COMMIT);
-
return true;
}
@@ -257,16 +229,13 @@ extends PublishingTestFactoryAbstract {
protected boolean wrapperAsyncExecutionWithFailure(
final PublishingTestContext context) {
- // given
- setupBookForJdo();
+ context.bind(preCommitListener);
// when
- withBookDoTransactional(book->{
+ withBookDo(book->{
context.runGiven();
- context.bind(preCommitListener);
-
// when - running synchronous
val asyncControl = returningVoid().withCheckRules(); // enforce rules
@@ -277,13 +246,8 @@ extends PublishingTestFactoryAbstract {
fail("unexpected code reach");
});
- context.unbind(preCommitListener);
-
});
- // then
- context.runVerify(VerificationStage.FAILURE_CASE);
-
return false;
}
@@ -291,50 +255,39 @@ extends PublishingTestFactoryAbstract {
private void setupBookForJdo() {
- transactionService.runTransactional(Propagation.REQUIRES_NEW, ()->{
- val pm = pmf.getPersistenceManager();
-
- // cleanup
- fixtureScripts.runPersona(JdoTestDomainPersona.PurgeAll);
+ val pm = pmf.getPersistenceManager();
- // given Inventory with 1 Book
+ // cleanup
+ fixtureScripts.runPersona(JdoTestDomainPersona.PurgeAll);
- val products = new HashSet<JdoProduct>();
+ // given Inventory with 1 Book
- products.add(JdoBook.of(
- "Sample Book", "A sample book for testing.", 99.,
- "Sample Author", "Sample ISBN", "Sample Publisher"));
+ val products = new HashSet<JdoProduct>();
- val inventory = JdoInventory.of("Sample Inventory", products);
- pm.makePersistent(inventory);
+ products.add(JdoBook.of(
+ "Sample Book", "A sample book for testing.", 99.,
+ "Sample Author", "Sample ISBN", "Sample Publisher"));
- inventory.getProducts().forEach(product->{
- val prod = pm.makePersistent(product);
+ val inventory = JdoInventory.of("Sample Inventory", products);
+ pm.makePersistent(inventory);
- _Probe.errOut("PROD ID: %s", JDOHelper.getObjectId(prod));
+ inventory.getProducts().forEach(product->{
+ val prod = pm.makePersistent(product);
- });
-
- //fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
-
- pm.flush();
+ _Probe.errOut("PROD ID: %s", JDOHelper.getObjectId(prod));
});
- }
- private void withBookDoTransactional(final CheckedConsumer<JdoBook> transactionalBookConsumer) {
+ //fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
- xrayEnterTansaction(Propagation.REQUIRES_NEW);
+ pm.flush();
- transactionService.runTransactional(Propagation.REQUIRES_NEW, ()->{
- val book = repository.allInstances(JdoBook.class).listIterator().next();
- transactionalBookConsumer.accept(book);
-
- })
- .optionalElseFail();
-
- xrayExitTansaction();
}
+ @SneakyThrows
+ private void withBookDo(final CheckedConsumer<JdoBook> transactionalBookConsumer) {
+ val book = repository.allInstances(JdoBook.class).listIterator().next();
+ transactionalBookConsumer.accept(book);
+ }
}
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJpa.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJpa.java
index a540521..e306d8b 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJpa.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJpa.java
@@ -27,7 +27,6 @@ import javax.inject.Inject;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Propagation;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
@@ -50,7 +49,7 @@ import org.apache.isis.testdomain.jpa.JpaTestDomainPersona;
import org.apache.isis.testdomain.jpa.entities.JpaBook;
import org.apache.isis.testdomain.jpa.entities.JpaInventory;
import org.apache.isis.testdomain.jpa.entities.JpaProduct;
-import org.apache.isis.testdomain.publishing.PublishingTestFactoryAbstract.PreCommitListener;
+import org.apache.isis.testdomain.publishing.PublishingTestFactoryAbstract.CommitListener;
import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts;
import static org.apache.isis.applib.services.wrapper.control.AsyncControl.returningVoid;
@@ -58,11 +57,12 @@ import static org.apache.isis.applib.services.wrapper.control.AsyncControl.retur
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
import lombok.val;
@Component
@Import({
- PreCommitListener.class
+ CommitListener.class
})
@RequiredArgsConstructor(onConstructor_ = {@Inject})
public class PublishingTestFactoryJpa
@@ -72,7 +72,7 @@ extends PublishingTestFactoryAbstract {
private final WrapperFactory wrapper;
private final ObjectManager objectManager;
private final FixtureScripts fixtureScripts;
- private final PreCommitListener preCommitListener;
+ private final CommitListener commitListener;
private final JpaSupportService jpaSupport;
@Getter(onMethod_ = {@Override}, value = AccessLevel.PROTECTED)
@@ -81,6 +81,13 @@ extends PublishingTestFactoryAbstract {
@Getter(onMethod_ = {@Override}, value = AccessLevel.PROTECTED)
private final TransactionService transactionService;
+ // -- TEST SETUP
+
+ @Override
+ protected void setupEntity(final PublishingTestContext context) {
+ // given
+ setupBookForJpa();
+ }
// -- TESTS - PROGRAMMATIC
@@ -88,12 +95,12 @@ extends PublishingTestFactoryAbstract {
protected boolean programmaticExecution(
final PublishingTestContext context) {
- // given
- setupBookForJpa();
+ context.bind(commitListener);
- context.bind(preCommitListener);
+ // This test does not trigger command or execution publishing, however it does trigger
+ // entity-change-publishing.
- withBookDoTransactional(book->{
+ withBookDo(book->{
context.runGiven();
@@ -104,13 +111,6 @@ extends PublishingTestFactoryAbstract {
});
- context.unbind(preCommitListener);
-
- // This test does not trigger command or execution publishing, however it does trigger
- // entity-change-publishing.
-
- // then
- context.runVerify(VerificationStage.POST_COMMIT_WHEN_PROGRAMMATIC);
return true;
}
@@ -121,16 +121,13 @@ extends PublishingTestFactoryAbstract {
protected boolean interactionApiExecution(
final PublishingTestContext context) {
- // given
- setupBookForJpa();
+ context.bind(commitListener);
// when
- withBookDoTransactional(book->{
+ withBookDo(book->{
context.runGiven();
- context.bind(preCommitListener);
-
// when
context.changeProperty(()->{
@@ -146,11 +143,6 @@ extends PublishingTestFactoryAbstract {
});
- context.unbind(preCommitListener);
-
- // then
- context.runVerify(VerificationStage.POST_COMMIT);
-
return true;
}
@@ -160,27 +152,19 @@ extends PublishingTestFactoryAbstract {
protected boolean wrapperSyncExecutionNoRules(
final PublishingTestContext context) {
- // given
- setupBookForJpa();
+ context.bind(commitListener);
// when
- withBookDoTransactional(book->{
+ withBookDo(book->{
context.runGiven();
- context.bind(preCommitListener);
-
// when - running synchronous
val syncControl = SyncControl.control().withSkipRules(); // don't enforce rules
context.changeProperty(()->wrapper.wrap(book, syncControl).setName("Book #2"));
- context.unbind(preCommitListener);
-
});
- // then
- context.runVerify(VerificationStage.POST_COMMIT);
-
return true;
}
@@ -188,16 +172,13 @@ extends PublishingTestFactoryAbstract {
protected boolean wrapperSyncExecutionWithFailure(
final PublishingTestContext context) {
- // given
- setupBookForJpa();
+ context.bind(commitListener);
// when
- withBookDoTransactional(book->{
+ withBookDo(book->{
context.runGiven();
- context.bind(preCommitListener);
-
// when - running synchronous
val syncControl = SyncControl.control().withCheckRules(); // enforce rules
@@ -205,14 +186,8 @@ extends PublishingTestFactoryAbstract {
wrapper.wrap(book, syncControl).setName("Book #2"); // should fail with DisabledException
});
- context.unbind(preCommitListener);
-
});
-
- // then
- context.runVerify(VerificationStage.FAILURE_CASE);
-
return false;
}
@@ -222,18 +197,17 @@ extends PublishingTestFactoryAbstract {
protected boolean wrapperAsyncExecutionNoRules(
final PublishingTestContext context) throws InterruptedException, ExecutionException, TimeoutException {
+ context.bind(commitListener);
+
// given
- setupBookForJpa();
val asyncControl = returningVoid().withSkipRules(); // don't enforce rules
// when
- withBookDoTransactional(book->{
+ withBookDo(book->{
context.runGiven();
- context.bind(preCommitListener);
-
// when - running asynchronous
wrapper.asyncWrap(book, asyncControl)
.setName("Book #2");
@@ -242,11 +216,6 @@ extends PublishingTestFactoryAbstract {
asyncControl.getFuture().get(10, TimeUnit.SECONDS);
- context.unbind(preCommitListener);
-
- // then
- context.runVerify(VerificationStage.POST_COMMIT);
-
return true;
}
@@ -254,15 +223,12 @@ extends PublishingTestFactoryAbstract {
protected boolean wrapperAsyncExecutionWithFailure(
final PublishingTestContext context) {
- // given
- setupBookForJpa();
+ context.bind(commitListener);
// when
- withBookDoTransactional(book->{
+ withBookDo(book->{
- context.runGiven();
- context.bind(preCommitListener);
// when - running synchronous
val asyncControl = returningVoid().withCheckRules(); // enforce rules
@@ -274,13 +240,8 @@ extends PublishingTestFactoryAbstract {
fail("unexpected code reach");
});
- context.unbind(preCommitListener);
-
});
- // then
- context.runVerify(VerificationStage.FAILURE_CASE);
-
return false;
}
@@ -288,50 +249,41 @@ extends PublishingTestFactoryAbstract {
private void setupBookForJpa() {
- transactionService.runTransactional(Propagation.REQUIRES_NEW, ()->{
-
- val em = jpaSupport.getEntityManagerElseFail(JpaBook.class);
-
- // cleanup
- fixtureScripts.runPersona(JpaTestDomainPersona.PurgeAll);
+ val em = jpaSupport.getEntityManagerElseFail(JpaBook.class);
- // given Inventory with 1 Book
+ // cleanup
+ fixtureScripts.runPersona(JpaTestDomainPersona.PurgeAll);
- val products = new HashSet<JpaProduct>();
+ // given Inventory with 1 Book
- products.add(JpaBook.of(
- "Sample Book", "A sample book for testing.", 99.,
- "Sample Author", "Sample ISBN", "Sample Publisher"));
+ val products = new HashSet<JpaProduct>();
- val inventory = JpaInventory.of("Sample Inventory", products);
- em.persist(inventory);
+ products.add(JpaBook.of(
+ "Sample Book", "A sample book for testing.", 99.,
+ "Sample Author", "Sample ISBN", "Sample Publisher"));
- inventory.getProducts().forEach(product->{
- em.persist(product);
+ val inventory = JpaInventory.of("Sample Inventory", products);
+ em.persist(inventory);
- _Probe.errOut("PROD ID: %s", product.getId());
+ inventory.getProducts().forEach(product->{
+ em.persist(product);
- });
-
- //fixtureScripts.runPersona(JpaTestDomainPersona.InventoryWith1Book);
-
- em.flush();
+ _Probe.errOut("PROD ID: %s", product.getId());
});
- }
- private void withBookDoTransactional(final CheckedConsumer<JpaBook> transactionalBookConsumer) {
+ //fixtureScripts.runPersona(JpaTestDomainPersona.InventoryWith1Book);
- xrayEnterTansaction(Propagation.REQUIRES_NEW);
+ em.flush();
+ }
- transactionService.runTransactional(Propagation.REQUIRES_NEW, ()->{
- val book = repository.allInstances(JpaBook.class).listIterator().next();
- transactionalBookConsumer.accept(book);
+ @SneakyThrows
+ private void withBookDo(final CheckedConsumer<JpaBook> bookConsumer) {
- })
- .optionalElseFail();
+ val book = repository.allInstances(JpaBook.class).listIterator().next();
+ bookConsumer.accept(book);
- xrayExitTansaction();
}
+
}