57 lines
2.0 KiB
Python
57 lines
2.0 KiB
Python
"""A small real HTTP service which registers its reachable address in Consul."""
|
|
import json
|
|
import os
|
|
import socket
|
|
import threading
|
|
import time
|
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
from urllib.request import Request, urlopen
|
|
|
|
INSTANCE = os.environ["INSTANCE_ID"]
|
|
CONSUL = os.environ.get("CONSUL_URL", "http://consul:8500")
|
|
ADDRESS = socket.gethostbyname(socket.gethostname())
|
|
|
|
|
|
class Handler(BaseHTTPRequestHandler):
|
|
def do_GET(self):
|
|
if self.path not in ("/", "/health"):
|
|
self.send_error(404)
|
|
return
|
|
body = json.dumps({"instance": INSTANCE, "address": ADDRESS, "port": 8080}).encode()
|
|
self.send_response(200)
|
|
self.send_header("Content-Type", "application/json")
|
|
self.send_header("Content-Length", str(len(body)))
|
|
self.end_headers()
|
|
self.wfile.write(body)
|
|
|
|
def log_message(self, *_):
|
|
pass
|
|
|
|
|
|
def register():
|
|
payload = {
|
|
"ID": INSTANCE, "Name": "orders", "Address": ADDRESS, "Port": 8080,
|
|
"Check": {"HTTP": f"http://{ADDRESS}:8080/health", "Interval": "2s", "Timeout": "1s"},
|
|
}
|
|
# No automatic deregistration: the failed service stays in the catalog for comparison.
|
|
for attempt in range(30):
|
|
try:
|
|
request = Request(CONSUL + "/v1/agent/service/register",
|
|
data=json.dumps(payload).encode(), method="PUT",
|
|
headers={"Content-Type": "application/json"})
|
|
with urlopen(request, timeout=2) as response:
|
|
response.read()
|
|
print(f"REGISTERED orders / {INSTANCE} -> {ADDRESS}:8080", flush=True)
|
|
return
|
|
except OSError:
|
|
time.sleep(1)
|
|
raise RuntimeError("Consul registration failed after 30 attempts")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
server = ThreadingHTTPServer(("0.0.0.0", 8080), Handler)
|
|
thread = threading.Thread(target=server.serve_forever, daemon=True)
|
|
thread.start()
|
|
register()
|
|
thread.join()
|