DBServer::SendMessage PHP Method

SendMessage() public method

Send message to instance
public SendMessage ( Scalr_Messaging_Msg $message, $isEventNotice = false, $delayed = false ) : Scalr_Messaging_Msg
$message Scalr_Messaging_Msg
return Scalr_Messaging_Msg
    public function SendMessage(Scalr_Messaging_Msg $message, $isEventNotice = false, $delayed = false)
    {
        $startTime = microtime(true);
        if (!$this->isScalarized) {
            return;
        }
        if ($this->farmId && $message->getName() != 'BeforeHostTerminate') {
            if ($this->GetFarmObject()->Status == FARM_STATUS::TERMINATED) {
                $this->Db->Execute("UPDATE messages SET status = ? WHERE messageid = ?", array(MESSAGE_STATUS::FAILED, $message->messageId));
                return;
            }
        }
        // We don't need to send any messages other then it's own to the server that is not in Running state
        if ($message->serverId != $this->serverId && !in_array($this->status, array(SERVER_STATUS::RUNNING, SERVER_STATUS::TEMPORARY, SERVER_STATUS::IMPORTING))) {
            return;
        }
        // Ignore OLD messages (ami-scripts)
        if (!$this->IsSupported("0.5")) {
            return;
        }
        // Put access data and reserialize message
        $pl = PlatformFactory::NewPlatform($this->platform);
        $pl->PutAccessData($this, $message);
        $logger = \Scalr::getContainer()->logger('DBServer');
        $serializer = Scalr_Messaging_XmlSerializer::getInstance();
        $cryptoTool = \Scalr::getContainer()->srzcrypto($this->GetKey(true));
        if ($this->GetProperty(\SERVER_PROPERTIES::SZR_MESSAGE_FORMAT) == 'json') {
            $serializer = Scalr_Messaging_JsonSerializer::getInstance();
            $rawMessage = $serializer->serialize($message);
            $messageType = 'json';
        } else {
            $rawMessage = $serializer->serialize($message);
            $messageType = 'xml';
        }
        //$rawJsonMessage = @json_encode($message);
        $time = microtime(true) - $startTime;
        // Add message to database
        $this->Db->Execute("INSERT INTO messages SET\n                `messageid`             = ?,\n                `processing_time`       = ?,\n                `server_id`             = ?,\n                `event_server_id`       = ?,\n                `message`               = ?,\n                `type`                  = 'out',\n                `message_name`          = ?,\n                `handle_attempts`       = ?,\n                `message_version`       = ?,\n                `dtlasthandleattempt`   = UTC_TIMESTAMP(),\n                `dtadded`               = NOW(),\n                `message_format`        = ?,\n                `event_id`              = ?\n            ON DUPLICATE KEY UPDATE handle_attempts = handle_attempts+1, dtlasthandleattempt = UTC_TIMESTAMP()\n            ", array($message->messageId, $time, $this->serverId, $message->serverId, $rawMessage, $message->getName(), $delayed ? '0' : '1', 2, $messageType, isset($message->eventId) ? $message->eventId : ''));
        if ($delayed) {
            return $message;
        }
        $isVPC = false;
        if ($this->farmId) {
            if (DBFarm::LoadByID($this->farmId)->GetSetting(Entity\FarmSetting::EC2_VPC_ID)) {
                $isVPC = true;
            }
        }
        if (!$this->remoteIp && !$this->localIp && !$isVPC) {
            return;
        }
        $cryptoTool->setCryptoKey($this->GetKey(true));
        $encMessage = $cryptoTool->encrypt($rawMessage);
        $timestamp = date("c", time());
        $signature = $cryptoTool->sign($encMessage, null, $timestamp);
        try {
            $request = new Request();
            $request->setRequestMethod('POST');
            $ctrlPort = $this->getPort(self::PORT_CTRL);
            $requestHost = $this->getSzrHost() . ":{$ctrlPort}";
            if ($isVPC) {
                $routerFarmRoleId = $this->GetFarmRoleObject()->GetSetting(Scalr_Role_Behavior_Router::ROLE_VPC_SCALR_ROUTER_ID);
                if ($routerFarmRoleId) {
                    $routerRole = DBFarmRole::LoadByID($routerFarmRoleId);
                } else {
                    $routerRole = $this->GetFarmObject()->GetFarmRoleByBehavior(ROLE_BEHAVIORS::VPC_ROUTER);
                }
                if ($routerRole) {
                    // No public IP need to use proxy
                    if (!$this->remoteIp) {
                        $requestHost = $routerRole->GetSetting(Scalr_Role_Behavior_Router::ROLE_VPC_IP) . ":80";
                        $request->addHeaders(array("X-Receiver-Host" => $this->localIp, "X-Receiver-Port" => $ctrlPort));
                        // There is public IP, can use it
                    } else {
                        $requestHost = "{$this->remoteIp}:{$ctrlPort}";
                    }
                }
            }
            //Prepare request
            $request->setRequestUrl("http://{$requestHost}/control");
            $request->setOptions(array('timeout' => \Scalr::config('scalr.system.instances_connection_timeout'), 'connecttimeout' => \Scalr::config('scalr.system.instances_connection_timeout')));
            $request->addHeaders(array("Date" => $timestamp, "X-Signature" => $signature, 'X-Server-Id' => $this->serverId));
            if ($messageType == 'json') {
                $request->addHeaders(array('Content-type' => 'application/json'));
            }
            $request->append($encMessage);
            // Send request
            $response = \Scalr::getContainer()->srzhttp->sendRequest($request);
            // Process response
            if ($response->getResponseCode() == 201) {
                $logger->info(sprintf("[FarmID: %s] Sending message '%s' via REST to server '%s' (server_id: %s) completed", $this->farmId, $message->getName(), $this->remoteIp, $this->serverId));
                if (in_array($message->getName(), array('ExecScript'))) {
                    $this->Db->Execute("DELETE FROM messages WHERE messageid = ?", array($message->messageId));
                } else {
                    if ($messageType != 'json') {
                        $this->Db->Execute("UPDATE messages SET status = ?, message = '' WHERE messageid = ?", array(MESSAGE_STATUS::HANDLED, $message->messageId));
                    } else {
                        $this->Db->Execute("UPDATE messages SET status = ? WHERE messageid = ?", array(MESSAGE_STATUS::HANDLED, $message->messageId));
                    }
                    if (!empty($message->eventId)) {
                        $this->Db->Execute("UPDATE events SET msg_sent = msg_sent + 1 WHERE event_id = ?", array($message->eventId));
                    }
                }
            } else {
                $logger->warn(sprintf("[FarmID: %s] Cannot deliver message '%s' (message_id: %s) via REST" . " to server '%s' (server_id: %s). Error: %s %s", $this->farmId, $message->getName(), $message->messageId, $this->remoteIp, $this->serverId, $response->getResponseCode(), $response->getResponseStatus()));
            }
        } catch (http\Exception $e) {
            if (isset($e->innerException)) {
                $msg = $e->innerException->getMessage();
            } else {
                $msg = $e->getMessage();
            }
            if ($this->farmId) {
                $logger->warn(new FarmLogMessage($this, sprintf("Cannot deliver message '%s' (message_id: %s) via REST to server '%s' (server_id: %s). Error: %s", $message->getName(), !empty($message->messageId) ? $message->messageId : null, !empty($this->remoteIp) ? $this->remoteIp : null, !empty($this->serverId) ? $this->serverId : null, !empty($msg) ? $msg : null)));
            } else {
                $logger->fatal(sprintf("Cannot deliver message '%s' (message_id: %s) via REST" . " to server '%s' (server_id: %s). Error: %s", $message->getName(), $message->messageId, $this->remoteIp, $this->serverId, $msg));
            }
            return false;
        }
        return $message;
    }