28:- module(consul, [
29 read_consul_key/2,
30 read_consul_key/3,
31 update_consul_key/2,
32 delete_consul_key/1,
33 consul_services/1,
34 consul_service/2,
35 register_consul_service/4,
36 deregister_consul_service/1
37 ]).
56:- use_module(library(http/http_client)). 57:- use_module(library(http/http_json)). 58:- use_module(library(http/json)). 59
60connection('http://localhost:8500/v1').
61kv_url(Key, URL) :- connection(Connection), format(atom(URL), '~w/kv/~w', [ Connection, Key ]).
62svs_url(URL) :- connection(Connection), format(atom(URL), '~w/catalog/services', [ Connection ]).
63sv_url(Service, URL) :- connection(Connection), format(atom(URL), '~w/catalog/service/~w', [ Connection, Service ]).
64reg_url(URL) :- connection(Connection), format(atom(URL), '~w/agent/service/register', [ Connection ]).
65dereg_url(Service, URL) :- connection(Connection), format(atom(URL), '~w/agent/service/deregister/~w', [ Connection, Service ]).
73consul_services(Services) :-
74 svs_url(URL),
75 http_get(URL, Result, [content_type('application/json'), json_object(dict)]),
76 findall(X, _ = Result.get(X), Services).
89consul_service(Service, Properties) :-
90 sv_url(Service, URL),
91 http_get(URL, Result, [content_type('application/json'), json_object(dict)]),
92 convlist([X,Y]>>(
93 get_dict('ServiceAddress', X, Address),
94 get_dict('ServicePort', X, Port),
95 get_dict('ServiceTags', X, Tags),
96 Y = service{host: Address, port: Port, tags: Tags}
97 ), Result, PropertiesFound),
98 (
99 PropertiesFound == [], !, fail ; Properties = PropertiesFound
100 ).
108read_consul_key(Key, Value) :-
109 read_consul_key(Key, Value, []).
121read_consul_key(Key, Value, Options) :-
122 catch(
123 (
124 kv_url(Key, URL),
125 http_get(URL, [Data|_], [content_type('application/json'), json_object(dict)]),
126 base64(V, Data.'Value'),
127 option(as(Type), Options, atom),
128 convert_result(V, Type, Value)
129 ),
130 error(existence_error(url,_),context(_,status(404,_))),
131 fail
132 ).
133
134convert_result(In, atom, In) :- !.
135convert_result(In, number, Out) :- atom_number(In, Out), !.
136convert_result(In, string, Out) :- atom_string(In, Out), !.
137convert_result(In, list, Out) :-
138 atom_string(In, Ins),
139 format(string(S), "lst(~w).", Ins),
140 open_string(S, Stream),
141 read_term(Stream, lst(Out), []),
142 !.
150delete_consul_key(Key) :-
151 kv_url(Key, URL),
152 http_delete(URL, _, [content_type('application/json'), json_object(dict)]).
161update_consul_key(Key, Value) :-
162 is_list(Value),
163 kv_url(Key, URL),
164 format(string(ValueToSend), "~w", [Value]),
165 http_put(URL, atom(ValueToSend), _, [content_type('application/json')]),
166 !.
167update_consul_key(Key, Value) :-
168 kv_url(Key, URL),
169 http_put(URL, atom(Value), _, [content_type('application/json')]).
179register_consul_service(Service, Host, Port, Tags) :-
180 Payload = _{ 'Name': Service, 'Tags': Tags, 'Address': Host, 'Port': Port},
181 with_output_to(string(PayloadJson), json_write(current_output, Payload, [])),
182 reg_url(URL),
183 http_put(URL, codes(PayloadJson), _, []).
190deregister_consul_service(Service) :-
191 dereg_url(Service, URL),
192 http_put(URL, _, _, [])
Consul client
An interface to consul:
The module requires a local consul agent running on the default port.
*/