PageRenderTime 27ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 1ms

/branches/1.2.0/src/class.DBInstance.php

http://scalr.googlecode.com/
PHP | 370 lines | 249 code | 59 blank | 62 comment | 21 complexity | 51733d6a9c94cbd42a3a94d31496d063 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, GPL-3.0
  1. <?php
  2. class DBInstance
  3. {
  4. const PROPERTY_SCALARIZR_PACKAGE_VERSION = 'scalarizr_pkg_version';
  5. public $ID;
  6. public $FarmID;
  7. public $ClientID;
  8. public $InstanceID;
  9. public $State;
  10. public $AMIID;
  11. public $InternalIP;
  12. public $ExternalIP;
  13. public $IsDBMaster;
  14. public $IncludeInDNS;
  15. public $RoleName;
  16. public $AvailZone;
  17. public $Index;
  18. public $Region;
  19. public $FarmRoleID;
  20. public $Uptime;
  21. public $IsRebootLaunched;
  22. public $ReplaceIID;
  23. public $ScalarizrPackageVersion;
  24. private $DB;
  25. private $Client;
  26. private $DBFarm;
  27. private $DBFarmRole;
  28. private $SettingsCache = array();
  29. private static $FieldPropertyMap = array(
  30. 'id' => 'ID',
  31. 'farmid' => 'FarmID',
  32. 'instance_id' => 'InstanceID',
  33. 'state' => 'State',
  34. 'ami_id' => 'AMIID',
  35. 'internal_ip' => 'InternalIP',
  36. 'external_ip' => 'ExternalIP',
  37. 'isdbmaster' => 'IsDBMaster',
  38. 'isactive' => 'IncludeInDNS',
  39. 'role_name' => 'RoleName',
  40. 'avail_zone' => 'AvailZone',
  41. 'index' => 'Index',
  42. 'region' => 'Region',
  43. 'farm_roleid' => 'FarmRoleID',
  44. 'uptime' => 'Uptime',
  45. 'replace_iid' => 'ReplaceIID',
  46. 'isrebootlaunched' => 'IsRebootLaunched',
  47. self::PROPERTY_SCALARIZR_PACKAGE_VERSION => 'ScalarizrPackageVersion'
  48. );
  49. private $Logger;
  50. /**
  51. * Constructor
  52. * @param $instance_id
  53. * @return void
  54. */
  55. public function __construct($instance_id)
  56. {
  57. $this->InstanceID = $instance_id;
  58. $this->DB = Core::GetDBInstance();
  59. $this->Logger = Logger::getLogger(__CLASS__);
  60. }
  61. public function __sleep()
  62. {
  63. // Init objects
  64. $this->GetDBFarmObject();
  65. $this->GetDBFarmRoleObject();
  66. $retval = array("ID", "FarmID", "InstanceID", "AMIID", "InternalIP", "ExternalIP", "AvailZone", "Index", "Region", "FarmRoleID", "RoleName");
  67. array_push($retval, "DBFarmRole");
  68. array_push($retval, "DBFarm");
  69. return $retval;
  70. }
  71. public function __wakeup()
  72. {
  73. $this->DB = Core::GetDBInstance();
  74. $this->Logger = Logger::getLogger(__CLASS__);
  75. }
  76. /**
  77. * Load DBInstance by database id
  78. * @param $id
  79. * @return DBInstance
  80. */
  81. static public function LoadByID($id)
  82. {
  83. $db = Core::GetDBInstance();
  84. $instance_info = $db->GetRow("SELECT * FROM farm_instances WHERE id=?", array($id));
  85. if (!$instance_info)
  86. throw new Exception(sprintf(_("Instance ID#%s not found in database"), $id));
  87. $DBInstance = new DBInstance($instance_info['instance_id']);
  88. foreach(self::$FieldPropertyMap as $k=>$v)
  89. {
  90. if ($instance_info[$k])
  91. $DBInstance->{$v} = $instance_info[$k];
  92. }
  93. return $DBInstance;
  94. }
  95. /**
  96. * Load DBInstance by Amazon Instance ID
  97. * @param $iid
  98. * @return DBInstance
  99. */
  100. static public function LoadByIID($iid)
  101. {
  102. $db = Core::GetDBInstance();
  103. $id = $db->GetRow("SELECT id FROM farm_instances WHERE instance_id=?", array($iid));
  104. if (!$id)
  105. throw new Exception(sprintf(_("Instance Amazon ID#%s not found in database"), $iid));
  106. return self::LoadByID($id);
  107. }
  108. public function ReLoad()
  109. {
  110. $instance_info = $this->DB->GetRow("SELECT * FROM farm_instances WHERE id=?", array($this->ID));
  111. if (!$instance_info)
  112. throw new Exception(sprintf(_("Cannot reload DBInstance object. Instance ID#%s not found in database"), $this->ID));
  113. foreach(self::$FieldPropertyMap as $k=>$v)
  114. {
  115. if ($instance_info[$k])
  116. $this->{$v} = $instance_info[$k];
  117. }
  118. }
  119. /**
  120. * Returns DBFarm Object
  121. * @return DBFarm
  122. */
  123. public function GetFarmObject()
  124. {
  125. if (!$this->DBFarm)
  126. $this->DBFarm = DBFarm::LoadByID($this->FarmID);
  127. return $this->DBFarm;
  128. }
  129. /**
  130. *
  131. * Returns DBFarmRole object
  132. * @return DBFarmRole
  133. */
  134. public function GetDBFarmRoleObject()
  135. {
  136. if (!$this->DBFarmRole)
  137. $this->DBFarmRole = DBFarmRole::LoadByID($this->FarmRoleID);
  138. return $this->DBFarmRole;
  139. }
  140. /**
  141. * returns DBFarm object
  142. * @return DBFarm
  143. */
  144. public function GetDBFarmObject()
  145. {
  146. if (!$this->DBFarm)
  147. $this->DBFarm = DBFarm::LoadByID($this->FarmID);
  148. return $this->DBFarm;
  149. }
  150. /**
  151. * Returns all instance settings
  152. * @return unknown_type
  153. */
  154. public function GetAllSettings()
  155. {
  156. $settings = $this->DB->GetAll("SELECT * FROM farm_instance_settings WHERE farm_instanceid=?", array($this->ID));
  157. $retval = array();
  158. foreach ($settings as $setting)
  159. $retval[$setting['name']] = $setting['value'];
  160. $this->SettingsCache = array_merge($this->SettingsCache, $retval);
  161. return $retval;
  162. }
  163. /**
  164. * Set Instance setting
  165. * @param string $name
  166. * @param mixed $value
  167. * @return void
  168. */
  169. public function SetSetting($name, $value)
  170. {
  171. $Reflect = new ReflectionClass($this);
  172. $consts = array_values($Reflect->getConstants());
  173. if (in_array($name, $consts))
  174. {
  175. $this->DB->Execute("REPLACE INTO farm_instance_settings SET `farm_instanceid`=?, `name`=?, `value`=?",
  176. array($this->ID, $name, $value)
  177. );
  178. $this->SettingsCache[$name] = $value;
  179. return true;
  180. }
  181. else
  182. throw new Exception("Unknown instance setting setting '{$name}'");
  183. }
  184. /**
  185. * Get Instance setting by name
  186. * @param string $name
  187. * @return mixed
  188. */
  189. public function GetSetting($name)
  190. {
  191. if (!$this->SettingsCache[$name])
  192. {
  193. $this->SettingsCache[$name] = $this->DB->GetOne("SELECT `value` FROM `farm_instance_settings` WHERE `farm_instanceid`=? AND `name` = ?",
  194. array(
  195. $this->ID,
  196. $name
  197. ));
  198. }
  199. return $this->SettingsCache[$name];
  200. }
  201. /**
  202. * Update specified property
  203. * @param string $prop
  204. * @param string $value
  205. * @return bool
  206. */
  207. public function UpdateProperty($prop, $value)
  208. {
  209. if (!self::$FieldPropertyMap[$prop])
  210. throw new Exception(sprintf(_("Invalid property name: %s"), $prop));
  211. return $this->DB->Execute("UPDATE farm_instances SET `{$prop}`=? WHERE id=?", array($value, $this->ID));
  212. }
  213. /**
  214. * Return information about scalarizr version installed on instance
  215. * @return array
  216. */
  217. public function GetScalarizrVersion()
  218. {
  219. preg_match("/^([0-9]+)\.([0-9]+)-([0-9]+)$/", $this->ScalarizrPackageVersion, $matches);
  220. return array("major" => $matches[1], "minor" => $matches[2], "revision" => $matches[3]);
  221. }
  222. public function IsSupported($v)
  223. {
  224. preg_match("/^([0-9]+)\.([0-9]+)\-([0-9]+)$/si", $v, $matches);
  225. $version = $this->GetScalarizrVersion();
  226. if ($version['major'] > $matches[1])
  227. return true;
  228. elseif ($version['major'] == $matches[1] && $version['minor'] > $matches[2])
  229. return true;
  230. elseif ($version['major'] == $matches[1] && $version['minor'] == $matches[2] && $version['revision'] >= $matches[3])
  231. return true;
  232. return false;
  233. }
  234. public function GetScalarizrConfig()
  235. {
  236. $farminfo = $this->DB->GetRow("SELECT * FROM farms WHERE id=?", array($this->FarmID));
  237. $Client = Client::Load($farminfo['clientid']);
  238. $config = "<config>
  239. <aws>
  240. <account-id>{$Client->AWSAccountID}</account-id>
  241. <access>
  242. <key>{$Client->AWSAccessKey}</key>
  243. <key-id>{$Client->AWSAccessKeyID}</key-id>
  244. </access>
  245. <keypair>
  246. <cert>{$Client->AWSCertificate}</cert>
  247. <pkey>{$Client->AWSPrivateKey}</pkey>
  248. </keypair>
  249. </aws>
  250. <scalr>
  251. <access>
  252. <key>{$Client->GetScalrAPIKey()}</key>
  253. <key-id>{$Client->ScalrKeyID}</key-id>
  254. </access>
  255. <callback-service-url>".CONFIG::$HTTP_PROTO."://".CONFIG::$EVENTHANDLER_URL."/cb_service.php</callback-service-url>
  256. </scalr>
  257. </config>";
  258. }
  259. /**
  260. * Send message to instance
  261. * @param ScalrMessage $message
  262. * @return bool
  263. */
  264. public function SendMessage(ScalrMessage $message)
  265. {
  266. //TODO: Create MessagingTransport object that implements IMessagingTransport.
  267. //TODO: SNMPMessagingTransport & AmazonSQSMessagingTransport
  268. // Add message to database
  269. $this->DB->Execute("INSERT INTO messages SET
  270. messageid = ?,
  271. instance_id = ?,
  272. message = ?,
  273. dtlastdeliveryattempt = NOW()
  274. ON DUPLICATE KEY UPDATE delivery_attempts = delivery_attempts+1, dtlastdeliveryattempt = NOW()
  275. ", array(
  276. $message->MessageID,
  277. $this->InstanceID,
  278. XMLMessageSerializer::Serialize($message)
  279. ));
  280. if ($this->IsSupported("0.5-1"))
  281. {
  282. if (!$this->ClientID)
  283. $this->ClientID = $this->DB->GetOne("SELECT clientid FROM farms WHERE id=?", array($this->FarmID));
  284. $Client = Client::Load($this->ClientID);
  285. $AmazonSQS = AmazonSQS::GetInstance($Client->AWSAccessKeyID, $Client->AWSAccessKey);
  286. try
  287. {
  288. $AmazonSQS->CreateQueue("queue-{$this->InstanceID}", 30);
  289. }
  290. catch(Exception $e)
  291. {
  292. $this->Logger->warn("Cannot create queue: {$e->getMessage()}");
  293. }
  294. $messageID = $AmazonSQS->SendMessage("queue-{$this->InstanceID}", XMLMessageSerializer::Serialize($message));
  295. $this->Logger->info("SQSMessage sent. MessageID: {$messageID}");
  296. }
  297. else
  298. {
  299. if ($this->ExternalIP)
  300. {
  301. $community = $this->DB->GetOne("SELECT hash FROM farms WHERE id=?", array($this->FarmID));
  302. $SNMP = new SNMP();
  303. $SNMP->Connect($this->ExternalIP, null, $community, null, null, true);
  304. $trap = $message->GetSNMPTrap();
  305. $res = $SNMP->SendTrap($trap);
  306. $this->Logger->info("[FarmID: {$this->FarmID}] Sending message ".get_class($message)." via SNMP ({$trap}) to '{$this->InstanceID}' ('{$this->ExternalIP}') complete ({$res})");
  307. }
  308. }
  309. }
  310. }
  311. ?>