public function callback(AMQPMessage $msg)
 {
     $routingKey = $msg->delivery_info['routing_key'];
     $method = 'read' . Inflector::camelize($routingKey);
     if (!isset($this->interpreters[$this->exchange])) {
         $interpreter = $this;
     } elseif (class_exists($this->interpreters[$this->exchange])) {
         $interpreter = new $this->interpreters[$this->exchange]();
         if (!$interpreter instanceof AmqpInterpreter) {
             throw new Exception(sprintf("Class '%s' is not correct interpreter class.", $this->interpreters[$this->exchange]));
         }
     } else {
         throw new Exception(sprintf("Interpreter class '%s' was not found.", $this->interpreters[$this->exchange]));
     }
     if (method_exists($interpreter, $method)) {
         $info = ['exchange' => $msg->get('exchange'), 'routing_key' => $msg->get('routing_key'), 'reply_to' => $msg->has('reply_to') ? $msg->get('reply_to') : null];
         $interpreter->{$method}(Json::decode($msg->body, true), $info);
     } else {
         if (!isset($this->interpreters[$this->exchange])) {
             $interpreter = new AmqpInterpreter();
         }
         $interpreter->log(sprintf("Unknown routing key '%s' for exchange '%s'.", $routingKey, $this->exchange), $interpreter::MESSAGE_ERROR);
         // debug the message
         $interpreter->log(print_r(Json::decode($msg->body, true), true), $interpreter::MESSAGE_INFO);
     }
 }
 public function callback(AMQPMessage $msg)
 {
     $routingKey = $msg->get('routing_key');
     $method = 'read' . Inflector::camelize($routingKey);
     $interpreter = isset($this->interpreters[$this->exchange]) ? $this->interpreters[$this->exchange] : (isset($this->interpreters['*']) ? $this->interpreters['*'] : null);
     if ($interpreter === null) {
         $interpreter = $this;
     } else {
         if (class_exists($interpreter)) {
             $interpreter = new $interpreter();
             if (!$interpreter instanceof AmqpInterpreter) {
                 throw new Exception(sprintf("Class '%s' is not correct interpreter class.", $interpreter));
             }
         } else {
             throw new Exception(sprintf("Interpreter class '%s' was not found.", $interpreter));
         }
     }
     if (method_exists($interpreter, $method) || is_callable([$interpreter, $method])) {
         $info = ['exchange' => $this->exchange, 'routing_key' => $routingKey, 'reply_to' => $msg->has('reply_to') ? $msg->get('reply_to') : null, 'delivery_tag' => $msg->get('delivery_tag')];
         try {
             $body = Json::decode($msg->body, true);
         } catch (\Exception $e) {
             $body = $msg->body;
         }
         $interpreter->{$method}($body, $info, $this->amqp->channel);
     } else {
         if (!$interpreter instanceof AmqpInterpreter) {
             $interpreter = new AmqpInterpreter();
         }
         $interpreter->log(sprintf("Unknown routing key '%s' for exchange '%s'.", $routingKey, $this->exchange), $interpreter::MESSAGE_ERROR);
         // debug the message
         $interpreter->log(print_r(Json::decode($msg->body, true), true), $interpreter::MESSAGE_INFO);
     }
 }
Exemple #3
0
 /**
  * @param AMQPMessage $amqpMessage The message to convert
  *
  * @return MessageInterface
  */
 public static function toMessage(AMQPMessage $amqpMessage)
 {
     $properties = array('content_type', 'content_encoding', 'app_id', 'correlation_id', 'delivery_tag', 'message_id', 'priority', 'reply_to', 'routing_key', 'exchange_name', 'timestamp', 'type', 'user_id');
     $propertyValues = array_map(function ($propertyName) use($amqpMessage) {
         if ($amqpMessage->has($propertyName)) {
             return $amqpMessage->get($propertyName);
         }
         return false;
     }, $properties);
     $headers = $amqpMessage->has('application_headers') ? $amqpMessage->get('application_headers')->getNativeData() : array();
     $message = new \Amqp\Message();
     $message->setPayload($amqpMessage->body)->setDeliveryMode($amqpMessage->get('delivery_mode'))->setHeaders($headers)->setProperties(array_combine($properties, $propertyValues));
     return $message;
 }
 /**
  * @param AMQPMessage $message
  *
  * @return AMQPTable
  */
 private function getHeaders(AMQPMessage $message)
 {
     if ($message->has('application_headers')) {
         return $message->get('application_headers');
     }
     return new AMQPTable();
 }
Exemple #5
0
 /**
  * @param string $name
  * @return string
  */
 private function getFromEnvelope(string $name) : string
 {
     if ($this->envelope->has($name)) {
         return $this->envelope->get($name);
     }
     return '';
 }
 public function execute(AMQPMessage $msg)
 {
     $body = json_decode($msg->body, true);
     if ($msg->has("application_headers")) {
         $nativeData = $msg->get("application_headers")->getNativeData();
     }
     return $this->readMessage($body, isset($nativeData['attempts']) ? $nativeData['attempts'] : 0);
 }
Exemple #7
0
 /**
  * @param AMQPMessage $queueMessage
  *
  * @return $this
  */
 protected function setPropertiesFromMessage($queueMessage)
 {
     foreach ($this->propertyMapping as $mqlibProperty => $amqpProperty) {
         if ($queueMessage->has($amqpProperty) && property_exists($this, $mqlibProperty)) {
             $this->{$mqlibProperty} = $amqpProperty;
         }
     }
     return $this;
 }
 /**
  * @param AmqpLibMessage $message
  *
  * @return AmqpMessage
  */
 public static function createMessage(AmqpLibMessage $message)
 {
     $properties = ['body' => $message->body];
     foreach (self::$PROPERTY_MAP as $name => $amqpLibName) {
         if ($message->has($amqpLibName)) {
             $properties[$name] = $message->get($amqpLibName);
         }
     }
     return CustomAmqpMessage::fromProperties($properties);
 }
 /**
  * @param AMQPMessage $message
  *
  * @return Request
  *
  * @throws \Exception
  */
 private function createRequest(AMQPMessage $message)
 {
     $topic = $message->delivery_info['routing_key'];
     $headers = $message->has('application_headers') ? $message->get('application_headers')->getNativeData() : [];
     $version = isset($headers['version']) ? $headers['version'] : null;
     $arguments = json_decode($message->getBody(), true);
     if (json_last_error() !== JSON_ERROR_NONE) {
         throw new EncodingException('Unable to decode request: ' . json_last_error_msg());
     }
     return new Request($topic, $version, $arguments, $headers);
 }
Exemple #10
0
 public function callback(AMQPMessage $Message)
 {
     try {
         $result = $Message->delivery_info['delivery_tag'];
         // отправляем ответ, если он вообще нужен
         if ($Message->has('reply_to')) {
             $Message->delivery_info['channel']->basic_publish(new AMQPMessage($this->_encode($result), ['correlation_id' => $Message->get('correlation_id')]), '', $Message->get('reply_to'));
         }
         // подтверждаем
         $Message->delivery_info['channel']->basic_ack($Message->delivery_info['delivery_tag']);
     } catch (\Exception $e) {
         $Message->delivery_info['channel']->basic_nack($Message->delivery_info['delivery_tag']);
     }
 }
 public function execute(AMQPMessage $msg)
 {
     if (!$msg->has('application_headers') || !isset($msg->get('application_headers')['x-death'])) {
         sleep(2);
         return false;
     }
     $message = json_decode($msg->body, true);
     /* Отправка задачи на исполнение */
     $producer = $this->container->get('old_sound_rabbit_mq.' . $message['producer'] . '_producer');
     if (isset($message['route'])) {
         $producer->publish($message['payload'], $message['route']);
     } else {
         $producer->publish($message['payload']);
     }
     /* Установка задачи с задержкой */
     if ($message['recurring']) {
         $this->sheduleJob($message);
     }
     return true;
 }
 /**
  * Handles a task.
  *
  * @param mixed $message
  */
 private function taskHandler(AMQPMessage $message)
 {
     /** @var AMQPChannel $channel */
     $channel = $message->delivery_info['channel'];
     // Listen to the "reply_to" queue
     $replyExchange = null;
     $replyQueue = null;
     if ($message->has('reply_to')) {
         list($replyExchange, $replyQueue) = explode(';', $message->get('reply_to'));
     }
     /** @var Task $task */
     $task = unserialize($message->body);
     try {
         $this->triggerEvent(self::EVENT_AFTER_TASK_UNSERIALIZATION, [$task]);
         $this->triggerEvent(self::EVENT_BEFORE_TASK_EXECUTION, [$task]);
         // Execute the task
         $this->getExecutor($task)->execute($task);
         $this->triggerEvent(self::EVENT_BEFORE_TASK_FINISHED, [$task]);
         $success = true;
         $e = null;
     } catch (Exception $e) {
         $success = false;
     }
     // Signal the job status to RabbitMQ
     if ($success) {
         $channel->basic_ack($message->delivery_info['delivery_tag']);
     } else {
         $channel->basic_reject($message->delivery_info['delivery_tag'], false);
     }
     $dispatcherNotified = false;
     // Signal the job status to the dispatcher
     if ($replyExchange) {
         $message = $success ? 'finished' : 'errored';
         $dispatcherNotified = $this->notifyDispatcher($replyExchange, $replyQueue, $message);
     }
     if ($success) {
         $this->triggerEvent(self::EVENT_ON_TASK_SUCCESS, [$task, $dispatcherNotified]);
     } else {
         $this->triggerEvent(self::EVENT_ON_TASK_ERROR, [$task, $e, $dispatcherNotified]);
     }
 }
Exemple #13
0
 /**
  * Handles a message.
  *
  * @param mixed $message
  */
 public function handle(AMQPMessage $message)
 {
     /** @var AMQPChannel $channel */
     $channel = $message->delivery_info['channel'];
     // Listen to the "reply_to" queue
     $replyExchange = null;
     $replyQueue = null;
     if ($message->has('reply_to')) {
         list($replyExchange, $replyQueue) = explode(';', $message->get('reply_to'));
     }
     $this->trigger(IWorker::BEFORE_UNSERIALIZATION, [$message]);
     $envelope = unserialize($message->body);
     try {
         // Execute the handler; consume the message
         $this->trigger(IWorker::BEFORE_CONSUMING, [$envelope]);
         $this->consume($envelope);
         $this->trigger(IWorker::AFTER_CONSUMING, [$envelope]);
         $success = true;
         $e = null;
     } catch (\Exception $e) {
         $success = false;
     }
     // Signal the job status to RabbitMQ
     if ($success) {
         $channel->basic_ack($message->delivery_info['delivery_tag']);
     } else {
         $channel->basic_reject($message->delivery_info['delivery_tag'], false);
     }
     $dispatcherNotified = false;
     // Signal the job status to the dispatcher
     if ($replyExchange) {
         $message = $success ? 'finished' : 'errored';
         $dispatcherNotified = $this->notifyDispatcher($replyExchange, $replyQueue, $message);
     }
     if ($success) {
         $this->trigger(IWorker::ON_HANDLER_SUCCESS, [$envelope, $dispatcherNotified]);
     } else {
         $this->trigger(IWorker::ON_HANDLER_ERROR, [$envelope, $e, $dispatcherNotified]);
     }
 }
 public function callback(AMQPMessage $msg)
 {
     $routingKey = $msg->delivery_info['routing_key'];
     $method = 'read' . Inflector::camelize($routingKey);
     if (!isset($this->interpreters[$this->queue])) {
         $interpreter = $this;
     } elseif (class_exists($this->interpreters[$this->queue])) {
         $interpreter = new $this->interpreters[$this->queue]();
         if (!$interpreter instanceof AmqpInterpreter) {
             throw new Exception(sprintf("Class '%s' is not correct interpreter class.", $this->interpreters[$this->queue]));
         }
     } else {
         throw new Exception(sprintf("Interpreter class '%s' was not found.", $this->interpreters[$this->queue]));
     }
     if (method_exists($interpreter, $method)) {
         $info = ['exchange' => $msg->get('exchange'), 'queue' => $this->queue, 'routing_key' => $msg->get('routing_key'), 'reply_to' => $msg->has('reply_to') ? $msg->get('reply_to') : null];
         try {
             $interpreter->{$method}(Json::decode($msg->body, true), $info);
         } catch (\Exception $exc) {
             $error_info = "consumer fail:" . $exc->getMessage() . PHP_EOL . "info:" . print_r($info, true) . PHP_EOL . "body:" . PHP_EOL . print_r($msg->body, true) . PHP_EOL . $exc->getTraceAsString();
             \Yii::warning($error_info, __METHOD__);
             $format = [Console::FG_RED];
             Console::stdout(Console::ansiFormat($error_info . PHP_EOL, $format));
             Console::stdout(Console::ansiFormat($exc->getTraceAsString() . PHP_EOL, $format));
         }
     } else {
         if (!isset($this->interpreters[$this->queue])) {
             $interpreter = new AmqpInterpreter();
         }
         $error_info = "Unknown routing key '{$routingKey}' for exchange '{$this->queue}'.";
         $error_info .= PHP_EOL . $msg->body;
         \Yii::warning($error_info, __METHOD__);
         $interpreter->log(sprintf("Unknown routing key '%s' for exchange '%s'.", $routingKey, $this->queue), $interpreter::MESSAGE_ERROR);
         // debug the message
         $interpreter->log(print_r(Json::decode($msg->body, true), true), $interpreter::MESSAGE_INFO);
     }
 }
Exemple #15
0
 /**
  * @param AMQPMessage $message
  * @param string      $header
  *
  * @return string|null
  */
 private function getMessageHeader(AMQPMessage $message, $header)
 {
     $headers = $message->has('application_headers') ? $message->get('application_headers') : [];
     return array_key_exists($header, $headers) ? $headers[$header] : null;
 }
 /**
  * Build AMQPEnvelope from a php-amqplib message;
  *
  * @param AMQPMessage $message
  * @return AMQPEnvelope
  */
 public static function fromAMQPMessage(AMQPMessage $message)
 {
     $envelope = new self();
     $envelope->app_id = $message->has('app_id') ? $message->get('app_id') : '';
     $envelope->body = $message->body;
     $envelope->content_encoding = $message->has('content_encoding') ? $message->get('content_encoding') : '';
     $envelope->content_type = $message->has('content_type') ? $message->get('content_type') : '';
     $envelope->correlation_id = $message->has('correlation_id') ? $message->get('correlation_id') : '';
     $envelope->delivery_mode = $message->has('delivery_mode') ? $message->get('delivery_mode') : '';
     $envelope->delivery_tag = $message->has('delivery_tag') ? $message->get('delivery_tag') : '';
     $envelope->exchange_name = $message->has('exchange') ? $message->get('exchange') : '';
     $envelope->expiration = $message->has('expiration') ? $message->get('expiration') : '';
     $envelope->headers = $message->has('application_headers') ? $message->get('application_headers')->getNativeData() : '';
     $envelope->message_id = $message->has('message_id') ? $message->get('message_id') : '';
     $envelope->priority = $message->has('priority') ? $message->get('priority') : '';
     $envelope->reply_to = $message->has('reply_to') ? $message->get('reply_to') : '';
     $envelope->routing_key = $message->has('routing_key') ? $message->get('routing_key') : '';
     $envelope->timestamp = $message->has('timestamp') ? $message->get('timestamp') : '';
     $envelope->type = $message->has('type') ? $message->get('type') : '';
     $envelope->user_id = $message->has('user_id') ? $message->get('user_id') : '';
     $envelope->is_redelivery = $message->has('redelivered') ? $message->get('redelivered') : '';
     return $envelope;
 }
Exemple #17
0
 /**
  * @param AMQPMessage $libMessage
  * @return Message
  * @throws \OutOfBoundsException
  */
 public function toMessage(AMQPMessage $libMessage)
 {
     $message = clone $this->getMessagePrototype();
     $message->setBody($libMessage->getBody());
     $message->setRoutingKey($libMessage->get($libMessage->has('routing_key') ? 'routing_key' : null));
     $message->setDeliveryTag($libMessage->has('delivery_tag') ? $libMessage->get('delivery_tag') : null);
     $message->setDeliveryMode($libMessage->has('delivery_mode') ? $libMessage->get('delivery_mode') : null);
     $message->setExchangeName($libMessage->has('exchange') ? $libMessage->get('exchange') : null);
     $message->setRedelivered($libMessage->has('redelivered') ? $libMessage->get('redelivered') : false);
     $message->setContentType($libMessage->has('content_type') ? $libMessage->get('content_type') : null);
     $message->setContentEncoding($libMessage->has('content_encoding') ? $libMessage->get('content_encoding') : null);
     $message->setType($libMessage->has('type') ? $libMessage->get('type') : null);
     $message->setDateTime($libMessage->has('timestamp') ? (new DateTime())->setTimestamp($libMessage->get('timestamp')) : null);
     $message->setPriority($libMessage->has('priority') ? $libMessage->get('priority') : null);
     $expiration = $libMessage->has('expiration') ? $libMessage->get('expiration') : null;
     $message->setExpiration(!empty($expiration) ? new \DateTime($libMessage->get('expiration')) : null);
     $message->setUserId($libMessage->has('user_id') ? $libMessage->get('user_id') : null);
     $message->setAppId($libMessage->has('app_id') ? $libMessage->get('app_id') : null);
     $message->setMessageId($libMessage->has('message_id') ? $libMessage->get('message_id') : null);
     $message->setReplyTo($libMessage->has('reply_to') ? $libMessage->get('reply_to') : null);
     $message->setCorrelationId($libMessage->has('correlation_id') ? $libMessage->get('correlation_id') : null);
     $message->setHeaders($libMessage->has('application_headers') ? $libMessage->get('application_headers') : []);
     return $message;
 }
 /**
  * @param \PhpAmqpLib\Message\AMQPMessage $message
  * @param string $exchange
  * @param string $routingKey
  *
  * @throws RuntimeException
  * @throws Exception|PhpAmqpLib\Exception\AMQPTimeoutException
  * @return mixed
  */
 protected function doSendAndReceive(\PhpAmqpLib\Message\AMQPMessage $message, $exchange, $routingKey)
 {
     if ($message->has('correlation_id')) {
         throw new RuntimeException('Illegal API usage. RPC style exchange can only be used if no correlationId property is set on beforehand.');
     }
     if ($message->has('reply_to')) {
         throw new RuntimeException('Illegal API usage. RPC style exchange can only be used if no replyTo property is set on beforehand.');
     }
     $replyQueue = $this->replyQueue;
     $replyTimeoutInMs = $this->replyTimeoutInMs;
     $mandatory = $this->mandatory;
     $immediate = $this->immediate;
     return $this->execute(function (\PhpAmqpLib\Channel\AMQPChannel $channel) use($message, $exchange, $routingKey, $replyQueue, $replyTimeoutInMs, $mandatory, $immediate) {
         $correlationId = Tx_Amqp_Util_Randomizer::generateUUID();
         if ($replyQueue === NULL) {
             // create a temporary (non-durable) exclusive auto-delete reply-queue
             list($replyQueue, , ) = $channel->queue_declare('', FALSE, FALSE, TRUE, TRUE);
         }
         $message->set('reply_to', $replyQueue);
         $message->set('correlation_id', $correlationId);
         $response = NULL;
         $callback = function (\PhpAmqpLib\Message\AMQPMessage $message) use($channel, $correlationId, &$response) {
             if ($correlationId == $message->get('correlation_id')) {
                 $channel->basic_ack($message->delivery_info['delivery_tag']);
                 $message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
                 $response = $message->body;
             }
         };
         $channel->basic_consume($replyQueue, '', FALSE, FALSE, FALSE, FALSE, $callback);
         $channel->basic_publish($message, $exchange, $routingKey, $mandatory, $immediate);
         while (count($channel->callbacks)) {
             try {
                 $channel->wait(NULL, FALSE, (double) $replyTimeoutInMs / 1000.0);
             } catch (\PhpAmqpLib\Exception\AMQPTimeoutException $e) {
                 // TODO: convert to own exception hierarchy?
                 throw $e;
             }
         }
         return $response;
     });
 }
 /**
  * @param AMQPMessage $message
  *
  * @return Response
  *
  * @throws ReplyException
  */
 private function createResponse(AMQPMessage $message)
 {
     $headers = $message->has('application_headers') ? $message->get('application_headers')->getNativeData() : [];
     if (!empty($headers['x-error'])) {
         throw new ReplyException($headers['x-error'], isset($headers['x-error-code']) ? $headers['x-error-code'] : 0);
     }
     $type = $message->has('content_type') ? $message->get('content_type') : null;
     $value = $this->encoder->decode(new Encoded($type, $message->getBody()));
     return new Response($value, $headers);
 }
 /**
  * @param AMQPMessage $message
  */
 public function consume(AMQPMessage $message)
 {
     $context = [];
     if ($message->has('correlation_id')) {
         $context['correlation_id'] = $message->get('correlation_id');
     }
     if ($this->logger) {
         $this->logger->info('received message with content-type ' . $message->get('content_type'), $context);
     }
     $contentType = new StringLiteral($message->get('content_type'));
     try {
         $deserializer = $this->deserializerLocator->getDeserializerForContentType($contentType);
         $domainMessage = $deserializer->deserialize(new StringLiteral($message->body));
         // If the deserializer did not return a DomainMessage yet, then
         // consider the returned value as the payload, and wrap it in a
         // DomainMessage.
         if (!$domainMessage instanceof DomainMessage) {
             $domainMessage = new DomainMessage(UUID::generateAsString(), 0, new Metadata($context), $domainMessage, DateTime::now());
         }
         $this->delayIfNecessary();
         if ($this->logger) {
             $this->logger->info('passing on message to event bus', $context);
         }
         $this->eventBus->publish(new DomainEventStream([$domainMessage]));
     } catch (\Exception $e) {
         if ($this->logger) {
             $this->logger->error($e->getMessage(), $context + ['exception' => $e]);
         }
         $message->delivery_info['channel']->basic_reject($message->delivery_info['delivery_tag'], false);
         if ($this->logger) {
             $this->logger->info('message rejected', $context);
         }
         return;
     }
     $message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
     if ($this->logger) {
         $this->logger->info('message acknowledged', $context);
     }
 }