@Override public InternalOperationChannel create(WaveletDeltaChannel deltaChannel, WaveletId waveletId, HashedVersion startVersion, Accessibility accessibility) { ConcurrencyControl cc = new ConcurrencyControl(loggers.cc, startVersion); if (unsavedDataListenerFactory != null) { cc.setUnsavedDataListener(unsavedDataListenerFactory.create(waveletId)); } return new OperationChannelImpl(loggers.ops, deltaChannel, cc, accessibility); } };
@Override public List<HashedVersion> getReconnectVersions() { if (state == State.CLOSED) { throw new IllegalStateException("Cannot query closed operation channel: " + this); } return cc.getReconnectionVersions(); }
/** * Constructs an operation channel for the named wave. * * Any sent operations before onConnection are queued to be sent upon * connection. * * @param opsLogger logger to use for operationChannel logging * @param deltaChannel delta channel server connection * @param cc concurrency control module */ OperationChannelImpl(LoggerBundle opsLogger, WaveletDeltaChannel deltaChannel, ConcurrencyControl cc, Accessibility accessibility) { this.deltaChannel = deltaChannel; this.cc = cc; this.accessibility = accessibility; this.logger = opsLogger; this.state = State.NOT_CONNECTED; cc.initialise(ccServerConnection, ccListener); }
public void init(int version, String intialBlipXml) { HashedVersion signature = genSignature(version); serverConnectionMock = new ServerConnectionMock(); ConcurrencyControl clientCC = new ConcurrencyControl(logger, signature); serverConnectionMock.setListener(clientCC); clientMock = new ClientMock( clientCC, intialBlipXml != null ? parse(intialBlipXml) : null, DEFAULT_CREATOR, serverConnectionMock); clientCC.initialise(serverConnectionMock, clientMock); try { clientCC.onOpen(signature, signature); } catch (ChannelException e) { fail("onOpen failed: " + e); } }
/** * Connects the channel at the provided version. */ private void connectChannel(long version, byte[] signature) throws ChannelException { final HashedVersion signatureInfo = HashedVersion.of(version, signature); deltaChannel = new MockWaveletDeltaChannel(); cc = new ConcurrencyControl(ccLogger, signatureInfo); operationChannel = new OperationChannelImpl(opLogger, deltaChannel, cc, Accessibility.READ_WRITE); operationChannel.setListener(listener); operationChannel.onConnection(signatureInfo, signatureInfo); }
@Override public WaveletOperation receive() { if (state == State.CLOSED) { // TODO(anorth): throw an exception here after Wally doesn't do this. logger.error().log("Cannot receive from closed operation channel: " + this); return null; } else { return cc.receive(); } }
/** * Flush the client's operation to cc. */ public void flush() throws TransformException { cc.onClientOperations(clientOperations.toArray(new WaveletOperation[] {})); clientOperations.clear(); }
@Override public void onConnection(HashedVersion connectVersion, HashedVersion currentVersion) throws ChannelException { Preconditions.checkState(state == State.NOT_CONNECTED, "OperationChannel received onConnection in state " + state); Preconditions.checkState(cc != null, "Cannot connect a closed channel"); state = State.CONNECTED; cc.onOpen(connectVersion, currentVersion); }
/** * Closes this channel permanently. */ @Override public void close() { Preconditions.checkState(state != State.CLOSED, "Cannot close already-closed channel"); state = State.CLOSED; cc.close(); // Disconnect everything. cc = null; deltaChannel = null; listener = null; }
/** * Closes this concurrency control. */ public void close() { if (unsavedDataListener != null) { unsavedDataListener.onClose(everythingIsCommitted()); } if (!clientOperationQueue.isEmpty()) { logger.error().log("Concurrency control closed with pending operations. Data has been lost"); } }
if (detectEchoBack(serverDelta)) { return;
public void init(int version, String intialBlipXml) { HashedVersion signature = genSignature(version); serverConnectionMock = new ServerConnectionMock(); ConcurrencyControl clientCC = new ConcurrencyControl(logger, signature); serverConnectionMock.setListener(clientCC); clientMock = new ClientMock( clientCC, intialBlipXml != null ? parse(intialBlipXml) : null, DEFAULT_CREATOR, serverConnectionMock); clientCC.initialise(serverConnectionMock, clientMock); try { clientCC.onOpen(signature, signature); } catch (ChannelException e) { fail("onOpen failed: " + e); } }
/** * Connects the channel at the provided version. */ private void connectChannel(long version, byte[] signature) throws ChannelException { final HashedVersion signatureInfo = HashedVersion.of(version, signature); deltaChannel = new MockWaveletDeltaChannel(); cc = new ConcurrencyControl(ccLogger, signatureInfo); operationChannel = new OperationChannelImpl(opLogger, deltaChannel, cc, Accessibility.READ_WRITE); operationChannel.setListener(listener); operationChannel.onConnection(signatureInfo, signatureInfo); }
/** * Gets the operations from concurrency control. */ public void receiveServerOperations() { WaveletOperation op; while ((op = cc.receive()) != null) { onServerOperation(op); } }
/** * Flush the client's operation to cc. */ public void flush() throws TransformException { cc.onClientOperations(clientOperations.toArray(new WaveletOperation[] {})); clientOperations.clear(); }
serverMock.addClientConnection(serverConnectionMock); ConcurrencyControl clientCC = new ConcurrencyControl(logger, genSignature(0)); serverConnectionMock.setListener(clientCC); new ClientMock(clientCC, parse(intialBlipXml), new ParticipantId(i + "@example.com"), serverConnectionMock); clientCC.initialise(serverConnectionMock, clientMock); clientCC.onOpen(signature, signature); } catch (ChannelException e) { fail("onOpen failed: " + e);
public void testSendToInaccessibleChanneFails() throws ChannelException { final HashedVersion connectSig = HashedVersion.unsigned(0); deltaChannel = new MockWaveletDeltaChannel(); cc = new ConcurrencyControl(ccLogger, connectSig); operationChannel = new OperationChannelImpl(opLogger, deltaChannel, cc, Accessibility.READ_ONLY); operationChannel.setListener(listener); operationChannel.onConnection(connectSig, connectSig); try { sendAndCheckRandomOp(operationChannel, connectSig.getVersion(), connectSig.getHistoryHash()); fail("Expected a channel exception"); } catch (ChannelException expected) { } }
/** * Gets the reconnection versions from concurrency control. */ public List<HashedVersion> getReconnectionVersions() { return cc.getReconnectionVersions(); }
/** * Gets the operations from concurrency control. */ public void receiveServerOperations() { WaveletOperation op; while ((op = cc.receive()) != null) { onServerOperation(op); } }
@Override public void send(WaveletOperation... operations) throws ChannelException { if (state == State.CLOSED) { // TODO(anorth): throw an exception here after fixing clients. logger.error().log("Cannot send to closed operation channel: " + this); } else if (accessibility.isWritable()) { try { cc.onClientOperations(operations); } catch (TransformException e) { throw new ChannelException(ResponseCode.INVALID_OPERATION, "Operation channel failed on send: " + this + ", " + deltaChannel + ", " + cc, e, Recoverable.NOT_RECOVERABLE, null, null); } } else { throw new ChannelException(ResponseCode.NOT_AUTHORIZED, "Attempt to write to inaccessible wavelet", null, Recoverable.NOT_RECOVERABLE, null, null); } }