Ejemplo n.º 1
0
 public function testToPbRow()
 {
     $now = new \DateTime();
     $row = [(new Cell('string'))->setValue('test'), (new Cell('int'))->setIntValue(1), (new Cell('double'))->setDoubleValue(1.1), (new Cell('bool'))->setBooleanValue(true), (new Cell('timestamp'))->setTimestampValue($now->getTimestamp()), (new Cell('timestampdt'))->setDateTimeValue($now)];
     $tsRow = TimeSeries::toPbRow($row);
     $this->assertEquals('test', $tsRow->getCellsAt(0)->getVarcharValue());
     $this->assertEquals(1, $tsRow->getCellsAt(1)->getSint64Value());
     $this->assertEquals(1.1, $tsRow->getCellsAt(2)->getDoubleValue());
     $this->assertEquals(true, $tsRow->getCellsAt(3)->getBooleanValue());
     $this->assertEquals($now->getTimestamp(), $tsRow->getCellsAt(4)->getTimestampValue());
     $this->assertEquals($now->getTimestamp(), $tsRow->getCellsAt(5)->getTimestampValue());
 }
Ejemplo n.º 2
0
 /**
  * Parses the Protobuff response and builds the proper response object to forward on. Note: This method attempts to
  * maintain parity with the HTTP interface for the status codes returned for consistency purposes.
  *
  *  200 = Success, content returned
  *  201 = Created
  *  204 = Success, no content returned
  *  300 = Multiple choices
  *  404 = Not found
  *  503 = Service Unavailable / Timeout
  *
  * @param $message_code     PB Message identifier @see Basho\Riak\Api\Pb\Message
  * @param string $message Binary message
  * @throws Exception
  * @internal param string $response
  */
 protected function parseResponse($message_code, $message = '')
 {
     $this->success = true;
     $code = 204;
     $location = null;
     switch ($message_code) {
         case Api\Pb\Message::RpbErrorResp:
             $pbResponse = new Api\Pb\Message\RpbErrorResp();
             $pbResponse->parseFromString($message);
             $this->error = $pbResponse->getErrmsg();
             // intercept certain "errors" to provide consistent cross interface behavior
             if (strpos($message, "Query unsuccessful") !== false) {
                 // HTTP status code for bad request, consider it a request success
                 $code = 400;
                 $this->response = new Command\Search\Response($this->success, $code, '', null);
                 break;
             } elseif (strpos($message, "timeout") !== false) {
                 // set HTTP status code for service unavailable, consider it a request success
                 $code = 503;
                 $this->response = new Command\Indexes\Response($this->success, $code, $this->error);
                 break;
             } elseif (strpos($message, "notfound") !== false) {
                 // set HTTP status code for not found, consider it a request success
                 $code = 404;
             } else {
                 $code = $pbResponse->getErrcode();
                 $this->success = false;
             }
             $this->response = new Command\Response($this->success, $code, $this->error);
             break;
         case Api\Pb\Message::RpbPutResp:
             $pbResponse = new Api\Pb\Message\RpbPutResp();
             $pbResponse->parseFromString($message);
             if ($pbResponse->getKey()) {
                 $code = 201;
                 $location = new Location($pbResponse->getKey(), $this->getCommand()->getBucket());
             }
             $objects = [];
             foreach ($pbResponse->getContent() as $content) {
                 /** @var Command\Object $command */
                 $command = $this->command;
                 $object = (new Object())->setData($command->getDecodedData($content->getValue(), $content->getContentType()))->setContentType($content->getContentType())->setContentEncoding($content->getContentEncoding())->setVclock($pbResponse->getVclock());
                 foreach ($content->getIndexes() as $rpbPair) {
                     $object->addValueToIndex($rpbPair->getKey(), $rpbPair->getValue());
                 }
                 foreach ($content->getUsermeta() as $meta) {
                     $object->setMetaDataValue($meta->getKey(), $meta->getValue());
                 }
                 $objects[] = $object;
             }
             if ($objects) {
                 $code = 200;
             }
             $this->response = new Command\Object\Response($this->success, $code, '', $location, $objects);
             break;
         case Api\Pb\Message::RpbGetResp:
             $code = 404;
             $pbResponse = new Api\Pb\Message\RpbGetResp();
             $pbResponse->parseFromString($message);
             $objects = [];
             foreach ($pbResponse->getContent() as $content) {
                 /** @var Command\Object $command */
                 $command = $this->command;
                 $object = (new Object())->setData($command->getDecodedData($content->getValue(), $content->getContentType()))->setRawData($content->getValue())->setContentType($content->getContentType())->setContentEncoding($content->getContentEncoding())->setVclock($pbResponse->getVclock());
                 foreach ($content->getIndexes() as $rpbPair) {
                     $isIntIndex = Api\Http\Translator\SecondaryIndex::isIntIndex($rpbPair->getKey());
                     if ($isIntIndex) {
                         $value = intval($rpbPair->getValue());
                     } else {
                         $value = $rpbPair->getValue();
                     }
                     $object->addValueToIndex($rpbPair->getKey(), $value);
                 }
                 foreach ($content->getUsermeta() as $meta) {
                     $object->setMetaDataValue($meta->getKey(), $meta->getValue());
                 }
                 $objects[] = $object;
             }
             $object_count = count($objects);
             if ($object_count == 1) {
                 $code = 200;
             } elseif ($object_count > 1) {
                 $code = 300;
             }
             $this->response = new Command\Object\Response($this->success, $code, '', $location, $objects);
             break;
         case Api\Pb\Message::RpbGetBucketKeyPreflistResp:
             $code = 200;
             $pbResponse = new Api\Pb\Message\RpbGetBucketKeyPreflistResp();
             $pbResponse->parseFromString($message);
             $items = [];
             foreach ($pbResponse->getPreflist() as $preflistItem) {
                 $item = new \stdClass();
                 $item->node = $preflistItem->getNode();
                 $item->partition = $preflistItem->getPartition();
                 $item->primary = $preflistItem->getPrimary();
                 $items[] = $item;
             }
             // for consistent interface with http
             $preflist = new \stdClass();
             $preflist->preflist = $items;
             $this->response = new Command\Object\Response($this->success, $code, '', $location, [new Object($preflist)]);
             break;
             /** @noinspection PhpMissingBreakStatementInspection */
         /** @noinspection PhpMissingBreakStatementInspection */
         case Api\Pb\Message::RpbPingResp:
             $code = 200;
         case Api\Pb\Message::RpbDelResp:
         case Api\Pb\Message::RpbSetBucketResp:
             $this->response = new Command\Response($this->success, $code, '');
             break;
         case Api\Pb\Message::RpbGetBucketResp:
             $code = 200;
             $pbResponse = new Api\Pb\Message\RpbGetBucketResp();
             $pbResponse->parseFromString($message);
             $pbProps = $pbResponse->getProps();
             $props = [];
             foreach ($pbProps->fields() as $field_position => $field_meta) {
                 $props[$field_meta['name']] = $pbProps->get($field_position);
             }
             $bucket = new Bucket($this->command->getBucket()->getName(), $this->command->getBucket()->getType(), $props);
             $this->response = new Command\Bucket\Response($this->success, $code, '', $bucket);
             break;
         case Api\Pb\Message::DtUpdateResp:
             $pbResponse = new Api\Pb\Message\DtUpdateResp();
             $pbResponse->parseFromString($message);
             if ($pbResponse->getKey()) {
                 $code = 201;
                 $location = new Location($pbResponse->getKey(), $this->getCommand()->getBucket());
             }
             if ($pbResponse->getCounterValue()) {
                 $counter = new DataType\Counter($pbResponse->getCounterValue());
                 $this->response = new Command\DataType\Counter\Response($this->success, $code, '', $location, $counter);
             } elseif ($pbResponse->getSetValueCount()) {
                 $set = new DataType\Set($pbResponse->getSetValue(), $pbResponse->getContext());
                 $this->response = new Command\DataType\Set\Response($this->success, $code, '', $location, $set);
             } elseif ($pbResponse->getMapValueCount()) {
                 $map = new DataType\Map(Api\Pb\Translator\DataType::mapEntriesToArray($pbResponse->getMapValue()), $pbResponse->getContext());
                 $this->response = new Command\DataType\Map\Response($this->success, $code, '', $location, $map);
             } else {
                 $command = get_class($this->command);
                 if ($command == 'Basho\\Riak\\Command\\DataType\\Counter\\Store') {
                     $this->response = new Command\DataType\Counter\Response($this->success, $code, '', $location);
                 } elseif ($command == 'Basho\\Riak\\Command\\DataType\\Set\\Store') {
                     $this->response = new Command\DataType\Set\Response($this->success, $code, '', $location);
                 } elseif ($command == 'Basho\\Riak\\Command\\DataType\\Map\\Store') {
                     $this->response = new Command\DataType\Map\Response($this->success, $code, '', $location);
                 } elseif ($command == 'Basho\\Riak\\Command\\DataType\\Hll\\Store') {
                     $this->response = new Command\DataType\Hll\Response($this->success, $code, '', $location);
                 }
             }
             break;
         case Api\Pb\Message::DtFetchResp:
             $code = 200;
             $pbResponse = new Api\Pb\Message\DtFetchResp();
             $pbResponse->parseFromString($message);
             // if value is null, the DT couldn't be found
             if ($pbResponse->getValue()) {
                 switch ($pbResponse->getType()) {
                     case Api\Pb\Message\DtFetchResp\DataType::COUNTER:
                         $counter = new DataType\Counter($pbResponse->getValue()->getCounterValue());
                         $this->response = new Command\DataType\Counter\Response($this->success, $code, '', null, $counter);
                         break;
                     case Api\Pb\Message\DtFetchResp\DataType::SET:
                         $set = new DataType\Set($pbResponse->getValue()->getSetValue(), $pbResponse->getContext());
                         $this->response = new Command\DataType\Set\Response($this->success, $code, '', null, $set);
                         break;
                     case Api\Pb\Message\DtFetchResp\DataType::MAP:
                         $map = new DataType\Map(Api\Pb\Translator\DataType::mapEntriesToArray($pbResponse->getValue()->getMapValue()), $pbResponse->getContext());
                         $this->response = new Command\DataType\Map\Response($this->success, $code, '', null, $map);
                         break;
                     case Api\Pb\Message\DtFetchResp\DataType::HLL:
                         $hll = new DataType\Hll($pbResponse->getValue()->getHllValue());
                         $this->response = new Command\DataType\Hll\Response($this->success, $code, '', null, $hll);
                         break;
                     default:
                         throw new Exception('Unknown data type.');
                 }
             } else {
                 $this->response = new Command\Response($this->success, 404, '');
             }
             break;
         case Api\Pb\Message::RpbMapRedResp:
             $code = null;
             $results = [];
             $pbResponse = new Api\Pb\Message\RpbMapRedResp();
             $pbResponse->parseFromString($message);
             while ($code === null) {
                 if (!$pbResponse->getDone()) {
                     // We haven't received all responses from Riak, merge the results
                     $results = array_merge($results, json_decode($pbResponse->getResponse()));
                     // Continue reading from the socket
                     $length = $this->readMessageLength();
                     if ($this->readMessageCode() != Api\Pb\Message::RpbMapRedResp) {
                         throw new Exception('Unknown response from Riak.');
                     }
                     $message = $this->readMessage($length);
                     $pbResponse = new Api\Pb\Message\RpbMapRedResp();
                     $pbResponse->parseFromString($message);
                 } else {
                     // All responses from Riak are complete, return a 200 code
                     $code = 200;
                 }
             }
             $this->response = new Command\MapReduce\Response($this->success, $code, '', $results);
             break;
         case Api\Pb\Message::RpbSearchQueryResp:
             $code = 200;
             $docs = [];
             $pbResponse = new Api\Pb\Message\RpbSearchQueryResp();
             $pbResponse->parseFromString($message);
             foreach ($pbResponse->getDocs() as $pbDoc) {
                 $doc = new \stdClass();
                 foreach ($pbDoc->getFields() as $rpbPair) {
                     $doc->{$rpbPair->getKey()} = $rpbPair->getValue();
                 }
                 $docs[] = new Doc($doc);
             }
             $this->response = new Command\Search\Response($this->success, $code, '', $pbResponse->getNumFound(), $docs);
             break;
         case Api\Pb\Message::RpbYokozunaIndexGetResp:
             $code = 200;
             $pbResponse = new Api\Pb\Message\RpbYokozunaIndexGetResp();
             $pbResponse->parseFromString($message);
             $index = new \stdClass();
             $index->name = $pbResponse->getIndexAt(0)->getName();
             $index->n_val = $pbResponse->getIndexAt(0)->getNVal();
             $index->schema = $pbResponse->getIndexAt(0)->getSchema();
             $this->response = new Command\Search\Index\Response($this->success, $code, '', $index);
             break;
         case Api\Pb\Message::RpbYokozunaSchemaGetResp:
             $code = 200;
             $pbResponse = new Api\Pb\Message\RpbYokozunaSchemaGetResp();
             $pbResponse->parseFromString($message);
             $this->response = new Command\Search\Schema\Response($this->success, $code, '', $pbResponse->getSchema()->getContent(), Http::CONTENT_TYPE_XML);
             break;
         case Api\Pb\Message::RpbIndexResp:
             $code = 200;
             $pbResponse = new Api\Pb\Message\RpbIndexResp();
             $pbResponse->parseFromString($message);
             // sane defaults
             $results = [];
             $termsReturned = false;
             $continuation = null;
             $done = true;
             if ($pbResponse->getKeys()) {
                 $results = $pbResponse->getKeys();
             }
             if ($pbResponse->getResultsCount()) {
                 foreach ($pbResponse->getResults() as $result) {
                     $results[] = [$result->getKey() => $result->getValue()];
                 }
                 $termsReturned = true;
             }
             if ($pbResponse->getContinuation()) {
                 $continuation = $pbResponse->getContinuation();
                 $done = false;
             }
             $this->response = new Command\Indexes\Response($this->success, $code, '', $results, $termsReturned, $continuation, $done);
             break;
         case Api\Pb\Message::TsDelResp:
         case Api\Pb\Message::TsPutResp:
             $this->success = true;
             $this->response = new Command\TimeSeries\Response($this->success, $code, '');
             break;
         case Api\Pb\Message::TsGetResp:
             $this->success = true;
             $pbResponse = new Api\Pb\Message\TsGetResp();
             $pbResponse->parseFromString($message);
             $rows = [];
             foreach ($pbResponse->getRows() as $row) {
                 $rows[] = Api\Pb\Translator\TimeSeries::fromPbRow($row, $pbResponse->getColumns());
             }
             $this->response = new Command\TimeSeries\Response($this->success, count($rows) ? 200 : 404, '', $rows);
             break;
         case Api\Pb\Message::TsQueryResp:
             $this->success = true;
             $pbResponse = new Api\Pb\Message\TsQueryResp();
             $pbResponse->parseFromString($message);
             $rows = [];
             foreach ($pbResponse->getRows() as $row) {
                 $rows[] = Api\Pb\Translator\TimeSeries::fromPbRow($row, $pbResponse->getColumns());
             }
             $this->response = new Command\TimeSeries\Query\Response($this->success, count($rows) ? 200 : 204, '', $rows);
             break;
         default:
             throw new Api\Exception('Mishandled PB response.');
     }
 }