diff options
author | Eike Stepper | 2010-04-17 08:37:16 +0000 |
---|---|---|
committer | Eike Stepper | 2010-04-17 08:37:16 +0000 |
commit | 0ff7c7433a8536e1804b79f93b7b29161009fad6 (patch) | |
tree | e1ea38d9da20cb676958abafb678114c82438b1e | |
parent | 1ba08d4762ff15430720cbd118d88e3a85154772 (diff) | |
download | cdo-0ff7c7433a8536e1804b79f93b7b29161009fad6.tar.gz cdo-0ff7c7433a8536e1804b79f93b7b29161009fad6.tar.xz cdo-0ff7c7433a8536e1804b79f93b7b29161009fad6.zip |
[256936] Support for Offline Mode
https://bugs.eclipse.org/bugs/show_bug.cgi?id=256936
6 files changed, 400 insertions, 267 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java index db879ad745..cd00892e04 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java @@ -389,13 +389,15 @@ public class MEMStore extends LongIDStore implements IMEMStore, BranchLoader public synchronized void addCommitInfo(CDOBranch branch, long timeStamp, String userID, String comment) { int index = commitInfos.size() - 1; - while (index > 0) + while (index >= 0) { CommitInfo info = commitInfos.get(index); if (timeStamp > info.getTimeStamp()) { break; } + + --index; } CommitInfo commitInfo = new CommitInfo(branch, timeStamp, userID, comment); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/OfflineClone.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/OfflineClone.java index a3c3b97d1c..a8021e1774 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/OfflineClone.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/OfflineClone.java @@ -11,9 +11,35 @@ package org.eclipse.emf.cdo.internal.server.syncing; import org.eclipse.emf.cdo.common.branch.CDOBranch; +import org.eclipse.emf.cdo.common.branch.CDOBranchVersion; +import org.eclipse.emf.cdo.common.commit.CDOCommitData; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOIDAndVersion; +import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.model.CDOPackageInfo; +import org.eclipse.emf.cdo.common.model.CDOPackageUnit; +import org.eclipse.emf.cdo.common.revision.CDORevisionKey; +import org.eclipse.emf.cdo.internal.server.TransactionCommitContext; +import org.eclipse.emf.cdo.server.StoreThreadLocal; +import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch; +import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager; +import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta; import org.eclipse.emf.cdo.spi.server.InternalCommitContext; import org.eclipse.emf.cdo.spi.server.InternalTransaction; +import org.eclipse.net4j.util.collection.IndexedList; +import org.eclipse.net4j.util.om.monitor.Monitor; +import org.eclipse.net4j.util.om.monitor.OMMonitor; +import org.eclipse.net4j.util.transaction.TransactionException; + +import org.eclipse.emf.spi.cdo.CDOSessionProtocol; +import org.eclipse.emf.spi.cdo.CDOSessionProtocol.CommitTransactionResult; + +import java.util.List; +import java.util.Map; + /** * @author Eike Stepper */ @@ -44,12 +70,256 @@ public class OfflineClone extends SynchronizableRepository { return createNormalCommitContext(transaction); } - + if (getState() != ONLINE) { return createBranchingCommitContext(transaction, branch); } - + return createWriteThroughCommitContext(transaction); } + + protected InternalCommitContext createBranchingCommitContext(InternalTransaction transaction, CDOBranch branch) + { + long timeStamp = createCommitTimeStamp(null); + CDOBranch offlineBranch = createOfflineBranch(branch, timeStamp - 1L); + transaction.setBranchPoint(offlineBranch.getHead()); + return new BranchingCommitContext(transaction, timeStamp); + } + + protected InternalCommitContext createWriteThroughCommitContext(InternalTransaction transaction) + { + return new WriteThroughCommitContext(transaction); + } + + protected CDOBranch createOfflineBranch(CDOBranch baseBranch, long baseTimeStamp) + { + try + { + StoreThreadLocal.setSession(getReplicatorSession()); + InternalCDOBranchManager branchManager = getBranchManager(); + return branchManager.createBranch(NEW_LOCAL_BRANCH, + "Offline-" + baseTimeStamp, (InternalCDOBranch)baseBranch, baseTimeStamp); //$NON-NLS-1$ + } + finally + { + StoreThreadLocal.release(); + } + } + + /** + * @author Eike Stepper + */ + protected static final class CommitContextData implements CDOCommitData + { + private InternalCommitContext commitContext; + + public CommitContextData(InternalCommitContext commitContext) + { + this.commitContext = commitContext; + } + + public boolean isEmpty() + { + return false; + } + + public List<CDOPackageUnit> getNewPackageUnits() + { + final InternalCDOPackageUnit[] newPackageUnits = commitContext.getNewPackageUnits(); + return new IndexedList<CDOPackageUnit>() + { + @Override + public CDOPackageUnit get(int index) + { + return newPackageUnits[index]; + } + + @Override + public int size() + { + return newPackageUnits.length; + } + }; + } + + public List<CDOIDAndVersion> getNewObjects() + { + final InternalCDORevision[] newObjects = commitContext.getNewObjects(); + return new IndexedList<CDOIDAndVersion>() + { + @Override + public CDOIDAndVersion get(int index) + { + return newObjects[index]; + } + + @Override + public int size() + { + return newObjects.length; + } + }; + } + + public List<CDORevisionKey> getChangedObjects() + { + final InternalCDORevisionDelta[] changedObjects = commitContext.getDirtyObjectDeltas(); + return new IndexedList<CDORevisionKey>() + { + @Override + public CDORevisionKey get(int index) + { + return changedObjects[index]; + } + + @Override + public int size() + { + return changedObjects.length; + } + }; + } + + public List<CDOIDAndVersion> getDetachedObjects() + { + final CDOID[] detachedObjects = commitContext.getDetachedObjects(); + return new IndexedList<CDOIDAndVersion>() + { + @Override + public CDOIDAndVersion get(int index) + { + return CDOIDUtil.createIDAndVersion(detachedObjects[index], CDOBranchVersion.UNSPECIFIED_VERSION); + } + + @Override + public int size() + { + return detachedObjects.length; + } + }; + } + } + + /** + * @author Eike Stepper + */ + protected final class WriteThroughCommitContext extends TransactionCommitContext + { + public WriteThroughCommitContext(InternalTransaction transaction) + { + super(transaction); + } + + @Override + public void write(OMMonitor monitor) + { + // Do nothing + } + + @Override + public void commit(OMMonitor monitor) + { + InternalTransaction transaction = getTransaction(); + + // Prepare commit to the master + CDOBranch branch = transaction.getBranch(); + String userID = getUserID(); + String comment = getCommitComment(); + CDOCommitData commitData = new CommitContextData(this); + + // Delegate commit to the master + CDOSessionProtocol sessionProtocol = getSynchronizer().getRemoteSession().getSessionProtocol(); + CommitTransactionResult result = sessionProtocol.commitDelegation(branch, userID, comment, commitData, monitor); + + // Stop if commit to master failed + String rollbackMessage = result.getRollbackMessage(); + if (rollbackMessage != null) + { + throw new TransactionException(rollbackMessage); + } + + // Prepare data needed for commit result and commit notifications + long timeStamp = result.getTimeStamp(); + setTimeStamp(timeStamp); + addMetaIDRanges(commitData.getNewPackageUnits()); + addIDMappings(result.getIDMappings()); + applyIDMappings(new Monitor()); + + // Commit to the local repository + super.preWrite(); + super.write(new Monitor()); + super.commit(new Monitor()); + + // Remember commit time in the local repository + setLastCommitTimeStamp(timeStamp); + setLastReplicatedCommitTime(timeStamp); + } + + @Override + protected long createTimeStamp() + { + // Already set after commit to the master + return getTimeStamp(); + } + + @Override + protected void lockObjects() throws InterruptedException + { + // Do nothing + } + + @Override + protected void adjustMetaRanges() + { + // Do nothing + } + + private void addMetaIDRanges(List<CDOPackageUnit> newPackageUnits) + { + for (CDOPackageUnit newPackageUnit : newPackageUnits) + { + for (CDOPackageInfo packageInfo : newPackageUnit.getPackageInfos()) + { + addMetaIDRange(packageInfo.getMetaIDRange()); + } + } + } + + private void addIDMappings(Map<CDOID, CDOID> idMappings) + { + for (Map.Entry<CDOID, CDOID> idMapping : idMappings.entrySet()) + { + CDOID oldID = idMapping.getKey(); + CDOID newID = idMapping.getValue(); + addIDMapping(oldID, newID); + } + } + } + + /** + * @author Eike Stepper + */ + protected final class BranchingCommitContext extends TransactionCommitContext + { + private long timeStamp; + + public BranchingCommitContext(InternalTransaction transaction, long timeStamp) + { + super(transaction); + this.timeStamp = timeStamp; + } + + @Override + protected void lockObjects() throws InterruptedException + { + // Do nothing + } + + @Override + protected long createTimeStamp() + { + return timeStamp; + } + } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java index ecc11288b1..41db1a9fe8 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java @@ -13,23 +13,10 @@ package org.eclipse.emf.cdo.internal.server.syncing; import org.eclipse.emf.cdo.common.CDOCommonRepository; import org.eclipse.emf.cdo.common.branch.CDOBranch; import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; -import org.eclipse.emf.cdo.common.branch.CDOBranchVersion; -import org.eclipse.emf.cdo.common.commit.CDOCommitData; import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; -import org.eclipse.emf.cdo.common.id.CDOID; -import org.eclipse.emf.cdo.common.id.CDOIDAndVersion; -import org.eclipse.emf.cdo.common.id.CDOIDUtil; -import org.eclipse.emf.cdo.common.model.CDOPackageInfo; -import org.eclipse.emf.cdo.common.model.CDOPackageUnit; -import org.eclipse.emf.cdo.common.revision.CDORevisionKey; import org.eclipse.emf.cdo.internal.server.Repository; -import org.eclipse.emf.cdo.internal.server.TransactionCommitContext; -import org.eclipse.emf.cdo.server.StoreThreadLocal; import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch; import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager; -import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit; -import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; -import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta; import org.eclipse.emf.cdo.spi.server.InternalCommitContext; import org.eclipse.emf.cdo.spi.server.InternalRepositorySynchronizer; import org.eclipse.emf.cdo.spi.server.InternalSession; @@ -37,13 +24,7 @@ import org.eclipse.emf.cdo.spi.server.InternalStore; import org.eclipse.emf.cdo.spi.server.InternalSynchronizableRepository; import org.eclipse.emf.cdo.spi.server.InternalTransaction; -import org.eclipse.net4j.util.collection.IndexedList; import org.eclipse.net4j.util.om.monitor.Monitor; -import org.eclipse.net4j.util.om.monitor.OMMonitor; -import org.eclipse.net4j.util.transaction.TransactionException; - -import org.eclipse.emf.spi.cdo.CDOSessionProtocol; -import org.eclipse.emf.spi.cdo.CDOSessionProtocol.CommitTransactionResult; import java.util.Arrays; import java.util.Collections; @@ -130,11 +111,21 @@ public abstract class SynchronizableRepository extends Repository.Default implem return lastReplicatedBranchID; } + protected void setLastReplicatedBranchID(int lastReplicatedBranchID) + { + this.lastReplicatedBranchID = lastReplicatedBranchID; + } + public long getLastReplicatedCommitTime() { return lastReplicatedCommitTime; } + protected void setLastReplicatedCommitTime(long lastReplicatedCommitTime) + { + this.lastReplicatedCommitTime = lastReplicatedCommitTime; + } + public boolean isSqueezeCommitInfos() { return synchronizer.isSqueezeCommitInfos(); @@ -200,19 +191,6 @@ public abstract class SynchronizableRepository extends Repository.Default implem return super.createCommitContext(transaction); } - protected InternalCommitContext createBranchingCommitContext(InternalTransaction transaction, CDOBranch branch) - { - long timeStamp = createCommitTimeStamp(null); - CDOBranch offlineBranch = createOfflineBranch(branch, timeStamp - 1L); - transaction.setBranchPoint(offlineBranch.getHead()); - return new BranchingCommitContext(transaction, timeStamp); - } - - protected InternalCommitContext createWriteThroughCommitContext(InternalTransaction transaction) - { - return new WriteThroughCommitContext(transaction); - } - @Override protected void doBeforeActivate() throws Exception { @@ -296,235 +274,4 @@ public abstract class SynchronizableRepository extends Repository.Default implem { setState(INITIAL); } - - protected CDOBranch createOfflineBranch(CDOBranch baseBranch, long baseTimeStamp) - { - try - { - StoreThreadLocal.setSession(replicatorSession); - InternalCDOBranchManager branchManager = getBranchManager(); - return branchManager.createBranch(NEW_LOCAL_BRANCH, - "Offline-" + baseTimeStamp, (InternalCDOBranch)baseBranch, baseTimeStamp); //$NON-NLS-1$ - } - finally - { - StoreThreadLocal.release(); - } - } - - /** - * @author Eike Stepper - */ - protected static final class CommitContextData implements CDOCommitData - { - private InternalCommitContext commitContext; - - public CommitContextData(InternalCommitContext commitContext) - { - this.commitContext = commitContext; - } - - public boolean isEmpty() - { - return false; - } - - public List<CDOPackageUnit> getNewPackageUnits() - { - final InternalCDOPackageUnit[] newPackageUnits = commitContext.getNewPackageUnits(); - return new IndexedList<CDOPackageUnit>() - { - @Override - public CDOPackageUnit get(int index) - { - return newPackageUnits[index]; - } - - @Override - public int size() - { - return newPackageUnits.length; - } - }; - } - - public List<CDOIDAndVersion> getNewObjects() - { - final InternalCDORevision[] newObjects = commitContext.getNewObjects(); - return new IndexedList<CDOIDAndVersion>() - { - @Override - public CDOIDAndVersion get(int index) - { - return newObjects[index]; - } - - @Override - public int size() - { - return newObjects.length; - } - }; - } - - public List<CDORevisionKey> getChangedObjects() - { - final InternalCDORevisionDelta[] changedObjects = commitContext.getDirtyObjectDeltas(); - return new IndexedList<CDORevisionKey>() - { - @Override - public CDORevisionKey get(int index) - { - return changedObjects[index]; - } - - @Override - public int size() - { - return changedObjects.length; - } - }; - } - - public List<CDOIDAndVersion> getDetachedObjects() - { - final CDOID[] detachedObjects = commitContext.getDetachedObjects(); - return new IndexedList<CDOIDAndVersion>() - { - @Override - public CDOIDAndVersion get(int index) - { - return CDOIDUtil.createIDAndVersion(detachedObjects[index], CDOBranchVersion.UNSPECIFIED_VERSION); - } - - @Override - public int size() - { - return detachedObjects.length; - } - }; - } - } - - /** - * @author Eike Stepper - */ - protected final class WriteThroughCommitContext extends TransactionCommitContext - { - public WriteThroughCommitContext(InternalTransaction transaction) - { - super(transaction); - } - - @Override - public void write(OMMonitor monitor) - { - // Do nothing - } - - @Override - public void commit(OMMonitor monitor) - { - InternalTransaction transaction = getTransaction(); - - // Prepare commit to the master - CDOBranch branch = transaction.getBranch(); - String userID = getUserID(); - String comment = getCommitComment(); - CDOCommitData commitData = new CommitContextData(this); - - // Delegate commit to the master - CDOSessionProtocol sessionProtocol = synchronizer.getRemoteSession().getSessionProtocol(); - CommitTransactionResult result = sessionProtocol.commitDelegation(branch, userID, comment, commitData, monitor); - - // Stop if commit to master failed - String rollbackMessage = result.getRollbackMessage(); - if (rollbackMessage != null) - { - throw new TransactionException(rollbackMessage); - } - - // Prepare data needed for commit result and commit notifications - long timeStamp = result.getTimeStamp(); - setTimeStamp(timeStamp); - addMetaIDRanges(commitData.getNewPackageUnits()); - addIDMappings(result.getIDMappings()); - applyIDMappings(new Monitor()); - - // Commit to the local repository - super.preWrite(); - super.write(new Monitor()); - super.commit(new Monitor()); - - // Remember commit time in the local repository - setLastCommitTimeStamp(timeStamp); - lastReplicatedCommitTime = timeStamp; - } - - @Override - protected long createTimeStamp() - { - // Already set after commit to the master - return getTimeStamp(); - } - - @Override - protected void lockObjects() throws InterruptedException - { - // Do nothing - } - - @Override - protected void adjustMetaRanges() - { - // Do nothing - } - - private void addMetaIDRanges(List<CDOPackageUnit> newPackageUnits) - { - for (CDOPackageUnit newPackageUnit : newPackageUnits) - { - for (CDOPackageInfo packageInfo : newPackageUnit.getPackageInfos()) - { - addMetaIDRange(packageInfo.getMetaIDRange()); - } - } - } - - private void addIDMappings(Map<CDOID, CDOID> idMappings) - { - for (Map.Entry<CDOID, CDOID> idMapping : idMappings.entrySet()) - { - CDOID oldID = idMapping.getKey(); - CDOID newID = idMapping.getValue(); - addIDMapping(oldID, newID); - } - } - } - - /** - * @author Eike Stepper - */ - protected final class BranchingCommitContext extends TransactionCommitContext - { - private long timeStamp; - - public BranchingCommitContext(InternalTransaction transaction, long timeStamp) - { - super(transaction); - this.timeStamp = timeStamp; - } - - @Override - protected void lockObjects() throws InterruptedException - { - // Do nothing - } - - @Override - protected long createTimeStamp() - { - return timeStamp; - } - } } diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Offline.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Offline.java index 22db4bc677..8a8cd0b548 100644 --- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Offline.java +++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Offline.java @@ -14,6 +14,7 @@ import org.eclipse.emf.cdo.server.IRepository; import org.eclipse.emf.cdo.server.IStore; import org.eclipse.emf.cdo.server.db.CDODBUtil; import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy; +import org.eclipse.emf.cdo.tests.FailoverTest; import org.eclipse.emf.cdo.tests.OfflineTest; import org.eclipse.emf.cdo.tests.config.impl.ConfigTest; @@ -73,6 +74,7 @@ public class AllTestsDBH2Offline extends DBConfigs testClasses.add(OfflineTest.class); // testClasses.add(OfflineSqueezedTest.class); + testClasses.add(FailoverTest.class); } /** diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsMEMOffline.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsMEMOffline.java index 14c15469e0..d950f45d70 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsMEMOffline.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsMEMOffline.java @@ -32,7 +32,7 @@ public class AllTestsMEMOffline extends AllTestsAllConfigs { // super.initTestClasses(testClasses); - // testClasses.add(OfflineTest.class); + testClasses.add(OfflineTest.class); // testClasses.add(OfflineSqueezedTest.class); testClasses.add(FailoverTest.class); } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/FailoverTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/FailoverTest.java index 43a565de90..fa16628df9 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/FailoverTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/FailoverTest.java @@ -10,9 +10,11 @@ */ package org.eclipse.emf.cdo.tests; +import org.eclipse.emf.cdo.common.CDOCommonRepository; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.spi.server.InternalRepository; +import org.eclipse.emf.cdo.spi.server.InternalSynchronizableRepository; import org.eclipse.emf.cdo.tests.model1.Company; import org.eclipse.emf.cdo.transaction.CDOTransaction; @@ -64,6 +66,18 @@ public class FailoverTest extends AbstractSyncingTest return true; } + @Override + public InternalSynchronizableRepository getRepository() + { + return (InternalSynchronizableRepository)super.getRepository(); + } + + @Override + public InternalSynchronizableRepository getRepository(String name) + { + return (InternalSynchronizableRepository)super.getRepository(name); + } + public void testMasterCommits_ArrivalInBackup() throws Exception { CDOSession session = openSession(getRepository().getName() + "_master"); @@ -183,4 +197,102 @@ public class FailoverTest extends AbstractSyncingTest // SUCCESS } } + + public void testPauseMasterTransport() throws Exception + { + CDOSession session = openSession(getRepository().getName() + "_master"); + CDOTransaction transaction = session.openTransaction(); + CDOResource resource = transaction.createResource("/my/resource"); + + Company company = getModel1Factory().createCompany(); + company.setName("Test"); + + resource.getContents().add(company); + long timeStamp = transaction.commit().getTimeStamp(); + + getOfflineConfig().stopMasterTransport(); + waitForOffline(getRepository()); + + for (int i = 0; i < 10; i++) + { + company.setName("Test" + i); + timeStamp = transaction.commit().getTimeStamp(); + } + + for (int i = 0; i < 10; i++) + { + company.getCategories().add(getModel1Factory().createCategory()); + timeStamp = transaction.commit().getTimeStamp(); + } + + for (int i = 0; i < 10; i++) + { + company.getCategories().remove(0); + timeStamp = transaction.commit().getTimeStamp(); + } + + getOfflineConfig().startMasterTransport(); + waitForOnline(getRepository()); + + assertEquals(timeStamp, getRepository().getLastReplicatedCommitTime()); + session.close(); + } + + public void testSwitchMaster() throws Exception + { + CDOSession session = openSession(getRepository().getName() + "_master"); + CDOTransaction transaction = session.openTransaction(); + CDOResource resource = transaction.createResource("/my/resource"); + + Company company = getModel1Factory().createCompany(); + company.setName("Test"); + + resource.getContents().add(company); + transaction.commit(); + + for (int i = 0; i < 10; i++) + { + company.setName("Test" + i); + transaction.commit(); + } + + for (int i = 0; i < 10; i++) + { + company.getCategories().add(getModel1Factory().createCategory()); + transaction.commit(); + } + + for (int i = 0; i < 5; i++) + { + company.getCategories().remove(0); + transaction.commit(); + } + + startBackupTransport(); + getRepository().setType(CDOCommonRepository.Type.MASTER); + getRepository(getRepository().getName() + "_master").setType(CDOCommonRepository.Type.BACKUP); + + company.setName("Commit should fail"); + + try + { + transaction.commit(); + fail("Exception expected"); + } + catch (Exception expected) + { + // SUCCESS + } + + session.close(); + session = openSession(); + transaction = session.openTransaction(); + resource = transaction.getResource("/my/resource"); + + company = (Company)resource.getContents().get(0); + company.setName("Commit should NOT fail"); + transaction.commit(); + + session.close(); + } } |