#pragma once
#include <chrono>
#include <cstdint>
#include <string>
#include <memory>
#include <mw/error.hpp>
#include "probe_status.h"
/// HTTP configuration; only a direct 2xx response is healthy.
struct HttpEndpoint
{
/// HTTP or HTTPS URL, after applying any service URL fallback.
std::string url;
};
/// TCP connection configuration.
struct TcpEndpoint
{
/// Hostname or IPv4/IPv6 address.
std::string host;
/// Destination port, from 1 to 65535.
std::uint16_t port;
};
/// UDP configuration; silence is OTHER, not proof of an open port.
struct UdpEndpoint
{
/// Hostname or IPv4/IPv6 address.
std::string host;
/// Destination port, from 1 to 65535.
std::uint16_t port;
/// Datagram bytes; defaults to an empty datagram.
std::string payload;
};
/// ICMP echo configuration for Linux ping sockets.
struct IcmpEndpoint
{
/// Hostname or IPv4/IPv6 address.
std::string host;
};
/// Measured result ready to be associated with a service and persisted.
struct ProbeResult
{
/// Outcome of the network check.
ProbeStatus status;
/// Probe start time in UTC Unix seconds.
std::int64_t timestamp;
/// Elapsed monotonic time in microseconds, including DNS resolution.
std::int64_t duration_microsecond;
};
/// A task-owned probe for one endpoint check.
class ProbeInterface
{
public:
/// Release the probe through its interface.
virtual ~ProbeInterface() = default;
/// Check the endpoint and measure its result.
/// Network failures return BAD; silent UDP endpoints return OTHER.
/// Local execution failures return errors.
virtual mw::E<ProbeResult> probe() = 0;
};
/// HTTP GET probe owning its endpoint configuration.
class HttpProbe final : public ProbeInterface
{
public:
/// Perform the configured HTTP GET check.
mw::E<ProbeResult> probe() override;
private:
HttpProbe(HttpEndpoint config, std::chrono::seconds timeout);
friend mw::E<std::unique_ptr<ProbeInterface>> createProbe(
const HttpEndpoint& config, std::chrono::seconds timeout);
HttpEndpoint config;
std::chrono::seconds timeout;
};
/// TCP connection probe owning its endpoint configuration.
class TcpProbe final : public ProbeInterface
{
public:
/// Perform the configured TCP connection check.
mw::E<ProbeResult> probe() override;
private:
TcpProbe(TcpEndpoint config, std::chrono::seconds timeout);
friend mw::E<std::unique_ptr<ProbeInterface>> createProbe(
const TcpEndpoint& config, std::chrono::seconds timeout);
TcpEndpoint config;
std::chrono::seconds timeout;
};
/// UDP request/reply probe owning its endpoint configuration.
class UdpProbe final : public ProbeInterface
{
public:
/// Perform the configured UDP request/reply check.
mw::E<ProbeResult> probe() override;
private:
UdpProbe(UdpEndpoint config, std::chrono::seconds timeout);
friend mw::E<std::unique_ptr<ProbeInterface>> createProbe(
const UdpEndpoint& config, std::chrono::seconds timeout);
UdpEndpoint config;
std::chrono::seconds timeout;
};
/// ICMP echo probe owning its endpoint configuration.
class IcmpProbe final : public ProbeInterface
{
public:
/// Perform the configured ICMP echo check.
mw::E<ProbeResult> probe() override;
private:
IcmpProbe(IcmpEndpoint config, std::chrono::seconds timeout);
friend mw::E<std::unique_ptr<ProbeInterface>> createProbe(
const IcmpEndpoint& config, std::chrono::seconds timeout);
IcmpEndpoint config;
std::chrono::seconds timeout;
};
/// Create a HTTP probe with a positive timeout for DNS and network I/O.
mw::E<std::unique_ptr<ProbeInterface>> createProbe(
const HttpEndpoint& config,
std::chrono::seconds timeout = std::chrono::seconds(5));
/// Create a TCP probe with a positive timeout for DNS and network I/O.
mw::E<std::unique_ptr<ProbeInterface>> createProbe(
const TcpEndpoint& config,
std::chrono::seconds timeout = std::chrono::seconds(5));
/// Create a UDP probe with a positive timeout for DNS and network I/O.
mw::E<std::unique_ptr<ProbeInterface>> createProbe(
const UdpEndpoint& config,
std::chrono::seconds timeout = std::chrono::seconds(5));
/// Create a ICMP probe with a positive timeout for DNS and network I/O.
mw::E<std::unique_ptr<ProbeInterface>> createProbe(
const IcmpEndpoint& config,
std::chrono::seconds timeout = std::chrono::seconds(5));