@Override public LocalWaveletContainer create(WaveletNotificationSubscriber notifiee, WaveletName waveletName, String waveDomain) { return new LocalWaveletContainerImpl(waveletName, notifiee, loadWaveletState( waveletLoadExecutor, deltaStore, waveletName, waveletLoadExecutor), waveDomain, storageContinuationExecutor); } };
@Override public WaveletDeltaRecord submitRequest(WaveletName waveletName, ProtocolSignedDelta signedDelta) throws OperationException, InvalidProtocolBufferException, InvalidHashException, PersistenceException, WaveletStateException { awaitLoad(); acquireWriteLock(); try { checkStateOk(); HashedVersion before = getCurrentVersion(); WaveletDeltaRecord result = transformAndApplyLocalDelta(signedDelta); HashedVersion after = getCurrentVersion(); // Only publish and persist the delta if it wasn't transformed away // (right now it never is since the current OT algorithm doesn't transform ops away) // and wasn't a duplicate of a previously applied delta. if (!after.equals(before)) { Preconditions.checkState(!result.isEmpty()); Preconditions.checkState(result.getAppliedAtVersion().equals(before)); ImmutableSet<String> domainsToNotify = domainsOf(Iterables.concat( accessSnapshot().getParticipants(), participantsRemovedBy(result.getTransformedDelta()))); notifyOfDeltas(ImmutableList.of(result), domainsToNotify); // We always persist a local delta immediately after it's applied // and after it's broadcast on the wave bus and to remote servers. persist(result.getResultingVersion(), domainsToNotify); } return result; } finally { releaseWriteLock(); } }
public void testSuccessfulLocalRequest() throws Exception { ProtocolSignedDelta addDelta = ProtocolSignedDelta.newBuilder() .addSignature(fakeSignature1) .setDelta(addParticipantProtoDelta(localWavelet).toByteString()) .build(); localWavelet.submitRequest(localWaveletName, addDelta); assertEquals(localWavelet.getCurrentVersion().getVersion(), 2); assertTrue(localWavelet.isDeltaSigner( localWavelet.getCurrentVersion(), fakeSigner1)); assertFalse(localWavelet.isDeltaSigner( localWavelet.getCurrentVersion(), fakeSigner2)); HashedVersion oldVersion = localWavelet.getCurrentVersion(); ProtocolSignedDelta removeDelta = ProtocolSignedDelta.newBuilder() .addSignature(fakeSignature2) .setDelta(ProtocolWaveletDelta.newBuilder(removeParticipantProtoDelta(localWavelet)) .setHashedVersion(serialize(localWavelet.getCurrentVersion())).build().toByteString()) .build(); localWavelet.submitRequest(localWaveletName, removeDelta); assertEquals(localWavelet.getCurrentVersion().getVersion(), 4); assertTrue(localWavelet.isDeltaSigner(oldVersion, fakeSigner1)); assertFalse(localWavelet.isDeltaSigner(oldVersion, fakeSigner2)); assertTrue(localWavelet.isDeltaSigner( localWavelet.getCurrentVersion(), fakeSigner2)); assertFalse(localWavelet.isDeltaSigner( localWavelet.getCurrentVersion(), fakeSigner1)); }
@Override public void setUp() throws Exception { super.setUp(); WaveletNotificationSubscriber notifiee = mock(WaveletNotificationSubscriber.class); DeltaStore deltaStore = new MemoryDeltaStore(); WaveletState localWaveletState = DeltaStoreBasedWaveletState.create(deltaStore.open(localWaveletName), PERSIST_EXECUTOR); localWavelet = new LocalWaveletContainerImpl(localWaveletName, notifiee, Futures.immediateFuture(localWaveletState), localDomain, STORAGE_CONTINUATION_EXECUTOR); localWavelet.awaitLoad(); WaveletState remoteWaveletState = DeltaStoreBasedWaveletState.create(deltaStore.open(remoteWaveletName), PERSIST_EXECUTOR); remoteWavelet = new RemoteWaveletContainerImpl(remoteWaveletName, notifiee, Futures.immediateFuture(remoteWaveletState), STORAGE_CONTINUATION_EXECUTOR); remoteWavelet.awaitLoad(); }
WaveletDelta transformed = maybeTransformSubmittedDelta( CoreWaveletOperationSerializer.deserialize(protocolDelta)); HashedVersion currentVersion = getCurrentVersion(); lookupAppliedDelta(transformed.getTargetVersion()); TransformedWaveletDelta dupDelta = lookupTransformedDelta(transformed.getTargetVersion()); LOG.info("Duplicate delta " + dupDelta + " for wavelet " + getWaveletName()); transformed.size(), applicationTimestamp); return applyDelta(appliedDelta, transformed);
/** * Tests that duplicate operations are a no-op. * * @throws Exception should not be thrown. */ public void testDuplicateOperations() throws Exception { assertEquals(0L, wavelet.getCurrentVersion().getVersion()); // create the wavelet. WaveletDeltaRecord v0Response = wavelet.submitRequest( WAVELET_NAME, createProtocolSignedDelta(addParticipantOp, HASHED_VERSION_ZERO)); assertEquals(1L, wavelet.getCurrentVersion().getVersion()); ProtocolSignedDelta psd = createProtocolSignedDelta( addBlipOp, v0Response.getResultingVersion()); WaveletDeltaRecord dar1 = wavelet.submitRequest(WAVELET_NAME, psd); assertEquals(2L, wavelet.getCurrentVersion().getVersion()); WaveletDeltaRecord dar2 = wavelet.submitRequest(WAVELET_NAME, psd); assertEquals(2L, wavelet.getCurrentVersion().getVersion()); assertEquals(dar1.getResultingVersion(), dar2.getResultingVersion()); }
public void testOperationsOfDifferentSizes() throws Exception { String docId = "b+somedoc"; DocOp docOp1 = new DocOpBuilder().characters("hi").build(); WaveletDelta delta1 = createDelta(docId, docOp1, localVersion0); WaveServerTestUtil.applyDeltaToWavelet(localWavelet, delta1, 0L); try { DocOp docOp2 = new DocOpBuilder().characters("bye").build(); WaveletDelta delta2 = createDelta(docId, docOp2, localWavelet.getCurrentVersion()); WaveServerTestUtil.applyDeltaToWavelet(localWavelet, delta2, 0L); fail("Composition of \"hi\" and \"bye\" did not throw OperationException"); } catch (OperationException expected) { // Correct } }
/** * Check that a container fails when removing non-existent participants and adding duplicate * participants, and that the partipant list is preserved correctly. */ private void assertFailedWaveletOperations(WaveletContainerImpl with) throws Exception { try { WaveServerTestUtil.applyDeltaToWavelet(with, removeParticipantDelta(with), 0L); fail("Should fail"); } catch (OperationException e) { // Correct } assertNull(localWavelet.accessSnapshot()); WaveServerTestUtil.applyDeltaToWavelet(with, addParticipantDelta(with), 0L); try { WaveServerTestUtil.applyDeltaToWavelet(with, addParticipantDelta(with), 0L); fail("Should fail"); } catch (OperationException e) { // Correct } assertEquals(with.accessSnapshot().getParticipants(), participants); try { WaveServerTestUtil.applyDeltaToWavelet(with, doubleRemoveParticipantDelta(with), 0L); fail("Should fail"); } catch (OperationException e) { // Correct } assertEquals(with.accessSnapshot().getParticipants(), participants); }
public void testLocalEmptyDelta() throws Exception { ProtocolSignedDelta emptyDelta = ProtocolSignedDelta.newBuilder() .addSignature(fakeSignature1) .setDelta(ProtocolWaveletDelta.newBuilder() .setAuthor(author.toString()) .setHashedVersion(serialize(localVersion0)) .build().toByteString()) .build(); try { localWavelet.submitRequest(localWaveletName, emptyDelta); fail("Should fail"); } catch (IllegalArgumentException e) { // Correct } }
public void testSuccessfulLocalRequest() throws Exception { ProtocolSignedDelta addDelta = ProtocolSignedDelta.newBuilder() .addSignature(fakeSignature1) .setDelta(addParticipantProtoDelta(localWavelet).toByteString()) .build(); localWavelet.submitRequest(localWaveletName, addDelta); assertEquals(localWavelet.getCurrentVersion().getVersion(), 2); assertTrue(localWavelet.isDeltaSigner( localWavelet.getCurrentVersion(), fakeSigner1)); assertFalse(localWavelet.isDeltaSigner( localWavelet.getCurrentVersion(), fakeSigner2)); HashedVersion oldVersion = localWavelet.getCurrentVersion(); ProtocolSignedDelta removeDelta = ProtocolSignedDelta.newBuilder() .addSignature(fakeSignature2) .setDelta(ProtocolWaveletDelta.newBuilder(removeParticipantProtoDelta(localWavelet)) .setHashedVersion(serialize(localWavelet.getCurrentVersion())).build().toByteString()) .build(); localWavelet.submitRequest(localWaveletName, removeDelta); assertEquals(localWavelet.getCurrentVersion().getVersion(), 4); assertTrue(localWavelet.isDeltaSigner(oldVersion, fakeSigner1)); assertFalse(localWavelet.isDeltaSigner(oldVersion, fakeSigner2)); assertTrue(localWavelet.isDeltaSigner( localWavelet.getCurrentVersion(), fakeSigner2)); assertFalse(localWavelet.isDeltaSigner( localWavelet.getCurrentVersion(), fakeSigner1)); }
@Override public void setUp() throws Exception { super.setUp(); WaveletNotificationSubscriber notifiee = mock(WaveletNotificationSubscriber.class); DeltaStore deltaStore = new MemoryDeltaStore(); AccessController localAccessController = mock(AccessController.class); AccessController remoteAccessController = mock(AccessController.class); WaveletState localWaveletState = DeltaStoreBasedWaveletState.create(deltaStore.open(localWaveletName), PERSIST_EXECUTOR); localWavelet = new LocalWaveletContainerImpl(localWaveletName, notifiee, Futures.immediateFuture(localWaveletState), localDomain, STORAGE_CONTINUATION_EXECUTOR, localAccessController); localWavelet.awaitLoad(); WaveletState remoteWaveletState = DeltaStoreBasedWaveletState.create(deltaStore.open(remoteWaveletName), PERSIST_EXECUTOR); remoteWavelet = new RemoteWaveletContainerImpl(remoteWaveletName, notifiee, Futures.immediateFuture(remoteWaveletState), STORAGE_CONTINUATION_EXECUTOR, remoteAccessController); remoteWavelet.awaitLoad(); }
/** * Tests that duplicate operations are a no-op. * * @throws Exception should not be thrown. */ public void testDuplicateOperations() throws Exception { assertEquals(0L, wavelet.getCurrentVersion().getVersion()); // create the wavelet. WaveletDeltaRecord v0Response = wavelet.submitRequest( WAVELET_NAME, createProtocolSignedDelta(addParticipantOp, HASHED_VERSION_ZERO)); assertEquals(1L, wavelet.getCurrentVersion().getVersion()); ProtocolSignedDelta psd = createProtocolSignedDelta( addBlipOp, v0Response.getResultingVersion()); WaveletDeltaRecord dar1 = wavelet.submitRequest(WAVELET_NAME, psd); assertEquals(2L, wavelet.getCurrentVersion().getVersion()); WaveletDeltaRecord dar2 = wavelet.submitRequest(WAVELET_NAME, psd); assertEquals(2L, wavelet.getCurrentVersion().getVersion()); assertEquals(dar1.getResultingVersion(), dar2.getResultingVersion()); }
public void testOperationsOfDifferentSizes() throws Exception { String docId = "b+somedoc"; DocOp docOp1 = new DocOpBuilder().characters("hi").build(); WaveletDelta delta1 = createDelta(docId, docOp1, localVersion0); WaveServerTestUtil.applyDeltaToWavelet(localWavelet, delta1, 0L); try { DocOp docOp2 = new DocOpBuilder().characters("bye").build(); WaveletDelta delta2 = createDelta(docId, docOp2, localWavelet.getCurrentVersion()); WaveServerTestUtil.applyDeltaToWavelet(localWavelet, delta2, 0L); fail("Composition of \"hi\" and \"bye\" did not throw OperationException"); } catch (OperationException expected) { // Correct } }
/** * Check that a container fails when removing non-existent participants and adding duplicate * participants, and that the partipant list is preserved correctly. */ private void assertFailedWaveletOperations(WaveletContainerImpl with) throws Exception { try { WaveServerTestUtil.applyDeltaToWavelet(with, removeParticipantDelta(with), 0L); fail("Should fail"); } catch (OperationException e) { // Correct } assertNull(localWavelet.accessSnapshot()); WaveServerTestUtil.applyDeltaToWavelet(with, addParticipantDelta(with), 0L); try { WaveServerTestUtil.applyDeltaToWavelet(with, addParticipantDelta(with), 0L); fail("Should fail"); } catch (OperationException e) { // Correct } assertEquals(with.accessSnapshot().getParticipants(), participants); try { WaveServerTestUtil.applyDeltaToWavelet(with, doubleRemoveParticipantDelta(with), 0L); fail("Should fail"); } catch (OperationException e) { // Correct } assertEquals(with.accessSnapshot().getParticipants(), participants); }
public void testLocalEmptyDelta() throws Exception { ProtocolSignedDelta emptyDelta = ProtocolSignedDelta.newBuilder() .addSignature(fakeSignature1) .setDelta(ProtocolWaveletDelta.newBuilder() .setAuthor(author.toString()) .setHashedVersion(serialize(localVersion0)) .build().toByteString()) .build(); try { localWavelet.submitRequest(localWaveletName, emptyDelta); fail("Should fail"); } catch (IllegalArgumentException e) { // Correct } }
.build(); try { localWavelet.submitRequest(localWaveletName, removeDelta); fail("Should fail"); } catch (OperationException e) { assertEquals(localWavelet.getCurrentVersion(), localVersion0); localWavelet.submitRequest(localWaveletName, addDelta); try { ProtocolSignedDelta addAgainDelta = ProtocolSignedDelta.newBuilder() .addSignature(fakeSignature2) .setDelta(ProtocolWaveletDelta.newBuilder(addParticipantProtoDelta(localWavelet)) .setHashedVersion(serialize(localWavelet.getCurrentVersion())) .build().toByteString()) .build(); localWavelet.submitRequest(localWaveletName, addAgainDelta); fail("Should fail"); } catch (OperationException e) { assertEquals(localWavelet.getCurrentVersion().getVersion(), 2); assertTrue(localWavelet.isDeltaSigner( localWavelet.getCurrentVersion(), fakeSigner1)); assertFalse(localWavelet.isDeltaSigner( localWavelet.getCurrentVersion(), fakeSigner2)); HashedVersion oldVersion = localWavelet.getCurrentVersion(); ProtocolSignedDelta rollbackDelta = ProtocolSignedDelta.newBuilder() .addSignature(fakeSignature1)
@Override protected void setUp() throws Exception { super.setUp(); addParticipantOp = ProtocolWaveletOperation.newBuilder() .setAddParticipant(AUTHOR) .build(); // An empty blip operation - creates a new document. addBlipOp = ProtocolWaveletOperation.newBuilder().setMutateDocument( MutateDocument.newBuilder().setDocumentId(BLIP_ID).setDocumentOperation( ProtocolDocumentOperation.newBuilder().build())).build(); WaveletNotificationSubscriber notifiee = mock(WaveletNotificationSubscriber.class); DeltaStore deltaStore = new MemoryDeltaStore(); WaveletState waveletState = DeltaStoreBasedWaveletState.create(deltaStore.open(WAVELET_NAME), PERSIST_EXECUTOR); AccessController accessController = mock(AccessController.class); wavelet = new LocalWaveletContainerImpl(WAVELET_NAME, notifiee, Futures.immediateFuture(waveletState), null, STORAGE_CONTINUATION_EXECUTOR, accessController); wavelet.awaitLoad(); }
@Override public LocalWaveletContainer create(WaveletNotificationSubscriber notifiee, WaveletName waveletName, String waveDomain) { return new LocalWaveletContainerImpl(waveletName, notifiee, WaveServerModule.loadWaveletState(waveletLoadExecutor, deltaStore, waveletName, persistExecutor), waveDomain, storageContinuationExecutor); } };
.build(); try { localWavelet.submitRequest(localWaveletName, removeDelta); fail("Should fail"); } catch (OperationException e) { assertEquals(localWavelet.getCurrentVersion(), localVersion0); localWavelet.submitRequest(localWaveletName, addDelta); try { ProtocolSignedDelta addAgainDelta = ProtocolSignedDelta.newBuilder() .addSignature(fakeSignature2) .setDelta(ProtocolWaveletDelta.newBuilder(addParticipantProtoDelta(localWavelet)) .setHashedVersion(serialize(localWavelet.getCurrentVersion())) .build().toByteString()) .build(); localWavelet.submitRequest(localWaveletName, addAgainDelta); fail("Should fail"); } catch (OperationException e) { assertEquals(localWavelet.getCurrentVersion().getVersion(), 2); assertTrue(localWavelet.isDeltaSigner( localWavelet.getCurrentVersion(), fakeSigner1)); assertFalse(localWavelet.isDeltaSigner( localWavelet.getCurrentVersion(), fakeSigner2)); HashedVersion oldVersion = localWavelet.getCurrentVersion(); ProtocolSignedDelta rollbackDelta = ProtocolSignedDelta.newBuilder() .addSignature(fakeSignature1)
@Override protected void setUp() throws Exception { super.setUp(); addParticipantOp = ProtocolWaveletOperation.newBuilder() .setAddParticipant(AUTHOR) .build(); // An empty blip operation - creates a new document. addBlipOp = ProtocolWaveletOperation.newBuilder().setMutateDocument( MutateDocument.newBuilder().setDocumentId(BLIP_ID).setDocumentOperation( ProtocolDocumentOperation.newBuilder().build())).build(); WaveletNotificationSubscriber notifiee = mock(WaveletNotificationSubscriber.class); DeltaStore deltaStore = new MemoryDeltaStore(); WaveletState waveletState = DeltaStoreBasedWaveletState.create(deltaStore.open(WAVELET_NAME), PERSIST_EXECUTOR); wavelet = new LocalWaveletContainerImpl(WAVELET_NAME, notifiee, Futures.immediateFuture(waveletState), null, STORAGE_CONTINUATION_EXECUTOR); wavelet.awaitLoad(); }