/** Send prepare message to the server and check that a valid acknowledged message is received. */ private void doHandshake(String contextService) throws ReplicatorException { try { // Send prepare message. toServer.print(messageGenerator.prepare()); toServer.flush(); // Receive & check acknowledged message. String header = fromServer.readLine(); if (logger.isDebugEnabled()) logger.debug("Received header: " + header); JSONObject obj = (JSONObject) parser.parse(header); long payloadLen = (Long) obj.get("payload"); if (logger.isDebugEnabled()) logger.debug("Payload length: " + payloadLen); String payload = NetworkClientFilter.Protocol.readPayload(fromServer, (int) payloadLen); if (logger.isDebugEnabled()) logger.debug("Received payload: " + payload); String type = (String) obj.get("type"); String service = (String) obj.get("service"); long returnCode = (Long) obj.get("return"); validateMessage(Protocol.TYPE_ACKNOWLEDGED, type, returnCode, service, payload); logger.info("Server: " + payload); } catch (ParseException e) { throw new ReplicatorException( "Server returned an invalid message during prepare-acknowledged message handshake: " + e, e); } catch (IOException e) { throw new ReplicatorException("prepare-acknowledged message handshake failed: " + e, e); } }
/** * Sends release message to the server. Confirms the success. Failure are logged, but otherwise * ignored. */ private void sendRelease() { try { // Send release message. toServer.print(messageGenerator.release()); toServer.flush(); // Receive & check acknowledged message. String header = fromServer.readLine(); if (header != null) { if (logger.isDebugEnabled()) logger.debug("Received header: " + header); JSONObject obj = (JSONObject) parser.parse(header); long payloadLen = (Long) obj.get("payload"); if (logger.isDebugEnabled()) logger.debug("Payload length: " + payloadLen); String payload = NetworkClientFilter.Protocol.readPayload(fromServer, (int) payloadLen); if (logger.isDebugEnabled()) logger.debug("Received payload: " + payload); String type = (String) obj.get("type"); long returnCode = (Long) obj.get("return"); if (type.equals(Protocol.TYPE_ACKNOWLEDGED)) { if (returnCode == 0) { logger.info("Server acknowledged filter release: " + payload); } else { logger.warn( "Server returned a non-zero code (" + returnCode + ") in response to release message: " + payload); } } else { logger.warn( "Server should have returned message of type \"" + Protocol.TYPE_ACKNOWLEDGED + "\", but returned \"" + type + "\" instead. Full message: " + header + payload); } } else { logger.warn("Server didn't send response to a release request"); } } catch (ParseException e) { logger.warn( "Error parsing message received back from the filtering server after release message (ignoring): " + e); } catch (IOException e) { logger.warn("Sending of release message to the filtering server failed (ignoring): " + e); } catch (ReplicatorException e) { logger.warn("Sending of release message to the filtering server failed (ignoring): " + e); } }
/** Sends column/key value to the server and receives filtered result. */ private Object sendToFilter( String transformation, long seqno, int row, String schema, String table, String column, Object value) throws ReplicatorException { try { // Convert various data types to string for transfer. String str = valueToString(value); // Send filter message. String send = messageGenerator.filter(transformation, seqno, row, schema, table, column, str); toServer.print(send); toServer.flush(); // Receive & check filtered message. String header = fromServer.readLine(); if (logger.isDebugEnabled()) logger.debug("Received header: " + header); if (header == null) throw new ReplicatorException("Server didn't send response to a filter request: " + send); JSONObject obj = (JSONObject) parser.parse(header); long payloadLen = (Long) obj.get("payload"); if (logger.isDebugEnabled()) logger.debug("Payload length: " + payloadLen); String payload = NetworkClientFilter.Protocol.readPayload(fromServer, (int) payloadLen); if (logger.isDebugEnabled()) logger.debug("Received payload: " + payload); String type = (String) obj.get("type"); long newSeqno = (Long) obj.get("seqno"); long newRow = (Long) obj.get("row"); String newSchema = (String) obj.get("schema"); String newTable = (String) obj.get("table"); long returnCode = (Long) obj.get("return"); String service = (String) obj.get("service"); // Validate that returned information matches what we requested. validateMessage(Protocol.TYPE_FILTERED, type, returnCode, service, payload); if (newSeqno != seqno) throw new ReplicatorException( "Expected to receive seqno " + seqno + ", but server sent " + newSeqno + " instead: " + header + payload); if (newRow != row) throw new ReplicatorException( "Expected to receive row " + row + ", but server sent " + newRow + " instead: " + header + payload); if (!newSchema.equals(schema)) throw new ReplicatorException( "Expected to receive schema " + schema + ", but server sent " + newSchema + " instead: " + header + payload); if (!newTable.equals(table)) throw new ReplicatorException( "Expected to receive table " + table + ", but server sent " + newTable + " instead: " + header + payload); // Convert result back to correct data type. return stringToValue(value, payload); } catch (ParseException e) { throw new ReplicatorException( "Server returned an invalid message during prepare-acknowledged message handshake: " + e, e); } catch (IOException e) { throw new ReplicatorException("prepare-acknowledged message handshake failed: " + e, e); } }