Changeset 1818

Show
Ignore:
Timestamp:
09/02/08 04:02:28 (4 months ago)
Author:
mikey
Message:

refactor: add net::stubbles::remote::protocol::easc::stubEASCMessageType
fix bugs in test case for net::stubbles::remote::protocol::easc::stubEASCHeader

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • labs/incubator/src/main/php/net/stubbles/remote/protocol/easc/stubEASCHeader.php

    r1817 r1818  
    99 * @version     $Id$ 
    1010 */ 
    11 stubClassLoader::load('net::stubbles::peer::stubSocket'); 
     11stubClassLoader::load('net::stubbles::lang::exceptions::stubIllegalArgumentException', 
     12                      'net::stubbles::peer::stubSocket', 
     13                      'net::stubbles::remote::protocol::easc::stubEASCMessageType' 
     14); 
    1215/** 
    1316 * Class for handling easc message headers. 
     
    7174     * type of message 
    7275     * 
    73      * @var  int 
     76     * @var  stubEASCMessageType 
    7477     */ 
    7578    protected $messageType; 
     
    9093     * constructor 
    9194     * 
    92      * @param  int   $magicNumber        magic easc protocol number 
    93      * @param  int   $versionMajor       major part of protocol version 
    94      * @param  int   $versionMinor       minor part of protocol version 
    95      * @param  int   $messageType        type of message that follows after header 
    96      * @param  bool  $transactionActive  whether a transaction is active or not 
    97      * @param  int   $dataLength         length of data after header 
    98      */ 
    99     public function __construct($magicNumber, $versionMajor, $versionMinor, $messageType, $transactionActive, $dataLength) 
     95     * @param  int                  $magicNumber        magic easc protocol number 
     96     * @param  int                  $versionMajor       major part of protocol version 
     97     * @param  int                  $versionMinor       minor part of protocol version 
     98     * @param  stubEASCMessageType  $messageType        type of message that follows after header 
     99     * @param  bool  ÂŽ              $transactionActive  whether a transaction is active or not 
     100     * @param  int                  $dataLength         length of data after header 
     101     */ 
     102    public function __construct($magicNumber, $versionMajor, $versionMinor, stubEASCMessageType $messageType, $transactionActive, $dataLength) 
    100103    { 
    101104        $this->magicNumber       = $magicNumber; 
     
    128131         
    129132        $header = unpack('Nmagic/cvmajor/cvminor/ctype/ctran/Nlength', $headerString); 
    130         return new self($header['magic'], $header['vmajor'], $header['vminor'], $header['type'], $header['tran'], $header['length']); 
     133        try { 
     134            $messageType = stubEASCMessageType::forValue(new ReflectionClass('stubEASCMessageType'), $header['type']); 
     135        } catch (stubIllegalArgumentException $iae) { 
     136            $messageType = stubEASCMessageType::$UNKNOWN; 
     137        } 
     138         
     139        return new self($header['magic'], 
     140                        $header['vmajor'], 
     141                        $header['vminor'], 
     142                        $messageType, 
     143                        (bool) $header['tran'], 
     144                        $header['length'] 
     145               ); 
    131146    } 
    132147 
     
    143158    { 
    144159        return $socket->write(pack('Nc4N',  
    145                                    self::DEFAULT_MAGIC_NUMBER, // magic number to ensure correctness of message 
    146                                    $this->versionMajor,        // version: major 
    147                                    $this->versionMinor,        // version: minor 
    148                                    $this->messageType,        // message type 
    149                                    $this->transactionActive,   // compression 
    150                                    $this->dataLength           // length of data to follow 
     160                                   self::DEFAULT_MAGIC_NUMBER, // magic number to ensure correctness of message 
     161                                   $this->versionMajor,        // version: major 
     162                                   $this->versionMinor,        // version: minor 
     163                                   $this->messageType->value(), // message type 
     164                                   $this->transactionActive,    // compression 
     165                                   $this->dataLength            // length of data to follow 
    151166                              ) 
    152167               ); 
     
    186201     * returns type of message that follows after header 
    187202     * 
    188      * @return  int 
     203     * @return  stubEASCMessageType 
    189204     */ 
    190205    public function getMessageType() 
  • labs/incubator/src/main/php/net/stubbles/remote/protocol/easc/stubEASCProtocolHandler.php

    r1817 r1818  
    88 * @version     $Id$ 
    99 */ 
    10 stubClassLoader::load('net::stubbles::remote::protocol::stubByteCountedString', 
     10stubClassLoader::load('net::stubbles::peer::stubBSDSocket', 
     11                      'net::stubbles::remote::stubRemoteException', 
     12                      'net::stubbles::remote::protocol::stubByteCountedString', 
    1113                      'net::stubbles::remote::protocol::stubProtocolHandler', 
    1214                      'net::stubbles::remote::protocol::easc::stubEASCException', 
    1315                      'net::stubbles::remote::protocol::easc::stubEASCHeader', 
    14                       'net::stubbles::peer::stubBSDSocket
     16                      'net::stubbles::remote::protocol::easc::stubEASCMessageType
    1517); 
    1618/** 
     
    4143    protected $socket;     
    4244    /** 
    43      * request message type: init 
    44      */ 
    45     const MSG_INIT        = 0x0000; 
    46     /** 
    47      * request message type: lookup 
    48      */ 
    49     const MSG_LOOKUP      = 0x0001; 
    50     /** 
    51      * request message type: call 
    52      */ 
    53     const MSG_CALL        = 0x0002; 
    54     /** 
    55      * request message type: finalize 
    56      */ 
    57     const MSG_FINALIZE    = 0x0003; 
    58     /** 
    59      * request message type: transaction operation 
    60      */ 
    61     const MSG_TRAN_OP     = 0x0004; 
    62     /** 
    63      * response message type: value 
    64      */ 
    65     const MSG_VALUE       = 0x0005; 
    66     /** 
    67      * response message type: exception 
    68      */ 
    69     const MSG_EXCEPTION   = 0x0006; 
    70     /** 
    71      * response message type: error 
    72      */ 
    73     const MSG_ERROR       = 0x0007; 
    74     /** 
    7545     * transaction message type: begin of transaction 
    7646     */ 
     
    11888        $this->socket->connect(); 
    11989        if ($url->getUser() !== null) { 
    120             $this->sendPacket(self::MSG_INIT, "\1", array(new stubByteCountedString($url->getUser()), 
     90            $this->sendPacket(stubEASCMessageType::$INITIALIZE, "\1", array(new stubByteCountedString($url->getUser()), 
    12191                                                          new stubByteCountedString($url->getPassword()) 
    12292                                                    ) 
    12393            ); 
    12494        } else { 
    125             $this->sendPacket(self::MSG_INIT, "\0"); 
     95            $this->sendPacket(stubEASCMessageType::$INITIALIZE, "\0"); 
    12696        } 
    12797    } 
     
    135105    public function lookup($name) 
    136106    { 
    137         return $this->sendPacket(self::MSG_LOOKUP, '', array(new stubByteCountedString($name))); 
     107        return $this->sendPacket(stubEASCMessageType::$LOOKUP, '', array(new stubByteCountedString($name))); 
    138108    } 
    139109 
     
    146116    public function begin($tran) 
    147117    { 
    148         return $this->sendPacket(self::MSG_TRAN_OP, pack('N', self::TRAN_BEGIN)); 
     118        return $this->sendPacket(stubEASCMessageType::$TRANSACTION, pack('N', self::TRAN_BEGIN)); 
    149119    } 
    150120 
     
    157127    public function rollback($tran) 
    158128    { 
    159         return $this->sendPacket(self::MSG_TRAN_OP, pack('N', self::TRAN_ROLLBACK)); 
     129        return $this->sendPacket(stubEASCMessageType::$TRANSACTION, pack('N', self::TRAN_ROLLBACK)); 
    160130    } 
    161131 
     
    168138    public function commit($tran) 
    169139    { 
    170         return $this->sendPacket(self::MSG_TRAN_OP, pack('N', self::TRAN_COMMIT)); 
     140        return $this->sendPacket(stubEASCMessageType::$TRANSACTION, pack('N', self::TRAN_COMMIT)); 
    171141    } 
    172142 
     
    182152    public function invoke($oid, $method, array $args) 
    183153    { 
    184         return $this->sendPacket(self::MSG_CALL, 
     154        return $this->sendPacket(stubEASCMessageType::$CALL, 
    185155                                 pack('NN', 0, $oid), 
    186156                                 array(new stubByteCountedString($method), 
     
    193163     * sends a packet, reads and evaluates the response 
    194164     * 
    195      * @param   int                           $type 
     165     * @param   stubEASCMessageType           $type 
    196166     * @param   string                        $data   optional 
    197167     * @param   array<stubByteCountedString>  $bytes  optional 
     
    200170     * @throws  stubEASCException    for unrecoverable errors 
    201171     */ 
    202     protected function sendPacket($type, $data = '', array $bytes = array()) 
     172    protected function sendPacket(stubEASCMessageType $type, $data = '', array $bytes = array()) 
    203173    { 
    204174        $bsize  = sizeof($bytes); 
     
    208178        } 
    209179 
    210         $requestHeader = new stubEASCHeader(stubEASCHeader::DEFAULT_MAGIC_NUMBER, 1, 0, $type, false, $length); 
     180        $requestHeader = new stubEASCHeader(stubEASCHeader::DEFAULT_MAGIC_NUMBER, 
     181                                            $this->version['major'], 
     182                                            $this->version['minor'], 
     183                                            $type, 
     184                                            false, 
     185                                            $length 
     186                         ); 
    211187        try { 
    212188            $requestHeader->writeToSocket($this->socket, $data); 
     
    226202        } elseif (stubEASCHeader::DEFAULT_MAGIC_NUMBER != $responseHeader->getMagicNumber()) { 
    227203            $this->socket->close(); 
    228             throw new stubEASCException('Magic number mismatch, got "' . $responseHeader->getMagicNumber() . '" but expected "' . stubEASCHeader::MAGIC_NUMBER . '".'); 
    229         } 
    230  
    231         // Perform actions based on response type 
    232         $context = array('handler' => $this); 
     204            throw new stubEASCException('Magic number mismatch, got "' . $responseHeader->getMagicNumber() . '" but expected "' . stubEASCHeader::DEFAULT_MAGIC_NUMBER . '".'); 
     205        } 
     206 
    233207        try { 
    234             switch ($responseHeader->getMessageType()) { 
    235                 case self::MSG_VALUE: 
    236                     $data = stubByteCountedString::readFrom($this->socket); 
    237                     return $this->serializer->unserialize(new stubPHPSerializedData($data), $context); 
    238  
    239                 case self::MSG_EXCEPTION: 
    240                     $data      = stubByteCountedString::readFrom($this->socket); 
    241                     $reference = $this->serializer->unserialize(new stubPHPSerializedData($data), $context); 
    242                     if ($reference instanceof stubRemoteException) { 
    243                         throw $reference; 
    244                     } elseif ($reference instanceof stubExceptionReference) { 
    245                         throw new stubRemoteException($reference->getMessage(), $reference); 
    246                     } 
    247                      
    248                     throw new stubRemoteException('lang.XPException', new XPException($this->stringOf($reference))); 
    249  
    250                 case self::MSG_ERROR: 
    251                     $message = stubByteCountedString::readFrom($this->socket);    // not serialized! 
    252                     $this->socket->close(); 
    253                     throw new stubRemoteException($message, new stubEASCException($message)); 
    254  
    255                 default: 
    256                     $data = $this->readBytes($responseHeader->getDataLength()); 
    257                     $this->socket->close(); 
    258                     throw new stubEASCException('Unknown message type: ' . $data); 
    259             } 
     208            $responseHeader->getMessageType()->process($this->socket, $this->serializer, array('handler' => $this)); 
    260209        } catch (stubConnectionException $ce) { 
    261210            throw new stubRemoteException($ce->getMessage(), $ce); 
    262211        } 
    263212    } 
    264  
    265     /** 
    266      * reads a specified number of bytes 
    267      * 
    268      * @param   int     $num 
    269      * @return  string  
    270      */ 
    271     protected function readBytes($amount) 
    272     { 
    273         $return = ''; 
    274         while (strlen($return) < $amount) { 
    275             $buffer = $this->socket->readBinary($amount - strlen($return)); 
    276             if (0 === strlen($buffer)) { 
    277                 return null; 
    278             } 
    279              
    280             $return .= $buffer; 
    281         } 
    282          
    283         return $return; 
    284     } 
    285  
    286     /** 
    287      * creates a string representation of a given value 
    288      * 
    289      * @param   mixed   $value 
    290      * @return  string 
    291      */ 
    292     protected function stringOf($value) 
    293     { 
    294         if ($value instanceof Proxy) { 
    295             $s = 'Proxy<'; 
    296             foreach ($value->getClass()->getInterfaces() as $iface) { 
    297                 $s .= $iface->getName() . ', '; 
    298             } 
    299              
    300             return substr($s, 0, -2) . '>'; 
    301         } 
    302          
    303         return xp::stringOf($value); 
    304     } 
    305213} 
    306214?> 
  • labs/incubator/src/test/php/net/stubbles/remote/protocol/easc/stubEASCHeaderTestCase.php

    r1817 r1818  
    3232    public function setUp() 
    3333    { 
    34         $this->eascHeader = new stubEASCHeader(stubEASCHeader::DEFAULT_MAGIC_NUMBER, 1, 0, 1, false, 4); 
     34        $this->eascHeader = new stubEASCHeader(stubEASCHeader::DEFAULT_MAGIC_NUMBER, 1, 0, stubEASCMessageType::$INITIALIZE, false, 4); 
    3535    } 
    3636 
     
    4545        $this->assertEquals(1, $this->eascHeader->getVersionMajor()); 
    4646        $this->assertEquals(0, $this->eascHeader->getVersionMinor()); 
    47         $this->assertEquals(1, $this->eascHeader->getMessageType()); 
     47        $this->assertSame(stubEASCMessageType::$INITIALIZE, $this->eascHeader->getMessageType()); 
    4848        $this->assertFalse($this->eascHeader->isTransactionActive()); 
    4949        $this->assertEquals(4, $this->eascHeader->getDataLength()); 
     
    6060        $mockSocket->expects($this->once()) 
    6161                   ->method('write') 
    62                    ->with($this->equalTo(pack('Nc4N', stubEASCHeader::DEFAULT_MAGIC_NUMBER, 1, 0, 1, false, 4))) 
     62                   ->with($this->equalTo(pack('Nc4N', stubEASCHeader::DEFAULT_MAGIC_NUMBER, 1, 0, stubEASCMessageType::$INITIALIZE->value(), false, 4))) 
    6363                   ->will($this->returnValue(stubEASCHeader::SIZE)); 
    6464        $this->assertEquals(stubEASCHeader::SIZE, $this->eascHeader->writeToSocket($mockSocket)); 
     
    7676                   ->method('readBinary') 
    7777                   ->with($this->equalTo(stubEASCHeader::SIZE)) 
    78                    ->will($this->returnValue(pack('Nc4N', stubEASCHeader::DEFAULT_MAGIC_NUMBER, 1, 0, 1, false, 4))); 
     78                   ->will($this->returnValue(pack('Nc4N', stubEASCHeader::DEFAULT_MAGIC_NUMBER, 1, 0, stubEASCMessageType::$INITIALIZE->value(), false, 4))); 
    7979        $eascHeader = stubEASCHeader::readFromSocket($mockSocket); 
    8080        $this->assertType('stubEASCHeader', $eascHeader); 
    81         $this->assertEquals(stubEASCHeader::DEFAULT_MAGIC_NUMBER, $this->eascHeader->getMagicNumber()); 
    82         $this->assertEquals(1, $this->eascHeader->getVersionMajor()); 
    83         $this->assertEquals(0, $this->eascHeader->getVersionMinor()); 
    84         $this->assertEquals(1, $this->eascHeader->getMessageType()); 
    85         $this->assertFalse($this->eascHeader->isTransactionActive()); 
    86         $this->assertEquals(4, $this->eascHeader->getDataLength()); 
     81        $this->assertEquals(stubEASCHeader::DEFAULT_MAGIC_NUMBER, $eascHeader->getMagicNumber()); 
     82        $this->assertEquals(1, $eascHeader->getVersionMajor()); 
     83        $this->assertEquals(0, $eascHeader->getVersionMinor()); 
     84        $this->assertSame(stubEASCMessageType::$INITIALIZE, $eascHeader->getMessageType()); 
     85        $this->assertFalse($eascHeader->isTransactionActive()); 
     86        $this->assertEquals(4, $eascHeader->getDataLength()); 
    8787    } 
    8888 
     
    101101        $this->assertNull(stubEASCHeader::readFromSocket($mockSocket)); 
    102102    } 
     103 
     104    /** 
     105     * no data on socket does not create an instance 
     106     * 
     107     * @test 
     108     */ 
     109    public function readFromSocketUnknownMessageType() 
     110    { 
     111        $mockSocket = $this->getMock('stubSocket', array(), array('localhost', 313)); 
     112        $mockSocket->expects($this->once()) 
     113                   ->method('readBinary') 
     114                   ->with($this->equalTo(stubEASCHeader::SIZE)) 
     115                   ->will($this->returnValue(pack('Nc4N', stubEASCHeader::DEFAULT_MAGIC_NUMBER, 1, 0, 0x0020, false, 4))); 
     116        $eascHeader = stubEASCHeader::readFromSocket($mockSocket); 
     117        $this->assertType('stubEASCHeader', $eascHeader); 
     118        $this->assertEquals(stubEASCHeader::DEFAULT_MAGIC_NUMBER, $eascHeader->getMagicNumber()); 
     119        $this->assertEquals(1, $eascHeader->getVersionMajor()); 
     120        $this->assertEquals(0, $eascHeader->getVersionMinor()); 
     121        $this->assertSame(stubEASCMessageType::$UNKNOWN, $eascHeader->getMessageType()); 
     122        $this->assertFalse($eascHeader->isTransactionActive()); 
     123        $this->assertEquals(4, $eascHeader->getDataLength()); 
     124    } 
    103125} 
    104126?>