| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- #include "consul.h"
- #include "HttpClient.h"
- using namespace hv;
- #include "json.hpp"
- using json = nlohmann::json;
- #define PROTOCOL "http://"
- #define API_VERSION "v1"
- static const char url_register[] = "/agent/service/register";
- static const char url_deregister[] = "/agent/service/deregister";
- static const char url_discover[] = "/catalog/service";
- static std::string make_url(const char* ip, int port, const char* url) {
- return asprintf(PROTOCOL "%s:%d/" API_VERSION "%s", ip, port, url);
- }
- static std::string make_ServiceID(consul_service_t* service) {
- return asprintf("%s-%s:%d", service->name, service->ip, service->port);
- }
- /*
- {
- "ID": "redis1",
- "Name": "redis",
- "Tags": [
- "primary",
- "v1"
- ],
- "Address": "127.0.0.1",
- "Port": 8000,
- "Meta": {
- "redis_version": "4.0"
- },
- "EnableTagOverride": false,
- "Check": {
- "DeregisterCriticalServiceAfter": "90m",
- "Args": ["/usr/local/bin/check_redis.py"],
- "HTTP": "http://localhost:5000/health",
- "Interval": "10s",
- "TTL": "15s"
- },
- "Weights": {
- "Passing": 10,
- "Warning": 1
- }
- }
- */
- int register_service(consul_node_t* node, consul_service_t* service, consul_health_t* health) {
- HttpRequest req;
- req.method = HTTP_PUT;
- req.url = make_url(node->ip, node->port, url_register);
- req.content_type = APPLICATION_JSON;
- json jservice;
- jservice["Name"] = service->name;
- if (*service->ip) {
- jservice["Address"] = service->ip;
- }
- jservice["Port"] = service->port;
- jservice["ID"] = make_ServiceID(service);
- json jcheck;
- if (*health->url == '\0') {
- snprintf(health->url, sizeof(health->url), "%s:%d", service->ip, service->port);
- }
- jcheck[health->protocol] = health->url;
- jcheck["Interval"] = asprintf("%dms", health->interval);
- jcheck["DeregisterCriticalServiceAfter"] = asprintf("%dms", health->interval * 3);
- jservice["Check"] = jcheck;
- req.body = jservice.dump();
- printd("PUT %s\n", req.url.c_str());
- printd("%s\n", req.body.c_str());
- HttpResponse res;
- int ret = http_client_send(&req, &res);
- printd("%s\n", res.body.c_str());
- return ret;
- }
- int deregister_service(consul_node_t* node, consul_service_t* service) {
- std::string url = make_url(node->ip, node->port, url_deregister);
- url += '/';
- url += make_ServiceID(service);
- HttpRequest req;
- req.method = HTTP_PUT;
- req.url = url;
- req.content_type = APPLICATION_JSON;
- printd("PUT %s\n", req.url.c_str());
- HttpResponse res;
- int ret = http_client_send(&req, &res);
- printd("%s\n", res.body.c_str());
- return ret;
- }
- int discover_services(consul_node_t* node, const char* service_name, std::vector<consul_service_t>& services) {
- std::string url = make_url(node->ip, node->port, url_discover);
- url += '/';
- url += service_name;
- HttpRequest req;
- req.method = HTTP_GET;
- req.url = url;
- HttpResponse res;
- printd("GET %s\n", req.url.c_str());
- int ret = http_client_send(&req, &res);
- if (ret != 0) return ret;
- printd("%s\n", res.body.c_str());
- json jroot = json::parse(res.body);
- if (!jroot.is_array()) return -1;
- if (jroot.size() == 0) return 0;
- consul_service_t service;
- std::string name, ip;
- services.clear();
- for (size_t i = 0; i < jroot.size(); ++i) {
- auto jservice = jroot[i];
- name = jservice["ServiceName"];
- if (jservice.contains("Address")) {
- ip = jservice["Address"];
- } else if (jservice.contains("ServiceAddress")) {
- ip = jservice["ServiceAddress"];
- } else if (jservice.contains("ServiceAddress6")) {
- ip = jservice["ServiceAddress6"];
- } else {
- continue;
- }
- int port = jservice["ServicePort"];
- strncpy(service.name, name.c_str(), sizeof(service.name));
- strncpy(service.ip, ip.c_str(), sizeof(service.ip));
- service.port = port;
- services.emplace_back(service);
- }
- return 0;
- }
|