Commit 0d1ac173 authored by Grégory Wisniewski's avatar Grégory Wisniewski

First part of replacement of handleUnexpectedPacket calls with raises of

UnexpectedPacketError exception. Update client (with tests) and admin nodes.
Those exceptions are now catched in dispatch() and redirect to
unexpectedPacket().


git-svn-id: https://svn.erp5.org/repos/neo/branches/prototype3@502 71dcc9de-d417-0410-9af5-da40c76e7ee4
parent 1ca2c441
......@@ -24,7 +24,7 @@ from neo.protocol import INVALID_UUID, RUNNING_STATE, BROKEN_STATE, \
from neo.node import MasterNode, StorageNode, ClientNode
from neo.connection import ClientConnection
from neo import protocol
from neo.protocol import Packet
from neo.protocol import Packet, UnexpectedPacketError
from neo.pt import PartitionTable
from neo.exception import PrimaryFailure
from neo.util import dump
......@@ -49,7 +49,7 @@ class MonitoringEventHandler(BaseEventHandler):
def connectionAccepted(self, conn, s, addr):
"""Called when a connection is accepted."""
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def connectionCompleted(self, conn):
app = self.app
......@@ -220,8 +220,7 @@ class MonitoringEventHandler(BaseEventHandler):
logging.warning("handleSendPartitionTable")
uuid = conn.getUUID()
if uuid is None:
self.handleUnexpectedPacket(conn, packet)
return
raise UnexpectedPacketError
app = self.app
nm = app.nm
......@@ -251,8 +250,7 @@ class MonitoringEventHandler(BaseEventHandler):
pt = app.pt
uuid = conn.getUUID()
if uuid is None:
self.handleUnexpectedPacket(conn, packet)
return
raise UnexpectedPacketError
node = app.nm.getNodeByUUID(uuid)
# This must be sent only by primary master node
......@@ -281,8 +279,7 @@ class MonitoringEventHandler(BaseEventHandler):
logging.warning("handleNotifyNodeInformation")
uuid = conn.getUUID()
if uuid is None:
self.handleUnexpectedPacket(conn, packet)
return
raise UnexpectedPacketError
app = self.app
nm = app.nm
......
......@@ -20,7 +20,7 @@ import logging
from neo.handler import EventHandler
from neo.connection import MTClientConnection
from neo import protocol
from neo.protocol import Packet, \
from neo.protocol import Packet, UnexpectedPacketError, \
MASTER_NODE_TYPE, STORAGE_NODE_TYPE, CLIENT_NODE_TYPE, \
INVALID_UUID, RUNNING_STATE, TEMPORARILY_DOWN_STATE, \
BROKEN_STATE, FEEDING_STATE, DISCARDED_STATE
......@@ -156,8 +156,7 @@ class PrimaryBoostrapEventHandler(BaseClientEventHandler):
def handleAnswerPrimaryMaster(self, conn, packet, primary_uuid, known_master_list):
uuid = conn.getUUID()
if uuid is None:
self.handleUnexpectedPacket(conn, packet)
return
raise UnexpectedPacketError
app = self.app
node = app.nm.getNodeByUUID(uuid)
......@@ -199,8 +198,7 @@ class PrimaryBoostrapEventHandler(BaseClientEventHandler):
def handleNotifyNodeInformation(self, conn, packet, node_list):
uuid = conn.getUUID()
if uuid is None:
self.handleUnexpectedPacket(conn, packet)
return
raise UnexpectedPacketError
app = self.app
nm = app.nm
......@@ -256,8 +254,7 @@ class PrimaryBoostrapEventHandler(BaseClientEventHandler):
# sendPartitionTable is only triggered after askPrimaryMaster.
uuid = conn.getUUID()
if uuid is None:
self.handleUnexpectedPacket(conn, packet)
return
raise UnexpectedPacketError
app = self.app
nm = app.nm
......
......@@ -21,7 +21,7 @@ import logging
import threading
from mock import Mock, ReturnValues
from neo import protocol
from neo.protocol import Packet, INVALID_UUID
from neo.protocol import Packet, UnexpectedPacketError, INVALID_UUID
from neo.protocol import ERROR, REQUEST_NODE_IDENTIFICATION, ACCEPT_NODE_IDENTIFICATION, \
PING, PONG, ASK_PRIMARY_MASTER, ANSWER_PRIMARY_MASTER, ANNOUNCE_PRIMARY_MASTER, \
REELECT_PRIMARY_MASTER, NOTIFY_NODE_INFORMATION, START_OPERATION, \
......@@ -342,25 +342,18 @@ class ClientEventHandlerTest(unittest.TestCase):
original_handleUnexpectedPacket = client_handler.__class__.handleUnexpectedPacket
client_handler.__class__.handleUnexpectedPacket = ClientHandler_handleUnexpectedPacket
try:
method(*args, **dict(kw))
self.assertRaises(UnexpectedPacketError, method, *args, **dict(kw))
finally:
# Restore original method
client_handler.__class__.handleUnexpectedPacket = original_handleUnexpectedPacket
# Check that packet was notified as unexpected.
self.assertEquals(len(call_list), 1)
# Return call_list in case caller wants to do extra checks on it.
return call_list
# Master node handler
def test_initialAnswerPrimaryMaster(self):
client_handler = PrimaryBoostrapEventHandler(None, self.getDispatcher())
conn = Mock({'getUUID': None})
call_list = self._testHandleUnexpectedPacketCalledWithMedhod(
self._testHandleUnexpectedPacketCalledWithMedhod(
client_handler, client_handler.handleAnswerPrimaryMaster,
args=(conn, None, 0, []))
# Nothing else happened, or a raise would have happened (app is None,
# and it's where things would happen)
self.assertEquals(call_list[0], (conn, None))
def test_nonMasterAnswerPrimaryMaster(self):
for node_type in (CLIENT_NODE_TYPE, STORAGE_NODE_TYPE):
......@@ -553,10 +546,9 @@ class ClientEventHandlerTest(unittest.TestCase):
def test_initialSendPartitionTable(self):
client_handler = PrimaryBoostrapEventHandler(None, self.getDispatcher())
conn = Mock({'getUUID': None})
call_list = self._testHandleUnexpectedPacketCalledWithMedhod(
self._testHandleUnexpectedPacketCalledWithMedhod(
client_handler, client_handler.handleSendPartitionTable,
args=(conn, None, None, None))
self.assertEquals(call_list[0], (conn, None))
def test_nonMasterSendPartitionTable(self):
for node_type in (CLIENT_NODE_TYPE, STORAGE_NODE_TYPE):
......@@ -644,10 +636,9 @@ class ClientEventHandlerTest(unittest.TestCase):
def test_initialNotifyNodeInformation(self):
client_handler = PrimaryBoostrapEventHandler(None, self.getDispatcher())
conn = Mock({'getUUID': None})
call_list = self._testHandleUnexpectedPacketCalledWithMedhod(
self._testHandleUnexpectedPacketCalledWithMedhod(
client_handler, client_handler.handleNotifyNodeInformation,
args=(conn, None, None))
self.assertEquals(call_list[0], (conn, None))
def test_nonMasterNotifyNodeInformation(self):
for node_type in (CLIENT_NODE_TYPE, STORAGE_NODE_TYPE):
......@@ -760,10 +751,9 @@ class ClientEventHandlerTest(unittest.TestCase):
app = App()
client_handler = PrimaryBoostrapEventHandler(app, self.getDispatcher())
conn = Mock({'getUUID': None})
call_list = self._testHandleUnexpectedPacketCalledWithMedhod(
self._testHandleUnexpectedPacketCalledWithMedhod(
client_handler, client_handler.handleNotifyPartitionChanges,
args=(conn, None, None, None))
self.assertEquals(call_list[0], (conn, None))
def test_nonMasterNotifyPartitionChanges(self):
for node_type in (CLIENT_NODE_TYPE, STORAGE_NODE_TYPE):
......
......@@ -18,7 +18,7 @@
import logging
from neo import protocol
from neo.protocol import Packet, PacketMalformedError
from neo.protocol import Packet, PacketMalformedError, UnexpectedPacketError
from neo.connection import ServerConnection
from protocol import ERROR, REQUEST_NODE_IDENTIFICATION, ACCEPT_NODE_IDENTIFICATION, \
......@@ -78,6 +78,10 @@ class EventHandler(object):
"""Called when a packet is received."""
self.dispatch(conn, packet)
def peerBroken(self, conn):
"""Called when a peer is broken."""
logging.error('%s:%d is broken', *(conn.getAddress()))
def packetMalformed(self, conn, packet, error_message):
"""Called when a packet is malformed."""
args = (conn.getAddress()[0], conn.getAddress()[1], error_message)
......@@ -90,9 +94,18 @@ class EventHandler(object):
conn.abort()
self.peerBroken(conn)
def peerBroken(self, conn):
"""Called when a peer is broken."""
logging.error('%s:%d is broken', *(conn.getAddress()))
def unexpectedPacket(self, conn, packet, message = None):
"""Handle an unexpected packet."""
if message is None:
message = 'unexpected packet type %s' % packet.getType()
else:
message = 'unexpected packet: %s' % message
logging.info('%s', message)
conn.notify(protocol.protocolError(message))
conn.abort()
self.peerBroken(conn)
# TODO: remove this old method name
handleUnexpectedPacket = unexpectedPacket
def dispatch(self, conn, packet):
"""This is a helper method to handle various packet types."""
......@@ -102,21 +115,12 @@ class EventHandler(object):
args = packet.decode() or ()
method(conn, packet, *args)
except (KeyError, ValueError):
self.handleUnexpectedPacket(conn, packet)
self.unexpectedPacket(conn, packet)
except UnexpectedPacketError, msg:
self.unexpectedPacket(conn, packet, msg)
except PacketMalformedError, msg:
self.packetMalformed(conn, packet, msg)
def handleUnexpectedPacket(self, conn, packet, message = None):
"""Handle an unexpected packet."""
if message is None:
message = 'unexpected packet type %s' % packet.getType()
else:
message = 'unexpected packet: ' + message
logging.info('%s', message)
conn.notify(protocol.protocolError(message))
conn.abort()
self.peerBroken(conn)
# Packet handlers.
def handleError(self, conn, packet, code, message):
......@@ -124,16 +128,16 @@ class EventHandler(object):
method = self.error_dispatch_table[code]
method(conn, packet, message)
except ValueError:
self.handleUnexpectedPacket(conn, packet, message)
raise UnexpectedPacketError(message)
def handleRequestNodeIdentification(self, conn, packet, node_type,
uuid, ip_address, port, name):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAcceptNodeIdentification(self, conn, packet, node_type,
uuid, ip_address, port,
num_partitions, num_replicas, your_uuid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handlePing(self, conn, packet):
logging.info('got a ping packet; am I overloaded?')
......@@ -143,148 +147,148 @@ class EventHandler(object):
pass
def handleAskPrimaryMaster(self, conn, packet):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnswerPrimaryMaster(self, conn, packet, primary_uuid,
known_master_list):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnnouncePrimaryMaster(self, conn, packet):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleReelectPrimaryMaster(self, conn, packet):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleNotifyNodeInformation(self, conn, packet, node_list):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAskLastIDs(self, conn, packet):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnswerLastIDs(self, conn, packet, loid, ltid, lptid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAskPartitionTable(self, conn, packet, offset_list):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnswerPartitionTable(self, conn, packet, ptid, row_list):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleSendPartitionTable(self, conn, packet, ptid, row_list):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleNotifyPartitionChanges(self, conn, packet, ptid, cell_list):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleStartOperation(self, conn, packet):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleStopOperation(self, conn, packet):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAskUnfinishedTransactions(self, conn, packet):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnswerUnfinishedTransactions(self, conn, packet, tid_list):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAskObjectPresent(self, conn, packet, oid, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnswerObjectPresent(self, conn, packet, oid, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleDeleteTransaction(self, conn, packet, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleCommitTransaction(self, conn, packet, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAskNewTID(self, conn, packet):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnswerNewTID(self, conn, packet, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAskNewOIDs(self, conn, packet):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnswerNewOIDs(self, conn, packet, oid_list):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleFinishTransaction(self, conn, packet, oid_list, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleNotifyTransactionFinished(self, conn, packet, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleLockInformation(self, conn, packet, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleNotifyInformationLocked(self, conn, packet, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleInvalidateObjects(self, conn, packet, oid_list, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleUnlockInformation(self, conn, packet, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAskStoreObject(self, conn, packet, oid, serial,
compression, checksum, data, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnswerStoreObject(self, conn, packet, status, oid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAbortTransaction(self, conn, packet, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAskStoreTransaction(self, conn, packet, tid, user, desc,
ext, oid_list):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnswerStoreTransaction(self, conn, packet, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAskObject(self, conn, packet, oid, serial, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnswerObject(self, conn, packet, oid, serial_start,
serial_end, compression, checksum, data):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAskTIDs(self, conn, packet, first, last, partition):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnswerTIDs(self, conn, packet, tid_list):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAskTransactionInformation(self, conn, packet, tid):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnswerTransactionInformation(self, conn, packet, tid,
user, desc, ext, oid_list):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAskObjectHistory(self, conn, packet, oid, first, last):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnswerObjectHistory(self, conn, packet, oid, history_list):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAskOIDs(self, conn, packet, first, last, partition):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
def handleAnswerOIDs(self, conn, packet, oid_list):
self.handleUnexpectedPacket(conn, packet)
raise UnexpectedPacketError
# Error packet handlers.
handleNotReady = handleUnexpectedPacket
handleOidNotFound = handleUnexpectedPacket
handleSerialNotFound = handleUnexpectedPacket
handleTidNotFound = handleUnexpectedPacket
handleNotReady = unexpectedPacket
handleOidNotFound = unexpectedPacket
handleSerialNotFound = unexpectedPacket
handleTidNotFound = unexpectedPacket
def handleProtocolError(self, conn, packet, message):
raise RuntimeError, 'protocol error: %s' % (message,)
......
......@@ -320,6 +320,7 @@ UUID_NAMESPACES = {
class ProtocolError(Exception): pass
class PacketMalformedError(ProtocolError): pass
class UnexpectedPacketError(ProtocolError): pass
decode_table = {}
......
......@@ -67,7 +67,7 @@ class testProtocol(unittest.TestCase):
def test_02_error(self):
p = protocol._error(10, "error message")
code, msg = p._decodeError()
code, msg = protocol._decodeError(p._body)
self.assertEqual(code, 10)
self.assertEqual(msg, "error message")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment