Mysql Openstack Stored Procedures

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску


Хранимые процедуры и отсылка оповещений об изменениях на HTTP

В MySQL есть такая возможность - использовать внешние пользовательские процедуры написанные на языке C
Это дает возможность сделать триггер который при апдейте таблицы будет форматировать JSON и отправлять на удаленный сервер (или сервера)
Идея на самом деле сомнительная потому что на время исполнения триггера таблица блокируется но как POC сойдет


INSERT

DELIMITER |
DROP TRIGGER IF EXISTS nova_instances_insert;
CREATE TRIGGER  nova_instances_insert
AFTER INSERT ON instances
FOR EACH ROW BEGIN
    SET @tt_json = (SELECT json_object(created_at,updated_at,id,user_id,project_id,image_ref,hostname,reservation_id,uuid,deleted ) FROM instances  WHERE uuid = NEW.uuid LIMIT 1);

    CALL send_http_data('http://172.16.169.34:8080/', @tt_json);
    CALL send_http_data('http://127.0.0.1:8081/', @tt_json);

END |
DELIMITER ;


BEFORE UPDATE

DELIMITER |
DROP TRIGGER IF EXISTS nova_instances_before_update;
CREATE TRIGGER nova_instances_before_update
BEFORE UPDATE ON instances
FOR EACH ROW BEGIN
    SET @tt_json = (SELECT json_object(created_at,updated_at,id,user_id,project_id,image_ref,hostname,reservation_id,uuid,deleted ) FROM instances  WHERE uuid = OLD.uuid LIMIT 1);

    CALL send_http_data('http://172.16.169.34:8080/', @tt_json);
    CALL send_http_data('http://127.0.0.1:8081/', @tt_json);

END |
DELIMITER ;

AFTER UPDATE

DELIMITER |
DROP TRIGGER IF EXISTS nova_instances_after_update;
CREATE TRIGGER nova_instances_after_update
AFTER UPDATE ON instances
FOR EACH ROW BEGIN
    SET @tt_json = (SELECT json_object(created_at,updated_at,id,user_id,project_id,image_ref,hostname,reservation_id,uuid,deleted ) FROM instances WHERE uuid= OLD.uuid LIMIT 1);

    CALL send_http_data('http://172.16.169.34:8080/', @tt_json);
    CALL send_http_data('http://127.0.0.1:8081/', @tt_json);

END |
DELIMITER ;


Log

Табличка для записи в лог того что отправляется (debug)

DROP TABLE IF EXISTS httplog;
CREATE TABLE `httplog` 
(
  `request` varchar(4096) DEFAULT NULL,
  `response` varchar(4096) DEFAULT NULL,
  `seq` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `local_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `host` varchar(512) DEFAULT NULL,
  PRIMARY KEY (`seq`)
);

Отправка по HTTP


DROP PROCEDURE IF EXISTS send_http_data;

DELIMITER |
CREATE PROCEDURE send_http_data(
IN http_host varchar(512),
IN http_data varchar(4096)
) BEGIN




    SET @tt_resu = (SELECT http_post(http_host, http_data));
    INSERT INTO httplog(host, request,response) values(http_host, http_data, @tt_resu);

END |
DELIMITER ;




    SET @tt_resu = (SELECT http_post(http_host, _data));
    INSERT INTO httplog(host, request,response) values(http_host, _data, @tt_resu);


DROP PROCEDURE IF EXISTS upload2;
DELIMITER |

CREATE PROCEDURE upload2()  BEGIN
  DECLARE done BOOLEAN DEFAULT FALSE;
  DECLARE json_data TEXT;
  DECLARE _uuid TEXT;
  DECLARE cur CURSOR FOR SELECT uuid from instances;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;

  OPEN cur;

  testLoop: LOOP
    FETCH cur INTO _uuid;
    IF done THEN
      LEAVE testLoop;
    END IF;

    SELECT json_object(created_at,updated_at,id,user_id,project_id,image_ref,hostname,reservation_id,uuid,deleted) FROM instances WHERE uuid=_uuid LIMIT 1  INTO json_data;

    CALL send_http_data('http://172.16.169.34:8080/', json_data);
    CALL send_http_data('http://127.0.0.1:8081/', json_data);

  END LOOP testLoop;

  CLOSE cur;
END |
DELIMITER ;

Ссылки