package org.neo4j.onlinebackup.net; import org.neo4j.onlinebackup.ha.ReadOnlySlave; public class ConnectToMasterJob extends ConnectionJob { private static enum Status implements JobStatus { SETUP_GREETING, SEND_GREETING, GET_RESPONSE, } private final ReadOnlySlave slave; private long masterVersion; private int retries = 0; public ConnectToMasterJob( Connection connection, ReadOnlySlave slave ) { super( connection, slave ); this.slave = slave; setStatus( Status.SETUP_GREETING ); } private boolean setupGreeting() { if ( retries > 20 ) { close(); } if ( !acquireWriteBuffer() ) { retries++; return false; } buffer.put( HeaderConstants.SLAVE_GREETING ); buffer.putLong( slave.getIdentifier() ); buffer.putLong( slave.getCreationTime() ); buffer.putLong( slave.getVersion() ); buffer.flip(); log( "Setup greeting" ); setStatus( Status.SEND_GREETING ); retries = 0; return true; } private boolean sendGreeting() { if ( retries > 20 ) { close(); } log( "Send greeting" ); connection.write(); if ( !buffer.hasRemaining() ) { releaseWriteBuffer(); setStatus( Status.GET_RESPONSE ); return true; } retries++; return false; } private boolean getResponse() { if ( retries > 20 ) { close(); } if ( !acquireReadBuffer() ) { retries++; return false; } try { // HEADER(1) + DB_VERISON(8) buffer.limit( 9 ); int read = connection.read(); log( "Get greeting response" ); if ( read == 1 || read == 9 ) { buffer.flip(); byte masterGreeting = buffer.get(); if ( masterGreeting == HeaderConstants.BYE ) { log( "Problem connecting to master " + connection + ". Got BYE." ); close(); return true; } else if ( masterGreeting != HeaderConstants.MASTER_GREETING ) { log( "Got unkown greeting[" + masterGreeting + "] from " + connection ); close(); } else if ( read != 9 ) { retries++; connection.pushBackAllReadData(); return false; } masterVersion = buffer.getLong(); log( "Got master version: " + masterVersion ); if ( masterVersion < slave.getVersion() ) { log( "Got wrong version [" + masterVersion + "]" ); close(); return true; } setNoRequeue(); setChainJob( new HandleMasterConnection( connection, slave, masterVersion ) ); return true; } else { retries++; if ( read > 0 ) { connection.pushBackAllReadData(); } return false; } } finally { releaseReadBuffer(); } } @Override public boolean performJob() { switch ( (Status) getStatus() ) { case SETUP_GREETING: return setupGreeting(); case SEND_GREETING: return sendGreeting(); case GET_RESPONSE: return getResponse(); default: throw new IllegalStateException( "Unkown status: " + getStatus() ); } } @Override void connectionClosed() { System.out.println( "Connection closed " + connection ); } public long getMasterVersion() { return masterVersion; } }