001: /**
002: * Sequoia: Database clustering technology.
003: * Copyright (C) 2006 Continuent, Inc.
004: * Contact: sequoia@continuent.org
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: *
018: * Initial developer(s): Gilles Rayrat.
019: * Contributor(s): ______________________.
020: */package org.continuent.sequoia.controller.core;
021:
022: import java.io.IOException;
023: import java.net.DatagramPacket;
024: import java.net.DatagramSocket;
025: import java.net.SocketException;
026:
027: import org.continuent.sequoia.common.i18n.Translate;
028: import org.continuent.sequoia.common.log.Trace;
029: import org.continuent.sequoia.common.util.Constants;
030:
031: /**
032: * Thread that responds to pings sent by the driver.<br>
033: * When receiving a ping, replies immediatly by a 'pong' to the sender.
034: *
035: * @author <a href="mailto:gilles.rayrat@continuent.com">Gilles Rayrat</a>
036: * @version 1.0
037: */
038: public class PingResponder extends Thread {
039: /** Socket for incomming pings */
040: DatagramSocket socket = null;
041: /** Incomming data buffer. Pings are only one byte long */
042: byte[] buffer = new byte[10];
043: /** Ping packet received */
044: DatagramPacket incomingPacket = new DatagramPacket(buffer,
045: buffer.length);
046: /** Data that will be sent in the pong packet */
047: static final byte pongData[] = { Constants.CONTROLLER_PING_VERSION };
048: /** Packet sent as a pong */
049: DatagramPacket pongPacket = new DatagramPacket(pongData,
050: pongData.length);
051: /** Logger instance. */
052: static protected Trace logger = Trace
053: .getLogger("org.continuent.sequoia.controller.core.Controller");
054:
055: /**
056: * Creates a new <code>PingResponder</code> object that will receive pings
057: * on the given UDP port
058: *
059: * @param port UDP port to receive pings on
060: * @throws SocketException
061: */
062: public PingResponder(int port) throws SocketException {
063: super ("PingResponder");
064: socket = new DatagramSocket(port);
065: }
066:
067: /**
068: * Main endless loop iterating on blocking ping reception + pong answer
069: */
070: public void run() {
071: while (true) {
072: byte[] data = null;
073: // 1. Receive ping. The receive function will not return until data is
074: // available on the socket
075: try {
076: socket.receive(incomingPacket);
077: data = incomingPacket.getData();
078: if (logger.isDebugEnabled()) {
079: String msg = Translate.get(
080: "controller.ping.responder.received.ping",
081: incomingPacket.getAddress().toString());
082: logger.debug(msg);
083: }
084: if (data[0] != Constants.CONTROLLER_PING_VERSION) {
085: if (logger.isDebugEnabled()) {
086: logger
087: .debug(Translate
088: .get(
089: "controller.ping.responder.wrong.protocol",
090: new String[] {
091: Byte
092: .toString(data[0]),
093: Byte
094: .toString(Constants.CONTROLLER_PING_VERSION) }));
095: }
096: data = null; // prevents from responding to unknown protocol
097: }
098: } catch (IOException e) {
099: if (logger.isDebugEnabled()) {
100: String msg = Translate
101: .get("controller.ping.responder.received.error");
102: logger.debug(msg, e);
103: }
104: }
105: // 2. Send pong as response
106: if (data != null) {
107: pongPacket.setAddress(incomingPacket.getAddress());
108: pongPacket.setPort(incomingPacket.getPort());
109: try {
110: socket.send(pongPacket);
111: if (logger.isDebugEnabled()) {
112: String msg = Translate.get(
113: "controller.ping.responder.send.pong",
114: incomingPacket.getAddress().toString());
115: logger.debug(msg);
116: }
117: } catch (IOException e) {
118: if (logger.isInfoEnabled()) {
119: logger.info(Translate.get(
120: "controller.ping.responder.send.error",
121: e));
122: }
123: }
124: }
125: }
126: }
127: }
|