Esempio n. 1
0
 /**
  * Send message to instance
  * @param Scalr_Messaging_Msg $message
  * @return Scalr_Messaging_Msg
  */
 public function SendMessage(Scalr_Messaging_Msg $message, $isEventNotice = false, $delayed = false)
 {
     $startTime = microtime(true);
     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`   = NOW(),\n                `dtadded`               = NOW(),\n                `message_format`        = ?,\n                `event_id`              = ?\n            ON DUPLICATE KEY UPDATE handle_attempts = handle_attempts+1, dtlasthandleattempt = NOW()\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->farmId, 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), $this->serverId));
         } 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;
 }
Esempio n. 2
0
 /**
  * Send message to instance
  * @param Scalr_Messaging_Msg $message
  * @return Scalr_Messaging_Msg
  */
 public function SendMessage(Scalr_Messaging_Msg $message, $isEventNotice = false, $delayed = false)
 {
     if ($this->farmId) {
         if ($this->GetFarmObject()->Status == FARM_STATUS::TERMINATED) {
             $this->Db->Execute("UPDATE messages SET status = ? WHERE messageid = ?", array(MESSAGE_STATUS::FAILED, $message->messageId));
             return;
         }
     }
     $logger = Logger::getLogger('DBServer');
     $serializer = Scalr_Messaging_XmlSerializer::getInstance();
     $cryptoTool = Scalr_Messaging_CryptoTool::getInstance();
     $rawMessage = $serializer->serialize($message);
     // Add message to database
     $this->Db->Execute("INSERT INTO messages SET\r\n\t\t\t\t`messageid`\t= ?,\r\n\t\t\t\t`server_id`\t= ?,\r\n\t\t\t\t`message`\t= ?,\r\n\t\t\t\t`type`\t\t= 'out',\r\n\t\t\t\t`message_name` = ?,\r\n\t\t\t\t`handle_attempts` = ?,\r\n\t\t\t\t`message_version` = ?,\r\n\t\t\t\t`dtlasthandleattempt` = NOW()\r\n\t\t\tON DUPLICATE KEY UPDATE handle_attempts = handle_attempts+1, dtlasthandleattempt = NOW()  \r\n\t\t\t", array($message->messageId, $this->serverId, $rawMessage, $message->getName(), $delayed ? '0' : '1', $this->IsSupported("0.5") ? 2 : 1));
     if ($this->platform == SERVER_PLATFORMS::RDS) {
         $logger->info("RDS platform doesn't support messaging. Skipping...");
         $this->Db->Execute("UPDATE messages SET status = ? WHERE messageid = ?", array(MESSAGE_STATUS::UNSUPPORTED, $message->messageId));
         return $message;
     }
     if ($delayed) {
         return $message;
     }
     if ($this->IsSupported("0.5") && !$isEventNotice) {
         if (!$this->remoteIp) {
             return;
         }
         // Put access data and reserialize message
         $pl = PlatformFactory::NewPlatform($this->platform);
         $pl->PutAccessData($this, $message);
         $rawMessage = $serializer->serialize($message);
         $cryptoKey = $this->GetKey(true);
         $encMessage = $cryptoTool->encrypt($rawMessage, $cryptoKey);
         list($signature, $timestamp) = $cryptoTool->sign($encMessage, $cryptoKey);
         try {
             $ctrlPort = $this->GetProperty(SERVER_PROPERTIES::SZR_CTRL_PORT);
             if (!$ctrlPort) {
                 $ctrlPort = 8013;
             }
             // Prepare request
             $request = new HttpRequest("http://{$this->remoteIp}:{$ctrlPort}/control", HTTP_METH_POST);
             $request->setOptions(array('timeout' => 4, 'connecttimeout' => 4));
             $request->setHeaders(array("Date" => $timestamp, "X-Signature" => $signature));
             $request->setRawPostData($encMessage);
             // Send request
             $request->send();
             // Process response
             if ($request->getResponseCode() == 201) {
                 $logger->info(sprintf("[FarmID: %s] Sending message '%s' via REST to server '%s' (server_id: %s) complete", $this->farmId, $message->getName(), $this->remoteIp, $this->serverId));
                 $this->Db->Execute("UPDATE messages SET status = ?, message = '' WHERE messageid = ?", array(MESSAGE_STATUS::HANDLED, $message->messageId));
             } 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, $request->getResponseCode(), $request->getResponseStatus()));
             }
         } catch (HttpException $e) {
             if (isset($e->innerException)) {
                 $msg = $e->innerException->getMessage();
             } else {
                 $msg = $e->getMessage();
             }
             if ($this->farmId) {
                 $logger->warn(new FarmLogMessage($this->farmId, sprintf("Cannot deliver message '%s' (message_id: %s) via REST" . " to server '%s' (server_id: %s). Error: %s %s", $message->getName(), $message->messageId, $this->remoteIp, $this->serverId, $request->getResponseCode(), $msg)));
             } else {
                 $logger->fatal(sprintf("Cannot deliver message '%s' (message_id: %s) via REST" . " to server '%s' (server_id: %s). Error: %s %s", $message->getName(), $message->messageId, $this->remoteIp, $this->serverId, $request->getResponseCode(), $msg));
             }
             return false;
         }
     } else {
         if ($this->remoteIp) {
             $community = $this->Db->GetOne("SELECT hash FROM farms WHERE id=?", array($this->farmId));
             $snmpClient = new Scalr_Net_Snmp_Client();
             $snmpClient->connect($this->remoteIp, 162, $community);
             $converter = Scalr_Messaging_SnmpConverter::getInstance();
             $trap = $converter->convert($message, $isEventNotice);
             $res = $snmpClient->sendTrap($trap);
             Logger::getLogger('DBServer')->info("[FarmID: {$this->farmId}] Sending message " . $message->getName() . " via SNMP ({$trap}) to '{$this->serverId}' ('{$this->remoteIp}') complete ({$res})");
         }
     }
     return $message;
 }