diff --git a/README.md b/README.md
index ecbef5741..a6daeb234 100644
--- a/README.md
+++ b/README.md
@@ -219,7 +219,7 @@ The main operator and integration tools under `cmd/` are:
## Future direction: from observation to action
-The longer-term direction is for xtcp2 to take network actions as well as observe. goip already constructs requests for a growing set of write operations, but **live kernel writes remain incomplete and disabled**: supported write commands serialize requests to `GOIP_WRITE_OUT` for validation and refuse to apply them. The [write-path and parity documentation](docs/netlink/README.md) tracks that work; the [network-control gRPC design](docs/design-network-control-grpc.md) describes proposed APIs, not an available service.
+The longer-term direction is for xtcp2 to take network actions as well as observe. goip constructs requests for a growing set of write operations, and the CLI's write commands serialize them to `GOIP_WRITE_OUT` for validation and refuse to apply them. The one live-write path is the opt-in [TCP route treatment controller](docs/tcp-controller.md): its actuator installs host routes in a private table through goip, with ownership and readback checks, and is disabled unless an operator enables it. The [write-path and parity documentation](docs/netlink/README.md) tracks the rest of that work; the [network-control gRPC design](docs/design-network-control-grpc.md) describes proposed APIs, not an available service.
Future network control and true BGP-origin/next-hop ASN enrichment are separate developments. Neither is required to use today's collection, inspection, or operational alerting features.
diff --git a/build/containers/clickhouse/format_schemas/xtcp_flat_record.proto b/build/containers/clickhouse/format_schemas/xtcp_flat_record.proto
index 657a035bb..794de6e47 100644
--- a/build/containers/clickhouse/format_schemas/xtcp_flat_record.proto
+++ b/build/containers/clickhouse/format_schemas/xtcp_flat_record.proto
@@ -94,7 +94,7 @@ message XtcpFlatRecord {
"class_id", "sock_opt", "c_group";
// ==== metadata (1-299) =====================================================
- // Free: 3-9, 11-19, 22-29, 33-39, 44-49, 52-59, 63-99, 108-119, 125-199,
+ // Free: 3-9, 11-19, 33-39, 44-49, 52-59, 63-99, 108-119, 125-199,
// 208-219, 225-299. Uplink slots are fixed at two (100s, 200s); a third slot
// would take 250-274, NOT 300 (that is the enrichment block).
@@ -123,6 +123,17 @@ message XtcpFlatRecord {
// -location flag or LOCATION env. Constant for every record from one
// daemon instance.
string location = 21;
+ // Controller provenance. Empty/zero means observation-only legacy producer.
+ string agent_id = 22;
+ string host_boot_id = 23;
+ string collection_id = 24;
+ uint64 treatment_state_revision = 25;
+ string treatment_assignment_id = 26;
+ uint64 treatment_generation = 27;
+ int64 treatment_applied_timestamp_ns = 28;
+ // True only when the observed socket algorithm matches a verified route
+ // assignment in this namespace. This does not prove initial-window exposure.
+ bool treatment_algorithm_exposed = 29;
// ---- metadata: network namespace identity (30s) --------------------------
// network namespace — best-effort human name (bind-mount name, else a
diff --git a/build/containers/clickhouse/initdb.d/sql/xtcp_treatment_migration.sql b/build/containers/clickhouse/initdb.d/sql/xtcp_treatment_migration.sql
new file mode 100644
index 000000000..c789114d7
--- /dev/null
+++ b/build/containers/clickhouse/initdb.d/sql/xtcp_treatment_migration.sql
@@ -0,0 +1,30 @@
+-- Apply to an existing deployment before enabling controller agents.
+-- Additive migration: never drop telemetry tables or reset Kafka offsets.
+ALTER TABLE xtcp.xtcp_flat_records_v2 ADD COLUMN IF NOT EXISTS agent_id String;
+ALTER TABLE xtcp.xtcp_flat_records_v2 ADD COLUMN IF NOT EXISTS host_boot_id String;
+ALTER TABLE xtcp.xtcp_flat_records_v2 ADD COLUMN IF NOT EXISTS collection_id String;
+ALTER TABLE xtcp.xtcp_flat_records_v2 ADD COLUMN IF NOT EXISTS treatment_state_revision UInt64;
+ALTER TABLE xtcp.xtcp_flat_records_v2 ADD COLUMN IF NOT EXISTS treatment_assignment_id String;
+ALTER TABLE xtcp.xtcp_flat_records_v2 ADD COLUMN IF NOT EXISTS treatment_generation UInt64;
+ALTER TABLE xtcp.xtcp_flat_records_v2 ADD COLUMN IF NOT EXISTS treatment_applied_timestamp_ns Int64;
+ALTER TABLE xtcp.xtcp_flat_records_v2 ADD COLUMN IF NOT EXISTS treatment_algorithm_exposed Bool;
+ALTER TABLE xtcp.xtcp_flat_records ADD COLUMN IF NOT EXISTS agent_id String;
+ALTER TABLE xtcp.xtcp_flat_records ADD COLUMN IF NOT EXISTS host_boot_id String;
+ALTER TABLE xtcp.xtcp_flat_records ADD COLUMN IF NOT EXISTS collection_id String;
+ALTER TABLE xtcp.xtcp_flat_records ADD COLUMN IF NOT EXISTS treatment_state_revision UInt64;
+ALTER TABLE xtcp.xtcp_flat_records ADD COLUMN IF NOT EXISTS treatment_assignment_id String;
+ALTER TABLE xtcp.xtcp_flat_records ADD COLUMN IF NOT EXISTS treatment_generation UInt64;
+ALTER TABLE xtcp.xtcp_flat_records ADD COLUMN IF NOT EXISTS treatment_applied_timestamp_ns Int64;
+ALTER TABLE xtcp.xtcp_flat_records ADD COLUMN IF NOT EXISTS treatment_algorithm_exposed Bool;
+ALTER TABLE xtcp.xtcp_flat_records_kafka ADD COLUMN IF NOT EXISTS agent_id String;
+ALTER TABLE xtcp.xtcp_flat_records_kafka ADD COLUMN IF NOT EXISTS host_boot_id String;
+ALTER TABLE xtcp.xtcp_flat_records_kafka ADD COLUMN IF NOT EXISTS collection_id String;
+ALTER TABLE xtcp.xtcp_flat_records_kafka ADD COLUMN IF NOT EXISTS treatment_state_revision UInt64;
+ALTER TABLE xtcp.xtcp_flat_records_kafka ADD COLUMN IF NOT EXISTS treatment_assignment_id String;
+ALTER TABLE xtcp.xtcp_flat_records_kafka ADD COLUMN IF NOT EXISTS treatment_generation UInt64;
+ALTER TABLE xtcp.xtcp_flat_records_kafka ADD COLUMN IF NOT EXISTS treatment_applied_timestamp_ns Int64;
+ALTER TABLE xtcp.xtcp_flat_records_kafka ADD COLUMN IF NOT EXISTS treatment_algorithm_exposed Bool;
+ALTER TABLE xtcp.xtcp_flat_records_v2_mv MODIFY QUERY
+SELECT fromUnixTimestamp64Nano(timestamp_ns) AS timestamp_ns, * EXCEPT (timestamp_ns)
+FROM xtcp.xtcp_flat_records_kafka
+WHERE length(_error) = 0 AND schema_version = 2;
diff --git a/build/containers/clickhouse/initdb.d/sql/xtcp_xtcp_flat_records.sql b/build/containers/clickhouse/initdb.d/sql/xtcp_xtcp_flat_records.sql
index 2d1ae1108..4454e1a77 100644
--- a/build/containers/clickhouse/initdb.d/sql/xtcp_xtcp_flat_records.sql
+++ b/build/containers/clickhouse/initdb.d/sql/xtcp_xtcp_flat_records.sql
@@ -342,6 +342,14 @@ CREATE TABLE IF NOT EXISTS xtcp.xtcp_flat_records_v2
-- https://clickhouse.com/docs/en/sql-reference/data-types/lowcardinality
hostname LowCardinality(String),
location LowCardinality(String),
+ agent_id String,
+ host_boot_id String,
+ collection_id String,
+ treatment_state_revision UInt64,
+ treatment_assignment_id String,
+ treatment_generation UInt64,
+ treatment_applied_timestamp_ns Int64,
+ treatment_algorithm_exposed Bool,
-- ---- metadata: network namespace identity (30s) ------------------------
netns String CODEC(ZSTD),
diff --git a/build/containers/clickhouse/initdb.d/sql/xtcp_xtcp_flat_records_kafka.sql b/build/containers/clickhouse/initdb.d/sql/xtcp_xtcp_flat_records_kafka.sql
index 4aad06239..78562a137 100644
--- a/build/containers/clickhouse/initdb.d/sql/xtcp_xtcp_flat_records_kafka.sql
+++ b/build/containers/clickhouse/initdb.d/sql/xtcp_xtcp_flat_records_kafka.sql
@@ -49,6 +49,14 @@ CREATE TABLE IF NOT EXISTS xtcp.xtcp_flat_records_kafka
-- https://clickhouse.com/docs/en/sql-reference/data-types/lowcardinality
hostname LowCardinality(String),
location LowCardinality(String),
+ agent_id String,
+ host_boot_id String,
+ collection_id String,
+ treatment_state_revision UInt64,
+ treatment_assignment_id String,
+ treatment_generation UInt64,
+ treatment_applied_timestamp_ns Int64,
+ treatment_algorithm_exposed Bool,
-- ---- metadata: network namespace identity (30s) ------------------------
netns String CODEC(ZSTD),
diff --git a/cmd/xtcp2-controller/main.go b/cmd/xtcp2-controller/main.go
new file mode 100644
index 000000000..27ce825da
--- /dev/null
+++ b/cmd/xtcp2-controller/main.go
@@ -0,0 +1,249 @@
+package main
+
+import (
+ "context"
+ "crypto/tls"
+ "encoding/json"
+ "errors"
+ "flag"
+ "fmt"
+ "log"
+ "net"
+ "net/http"
+ "os"
+ "os/signal"
+ "strings"
+ "sync"
+ "syscall"
+ "time"
+
+ pb "github.com/randomizedcoder/xtcp2/gen/go/xtcp_treatment"
+ "github.com/randomizedcoder/xtcp2/pkg/treatment/controller"
+ "github.com/randomizedcoder/xtcp2/pkg/treatment/controller/evidence"
+ chwarehouse "github.com/randomizedcoder/xtcp2/pkg/treatment/controller/evidence/clickhouse"
+ "github.com/randomizedcoder/xtcp2/pkg/treatment/controller/store/postgres"
+ "github.com/randomizedcoder/xtcp2/pkg/treatment/identity"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/credentials"
+)
+
+func main() {
+ if e := run(); e != nil {
+ log.Print(e)
+ os.Exit(1)
+ }
+}
+
+// options are the controller's command-line settings.
+type options struct {
+ listen, statusListen string
+ cert, key, ca string
+ dsnFile string
+ migrate bool
+ clickhouse, table string
+ templateFile string
+ discoveryInterval, discoveryWindow time.Duration
+}
+
+func parseFlags() (*options, error) {
+ o := new(options)
+ flag.StringVar(&o.listen, "listen", ":9443", "mTLS gRPC listener")
+ flag.StringVar(&o.statusListen, "statusListen", "127.0.0.1:9444", "mTLS status/metrics HTTP listener")
+ flag.StringVar(&o.cert, "cert", "", "server certificate")
+ flag.StringVar(&o.key, "key", "", "server private key")
+ flag.StringVar(&o.ca, "ca", "", "client CA")
+ flag.StringVar(&o.dsnFile, "databaseDSNFile", "", "file containing PostgreSQL DSN (or XTCP_CONTROLLER_DATABASE_DSN)")
+ flag.BoolVar(&o.migrate, "migrate", false, "apply additive PostgreSQL schema before serving")
+ flag.StringVar(&o.clickhouse, "clickhouse", "", "ClickHouse HTTP(S) endpoint; absent disables analysis and lease renewal")
+ flag.StringVar(&o.table, "clickhouseTable", "xtcp.xtcp_flat_records_v2", "source telemetry table")
+ flag.StringVar(&o.templateFile, "discoveryTemplates", "", "optional JSON array of candidate discovery templates")
+ flag.DurationVar(&o.discoveryInterval, "discoveryInterval", 30*time.Minute, "candidate discovery interval (at least one minute; checked on maintenance ticks)")
+ flag.DurationVar(&o.discoveryWindow, "discoveryWindow", time.Hour, "candidate discovery lookback (one minute to seven days)")
+ flag.Parse()
+ if o.discoveryInterval < time.Minute || o.discoveryInterval > 24*time.Hour || o.discoveryWindow < time.Minute || o.discoveryWindow > 7*24*time.Hour {
+ return nil, fmt.Errorf("discovery interval must be 1m..24h and window 1m..168h")
+ }
+ return o, nil
+}
+
+// dsn reads the PostgreSQL DSN from the file flag or the environment.
+func (o *options) dsn() (string, error) {
+ dsn := os.Getenv("XTCP_CONTROLLER_DATABASE_DSN")
+ if o.dsnFile != "" {
+ b, e := os.ReadFile(o.dsnFile)
+ if e != nil {
+ return "", e
+ }
+ dsn = strings.TrimSpace(string(b))
+ }
+ if dsn == "" {
+ return "", fmt.Errorf("PostgreSQL DSN required")
+ }
+ return dsn, nil
+}
+
+// templates loads the discovery templates, which need a warehouse.
+func (o *options) templates(warehouse *chwarehouse.Client) ([]controller.DiscoveryTemplate, error) {
+ if o.templateFile == "" {
+ return nil, nil
+ }
+ b, e := os.ReadFile(o.templateFile)
+ if e != nil {
+ return nil, e
+ }
+ var templates []controller.DiscoveryTemplate
+ if e = json.Unmarshal(b, &templates); e != nil {
+ return nil, e
+ }
+ if warehouse == nil {
+ return nil, fmt.Errorf("discovery requires ClickHouse")
+ }
+ return templates, nil
+}
+
+// openStore connects to PostgreSQL and applies the schema when asked.
+func (o *options) openStore(ctx context.Context) (*postgres.Store, error) {
+ dsn, err := o.dsn()
+ if err != nil {
+ return nil, err
+ }
+ db, err := postgres.Open(ctx, dsn)
+ if err != nil {
+ return nil, err
+ }
+ if o.migrate {
+ if err = db.Migrate(ctx); err != nil {
+ return nil, errors.Join(err, db.Close())
+ }
+ }
+ return db, nil
+}
+
+// warehouse is one adapter behind two ports: evidence.Source for analysis
+// and lease renewal, evidence.Warehouse for discovery. Both are nil without
+// -clickhouse.
+func (o *options) warehouse() (*chwarehouse.Client, evidence.Source) {
+ if o.clickhouse == "" {
+ return nil, nil
+ }
+ w := &chwarehouse.Client{URL: o.clickhouse, Table: o.table, Username: os.Getenv("XTCP_CLICKHOUSE_USER"), Password: os.Getenv("XTCP_CLICKHOUSE_PASSWORD")}
+ return w, w
+}
+
+func run() (err error) {
+ o, err := parseFlags()
+ if err != nil {
+ return err
+ }
+ ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGTERM, syscall.SIGINT)
+ defer cancel()
+ tlsConfig, e := identity.TLSConfig(o.cert, o.key, o.ca, "", true)
+ if e != nil {
+ return e
+ }
+ db, e := o.openStore(ctx)
+ if e != nil {
+ return e
+ }
+ defer func() {
+ if cerr := db.Close(); cerr != nil {
+ log.Printf("database close: %v", cerr)
+ }
+ }()
+ warehouse, source := o.warehouse()
+ s := &controller.Server{Store: db, Hub: controller.NewNotificationHub(), DiscoveryWindow: o.discoveryWindow, EvidenceSource: source}
+ templates, e := o.templates(warehouse)
+ if e != nil {
+ return e
+ }
+ // grpcServer.Serve owns the listener and closes it when it stops.
+ listener, e := (&net.ListenConfig{}).Listen(ctx, "tcp", o.listen)
+ if e != nil {
+ return e
+ }
+ grpcServer := grpc.NewServer(append(controller.GRPCOptions(), grpc.Creds(credentials.NewTLS(tlsConfig)))...)
+ pb.RegisterAgentControlServiceServer(grpcServer, s)
+ pb.RegisterOperatorServiceServer(grpcServer, s)
+ var wg sync.WaitGroup
+ wg.Add(2)
+ go func() { defer wg.Done(); s.RunNotifications(ctx) }()
+ go func() { defer wg.Done(); housekeep(ctx, s, source, warehouse, templates, o.discoveryInterval) }()
+ statusServer := &http.Server{Addr: o.statusListen, Handler: s.StatusHandler(), TLSConfig: tlsConfig.Clone(), ReadHeaderTimeout: 5 * time.Second, ReadTimeout: 15 * time.Second, WriteTimeout: 15 * time.Second, IdleTimeout: time.Minute}
+ failed := make(chan error, 2)
+ go func() { failed <- grpcServer.Serve(listener) }()
+ if o.statusListen != "" {
+ go func() {
+ l, e := (&net.ListenConfig{}).Listen(ctx, "tcp", o.statusListen)
+ if e != nil {
+ failed <- e
+ return
+ }
+ failed <- statusServer.Serve(tls.NewListener(l, statusServer.TLSConfig))
+ }()
+ }
+ log.Printf("xtcp2 controller listening on %s; human review required", o.listen)
+ select {
+ case <-ctx.Done():
+ case e = <-failed:
+ cancel()
+ }
+ shutdown, done := context.WithTimeout(context.Background(), 5*time.Second)
+ defer done()
+ if serr := statusServer.Shutdown(shutdown); serr != nil {
+ log.Printf("status listener shutdown: %v", serr)
+ }
+ stopped := make(chan struct{})
+ go func() { grpcServer.GracefulStop(); close(stopped) }()
+ select {
+ case <-stopped:
+ case <-shutdown.Done():
+ grpcServer.Stop()
+ }
+ wg.Wait()
+ if e == grpc.ErrServerStopped || e == http.ErrServerClosed {
+ return nil
+ }
+ return e
+}
+
+// housekeep runs maintenance every minute, and discovery on its own
+// cadence, under the housekeeping lease until ctx is done.
+func housekeep(ctx context.Context, s *controller.Server, source evidence.Source, warehouse *chwarehouse.Client, templates []controller.DiscoveryTemplate, interval time.Duration) {
+ tick := time.NewTicker(time.Minute)
+ defer tick.Stop()
+ nextDiscovery := time.Now()
+ leader := false
+ for {
+ // Discovery is due on this replica's own cadence whether or not
+ // it holds the lease, so a follower that becomes leader does not
+ // run a backlog of passes.
+ var due evidence.Warehouse
+ if warehouse != nil && !time.Now().Before(nextDiscovery) {
+ due = warehouse
+ // Keep the cadence independent of query duration; otherwise a
+ // one-minute interval can accidentally skip every other tick.
+ for !nextDiscovery.After(time.Now()) {
+ nextDiscovery = nextDiscovery.Add(interval)
+ }
+ }
+ held, e := s.Housekeep(ctx, source, due, templates)
+ if e != nil {
+ log.Printf("controller housekeeping: %v", e)
+ }
+ // A failed Lease call reports held=false with an error; that is
+ // not a follower, so the leader state is kept until it answers.
+ if (e == nil || held) && held != leader {
+ leader = held
+ if held {
+ log.Print("controller housekeeping: this replica holds the lease")
+ } else {
+ log.Print("controller housekeeping: another replica holds the lease; skipping passes")
+ }
+ }
+ select {
+ case <-ctx.Done():
+ return
+ case <-tick.C:
+ }
+ }
+}
diff --git a/cmd/xtcp2-controllerctl/main.go b/cmd/xtcp2-controllerctl/main.go
new file mode 100644
index 000000000..5a2615442
--- /dev/null
+++ b/cmd/xtcp2-controllerctl/main.go
@@ -0,0 +1,92 @@
+package main
+
+import (
+ "context"
+ "flag"
+ "fmt"
+ "log"
+ "os"
+ "time"
+
+ pb "github.com/randomizedcoder/xtcp2/gen/go/xtcp_treatment"
+ "github.com/randomizedcoder/xtcp2/pkg/treatment"
+ "github.com/randomizedcoder/xtcp2/pkg/treatment/identity"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/credentials"
+ "google.golang.org/protobuf/encoding/prototext"
+ "google.golang.org/protobuf/proto"
+)
+
+func main() {
+ if e := run(); e != nil {
+ log.Print(e)
+ os.Exit(1)
+ }
+}
+func run() error {
+ target := flag.String("controller", "localhost:9443", "controller address")
+ name := flag.String("serverName", "", "TLS server name")
+ cert := flag.String("cert", "", "operator certificate")
+ key := flag.String("key", "", "operator key")
+ ca := flag.String("ca", "", "server CA")
+ method := flag.String("method", "inspect", "propose, analyze, review, control, inspect")
+ file := flag.String("file", "", "protobuf-text request file (empty InspectRequest if omitted)")
+ flag.Parse()
+ tls, e := identity.TLSConfig(*cert, *key, *ca, *name, false)
+ if e != nil {
+ return e
+ }
+ conn, e := grpc.NewClient(*target, grpc.WithTransportCredentials(credentials.NewTLS(tls)), grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(treatment.MaxStateBytes)))
+ if e != nil {
+ return e
+ }
+ defer func() {
+ if cerr := conn.Close(); cerr != nil {
+ log.Printf("close: %v", cerr)
+ }
+ }()
+ ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
+ defer cancel()
+ client := pb.NewOperatorServiceClient(conn)
+ var req, response proto.Message
+ switch *method {
+ case "propose":
+ req = new(pb.ProposeRequest)
+ case "review":
+ req = new(pb.ReviewRequest)
+ case "analyze":
+ req = new(pb.AnalyzeRequest)
+ case "control":
+ req = new(pb.ControlRequest)
+ case "inspect":
+ req = new(pb.InspectRequest)
+ default:
+ return fmt.Errorf("unknown method %q", *method)
+ }
+ if *file != "" {
+ b, e := os.ReadFile(*file)
+ if e != nil {
+ return e
+ }
+ if e = prototext.Unmarshal(b, req); e != nil {
+ return e
+ }
+ }
+ switch r := req.(type) {
+ case *pb.ProposeRequest:
+ response, e = client.Propose(ctx, r)
+ case *pb.ReviewRequest:
+ response, e = client.Review(ctx, r)
+ case *pb.AnalyzeRequest:
+ response, e = client.Analyze(ctx, r)
+ case *pb.ControlRequest:
+ response, e = client.Control(ctx, r)
+ case *pb.InspectRequest:
+ response, e = client.Inspect(ctx, r)
+ }
+ if e != nil {
+ return e
+ }
+ fmt.Print(prototext.Format(response))
+ return nil
+}
diff --git a/cmd/xtcp2-treatment-agent/main.go b/cmd/xtcp2-treatment-agent/main.go
new file mode 100644
index 000000000..d28debbb0
--- /dev/null
+++ b/cmd/xtcp2-treatment-agent/main.go
@@ -0,0 +1,75 @@
+// xtcp2-treatment-agent runs the TCP route treatment agent as its own
+// process: the mTLS check-in loop, desired-state watch, journal and kernel
+// route reconciliation, beside an xtcp2 daemon that reads the journal with
+// -treatmentAttribution. It is the same library cmd/xtcp2 embeds when built
+// with the treatment tag; the watchdog (xtcp2-treatmentctl -mode=watchdog)
+// stays a separate process in both arrangements.
+//
+// SIGHUP checks in and reconciles immediately; SIGINT/SIGTERM stop the agent
+// and leave installed routes for the next start or the watchdog to govern.
+package main
+
+import (
+ "context"
+ "flag"
+ "log"
+ "os"
+ "os/signal"
+ "syscall"
+
+ "github.com/randomizedcoder/xtcp2/pkg/treatment/agent"
+)
+
+var (
+ version = "dev"
+ commit = "none"
+ date = "unknown"
+)
+
+func main() {
+ if err := run(); err != nil {
+ log.Print(err)
+ os.Exit(1)
+ }
+}
+
+func run() (err error) {
+ config := flag.String("config", "/etc/xtcp2/controller-agent.json", "agent configuration (shared with xtcp2-treatmentctl)")
+ showVersion := flag.Bool("version", false, "print version and exit")
+ flag.Parse()
+ if *showVersion {
+ log.Printf("xtcp2-treatment-agent %s (%s, %s)", version, commit, date)
+ return nil
+ }
+ ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
+ defer cancel()
+ c, err := agent.LoadConfig(*config)
+ if err != nil {
+ return err
+ }
+ a, err := agent.New(ctx, c)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ if cerr := a.Close(); cerr != nil && err == nil {
+ err = cerr
+ }
+ }()
+ hup := make(chan os.Signal, 1)
+ signal.Notify(hup, syscall.SIGHUP)
+ defer signal.Stop(hup)
+ go func() {
+ for {
+ select {
+ case <-ctx.Done():
+ return
+ case <-hup:
+ a.Wake()
+ }
+ }
+ }()
+ log.Printf("xtcp2-treatment-agent %s: %s journal=%s", version, c, c.Directory)
+ a.Run(ctx)
+ return nil
+}
diff --git a/cmd/xtcp2-treatmentctl/main.go b/cmd/xtcp2-treatmentctl/main.go
new file mode 100644
index 000000000..845b6bb9b
--- /dev/null
+++ b/cmd/xtcp2-treatmentctl/main.go
@@ -0,0 +1,90 @@
+// xtcp2-treatmentctl is the local, filesystem-permission-protected emergency
+// interface and independent lease watchdog. It never needs a controller RPC,
+// a certificate or DNS: it builds on pkg/treatment/local and
+// pkg/treatment/reconcile only, and the import-boundary test keeps it that way.
+package main
+
+import (
+ "context"
+ "flag"
+ "fmt"
+ "log"
+ "os"
+ "os/signal"
+ "path/filepath"
+ "syscall"
+ "time"
+
+ "github.com/randomizedcoder/xtcp2/pkg/treatment/local"
+ "github.com/randomizedcoder/xtcp2/pkg/treatment/reconcile"
+)
+
+func main() {
+ if err := run(); err != nil {
+ log.Print(err)
+ os.Exit(1)
+ }
+}
+func run() error {
+ config := flag.String("config", "/etc/xtcp2/controller-agent.json", "agent configuration")
+ mode := flag.String("mode", "status", "status, suspend, resume, reconcile, or watchdog")
+ reason := flag.String("reason", "", "required for suspend/resume")
+ flag.Parse()
+ ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
+ defer cancel()
+ c, e := local.LoadConfig(*config)
+ if e != nil {
+ return e
+ }
+ h, e := local.New(c, nil)
+ if e != nil {
+ return e
+ }
+ switch *mode {
+ case "status":
+ // Read without the lock: the snapshot is replaced atomically and
+ // status must answer while a reconcile pass holds the journal.
+ b, e := os.ReadFile(filepath.Join(c.Directory, reconcile.SnapshotFile))
+ if e != nil {
+ return e
+ }
+ _, e = os.Stdout.Write(b)
+ return e
+ case "suspend", "resume":
+ // Waits for a reconcile pass in progress; a watchdog pass is bounded
+ // at 25 s, so a longer wait means the journal is wedged.
+ hold, cancelHold := context.WithTimeout(ctx, 30*time.Second)
+ defer cancelHold()
+ if e = h.Reconciler.SuspendLocal(hold, *mode == "suspend", *reason); e != nil {
+ return e
+ }
+ case "reconcile":
+ case "watchdog":
+ t := time.NewTicker(30 * time.Second)
+ defer t.Stop()
+ for {
+ pass, cancelPass := context.WithTimeout(ctx, 25*time.Second)
+ _, e = h.Reconciler.Run(pass, nil, reconcile.ModeExpiryOnly)
+ cancelPass()
+ if e != nil {
+ log.Printf("watchdog: %v", e)
+ }
+ select {
+ case <-ctx.Done():
+ return nil
+ case <-t.C:
+ }
+ }
+ default:
+ return fmt.Errorf("unknown mode %q", *mode)
+ }
+ s, e := h.Reconciler.Run(ctx, nil, reconcile.ModeFull)
+ if s != nil {
+ if b, err := reconcile.MarshalText(s); err == nil {
+ if _, werr := os.Stdout.Write(b); werr != nil && e == nil {
+ e = werr
+ }
+ }
+ }
+ return e
+}
diff --git a/cmd/xtcp2/testdata/defineflags-golden.txt b/cmd/xtcp2/testdata/defineflags-golden.txt
index 589ae7241..235a9e412 100644
--- a/cmd/xtcp2/testdata/defineflags-golden.txt
+++ b/cmd/xtcp2/testdata/defineflags-golden.txt
@@ -121,6 +121,8 @@ s3UploadMaxAttempts 10 s3parquet: max upload attempts (original + retries) befor
tag label applied to the protobuf
timeout 5s Poll timeout per name space
topic xtcp Kafka or NSQ topic
+treatmentAttribution optional journal directory of a standalone xtcp2-treatment-agent (its config's directory, default /var/lib/xtcp2/routes); this daemon only reads the snapshot and stamps treatment provenance onto records. Mutually exclusive with -treatmentConfig
+treatmentConfig optional controller agent JSON config, running the treatment agent inside this daemon; needs a build with the treatment tag; route application requires enable_apply. Mutually exclusive with -treatmentAttribution
uplinkCount 2 number of uplink slots to populate for LLDP/NIC enrichment (hosts are typically dual-homed = 2; max 2). Falls back to UPLINK_COUNT env.
uplinkInterfaces comma-separated explicit uplink interface names (e.g. "eth0,eth1") overriding default-route auto-detection for -enrichLldp/-enrichNic. Falls back to UPLINK_INTERFACES env.
v false show version
diff --git a/cmd/xtcp2/treatments.go b/cmd/xtcp2/treatments.go
new file mode 100644
index 000000000..0618020cd
--- /dev/null
+++ b/cmd/xtcp2/treatments.go
@@ -0,0 +1,125 @@
+package main
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "sync"
+ "sync/atomic"
+
+ flat "github.com/randomizedcoder/xtcp2/gen/go/xtcp_flat_record"
+ "github.com/randomizedcoder/xtcp2/pkg/treatment/attribution"
+)
+
+// The treatment feature reaches the daemon in one of two ways, selected by
+// flag and never both:
+//
+// - -treatmentAttribution
: always compiled. A standalone
+// xtcp2-treatment-agent owns the journal in ; the daemon only reads
+// the snapshot and stamps provenance onto records. No gRPC client, no
+// TLS material, no kernel writes in this process.
+// - -treatmentConfig : compiled only with the `treatment` build tag
+// (treatments_embedded.go), which registers embeddedTreatmentAgent. The
+// agent runs in-process and feeds the same stamper.
+//
+// Asking an untagged binary for -treatmentConfig is fatal, like asking a slim
+// build for an enricher it lacks: a missing build tag is a property of the
+// artifact, identical on every host, and must not degrade silently.
+//
+// Location has one rule in both modes. The agent's location is bound to its
+// certificate (spiffe://xtcp/agent//) and evidence queries
+// filter by it. When this daemon has no -location/LOCATION of its own, its
+// records take the agent's, logged once. When it has one and the agent's
+// differs, the embedded agent refuses to start, naming both, and the
+// attribution watcher keeps the daemon's label and logs the disagreement
+// once (pkg/treatment/attribution). Nothing rewrites a label silently.
+
+// treatmentFeeder is whichever mode is running.
+type treatmentFeeder struct {
+ stamp func(*flat.XtcpFlatRecord)
+ wake func()
+}
+
+var activeTreatments atomic.Pointer[treatmentFeeder]
+
+// embeddedTreatmentAgent is nil unless built with -tags treatment. location
+// is the daemon's own, after -location and LOCATION, empty when it has none.
+var embeddedTreatmentAgent func(ctx context.Context, path, location string) (*treatmentFeeder, func(), error)
+
+var errTreatmentNotCompiled = errors.New("-treatmentConfig requested but the treatment agent is not compiled into this binary; rebuild with '-tags treatment' (or use a full `xtcp2` Nix attribute), or run xtcp2-treatment-agent beside this daemon and point it at the journal with -treatmentAttribution")
+
+// checkTreatmentFlags rejects the combinations that are configuration
+// errors regardless of the controller's availability.
+func checkTreatmentFlags(configPath, attributionDir string) error {
+ if configPath != "" && attributionDir != "" {
+ return errors.New("-treatmentConfig and -treatmentAttribution are mutually exclusive: either embed the agent or read a standalone agent's journal")
+ }
+ if configPath != "" && embeddedTreatmentAgent == nil {
+ return errTreatmentNotCompiled
+ }
+ return nil
+}
+
+// checkTreatmentLocation applies the location rule to the embedded agent:
+// an empty daemon location adopts the agent's; a set one must equal it.
+func checkTreatmentLocation(daemon, agent string) error {
+ if daemon != "" && daemon != agent {
+ return fmt.Errorf("this daemon's -location/LOCATION is %q but the treatment agent's certificate-bound location is %q; set them equal or drop -location so records take the agent's", daemon, agent)
+ }
+ return nil
+}
+
+// treatmentStamper is the hook installed on the collector, nil when no mode
+// is active.
+func treatmentStamper() func(*flat.XtcpFlatRecord) {
+ if f := activeTreatments.Load(); f != nil {
+ return f.stamp
+ }
+ return nil
+}
+
+// reconcileTreatments is the SIGHUP action: check in now, or re-read the
+// journal now.
+func reconcileTreatments() {
+ if f := activeTreatments.Load(); f != nil {
+ f.wake()
+ }
+}
+
+// startTreatments starts the selected mode and returns its stop function.
+// Errors from here are runtime conditions (unreadable config, bad journal
+// directory, controller unreachable) and must not stop socket telemetry.
+func startTreatments(parent context.Context, configPath, attributionDir, location string) (func(), error) {
+ if err := checkTreatmentFlags(configPath, attributionDir); err != nil {
+ return nil, err
+ }
+ switch {
+ case configPath != "":
+ ctx, cancel := context.WithCancel(parent)
+ f, stop, err := embeddedTreatmentAgent(ctx, configPath, location)
+ if err != nil {
+ cancel()
+ return nil, err
+ }
+ activeTreatments.Store(f)
+ return func() { cancel(); stop(); activeTreatments.CompareAndSwap(f, nil) }, nil
+ case attributionDir != "":
+ return startAttribution(parent, attributionDir, location)
+ }
+ return func() {}, nil
+}
+
+func startAttribution(parent context.Context, dir, location string) (func(), error) {
+ var stamper attribution.Stamper
+ w, err := attribution.NewWatcher(attribution.WatchConfig{Dir: dir, Location: location}, &stamper)
+ if err != nil {
+ return nil, fmt.Errorf("treatment attribution: %w", err)
+ }
+ ctx, cancel := context.WithCancel(parent)
+ f := &treatmentFeeder{stamp: stamper.Stamp, wake: w.Wake}
+ activeTreatments.Store(f)
+ var wg sync.WaitGroup
+ wg.Add(1)
+ go func() { defer wg.Done(); w.Run(ctx) }()
+ return func() { cancel(); wg.Wait(); activeTreatments.CompareAndSwap(f, nil) }, nil
+}
diff --git a/cmd/xtcp2/treatments_embedded.go b/cmd/xtcp2/treatments_embedded.go
new file mode 100644
index 000000000..8e9b31901
--- /dev/null
+++ b/cmd/xtcp2/treatments_embedded.go
@@ -0,0 +1,41 @@
+//go:build treatment
+
+package main
+
+import (
+ "context"
+ "log"
+ "sync"
+
+ "github.com/randomizedcoder/xtcp2/pkg/treatment/agent"
+)
+
+// Built with -tags treatment: the controller agent runs inside the daemon
+// and stamps records in-process. This file is the only place cmd/xtcp2
+// imports pkg/treatment/agent, so an untagged build links neither the gRPC
+// client nor the TLS identity code.
+func init() { embeddedTreatmentAgent = startEmbeddedTreatmentAgent }
+
+func startEmbeddedTreatmentAgent(ctx context.Context, path, location string) (*treatmentFeeder, func(), error) {
+ c, err := agent.LoadConfig(path)
+ if err != nil {
+ return nil, nil, err
+ }
+ // Before any credential is read: a label disagreement is a deployment
+ // error, not a runtime one, and the message should be the first thing
+ // in the log.
+ if err = checkTreatmentLocation(location, c.Location); err != nil {
+ return nil, nil, err
+ }
+ if location == "" {
+ log.Printf("treatment agent: this daemon has no -location/LOCATION; records take the agent's %q", c.Location)
+ }
+ a, err := agent.New(ctx, c)
+ if err != nil {
+ return nil, nil, err
+ }
+ var wg sync.WaitGroup
+ wg.Add(1)
+ go func() { defer wg.Done(); a.Run(ctx) }()
+ return &treatmentFeeder{stamp: a.Stamp, wake: a.Wake}, func() { wg.Wait(); a.Close() }, nil
+}
diff --git a/cmd/xtcp2/treatments_embedded_test.go b/cmd/xtcp2/treatments_embedded_test.go
new file mode 100644
index 000000000..55c70ab73
--- /dev/null
+++ b/cmd/xtcp2/treatments_embedded_test.go
@@ -0,0 +1,63 @@
+//go:build treatment
+
+package main
+
+import (
+ "context"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+// With the tag the embedded agent is registered and -treatmentConfig is a
+// runtime path: an unreadable config is an error, not a fatal build mismatch.
+func TestEmbeddedTreatmentAgentRegistered(t *testing.T) {
+ if embeddedTreatmentAgent == nil {
+ t.Fatal("treatment tag did not register the embedded agent")
+ }
+ if err := checkTreatmentFlags("/etc/xtcp2/controller-agent.json", ""); err != nil {
+ t.Fatalf("tagged build refused -treatmentConfig: %v", err)
+ }
+ path := filepath.Join(t.TempDir(), "agent.json")
+ if err := os.WriteFile(path, []byte(`{"agent_id":"host","location":"dc","controller":"127.0.0.1:1","certificate":"/nonexistent.crt","private_key":"/nonexistent.key","ca":"/nonexistent-ca.crt"}`), 0600); err != nil {
+ t.Fatal(err)
+ }
+ stop, err := startTreatments(context.Background(), path, "", "dc")
+ if err == nil || stop != nil || !strings.Contains(err.Error(), "nonexistent") {
+ t.Fatalf("missing credentials must fail at start: %v", err)
+ }
+ if activeTreatments.Load() != nil {
+ t.Fatal("failed start left a feeder active")
+ }
+}
+
+// The embedded agent's location rule runs before any credential is read.
+func TestEmbeddedTreatmentAgentLocation(t *testing.T) {
+ path := filepath.Join(t.TempDir(), "agent.json")
+ if err := os.WriteFile(path, []byte(`{"agent_id":"host","location":"dc1","controller":"127.0.0.1:1","certificate":"/nonexistent.crt","private_key":"/nonexistent.key","ca":"/nonexistent-ca.crt"}`), 0600); err != nil {
+ t.Fatal(err)
+ }
+ for _, tc := range []struct {
+ name, description string
+ daemon string
+ expected string
+ }{
+ {"unset", "positive: a daemon without a location adopts the agent's and proceeds to credentials", "", "nonexistent"},
+ {"equal", "positive: an equal location proceeds to credentials", "dc1", "nonexistent"},
+ {"differs", "negative: a different location is refused before any credential is read", "dc2", `"dc2"`},
+ } {
+ t.Run(tc.name, func(t *testing.T) {
+ stop, err := startTreatments(context.Background(), path, "", tc.daemon)
+ if err == nil || stop != nil || !strings.Contains(err.Error(), tc.expected) {
+ t.Fatalf("%s: err=%v, want %q", tc.description, err, tc.expected)
+ }
+ if tc.name == "differs" && strings.Contains(err.Error(), "nonexistent") {
+ t.Fatalf("%s: credentials were read before the location check", tc.description)
+ }
+ if activeTreatments.Load() != nil {
+ t.Fatal("failed start left a feeder active")
+ }
+ })
+ }
+}
diff --git a/cmd/xtcp2/treatments_test.go b/cmd/xtcp2/treatments_test.go
new file mode 100644
index 000000000..d2c2a52d8
--- /dev/null
+++ b/cmd/xtcp2/treatments_test.go
@@ -0,0 +1,200 @@
+package main
+
+import (
+ "context"
+ "errors"
+ "net/netip"
+ "os"
+ "strings"
+ "syscall"
+ "testing"
+ "time"
+
+ "github.com/randomizedcoder/xtcp2/gen/go/xtcp_config"
+ flat "github.com/randomizedcoder/xtcp2/gen/go/xtcp_flat_record"
+ "github.com/randomizedcoder/xtcp2/pkg/treatment"
+ "github.com/randomizedcoder/xtcp2/pkg/treatment/reconcile"
+ "golang.org/x/sys/unix"
+)
+
+func TestSIGHUPReconcilesWithoutRebaselineOrShutdown(t *testing.T) {
+ sigs := make(chan os.Signal, 3)
+ complete := make(chan struct{}, 1)
+ complete <- struct{}{}
+ reconciled := make(chan struct{}, 1)
+ rebaselined := make(chan struct{}, 1)
+ done := make(chan struct{})
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+ go func() {
+ awaitSignalAndShutdown(sigs, cancel, complete, time.Second, false, func() { rebaselined <- struct{}{} }, func() { reconciled <- struct{}{} })
+ close(done)
+ }()
+ sigs <- syscall.SIGHUP
+ select {
+ case <-reconciled:
+ case <-time.After(time.Second):
+ t.Fatal("SIGHUP did not reconcile")
+ }
+ select {
+ case <-ctx.Done():
+ t.Fatal("SIGHUP shut down daemon")
+ case <-rebaselined:
+ t.Fatal("SIGHUP changed link baseline")
+ default:
+ }
+ sigs <- syscall.SIGUSR1
+ select {
+ case <-rebaselined:
+ case <-time.After(time.Second):
+ t.Fatal("SIGUSR1 regression")
+ }
+ sigs <- syscall.SIGTERM
+ select {
+ case <-done:
+ case <-time.After(time.Second):
+ t.Fatal("SIGTERM did not stop")
+ }
+}
+
+func TestCheckTreatmentFlags(t *testing.T) {
+ saved := embeddedTreatmentAgent
+ t.Cleanup(func() { embeddedTreatmentAgent = saved })
+ for _, tc := range []struct {
+ name, description string
+ config, dir string
+ compiled bool
+ expected string
+ }{
+ {"none", "positive: neither flag is the observation-only daemon", "", "", false, ""},
+ {"attribution", "positive: the journal reader is always available", "", "/var/lib/xtcp2/routes", false, ""},
+ {"embedded-tagged", "positive: -treatmentConfig works when the agent is compiled in", "/etc/xtcp2/a.json", "", true, ""},
+ {"embedded-untagged", "negative: -treatmentConfig without the build tag is a fatal artifact mismatch", "/etc/xtcp2/a.json", "", false, "not compiled into this binary"},
+ {"both", "negative: both modes at once is a configuration error even when tagged", "/etc/xtcp2/a.json", "/var/lib/xtcp2/routes", true, "mutually exclusive"},
+ {"both-untagged", "corner: mutual exclusion is reported before the missing tag", "/etc/xtcp2/a.json", "/var/lib/xtcp2/routes", false, "mutually exclusive"},
+ } {
+ t.Run(tc.name, func(t *testing.T) {
+ embeddedTreatmentAgent = nil
+ if tc.compiled {
+ embeddedTreatmentAgent = func(context.Context, string, string) (*treatmentFeeder, func(), error) { return nil, nil, nil }
+ }
+ err := checkTreatmentFlags(tc.config, tc.dir)
+ if tc.expected == "" {
+ if err != nil {
+ t.Fatalf("%s: %v", tc.description, err)
+ }
+ return
+ }
+ if err == nil || !strings.Contains(err.Error(), tc.expected) {
+ t.Fatalf("%s: expected %q, got %v", tc.description, tc.expected, err)
+ }
+ if tc.name == "embedded-untagged" && !errors.Is(err, errTreatmentNotCompiled) {
+ t.Fatal("missing tag must be the sentinel error so main can make it fatal")
+ }
+ })
+ }
+}
+
+// The location rule for the embedded agent, with the daemon's label resolved
+// the way main resolves it: -location first, LOCATION from the environment
+// over it. The standalone counterpart (keep the daemon's label, adopt when
+// there is none) is pkg/treatment/attribution's TestWatcherRefresh rows.
+func TestCheckTreatmentLocation(t *testing.T) {
+ for _, tc := range []struct {
+ name, description string
+ flag, env string
+ agent string
+ expected []string // substrings of the error; empty means start
+ }{
+ {"flag-unset", "positive: no -location and no LOCATION adopts the agent's certificate-bound location", "", "", "dc1", nil},
+ {"flag-equal", "positive: -location equal to the agent's starts", "dc1", "", "dc1", nil},
+ {"env-equal", "positive: LOCATION equal to the agent's starts", "", "dc1", "dc1", nil},
+ {"flag-differs", "negative: -location differing from the agent's refuses, naming both", "dc2", "", "dc1", []string{`"dc2"`, `"dc1"`}},
+ {"env-differs", "negative: LOCATION differing from the agent's refuses the same way; the flag alone is not what counts", "", "dc2", "dc1", []string{`"dc2"`, `"dc1"`}},
+ {"env-over-flag", "corner: LOCATION overrides -location, as it does for every record, so the override is what is compared", "dc1", "dc2", "dc1", []string{`"dc2"`}},
+ {"case", "boundary: labels are compared exactly; DC1 is not dc1", "DC1", "", "dc1", []string{`"DC1"`, `"dc1"`}},
+ } {
+ t.Run(tc.name, func(t *testing.T) {
+ if tc.env != "" {
+ t.Setenv("LOCATION", tc.env)
+ } else {
+ os.Unsetenv("LOCATION")
+ }
+ c := &xtcp_config.XtcpConfig{Location: tc.flag}
+ envOverrideLabeling(c, 0)
+ err := checkTreatmentLocation(c.Location, tc.agent)
+ if len(tc.expected) == 0 {
+ if err != nil {
+ t.Fatalf("%s: %v", tc.description, err)
+ }
+ return
+ }
+ if err == nil {
+ t.Fatalf("%s: expected an error", tc.description)
+ }
+ for _, want := range tc.expected {
+ if !strings.Contains(err.Error(), want) {
+ t.Fatalf("%s: error %q does not name %s", tc.description, err, want)
+ }
+ }
+ })
+ }
+}
+
+// Attribution mode installs a stamper fed from the journal directory and
+// SIGHUP re-reads it; stopping removes the feeder.
+func TestStartTreatmentsAttributionMode(t *testing.T) {
+ dir := t.TempDir()
+ now := time.Unix(1700000000, 0)
+ cubic := "cubic"
+ d := &treatment.DesiredState{AgentID: "host-1", Revision: 1, IssuedAt: now, Assignments: []treatment.Assignment{{ExperimentID: "trial-1", Generation: 1, Mode: treatment.ModeStable, Treatment: treatment.Treatment{ID: "cubic", Revision: 1, Destination: netip.MustParsePrefix("192.0.2.1/32"), Settings: treatment.TCPSettings{CongestionControl: &cubic}}}}}
+ write := func(revision uint64) {
+ d.Revision = revision
+ err := reconcile.Journal{Dir: dir}.WithLock(context.Background(), func(s *reconcile.State, save func() error) error {
+ *s = reconcile.State{AgentID: "host-1", Location: "dc1", BootID: "boot-1", Desired: d, Records: []reconcile.Record{{ApplicationRecord: treatment.ApplicationRecord{Assignment: d.Assignments[0], Status: treatment.ApplyVerified, AppliedAt: now}}}}
+ return save()
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+ write(1)
+ if treatmentStamper() != nil {
+ t.Fatal("stamper active before start")
+ }
+ stop, err := startTreatments(context.Background(), "", dir, "dc1")
+ if err != nil {
+ t.Fatal(err)
+ }
+ stamp := treatmentStamper()
+ if stamp == nil {
+ t.Fatal("attribution mode installed no stamper")
+ }
+ var st unix.Stat_t
+ if err := unix.Stat("/proc/self/ns/net", &st); err != nil {
+ t.Skip("cannot resolve own network namespace")
+ }
+ r := &flat.XtcpFlatRecord{Location: "dc1", NetnsInode: st.Ino, InetDiagMsgFamily: 2, InetDiagMsgSocketDestination: []byte{192, 0, 2, 1}, InetDiagCong: "cubic"}
+ deadline := time.Now().Add(5 * time.Second)
+ for stamp(r); r.TreatmentStateRevision != 1 && time.Now().Before(deadline); stamp(r) {
+ time.Sleep(10 * time.Millisecond)
+ }
+ if r.TreatmentStateRevision != 1 || r.AgentId != "host-1" || r.TreatmentAssignmentId != "trial-1" || !r.TreatmentAlgorithmExposed {
+ t.Fatalf("journal not attributed: %+v", r)
+ }
+ write(2)
+ reconcileTreatments()
+ for stamp(r); r.TreatmentStateRevision != 2 && time.Now().Before(deadline); stamp(r) {
+ time.Sleep(10 * time.Millisecond)
+ }
+ if r.TreatmentStateRevision != 2 {
+ t.Fatal("SIGHUP did not re-read the journal")
+ }
+ stop()
+ if treatmentStamper() != nil {
+ t.Fatal("stop left the feeder active")
+ }
+ if _, err := startTreatments(context.Background(), "", "", "dc1"); err != nil {
+ t.Fatal("no-mode start must succeed")
+ }
+}
diff --git a/cmd/xtcp2/xtcp2.go b/cmd/xtcp2/xtcp2.go
index 4d56205ed..53edfe198 100644
--- a/cmd/xtcp2/xtcp2.go
+++ b/cmd/xtcp2/xtcp2.go
@@ -253,32 +253,34 @@ var (
// short and lets the per-section helpers (printFlags, buildConfig,
// startProfile) take a single argument instead of 30 positional ones.
type mainFlags struct {
- nltimeout *uint64
- pollFrequency *time.Duration
- pollTimeout *time.Duration
- maxLoops *uint64
- netlinkers *uint
- nlmsgSeq *uint
- packetSize *uint64
- packetSizeMply *uint
- writeFiles *uint
- capturePath *string
- modulus *uint64
- marshal *string
- columns *string
- envelopeFlushBytes *uint
- envelopeFlushRows *uint
- kafkaCompression *string
- s3Endpoint *string
- s3Bucket *string
- s3Prefix *string
- s3AccessKey *string
- s3SecretKey *string
- s3Region *string
- s3SkipBucketProbe *bool
- s3AllowInsecure *bool
- s3CAFile *string
- s3ParquetFlushBytes *uint
+ treatmentConfig *string
+ treatmentAttribution *string
+ nltimeout *uint64
+ pollFrequency *time.Duration
+ pollTimeout *time.Duration
+ maxLoops *uint64
+ netlinkers *uint
+ nlmsgSeq *uint
+ packetSize *uint64
+ packetSizeMply *uint
+ writeFiles *uint
+ capturePath *string
+ modulus *uint64
+ marshal *string
+ columns *string
+ envelopeFlushBytes *uint
+ envelopeFlushRows *uint
+ kafkaCompression *string
+ s3Endpoint *string
+ s3Bucket *string
+ s3Prefix *string
+ s3AccessKey *string
+ s3SecretKey *string
+ s3Region *string
+ s3SkipBucketProbe *bool
+ s3AllowInsecure *bool
+ s3CAFile *string
+ s3ParquetFlushBytes *uint
pollJitterPct *uint
s3FlushInterval *time.Duration
@@ -444,6 +446,8 @@ func defaultDest() string {
// of all 92 are pinned by cmd/xtcp2/testdata/defineflags-golden.txt.
func defineFlags() *mainFlags {
f := &mainFlags{}
+ f.treatmentConfig = flag.String("treatmentConfig", "", "optional controller agent JSON config, running the treatment agent inside this daemon; needs a build with the treatment tag; route application requires enable_apply. Mutually exclusive with -treatmentAttribution")
+ f.treatmentAttribution = flag.String("treatmentAttribution", "", "optional journal directory of a standalone xtcp2-treatment-agent (its config's directory, default /var/lib/xtcp2/routes); this daemon only reads the snapshot and stamps treatment provenance onto records. Mutually exclusive with -treatmentConfig")
f.nltimeout = flag.Uint64("nltimeout", nltimeoutCst, "Netlink socket timeout in milliseconds. Zero(0) for no timeout")
f.pollFrequency = flag.Duration("frequency", pollFrequencyCst, "Poll frequency")
f.pollTimeout = flag.Duration("timeout", pollTimeoutCst, "Poll timeout per name space")
@@ -1098,7 +1102,7 @@ func runMain(ctx context.Context) int {
defer cancel()
complete := make(chan struct{}, signalChannelSizeCst)
- initSignalHandler(cancel, complete, linkMonitorHTTP.rebaseline)
+ initSignalHandler(cancel, complete, linkMonitorHTTP.rebaseline, reconcileTreatments)
f := defineFlags()
flag.Parse()
@@ -1128,6 +1132,12 @@ func runMain(ctx context.Context) int {
fmt.Fprintln(os.Stderr, "xtcp2: config validation failed:", err)
return exitUsage
}
+ if err := checkTreatmentFlags(*f.treatmentConfig, *f.treatmentAttribution); err != nil {
+ // A build without the agent, or both modes at once, is a property of
+ // the deployment that is identical on every host: fail loudly.
+ fmt.Fprintln(os.Stderr, "xtcp2:", err)
+ return exitUsage
+ }
specs, warnings, err := listeners.Resolve(c, readSecretFile)
for _, w := range warnings {
log.Printf("WARNING: %s", w)
@@ -1176,6 +1186,14 @@ func runMain(ctx context.Context) int {
return exitCodeFor(err)
}
+ // c.Location, not the flag: LOCATION from the environment counts too.
+ stopTreatments, err := startTreatments(runCtx, *f.treatmentConfig, *f.treatmentAttribution, c.Location)
+ if err != nil {
+ // Controller availability/configuration must not stop socket telemetry.
+ log.Printf("treatment agent unavailable: %v", err)
+ } else {
+ defer stopTreatments()
+ }
daemonRunner(runCtx, cancel, c, grpcLns)
closeGRPCListeners(grpcLns)
// The signal handler exits once complete is sent, so drain first.
@@ -1195,6 +1213,9 @@ func runMain(ctx context.Context) int {
// and run RunWithPoller until ctx cancels the WG.
func runDaemonDefault(ctx context.Context, cancel context.CancelFunc, c *xtcp_config.XtcpConfig, grpcLns []xtcp.GRPCListener) {
x := xtcp.NewXTCP(ctx, cancel, c)
+ if stamp := treatmentStamper(); stamp != nil {
+ x.SetTreatmentStamper(stamp)
+ }
x.SetGRPCListeners(grpcLns)
detach, err := linkMonitorHTTP.attach(x)
if err != nil {
@@ -1338,15 +1359,15 @@ func envWithoutKey(env []string, key string) []string {
// goroutine, so a SIGTERM sent while flags are still being parsed takes the
// graceful path instead of Go's default, which exits at once. (Go drops a
// SIGUSR1 that arrives before any Notify; it never kills the process.)
-func initSignalHandler(cancel context.CancelFunc, complete <-chan struct{}, rebaseline func()) {
+func initSignalHandler(cancel context.CancelFunc, complete <-chan struct{}, rebaseline func(), reconcile ...func()) {
c := notifySignals()
- go awaitSignalAndShutdown(c, cancel, complete, cancelSleepTimeCst, true, rebaseline)
+ go awaitSignalAndShutdown(c, cancel, complete, cancelSleepTimeCst, true, rebaseline, reconcile...)
}
// notifySignals routes SIGINT, SIGTERM and SIGUSR1 to the returned channel.
func notifySignals() chan os.Signal {
c := make(chan os.Signal, signalChannelSizeCst)
- signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGUSR1)
+ signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGUSR1, syscall.SIGHUP)
return c
}
@@ -1363,12 +1384,20 @@ func awaitSignalAndShutdown(
timeout time.Duration,
doExit bool,
rebaseline func(),
+ reconcile ...func(),
) {
// SIGUSR1 never shuts down; a nil rebaseline ignores it.
- for sig := <-sigs; sig == syscall.SIGUSR1; sig = <-sigs {
- if rebaseline != nil {
+ for sig := <-sigs; sig == syscall.SIGUSR1 || sig == syscall.SIGHUP; sig = <-sigs {
+ if sig == syscall.SIGUSR1 && rebaseline != nil {
rebaseline()
}
+ if sig == syscall.SIGHUP {
+ for _, fn := range reconcile {
+ if fn != nil {
+ fn()
+ }
+ }
+ }
}
log.Printf("Signal caught, closing application")
cancel()
diff --git a/cmd/xtcp2/xtcp2_flags_helpers_test.go b/cmd/xtcp2/xtcp2_flags_helpers_test.go
index a33f39ccd..71c129f4f 100644
--- a/cmd/xtcp2/xtcp2_flags_helpers_test.go
+++ b/cmd/xtcp2/xtcp2_flags_helpers_test.go
@@ -89,7 +89,7 @@ const (
// mainFlags field must be a registered flag and every registered flag must
// have a field. A flag added without a field, or a field that stops being
// registered, is the drift this file exists to notice.
- mainFlagsFieldCountCst = 128
+ mainFlagsFieldCountCst = 130 // + treatmentConfig (embedded agent) and treatmentAttribution (journal reader)
printFlagsGoldenCst = "testdata/printflags-golden.txt"
defineFlagsGoldenCst = "testdata/defineflags-golden.txt"
@@ -155,32 +155,34 @@ func populatedMainFlags() *mainFlags {
ms := func(v int) *time.Duration { d := time.Duration(v) * time.Millisecond; return &d }
return &mainFlags{
- nltimeout: u64(101),
- pollFrequency: ms(102),
- pollTimeout: ms(103),
- maxLoops: u64(104),
- netlinkers: u(105),
- nlmsgSeq: u(106),
- packetSize: u64(107),
- packetSizeMply: u(108),
- writeFiles: u(109),
- capturePath: s("capturePath-v"),
- modulus: u64(110),
- marshal: s("marshal-v"),
- columns: s("columns-v"),
- envelopeFlushBytes: u(111),
- envelopeFlushRows: u(112),
- kafkaCompression: s("kafkaCompression-v"),
- s3Endpoint: s("s3Endpoint-v"),
- s3Bucket: s("s3Bucket-v"),
- s3Prefix: s("s3Prefix-v"),
- s3AccessKey: s(fakeS3AccessSentinelCst),
- s3SecretKey: s(fakeS3SigningSentinelCst),
- s3Region: s("s3Region-v"),
- s3SkipBucketProbe: b(true),
- s3AllowInsecure: b(true),
- s3CAFile: s("s3CAFile-v"),
- s3ParquetFlushBytes: u(113),
+ treatmentConfig: s("/etc/xtcp2/test-treatment-config.json"),
+ treatmentAttribution: s("/var/lib/xtcp2/test-treatment-routes"),
+ nltimeout: u64(101),
+ pollFrequency: ms(102),
+ pollTimeout: ms(103),
+ maxLoops: u64(104),
+ netlinkers: u(105),
+ nlmsgSeq: u(106),
+ packetSize: u64(107),
+ packetSizeMply: u(108),
+ writeFiles: u(109),
+ capturePath: s("capturePath-v"),
+ modulus: u64(110),
+ marshal: s("marshal-v"),
+ columns: s("columns-v"),
+ envelopeFlushBytes: u(111),
+ envelopeFlushRows: u(112),
+ kafkaCompression: s("kafkaCompression-v"),
+ s3Endpoint: s("s3Endpoint-v"),
+ s3Bucket: s("s3Bucket-v"),
+ s3Prefix: s("s3Prefix-v"),
+ s3AccessKey: s(fakeS3AccessSentinelCst),
+ s3SecretKey: s(fakeS3SigningSentinelCst),
+ s3Region: s("s3Region-v"),
+ s3SkipBucketProbe: b(true),
+ s3AllowInsecure: b(true),
+ s3CAFile: s("s3CAFile-v"),
+ s3ParquetFlushBytes: u(113),
pollJitterPct: u(114),
s3FlushInterval: ms(115),
diff --git a/docs/README.md b/docs/README.md
index 9bcd20b99..13c8efc29 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,6 +1,6 @@
# xtcp2 documentation
-This is the documentation hub for **xtcp2**, a Linux network observability suite for TCP socket diagnostics, network-state inspection, Ethernet/RDMA port health, and enriched telemetry. If you just want the feature summary or to build and run it, start with the [top-level README](../README.md). This hub explains *how it works* and links to detailed feature documentation.
+This is the documentation hub for **xtcp2**, a Linux network observability suite for TCP socket diagnostics, network-state inspection, Ethernet/RDMA port health, and enriched telemetry. xtcp2 observes by default and changes nothing on the host; the one exception is the opt-in, human-reviewed [TCP route treatment controller](tcp-controller.md), which an operator has to deploy and enable and whose actuator only ever touches routes it owns. If you just want the feature summary or to build and run it, start with the [top-level README](../README.md). This hub explains *how it works* and links to detailed feature documentation.
## Table of contents
@@ -30,6 +30,14 @@ This project is a complete rewrite of the original [xtcp](https://github.com/ran
Each feature has a dedicated document with its own table of contents and component breakdown.
+### [Reviewed TCP route treatments](tcp-controller.md)
+
+An optional controller uses ClickHouse evidence and PostgreSQL state to propose
+destination-specific TCP treatments, run human-reviewed canaries, and withdraw
+failed trials. Agents persist protobuf-text journals and reconcile owned routes;
+an independent watchdog enforces trial expiry. Route application is disabled by
+default. The controller has its own mTLS listener and operator client.
+
### [Netlink TCP collection](netlink/collection.md)
Reads TCP socket state from the kernel via the `inet_diag` netlink interface. A registry of 13 attribute deserializers (`info`, `cong`, `meminfo`, `skmem`, `bbr`, `dctcp`, `vegas`, `tos`, `tc`, `shut`, `classid`, `cgroup`, `sockopt`) decodes each socket's attributes into a flat record; you choose which to decode with `-deserializers`.
@@ -44,7 +52,7 @@ Combines `/proc//ns/net` discovery with bind-mounted namespaces under `/run
### [Ethernet/RDMA statistics and link health](../cmd/go-link-monitor/README.md)
-`go-link-monitor` collects netdev, ethtool driver/PHY, RDMA, and host protocol statistics. It tracks a persisted up-link baseline, speed/duplex/width, flaps, errors, and collector health, exposing a sparse problem summary and detailed Prometheus category/interface paths. It is also [embedded in xtcp2 and enabled by default](design-linkmonitor-in-xtcp2.md). Optional read-only [goip HTTP paths](../cmd/go-link-monitor/IP-ARGV-PATHS-DESIGN.md) support remote inspection. Alerting systems consume the signals; the monitor does not perform remediation.
+`go-link-monitor` collects netdev, ethtool driver/PHY, RDMA, and host protocol statistics. It tracks a persisted up-link baseline, speed/duplex/width, flaps, errors, and collector health, exposing a sparse problem summary and detailed Prometheus category/interface paths. It is also [embedded in xtcp2 and enabled by default](design-linkmonitor-in-xtcp2.md). Optional read-only [goip HTTP paths](../cmd/go-link-monitor/IP-ARGV-PATHS-DESIGN.md) support remote inspection. Alerting systems consume the signals; the monitor does not perform remediation. The only xtcp2 component that changes host state is the opt-in [treatment controller](tcp-controller.md), and it does so only after operator review.
### [Metadata enrichment](design-metadata-enrichment.md)
diff --git a/docs/benchmarks/tcp-controller/after.txt b/docs/benchmarks/tcp-controller/after.txt
new file mode 100644
index 000000000..76591e3ea
--- /dev/null
+++ b/docs/benchmarks/tcp-controller/after.txt
@@ -0,0 +1,90 @@
+goos: linux
+goarch: amd64
+pkg: github.com/randomizedcoder/xtcp2/pkg/treatment
+cpu: AMD Ryzen Threadripper PRO 3945WX 12-Cores
+BenchmarkFleetEvidence/Validate/100-24 15618 22979 ns/op 3500 B/op 3 allocs/op
+BenchmarkFleetEvidence/Validate/100-24 15716 22848 ns/op 3500 B/op 3 allocs/op
+BenchmarkFleetEvidence/Validate/100-24 15710 23008 ns/op 3500 B/op 3 allocs/op
+BenchmarkFleetEvidence/Safety/100-24 10000 32458 ns/op 10499 B/op 9 allocs/op
+BenchmarkFleetEvidence/Safety/100-24 10000 32123 ns/op 10499 B/op 9 allocs/op
+BenchmarkFleetEvidence/Safety/100-24 8842 34691 ns/op 10499 B/op 9 allocs/op
+BenchmarkFleetEvidence/Evaluate/100-24 6694 59860 ns/op 12998 B/op 15 allocs/op
+BenchmarkFleetEvidence/Evaluate/100-24 5942 61621 ns/op 12998 B/op 15 allocs/op
+BenchmarkFleetEvidence/Evaluate/100-24 6594 58432 ns/op 12998 B/op 15 allocs/op
+BenchmarkFleetEvidence/Validate/1000-24 1266 274384 ns/op 54673 B/op 5 allocs/op
+BenchmarkFleetEvidence/Validate/1000-24 1401 272011 ns/op 54674 B/op 5 allocs/op
+BenchmarkFleetEvidence/Validate/1000-24 1309 286308 ns/op 54676 B/op 5 allocs/op
+BenchmarkFleetEvidence/Safety/1000-24 1011 364178 ns/op 164025 B/op 15 allocs/op
+BenchmarkFleetEvidence/Safety/1000-24 1039 357506 ns/op 164026 B/op 15 allocs/op
+BenchmarkFleetEvidence/Safety/1000-24 936 354571 ns/op 164032 B/op 15 allocs/op
+BenchmarkFleetEvidence/Evaluate/1000-24 859 419171 ns/op 188634 B/op 21 allocs/op
+BenchmarkFleetEvidence/Evaluate/1000-24 858 415074 ns/op 188635 B/op 21 allocs/op
+BenchmarkFleetEvidence/Evaluate/1000-24 885 418120 ns/op 188635 B/op 21 allocs/op
+BenchmarkFleetEvidence/Validate/10000-24 132 2717192 ns/op 437242 B/op 33 allocs/op
+BenchmarkFleetEvidence/Validate/10000-24 133 2698856 ns/op 437236 B/op 33 allocs/op
+BenchmarkFleetEvidence/Validate/10000-24 129 2779841 ns/op 437253 B/op 33 allocs/op
+BenchmarkFleetEvidence/Safety/10000-24 91 4062183 ns/op 1311648 B/op 99 allocs/op
+BenchmarkFleetEvidence/Safety/10000-24 98 4027768 ns/op 1311664 B/op 99 allocs/op
+BenchmarkFleetEvidence/Safety/10000-24 93 4071155 ns/op 1311647 B/op 99 allocs/op
+BenchmarkFleetEvidence/Evaluate/10000-24 80 4641976 ns/op 1557547 B/op 106 allocs/op
+BenchmarkFleetEvidence/Evaluate/10000-24 86 4598309 ns/op 1557578 B/op 106 allocs/op
+BenchmarkFleetEvidence/Evaluate/10000-24 86 4536670 ns/op 1557578 B/op 106 allocs/op
+PASS
+ok github.com/randomizedcoder/xtcp2/pkg/treatment 9.859s
+goos: linux
+goarch: amd64
+pkg: github.com/randomizedcoder/xtcp2/pkg/treatment/agent
+cpu: AMD Ryzen Threadripper PRO 3945WX 12-Cores
+BenchmarkStamp/routes=1/match=true-24 10065704 35.36 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=1/match=true-24 10003551 35.31 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=1/match=true-24 9843661 35.27 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=1/match=false-24 17960965 19.45 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=1/match=false-24 18524896 19.36 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=1/match=false-24 18477922 19.34 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=100/match=true-24 10218624 34.42 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=100/match=true-24 10379076 34.12 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=100/match=true-24 10432940 34.46 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=100/match=false-24 16772404 21.60 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=100/match=false-24 16571926 21.36 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=100/match=false-24 16649026 21.53 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=4096/match=true-24 10058797 36.59 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=4096/match=true-24 9458271 37.78 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=4096/match=true-24 9816648 36.13 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=4096/match=false-24 15207280 23.66 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=4096/match=false-24 14958738 23.85 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=4096/match=false-24 15022704 24.07 ns/op 0 B/op 0 allocs/op
+BenchmarkPublish/1-24 1435836 250.2 ns/op 360 B/op 3 allocs/op
+BenchmarkPublish/1-24 1423382 252.5 ns/op 360 B/op 3 allocs/op
+BenchmarkPublish/1-24 1395063 257.7 ns/op 360 B/op 3 allocs/op
+BenchmarkPublish/100-24 26905 13185 ns/op 9392 B/op 12 allocs/op
+BenchmarkPublish/100-24 27619 13046 ns/op 9392 B/op 12 allocs/op
+BenchmarkPublish/100-24 28101 12880 ns/op 9392 B/op 12 allocs/op
+BenchmarkPublish/4096-24 511 687413 ns/op 652373 B/op 49 allocs/op
+BenchmarkPublish/4096-24 523 690086 ns/op 652352 B/op 49 allocs/op
+BenchmarkPublish/4096-24 523 680441 ns/op 652352 B/op 49 allocs/op
+PASS
+ok github.com/randomizedcoder/xtcp2/pkg/treatment/agent 9.879s
+goos: linux
+goarch: amd64
+pkg: github.com/randomizedcoder/xtcp2/pkg/treatment/controller
+cpu: AMD Ryzen Threadripper PRO 3945WX 12-Cores
+BenchmarkNotificationFleet/100-24 26011 13993 ns/op 0 B/op 0 allocs/op
+BenchmarkNotificationFleet/100-24 26156 13745 ns/op 0 B/op 0 allocs/op
+BenchmarkNotificationFleet/100-24 25989 13681 ns/op 0 B/op 0 allocs/op
+BenchmarkNotificationFleet/1000-24 2479 141174 ns/op 43 B/op 0 allocs/op
+BenchmarkNotificationFleet/1000-24 2698 139311 ns/op 40 B/op 0 allocs/op
+BenchmarkNotificationFleet/1000-24 2552 138808 ns/op 42 B/op 0 allocs/op
+BenchmarkNotificationFleet/10000-24 248 1463026 ns/op 3522 B/op 0 allocs/op
+BenchmarkNotificationFleet/10000-24 244 1508009 ns/op 3579 B/op 0 allocs/op
+BenchmarkNotificationFleet/10000-24 178 2066908 ns/op 4907 B/op 0 allocs/op
+PASS
+ok github.com/randomizedcoder/xtcp2/pkg/treatment/controller 3.349s
+goos: linux
+goarch: amd64
+pkg: github.com/randomizedcoder/xtcp2/internal/goip
+cpu: AMD Ryzen Threadripper PRO 3945WX 12-Cores
+BenchmarkTreatmentPlanRoute-24 371434 917.5 ns/op 756 B/op 10 allocs/op
+BenchmarkTreatmentPlanRoute-24 402067 1501 ns/op 756 B/op 10 allocs/op
+BenchmarkTreatmentPlanRoute-24 346634 1116 ns/op 756 B/op 10 allocs/op
+PASS
+ok github.com/randomizedcoder/xtcp2/internal/goip 1.344s
diff --git a/docs/benchmarks/tcp-controller/before.txt b/docs/benchmarks/tcp-controller/before.txt
new file mode 100644
index 000000000..8f170ecf1
--- /dev/null
+++ b/docs/benchmarks/tcp-controller/before.txt
@@ -0,0 +1,72 @@
+goos: linux
+goarch: amd64
+pkg: github.com/randomizedcoder/xtcp2/pkg/treatment
+cpu: AMD Ryzen Threadripper PRO 3945WX 12-Cores
+BenchmarkFleetEvidence/Validate/100-24 12350 28991 ns/op 6703 B/op 9 allocs/op
+BenchmarkFleetEvidence/Validate/100-24 12961 28114 ns/op 6703 B/op 9 allocs/op
+BenchmarkFleetEvidence/Validate/100-24 12174 29855 ns/op 6704 B/op 9 allocs/op
+BenchmarkFleetEvidence/Safety/100-24 8277 47316 ns/op 20110 B/op 27 allocs/op
+BenchmarkFleetEvidence/Safety/100-24 7406 47468 ns/op 20111 B/op 27 allocs/op
+BenchmarkFleetEvidence/Safety/100-24 7742 46274 ns/op 20110 B/op 27 allocs/op
+BenchmarkFleetEvidence/Evaluate/100-24 4461 74733 ns/op 25877 B/op 51 allocs/op
+BenchmarkFleetEvidence/Evaluate/100-24 4440 73695 ns/op 25877 B/op 51 allocs/op
+BenchmarkFleetEvidence/Evaluate/100-24 4948 80849 ns/op 25879 B/op 51 allocs/op
+BenchmarkFleetEvidence/Validate/1000-24 1104 318501 ns/op 108898 B/op 20 allocs/op
+BenchmarkFleetEvidence/Validate/1000-24 1156 322431 ns/op 108898 B/op 20 allocs/op
+BenchmarkFleetEvidence/Validate/1000-24 1144 324561 ns/op 108896 B/op 20 allocs/op
+BenchmarkFleetEvidence/Safety/1000-24 643 562375 ns/op 326712 B/op 60 allocs/op
+BenchmarkFleetEvidence/Safety/1000-24 640 558050 ns/op 326706 B/op 60 allocs/op
+BenchmarkFleetEvidence/Safety/1000-24 656 552844 ns/op 326704 B/op 60 allocs/op
+BenchmarkFleetEvidence/Evaluate/1000-24 544 666721 ns/op 375536 B/op 102 allocs/op
+BenchmarkFleetEvidence/Evaluate/1000-24 556 640359 ns/op 375537 B/op 102 allocs/op
+BenchmarkFleetEvidence/Evaluate/1000-24 561 672998 ns/op 375549 B/op 102 allocs/op
+BenchmarkFleetEvidence/Validate/10000-24 100 3383939 ns/op 874017 B/op 79 allocs/op
+BenchmarkFleetEvidence/Validate/10000-24 100 3430797 ns/op 874017 B/op 79 allocs/op
+BenchmarkFleetEvidence/Validate/10000-24 100 3399253 ns/op 874004 B/op 79 allocs/op
+BenchmarkFleetEvidence/Safety/10000-24 69 5898750 ns/op 2621959 B/op 239 allocs/op
+BenchmarkFleetEvidence/Safety/10000-24 67 5839557 ns/op 2621904 B/op 239 allocs/op
+BenchmarkFleetEvidence/Safety/10000-24 69 6979109 ns/op 2621891 B/op 239 allocs/op
+BenchmarkFleetEvidence/Evaluate/10000-24 57 7482686 ns/op 3391637 B/op 317 allocs/op
+BenchmarkFleetEvidence/Evaluate/10000-24 57 7597250 ns/op 3391704 B/op 317 allocs/op
+BenchmarkFleetEvidence/Evaluate/10000-24 48 7077716 ns/op 3391590 B/op 317 allocs/op
+PASS
+ok github.com/randomizedcoder/xtcp2/pkg/treatment 10.133s
+goos: linux
+goarch: amd64
+pkg: github.com/randomizedcoder/xtcp2/pkg/treatment/agent
+cpu: AMD Ryzen Threadripper PRO 3945WX 12-Cores
+BenchmarkStamp/routes=1/match=true-24 10195333 34.84 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=1/match=true-24 9735492 33.69 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=1/match=true-24 10685922 33.50 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=1/match=false-24 16964254 18.90 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=1/match=false-24 18726810 19.14 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=1/match=false-24 19162561 23.49 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=100/match=true-24 10103883 35.42 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=100/match=true-24 10498788 33.87 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=100/match=true-24 10056416 35.61 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=100/match=false-24 16187679 21.65 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=100/match=false-24 14169679 26.08 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=100/match=false-24 13624152 22.02 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=4096/match=true-24 10212040 35.09 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=4096/match=true-24 10251448 34.39 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=4096/match=true-24 9137064 39.17 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=4096/match=false-24 15448830 22.74 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=4096/match=false-24 14805097 26.18 ns/op 0 B/op 0 allocs/op
+BenchmarkStamp/routes=4096/match=false-24 14845970 24.18 ns/op 0 B/op 0 allocs/op
+PASS
+ok github.com/randomizedcoder/xtcp2/pkg/treatment/agent 6.472s
+goos: linux
+goarch: amd64
+pkg: github.com/randomizedcoder/xtcp2/pkg/treatment/controller
+cpu: AMD Ryzen Threadripper PRO 3945WX 12-Cores
+BenchmarkNotificationFleet/100-24 26456 13532 ns/op 0 B/op 0 allocs/op
+BenchmarkNotificationFleet/100-24 26252 13689 ns/op 0 B/op 0 allocs/op
+BenchmarkNotificationFleet/100-24 26132 13644 ns/op 0 B/op 0 allocs/op
+BenchmarkNotificationFleet/1000-24 2419 148186 ns/op 45 B/op 0 allocs/op
+BenchmarkNotificationFleet/1000-24 2572 161498 ns/op 42 B/op 0 allocs/op
+BenchmarkNotificationFleet/1000-24 2372 146506 ns/op 45 B/op 0 allocs/op
+BenchmarkNotificationFleet/10000-24 226 1923710 ns/op 3864 B/op 0 allocs/op
+BenchmarkNotificationFleet/10000-24 243 1516583 ns/op 3594 B/op 0 allocs/op
+BenchmarkNotificationFleet/10000-24 190 1779397 ns/op 4597 B/op 0 allocs/op
+PASS
+ok github.com/randomizedcoder/xtcp2/pkg/treatment/controller 3.460s
diff --git a/docs/benchmarks/tcp-controller/postgres-indexes.txt b/docs/benchmarks/tcp-controller/postgres-indexes.txt
new file mode 100644
index 000000000..c05e54e6e
--- /dev/null
+++ b/docs/benchmarks/tcp-controller/postgres-indexes.txt
@@ -0,0 +1,46 @@
+# nix build .#bench-tcp-controller-postgres-indexes
+# postgres (PostgreSQL) 18.6, go version go1.27.3 linux/amd64
+=== RUN TestPostgresExperimentQueryIndexes
+=== RUN TestPostgresExperimentQueryIndexes/old-destination
+ postgres_test.go:174: 100005 experiments: unindexed 22.274 ms, indexed 0.021 ms (xtcp_treatment_experiments_destination)
+=== RUN TestPostgresExperimentQueryIndexes/absent-destination
+ postgres_test.go:174: 100005 experiments: unindexed 21.472 ms, indexed 0.020 ms (xtcp_treatment_experiments_destination)
+=== RUN TestPostgresExperimentQueryIndexes/active-budget
+ postgres_test.go:174: 100005 experiments: unindexed 18.080 ms, indexed 0.016 ms (xtcp_treatment_experiments_destination)
+=== RUN TestPostgresExperimentQueryIndexes/idle-budget
+ postgres_test.go:174: 100005 experiments: unindexed 25.644 ms, indexed 0.020 ms (xtcp_treatment_experiments_location_status)
+--- PASS: TestPostgresExperimentQueryIndexes (1.19s)
+ --- PASS: TestPostgresExperimentQueryIndexes/old-destination (0.02s)
+ --- PASS: TestPostgresExperimentQueryIndexes/absent-destination (0.02s)
+ --- PASS: TestPostgresExperimentQueryIndexes/active-budget (0.02s)
+ --- PASS: TestPostgresExperimentQueryIndexes/idle-budget (0.03s)
+=== RUN TestPostgresExperimentQueryIndexes
+=== RUN TestPostgresExperimentQueryIndexes/old-destination
+ postgres_test.go:174: 100005 experiments: unindexed 22.485 ms, indexed 0.023 ms (xtcp_treatment_experiments_destination)
+=== RUN TestPostgresExperimentQueryIndexes/absent-destination
+ postgres_test.go:174: 100005 experiments: unindexed 19.972 ms, indexed 0.019 ms (xtcp_treatment_experiments_destination)
+=== RUN TestPostgresExperimentQueryIndexes/active-budget
+ postgres_test.go:174: 100005 experiments: unindexed 18.097 ms, indexed 0.019 ms (xtcp_treatment_experiments_destination)
+=== RUN TestPostgresExperimentQueryIndexes/idle-budget
+ postgres_test.go:174: 100005 experiments: unindexed 24.627 ms, indexed 0.020 ms (xtcp_treatment_experiments_location_status)
+--- PASS: TestPostgresExperimentQueryIndexes (1.18s)
+ --- PASS: TestPostgresExperimentQueryIndexes/old-destination (0.02s)
+ --- PASS: TestPostgresExperimentQueryIndexes/absent-destination (0.02s)
+ --- PASS: TestPostgresExperimentQueryIndexes/active-budget (0.02s)
+ --- PASS: TestPostgresExperimentQueryIndexes/idle-budget (0.03s)
+=== RUN TestPostgresExperimentQueryIndexes
+=== RUN TestPostgresExperimentQueryIndexes/old-destination
+ postgres_test.go:174: 100005 experiments: unindexed 20.488 ms, indexed 0.023 ms (xtcp_treatment_experiments_destination)
+=== RUN TestPostgresExperimentQueryIndexes/absent-destination
+ postgres_test.go:174: 100005 experiments: unindexed 19.139 ms, indexed 0.016 ms (xtcp_treatment_experiments_destination)
+=== RUN TestPostgresExperimentQueryIndexes/active-budget
+ postgres_test.go:174: 100005 experiments: unindexed 16.850 ms, indexed 0.016 ms (xtcp_treatment_experiments_destination)
+=== RUN TestPostgresExperimentQueryIndexes/idle-budget
+ postgres_test.go:174: 100005 experiments: unindexed 24.134 ms, indexed 0.019 ms (xtcp_treatment_experiments_location_status)
+--- PASS: TestPostgresExperimentQueryIndexes (1.20s)
+ --- PASS: TestPostgresExperimentQueryIndexes/old-destination (0.02s)
+ --- PASS: TestPostgresExperimentQueryIndexes/absent-destination (0.02s)
+ --- PASS: TestPostgresExperimentQueryIndexes/active-budget (0.02s)
+ --- PASS: TestPostgresExperimentQueryIndexes/idle-budget (0.03s)
+PASS
+ok github.com/randomizedcoder/xtcp2/pkg/treatment/controller/store/postgres 3.566s
diff --git a/docs/build-flavors.md b/docs/build-flavors.md
index 3ffcfd95c..edc466944 100644
--- a/docs/build-flavors.md
+++ b/docs/build-flavors.md
@@ -259,9 +259,13 @@ The absent ones are published as `0` deliberately: a binary built without the ta
| `enrich.go`, `enrich_core.go` | (none) | always |
| `enrich_asn.go` | `//go:build enrich_asn` | only with `-tags enrich_asn` |
| `enrich_locality.go` | `//go:build enrich_locality` | only with `-tags enrich_locality` |
+| `cmd/xtcp2/treatments.go` (journal reader, `-treatmentAttribution`) | (none) | always |
+| `cmd/xtcp2/treatments_embedded.go` (embedded agent, `-treatmentConfig`) | `//go:build treatment` | only with `-tags treatment` |
Each tagged file calls `RegisterDestination(scheme, factory)` / `RegisterEnricher(name, factory)` from its `init()`. With the tag off the file isn't compiled, so the registry simply lacks that entry — no `!tag` stub file is needed. Both registries panic on a duplicate registration, which can only mean two files claimed the same tag.
+The treatment agent follows the same shape one level up, in `cmd/xtcp2`: the untagged file registers nothing, so `-treatmentConfig` is refused with a message naming the tag and the standalone alternative, while `-treatmentAttribution` (read a standalone `xtcp2-treatment-agent`'s journal, stamp provenance) is always compiled. `mkGoBinary`'s `treatment` knob defaults to "on for the full destination set, off for the slim flavors", so `xtcp2` / `xtcp2-all` embed the agent and `xtcp2-min` & co. pair with the standalone binary. `pkg/treatment/boundaries_test.go` walks `cmd/xtcp2` both ways and asserts the untagged closure never reaches the agent, the TLS identity code or the RPC proto. See [tcp-controller.md](tcp-controller.md#agent-deployment).
+
The rule that makes this work is that **no tagged package's type may appear on the `XTCP` struct**: `dest` is a `Destination` interface, and the two enrichers are `asnLookuper` / `localityEnricher` interfaces declared in untagged code. A single `*ipasn.Index`-typed field would re-link parquet-go into every flavor and silently undo the whole scheme.
The CLI distinguishes "unknown" from "known but not compiled in", for both:
@@ -287,6 +291,7 @@ The destination case is *unavailable* — the daemon has nowhere to send records
```sh
go test -tags 'enrich_asn enrich_locality' ./pkg/xtcp/ ./cmd/xtcp2/
go test -tags 'dest_s3parquet enrich_asn enrich_locality' ./pkg/xtcp/
+go test -tags treatment ./cmd/xtcp2/ ./cmd/xtcp2-treatment-agent/ # nix build .#test-focused-xtcp-treatment
```
`nix flake check` does this for you via `nix/tests/go-test-flavors.nix`, which has one target per flavor plus an `all` target. The registry and hot-path tests (`enrich_core_test.go`, `enrich_seam_test.go`) are deliberately **untagged** and derive their expectations from `EnricherCompiledIn`, so they assert correct behaviour in every flavor — including the builds that lack the code.
@@ -294,9 +299,9 @@ go test -tags 'dest_s3parquet enrich_asn enrich_locality' ./pkg/xtcp/
## Building outside Nix
```bash
-# Full xtcp2 (every destination + every enricher):
+# Full xtcp2 (every destination + every enricher + the embedded treatment agent):
CGO_ENABLED=0 go build \
- -tags "netgo,osusergo,dest_kafka,dest_nats,dest_nsq,dest_valkey,dest_s3parquet,enrich_asn,enrich_locality" \
+ -tags "netgo,osusergo,dest_kafka,dest_nats,dest_nsq,dest_valkey,dest_s3parquet,enrich_asn,enrich_locality,treatment" \
-ldflags "-s -w" -trimpath -o xtcp2 ./cmd/xtcp2
# Unix-domain-socket flavor (stdlib only, no enrichers):
diff --git a/docs/examples/controller-agent.json b/docs/examples/controller-agent.json
new file mode 100644
index 000000000..0a76b77a5
--- /dev/null
+++ b/docs/examples/controller-agent.json
@@ -0,0 +1,15 @@
+{
+ "agent_id": "host-001",
+ "location": "dc-example",
+ "controller": "controller.example.net:9443",
+ "server_name": "controller.example.net",
+ "certificate": "/etc/xtcp2/agent.crt",
+ "private_key": "/etc/xtcp2/agent.key",
+ "ca": "/etc/xtcp2/controller-ca.crt",
+ "directory": "/var/lib/xtcp2/routes",
+ "enable_apply": false,
+ "table": 10002,
+ "rule_priority": 30000,
+ "protocol": 242,
+ "protected_prefixes": ["192.0.2.0/24", "2001:db8:ffff::/48"]
+}
diff --git a/docs/examples/controller-discovery.json b/docs/examples/controller-discovery.json
new file mode 100644
index 000000000..53877fc95
--- /dev/null
+++ b/docs/examples/controller-discovery.json
@@ -0,0 +1,23 @@
+[
+ {
+ "id": "nearby-cubic",
+ "location": "dc-example",
+ "congestion_control": "cubic",
+ "rto_min_ms": 5,
+ "quick_ack": true,
+ "initial_congestion_window": 100,
+ "initial_receive_window": 100,
+ "minimum_rtt_ms": 0,
+ "maximum_rtt_ms": 2,
+ "minimum_retransmission_ratio": 0,
+ "prefixes": ["10.0.0.0/8"]
+ },
+ {
+ "id": "distant-loss-bbr",
+ "location": "dc-example",
+ "congestion_control": "bbr",
+ "minimum_rtt_ms": 150,
+ "maximum_rtt_ms": 2000,
+ "minimum_retransmission_ratio": 0.001
+ }
+]
diff --git a/docs/examples/xtcp2-treatment-agent.service b/docs/examples/xtcp2-treatment-agent.service
new file mode 100644
index 000000000..bf6983142
--- /dev/null
+++ b/docs/examples/xtcp2-treatment-agent.service
@@ -0,0 +1,21 @@
+[Unit]
+Description=xtcp2 TCP route treatment agent (standalone)
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+Type=simple
+User=root
+ExecStart=/usr/local/bin/xtcp2-treatment-agent -config=/etc/xtcp2/controller-agent.json
+# Check in and reconcile now; the embedded agent does the same on SIGHUP.
+ExecReload=/bin/kill -HUP $MAINPID
+Restart=always
+RestartSec=2s
+StateDirectory=xtcp2
+StateDirectoryMode=0750
+AmbientCapabilities=CAP_NET_ADMIN CAP_SYS_PTRACE
+CapabilityBoundingSet=CAP_NET_ADMIN CAP_SYS_PTRACE
+NoNewPrivileges=true
+
+[Install]
+WantedBy=multi-user.target
diff --git a/docs/examples/xtcp2-treatment-watchdog.service b/docs/examples/xtcp2-treatment-watchdog.service
new file mode 100644
index 000000000..ca847fff4
--- /dev/null
+++ b/docs/examples/xtcp2-treatment-watchdog.service
@@ -0,0 +1,18 @@
+[Unit]
+Description=xtcp2 independent TCP treatment lease watchdog
+After=local-fs.target
+
+[Service]
+Type=simple
+User=root
+ExecStart=/usr/local/bin/xtcp2-treatmentctl -mode=watchdog -config=/etc/xtcp2/controller-agent.json
+Restart=always
+RestartSec=2s
+StateDirectory=xtcp2
+StateDirectoryMode=0750
+AmbientCapabilities=CAP_NET_ADMIN CAP_SYS_PTRACE
+CapabilityBoundingSet=CAP_NET_ADMIN CAP_SYS_PTRACE
+NoNewPrivileges=true
+
+[Install]
+WantedBy=multi-user.target
diff --git a/docs/integration-testing.md b/docs/integration-testing.md
index 38a36994d..179b98d83 100644
--- a/docs/integration-testing.md
+++ b/docs/integration-testing.md
@@ -8,6 +8,7 @@ A comprehensive Nix-driven setup that boots xtcp2 inside QEMU microvms alongside
- [Test surfaces at a glance](#test-surfaces-at-a-glance)
- [Quick start](#quick-start)
- [Architecture](#architecture)
+- [TCP controller integration](#tcp-controller-integration)
- [Microvm flavors](#microvm-flavors)
- [Components](#components)
- [xtcp2 daemon](#xtcp2-daemon)
@@ -27,6 +28,109 @@ A comprehensive Nix-driven setup that boots xtcp2 inside QEMU microvms alongside
- [Typical workflows](#typical-workflows)
- [Troubleshooting](#troubleshooting)
+## TCP controller integration
+
+Run `nix run path:.#test-tcp-controller-vm -- --accel=auto` for a fresh
+controller test, or `nix build path:.#checks.x86_64-linux.vm-tcp-controller -L`
+for the cached KVM check. It also participates in `vm-all` and `integration-all`.
+The configuration is in `nix/tests/tcp-controller/`; the test driver is Go in
+`tools/tcp-controller-integration/`, using the generated controller gRPC client.
+
+Six agent guests run the existing `tcp_client` load generator and real xtcp2
+service. A seventh guest runs `tcp_server`, PostgreSQL, ClickHouse and the
+controller. Six hosts satisfy the production requirement for four treated hosts
+and two controls. Each agent has 32 connections to each of two destination
+addresses. `tc netem` adds 5 ms and 80 ms of outbound delay respectively;
+management traffic stays unshaped. UNIX datagram links connect the guests to a
+bridge inside the controller guest, without host networking privileges or
+external network access. Allow approximately 9 GiB for guest memory, plus QEMU
+overhead. KVM is preferred; `--accel=tcg` is available for software emulation.
+
+The Go driver verifies measured RTT separation in ClickHouse, reviewed nearby
+route application on one host (`congctl cubic`, `rto_min 5ms`, `quickack 1`,
+`initcwnd 100`, `initrwnd 100`), existing Reno versus newly exposed CUBIC sockets,
+durable prototext state across daemon/controller restarts, local and fleet holds,
+and reviewed expansion to two hosts. It then raises one treated host's delay to
+180 ms and requires automatic rollback from measured harm. Finally, it stops
+the controller and one agent, advances that isolated guest's clock past the
+unchanged one-hour trial lease, and requires the independent watchdog to remove
+the route without resurrecting it after restart/reconnection. Main routes and
+the system default congestion algorithm must remain unchanged.
+
+This is a functional safety test, not a benchmark claiming that CUBIC improves
+the synthetic workload. Observation intervals are shortened to 20 seconds using
+the existing policy configuration; production authorization and lease behavior
+are unchanged. The test exercises the direct protobuf/HTTP ingest path, not the
+Kafka pipeline or automatic candidate discovery. It does not test reboot or
+completion of a fleet-wide rollout.
+
+Evidence is retained under `~/.cache/xtcp2-vm/tcp-controller//` (or
+`$XDG_CACHE_HOME`): controller and agent serial logs, RTT measurements, agent
+journals/routes/prototext state, a PostgreSQL dump and a bounded recent telemetry
+sample. Runtime-generated credentials remain inside the disposable guests.
+The unauthenticated fixture HTTP endpoint is test-only and confined to the
+isolated guest network; production controller communication uses mTLS.
+
+For repeated changes over time, run the Go-driven soak variant:
+
+```sh
+nix run path:.#test-tcp-controller-soak-vm -- --cycles=3 --interval=3m
+```
+
+The default takes roughly 30 minutes: three cycles of three RTT phases, followed
+by a cooldown check. `--cycles=2..6` and `--interval=3m|4m|5m` control the run;
+`--accel` and `--keep` work as in the short test. The optional cached check is
+`checks.x86_64-linux.vm-tcp-controller-soak`. It is excluded from `vm-all` and
+included in `integration-all -- --soak` as a fixed-cycle run; the aggregate's
+`--duration` applies to its other soak runners.
+
+Each cycle sends the six agents to a fresh destination and changes its netem
+delay from 180 ms to 5 ms and back to 180 ms. High RTT must produce no nearby
+candidate. Low RTT must cause the **controller's scheduled discovery** to propose
+a new experiment with the same five nearby route settings. The test verifies
+that discovery has applied no routes,
+then acts as an authenticated test operator to approve the first canary. It
+checks all five installed kernel metrics and actual CUBIC socket exposure,
+and rejects any unapproved expansion. When
+RTT rises again, an active trial must roll back automatically based on measured
+harm; the driver never requests a rollback. The aggressive profile can also
+cross a safety guard during the low-RTT phase. Such an early withdrawal is
+accepted only with valid harmful evidence, observed canary exposure and verified
+route removal. It is recorded separately as `low_rtt_safety_rollback`, and the
+test continues to require that the route stays withdrawn. At least one cycle
+must exercise an injected-latency rollback with high RTT on the canary; early
+withdrawals cannot substitute for that coverage. The summary reports both counts.
+
+This variant uses a one-minute discovery interval and lookback, leaving the
+production defaults (30 minutes and one hour), review requirements, rollout
+timing and 24-hour destination cooldown intact. Its discovery template explicitly
+sets `maximum_rtt_increase=1.0` (100%): the production 10% guard allows only about
+0.5 ms at this fixture's low RTT and can trigger before netem changes. The wider
+test tolerance still requires automatic rollback for the 5 ms to 180 ms jump.
+Production templates keep the 10% default unless explicitly configured otherwise.
+The retransmission guard remains unchanged at 0.005 (0.5 percentage points).
+Fresh destinations allow each
+cycle to discover a new candidate without bypassing that cooldown. The final
+phase revisits the first destination at low RTT and verifies that it stays
+withdrawn. New load connections reset TCP_INFO's lifetime minimum RTT at the
+start of discovery phases; the regression phase retains the treated sockets.
+The fixed 80 ms reference traffic continues throughout.
+
+Evidence under `~/.cache/xtcp2-vm/tcp-controller-soak//artifacts/`
+includes `soak-events.jsonl` (RTT changes, proposals, explicit test approvals and
+automatic rollbacks), `soak-rtt.csv` (per-host RTT and algorithm/exposure samples
+every 15 seconds), and `soak-summary.json`. These are written during the run so
+they can be inspected while the guests are running. The controller still
+requires an operator to approve treatment application; this test does not make
+it an autonomous optimizer or demonstrate that CUBIC outperforms Reno.
+
+To view the decision timeline for a run:
+
+```sh
+jq -r '[.at, .event, .destination, (.experiment.id // "")] | @tsv' \
+ ~/.cache/xtcp2-vm/tcp-controller-soak//artifacts/soak-events.jsonl
+```
+
## Introduction
This is the heavy integration-testing side of xtcp2. Unit tests live in `pkg/*/_test.go` and are run by `go test ./...`; the work documented here exercises code paths that only fire under a real Linux kernel, real namespaces, real network sockets, a real Kafka broker, and so on.
diff --git a/docs/netlink/README.md b/docs/netlink/README.md
index 49f8ba50f..18030ac1b 100644
--- a/docs/netlink/README.md
+++ b/docs/netlink/README.md
@@ -59,8 +59,12 @@ nix run .#microvm-x86_64-goip-parity # the live tier; needs /dev/kvm, not r
## Two constraints worth knowing up front
-> **No live kernel writes today.** Inspection sends read requests; implemented
-> write verbs serialize dry-run requests for validation rather than applying them.
+> **One live kernel write path, opted in.** Inspection sends read requests;
+> the CLI's write verbs serialize dry-run requests for validation rather than
+> applying them. The single exception is the treatment route actuator in
+> [`internal/goip/actuate`](../../internal/goip/actuate), which installs
+> host routes in a private table behind an explicit `enable_apply` setting
+> ([tcp-controller.md](../tcp-controller.md#supported-routes-and-tcp-semantics)).
The original expansion plan's read-only constraint was narrowed as dry-run
write support landed. The first paths were `ip route` and `ip link` — see
@@ -76,7 +80,13 @@ since its G3-T03, `RTM_NEWNEXTHOP` and `RTM_DELNEXTHOP`, and, since its G3-T04,
`RTM_NEWADDRLABEL` and `RTM_DELADDRLABEL`, and, since its G3-T05,
`RTM_SETNEIGHTBL` and `RTM_SETSTATS`, and, since its G3-T06,
`RTM_NEWLINKPROP` and `RTM_DELLINKPROP`. Requests built there are written to a file for
-comparison and never sent; no automated path applies a write to a live kernel.
+comparison and never sent by the CLI. The one path that does send is
+`goip.NetlinkSource.ApplyRouteControl`, reached only by the treatment
+actuator: it admits acknowledged `RTM_NEWROUTE`/`RTM_DELROUTE`/`RTM_NEWRULE`/
+`RTM_DELRULE` requests built from `xtcpnl.RouteWrite` and `xtcpnl.RuleWrite`,
+never from argv, and the actuator checks ownership and reads back after
+every mutation.
+
Both dry runs have since landed on that gate: `goip link
add|set|change|replace|delete` and `goip route
add|change|replace|prepend|append|test|delete` build `ip`'s request
@@ -90,7 +100,8 @@ now do too, and refuse with
Supported families have expanded beyond those initial paths; the
[coverage tracker](coverage-status.md) records current supported operations.
Coverage of parsing and dry-run requests does not establish live mutation
-support. Future action-taking is described in the
+support; the actuator's two route forms and one rule are the whole of it.
+Broader action-taking is described in the
[network-control gRPC design](../design-network-control-grpc.md), which is a
proposal rather than an available service. Comparisons with libraries that
configure the kernel must preserve that distinction.
diff --git a/docs/socket-analysis.md b/docs/socket-analysis.md
index 94547c5fd..7abe320df 100644
--- a/docs/socket-analysis.md
+++ b/docs/socket-analysis.md
@@ -4,6 +4,10 @@ This guide is for a **data / analytics team** turning xtcp2's per-socket TCP tel
Read [parquet-format.md](parquet-format.md) first for how to load the data and what the columns mean; this doc is the analysis companion.
+To turn those observations into reviewed canaries, see the
+[TCP treatment controller](tcp-controller.md), including destination scope,
+actual socket exposure, persistence, and emergency withdrawal.
+
## Table of contents
- [The RTT-band mental model](#the-rtt-band-mental-model)
diff --git a/docs/status-tcp-controller.md b/docs/status-tcp-controller.md
new file mode 100644
index 000000000..c500e6043
--- /dev/null
+++ b/docs/status-tcp-controller.md
@@ -0,0 +1,308 @@
+# TCP route treatment controller: rework status
+
+Tracking document for the architecture-review rework of the treatment control
+plane (PR #282, branch `feat/tcp-route-controller`). The plan is the review
+itself: 12 work items applied as separate commits so the PR history reads as the
+review being addressed. Items are listed in execution order.
+
+| # | Item | State | Commit |
+| --- | --- | --- | --- |
+| 1 | `pkg/treatment/identity` extracted; import-boundary test | done | 7dc118ca |
+| 2 | `pkg/treatment` split by audience (`reconcile`, `experiment`, `agent`) | done | 2ca932f8 |
+| 8 | proto moved to `xtcp_treatment/v1` with `buf.validate` rules | done | 460164b1 |
+| 3 | explicit state machine; `Outcome` enum | done | 85b2cf59 |
+| 4 | repository ports, relational schema, pgx, domain types, `wire` | done | eae1d87d |
+| D1 | dual-mode agent, part 1: journal-specific proto, proto-free `reconcile`, `local`, `attribution`, watchdog off the agent | done | 6398338a |
+| D2 | dual-mode agent, part 2: `-treatmentAttribution` journal watcher, `treatment` build tag, `cmd/xtcp2-treatment-agent`, Nix and module wiring | done | 87321a63, fix 20f3a35a |
+| 5 | evidence port (`Source`, `CandidateSource`, `Warehouse`), ClickHouse as one adapter | done | caba9bc4 |
+| 6 | auth as interceptor with per-RPC role option | done | d7fefee4 |
+| 7 | typed `xtcpnl.RuleWrite`; backend to `internal/goip/actuate` | done | 3a2843b2 |
+| 9 | identity/location startup check | done | 9372e0bf |
+| 10 | blocking journal lock | done | 3478d9b3 |
+| 11 | scale: notification watermark, heartbeat split, leader lease | done | 91ccde4a |
+| 12 | docs: threat model, naming, SIGHUP, philosophy sentence | done | b6df3de9 |
+| L | lint: comprehensive tier clean on the new code; `lint-baseline` gate passes | done | c3981ff1 |
+| F1 | follow-up: `Experiments.List` and `Get` in a fixed number of statements | done | 75093584, lint 5ccc671e |
+| F2 | follow-up: help smoke for the four treatment binaries and `zstd-probe` | done | 926c2c74 |
+| F3 | follow-up: reproducible index timings (`bench-tcp-controller-postgres-indexes`) | done | 30a21cdd |
+| F4 | follow-up: generated coverage table (`coverage-table.md` from the unit target) | done | 30a21cdd |
+| F5 | follow-up: evidence bound to `(agent_id, boot_id, collection_id)` sessions | done | c2bf7d2d, cap 12cc5f6c, lint 87261db8 |
+
+Dual-mode agent (library + `cmd/xtcp2-treatment-agent` + `treatment` build tag
+in `cmd/xtcp2`, with an `attribution` journal reader for the untagged daemon)
+is decided and lands after item 4 as D1 and D2; the watchdog stays a separate
+process.
+
+## D1 notes
+
+- The journal is `xtcp_treatment_journal.v1.Journal` (prototext), generated
+ into its own Go package so the host side never links the RPC stubs. Field
+ numbers and names differ from the old `LocalState`; an old snapshot fails
+ closed with "invalid treatment journal". No deployed journals exist yet.
+- `reconcile.State`/`reconcile.Record` are the host-side types; `Record`
+ embeds `treatment.ApplicationRecord` plus the kernel-local fields, so a
+ check-in (`State.Reports()`) cannot leak route bytes by construction.
+- `pkg/treatment/local` owns `Config`, `LoadConfig`, `HostIdentity` and the
+ goip adapter; `agent.Config` is an alias. The watchdog builds on `local`
+ and `reconcile` only.
+- `pkg/treatment/attribution` holds the exposure index and `Stamp`; the agent
+ publishes an index after every pass (identity-only before the first).
+
+## Item 4 notes
+
+- Domain types live in `pkg/treatment/model.go` and `enums.go`; the generated
+ proto is wire-only and converted in `pkg/treatment/wire`.
+- `Experiment.UpdatedAt` is a domain field (proto `updated_at = 14`) stamped by
+ the controller clock, so the discovery cooldown is testable on both stores.
+- Evidence is stored once (`xtcp_treatment_evidence` + `_hosts`) with a content
+ digest; re-using an evidence ID for different content or another experiment
+ is `store.ErrEvidenceConflict`. The digest hashes timestamps at microsecond
+ precision because that is what `timestamptz` keeps.
+- Every handler test runs against the in-memory store and, with
+ `XTCP_CONTROLLER_TEST_DSN`, against PostgreSQL; both stores pass the shared
+ conformance suite in `store/storetest`.
+
+## D2 notes
+
+- `cmd/xtcp2/treatments.go` is always built and owns `-treatmentAttribution`
+ (an `attribution.Watcher` over the journal directory) and the fatal checks;
+ `treatments_embedded.go` (`//go:build treatment`) registers the embedded
+ agent for `-treatmentConfig`. Both flags exist in every build so the flag
+ golden is flavor-neutral; the untagged daemon refuses `-treatmentConfig`.
+- `mkGoBinary` gained `treatment ? null`: fat builds (full destination set)
+ embed the agent, slim flavors do not. `xtcp2-treatment-agent` joined
+ `binaryNames`; `test-focused-xtcp-treatment` runs the tagged daemon tests.
+- The NixOS module gained `treatments.mode` (`embedded` | `standalone`),
+ `agentPackage` and `journalDirectory`; standalone adds the
+ `xtcp2-treatment-agent` service. The VM fixture runs standalone with
+ `xtcp2-min`, which exercises the journal watcher end to end.
+- The boundary walk now honours build tags (`go/build.Context.MatchFile`), so
+ it asserts the untagged daemon never reaches the agent, identity or the
+ RPC proto, and the tagged one does reach the agent but never the controller.
+- The first VM run of 87321a63 failed at the fresh six-host baseline with
+ `invalid evidence population`: in standalone mode the slim daemon had no
+ `-location`, so every record shipped `location=""` and the ClickHouse
+ analysis (which filters by location) saw no hosts. The watcher now adopts
+ the journal's location when the daemon has none and still keeps its own
+ when one is set (logged once either way). The rerun pinned to 20f3a35a
+ passed (seven sentinels).
+
+## Item 5 notes
+
+- `pkg/treatment/controller/evidence` holds the ports and the controller's
+ window policy (`WindowFor`, `SettleDelay`, `MaxWindow`); the controller
+ root no longer contains SQL text, an HTTP client or the word ClickHouse.
+- `evidence/clickhouse` is the adapter: `analysis.sql` moved there unchanged,
+ the discovery query became `discovery.sql`, both embedded. `Candidates`
+ returns an error (not a skipped row) when a destination does not decode,
+ because that means the table is not the schema the adapter was written for.
+- Handler tests use `fixedEvidence` and `fakeWarehouse`; the adapter keeps
+ the transport, evidence and (new) candidate contract tables plus the
+ real-SQL `TestClickHouseAnalysisCounterDeltas` the Nix harness greps for.
+- `artifact_sha256` is documented as the digest of the unarchived response.
+ Archiving responses to the S3 destination remains a possible follow-up.
+
+## Item 6 notes
+
+- `identity.Policy` (method -> role) with `UnaryInterceptor`/`StreamInterceptor`
+ and `Authorize`; identity resolved once per call and stored in the context
+ (`WithIdentity`/`FromContext`). `identity.Agent`/`Operator` prefer that
+ identity and fall back to the peer, so handler-level tests and direct calls
+ are unchanged. Agent unary requests are additionally checked generically:
+ `GetAgentId()` must be the caller and a non-empty `GetLocation()` must be
+ the certificate's.
+- `controller.RolePolicy()` derives the table from the proto option over
+ both service descriptors; `controller.GRPCOptions()` is what main passes
+ to `grpc.NewServer` (interceptors + message bounds). A method without a
+ role option is simply absent from the policy and refused for everyone.
+- Tests: identity interceptor tables (unary, stream, resolve precedence),
+ the mTLS bufconn test now runs through the interceptors and checks an
+ undeclared method fails closed, and `TestEveryMethodAgainstEveryRole`
+ tries every served method with each of three callers.
+
+## Item 7 notes
+
+- `xtcpnl.RuleWrite` (+ `RuleAttr*`, `EncodeFibRuleHdr`,
+ `BuildRuleWriteRequest`) is `RouteWrite`'s counterpart for `RTM_NEWRULE`/
+ `RTM_DELRULE`. `Table` is a u32: 1..255 goes in the header byte, above
+ that the header is `RT_TABLE_UNSPEC` and `FRA_TABLE` is written first,
+ which is also what the argv `table` keyword does at its position.
+- `internal/goip/actuate` holds the backend (`actuate.Backend`,
+ `RouteTreatment`, `TCPRouteSettings`), split into `actuate.go`, `rules.go`
+ and `routes.go`; `rule()` builds from fields and refuses out-of-range
+ table/priority/protocol before encoding. `NetlinkSource.ApplyRouteControl`
+ stays in `internal/goip/route_control.go` because it needs the socket's
+ unexported descriptor; it is the only live-write entry point.
+- Tests: `TestBuildRuleWriteRequest` (hand-written hex) and
+ `TestRuleWriteReadsBack` in `pkg/xtcpnl`; `TestRuleWriteTypedMatchesArgv`
+ in `internal/goip` compares typed and `parseRuleWriteArgs` bytes for the
+ treatment rule, v6, delete, table 255, /32, /128 and `not`;
+ `TestTreatmentRuleRequest` in `actuate` reads the owned rule back and
+ covers the refused ranges. The goip hermetic-import test pins the new
+ package in goip's closure; the Nix harness and docs point at
+ `./internal/goip/actuate`.
+
+## Item 9 notes
+
+- One rule for both modes, in `cmd/xtcp2/treatments.go`: an empty daemon
+ location adopts the agent's (logged once); a set one must equal the
+ agent's certificate-bound location. Embedded, `checkTreatmentLocation`
+ runs right after `agent.LoadConfig` and before any credential is read,
+ so a mismatch is the first line in the log and the agent does not start
+ (telemetry continues). Standalone, the attribution watcher already kept
+ the daemon's label and adopted the journal's when there was none
+ (20f3a35a); unchanged.
+- main now passes `c.Location` (after `envOverrideLabeling`) to
+ `startTreatments`, so `LOCATION` from the environment counts in both
+ modes; it used to pass the raw flag.
+- `agent.New` names both sides when config and certificate disagree.
+- Tests: `TestCheckTreatmentLocation` (flag/env/equal/differs/override/case,
+ through `envOverrideLabeling`), tagged
+ `TestEmbeddedTreatmentAgentLocation` (unset and equal reach the
+ credential error, differs is refused before it), and the existing
+ attribution watcher rows for the standalone side.
+
+## Item 10 notes
+
+- `Journal.WithLock(ctx, fn)` waits for the flock (non-blocking attempts with
+ a 1 to 50 ms doubling delay, since a blocking flock cannot be interrupted by
+ a context) and returns `ErrJournalBusy` wrapping `ctx.Err()` at the
+ deadline, before reading the snapshot. Under the lock it sweeps
+ `.pending-*` files, which only a writer that died mid-write can leave.
+ `Reconciler.Run` passes its ctx; `SuspendLocal` gained a ctx and
+ `treatmentctl suspend|resume` bounds it at 30 s. `status` was already
+ lock-free and stays so; no `LOCK_NB` entry point is needed.
+- Tests: `TestJournalLockWaits` (uncontended, contended-waits, ctx-deadline,
+ zero-budget), `TestJournalLockFreeReadUnderLock`, and
+ `TestJournalLockHolderDies`, which kills a child test process holding the
+ lock with a half-written temp file and checks the lock is free, the
+ snapshot intact and the temp file swept.
+
+## Item 11 notes
+
+- Notification scan: `Agents.DesiredRevisions` (full scan) became
+ `Agents.DesiredSince(ctx, since) []DesiredRevision{AgentID, Revision,
+ UpdatedAt}` with `>=` on `desired_updated_at`, ordered by stamp then ID.
+ `SaveDesired` and `Enroll` stamp with `clock_timestamp()` rather than
+ `now()`: `now()` is transaction start, which precedes the advisory lock, so
+ a stamp could sort before a row that committed earlier. With every stamping
+ writer under the mutation lock, stamps commit in order and the watermark
+ (newest stamp less a one-second margin, store clock only) cannot skip a
+ row; the margin covers a store clock step under a second and the hub drops
+ the repeats it causes. A step larger than the margin leaves that revision
+ to the agent's next check-in, which always returns desired state on a
+ revision mismatch. `TestNotifyWatermark` walks a scanner through first
+ scan, change, no change, equal stamp, scan failure, future stamp and
+ behind-watermark steps.
+- Heartbeat split: `report_digest` column on `xtcp_treatment_agents` holds a
+ SHA-256 over the algorithm list and every record in insert-column form.
+ `Observe` does one `UPDATE ... FROM (... FOR UPDATE) RETURNING
+ o.report_digest` and rewrites the child rows only when the digest changed.
+ `TestPostgresObserveRewritesOnlyChangedReports` compares row `xmin` values
+ across identical, heartbeat-only, status, timestamp, order, algorithm and
+ dropped-record reports.
+- Leader lease: `Store.Lease(ctx, name, fn) (held bool, err error)`.
+ Postgres takes `pg_try_advisory_lock(fnv64a(name))` on a dedicated
+ `db.Conn`, unlocks after `fn` with a bounded context, and discards the
+ connection if the unlock fails so a pooled connection never carries the
+ lock. Memory is a try-lock map outside the Tx snapshot.
+ `Server.Housekeep` runs `Maintain` and, when due, `Discover` under the
+ `housekeeping` lease; the controller main loop logs leader transitions
+ and advances its discovery cadence whether or not it held the lease.
+ Conformance rows: free, held-elsewhere, released-on-error,
+ independent-names, cancelled-context; `TestHousekeepLease` covers the
+ controller side.
+- The schema is pre-release, so `report_digest` is added to the `CREATE
+ TABLE` rather than through an `ALTER TABLE ... ADD COLUMN IF NOT EXISTS`.
+
+## Item 12 notes
+
+- `docs/tcp-controller.md` gained "Trust boundaries and threat model"
+ (principal table, defence in depth on the route, the evidence boundary:
+ host-stamped agent ID and location over an unauthenticated telemetry
+ pipeline, what bounds it today, what is not done) and "Names and surfaces"
+ (`treatment` for the feature, `controller` for the server role, `route`
+ for the kernel object; why `xtcp2-treatmentctl` is not part of `xtcp2ctl`;
+ the three configuration surfaces). The naming decision is to keep the
+ current binary names; no renames.
+- SIGHUP: documented as "reconcile now" only, in both daemon modes and the
+ standalone agent; the daemon has no admin RPC yet, so the signal stays
+ until the network-control admin API exists. `xtcp2-treatmentctl
+ -mode=reconcile` is the controller-free full pass.
+- `docs/README.md`: the hub intro and the link-monitor paragraph now say that
+ xtcp2 observes by default and that the treatment controller is the one
+ opt-in, operator-reviewed component that changes host state.
+
+## Lint notes
+
+- The comprehensive tier went from 107 findings to zero on the treatment
+ packages, the four binaries, `internal/goip/actuate` and the integration
+ tool, with no `//nolint`, no exclusions and no threshold changes. Long
+ functions (`reconcile.Run`, `Maintain`, `Control`, `Evaluate`, `Plan`, the
+ controller `main`) were split into named steps with unchanged behavior;
+ close, rollback and unlock errors are now joined into the returned error.
+- The ClickHouse SQL test finds `clickhouse` on `PATH` (the unit check adds
+ it to `nativeBuildInputs`) instead of `XTCP_CLICKHOUSE_TEST_BINARY`.
+
+## Follow-up notes (F1-F5)
+
+- F1: `loadMany` reads experiment rows, cohorts and phases with
+ `id = ANY($1)`, then every referenced evidence document and its hosts in
+ two more statements; `List` adds the ID lookup. `TestPostgresListStatements`
+ pins List at six statements and Get at five whatever the population, using
+ `pgtest.OpenCounting` (a pgx query tracer) rather than a hook in the store.
+- F2: `ipmeta-bootstrap` was also missing from `cmdNames` but exits 1 on
+ `-help` (its `ContinueOnError` flag set returns `flag.ErrHelp` as an error),
+ so it stays out; see TODO.
+- F3: the index timings come from the Nix PostgreSQL 18.6 fixture: median
+ 22.27 ms without indexes, 0.023 ms with them, for an old destination's
+ cooldown lookup. The fixture setup is shared with the unit and race targets.
+- F4: per-package coverage, no `-coverpkg`, so `pkg/treatment` reads 56.0%:
+ its enum, `Clone` and `Equal` methods are exercised from other packages.
+- F5: the agent owns a per-process nonce, writes it into the journal header
+ on its first pass after starting (`Reconciler.CollectionID`; a reconciler
+ without one, the watchdog, keeps the header's), and reports it as
+ `Capabilities.collection_id`, which is now required. `Agents.Observe`
+ upserts the session and refreshes `last_seen` at most every five minutes;
+ `Agents.Sessions` returns sessions overlapping a window and housekeeping
+ prunes those older than eight days. `Sessions` returns at most
+ `MaxSessionsPerAgent` (8) per agent, the most recently seen, so an enrolled
+ host that rotates its nonce on every check-in unbinds only its own older
+ records instead of pushing the window past `evidence.MaxSessions` and
+ failing evidence for its whole cohort (raised by the commit security
+ review, fixed in the follow-up commit). Every evidence window (analyze,
+ maintenance, discovery baseline, and the VM driver's own baseline) carries
+ the population's sessions widened by ten minutes; `analysis.sql`
+ (`tcp-host-deltas-v2-bound`) measures only bound sockets and returns
+ `unbound_sockets` per host. Discovery keeps only enrolled candidates and
+ skips a candidate with fewer than three. The evidence digest hashes
+ `unbound_sockets` only when non-zero, so evidence stored before the column
+ keeps its digest. Schema additions are `ADD COLUMN IF NOT EXISTS`. The VM
+ test gains `TCP_CONTROLLER_BINDING_PASS`: the driver copies a cohort host's
+ recent records under a fake boot and nonce and requires `Analyze` to count
+ them as unbound; the safety analysis that follows runs with them present. The run at 87261db8 passed all eight sentinels; in the
+ binding evidence the spoofed host kept its 32 bound sockets and reported 32
+ unbound, and the other five hosts reported none.
+- Proto regeneration: `regen-protos` now emits protoc-gen-go v1.36.12 and a
+ newer protoc for C++, while the committed output for the other protos is
+ older, so only the two treatment protos' generated files were committed and
+ the drift in the rest was reverted.
+
+## TODO
+
+- The watchdog and `pkg/treatment/local` still link gRPC, through
+ `pkg/xtcpnl` -> `gen/go/xtcp_flat_record`, whose Go package carries that
+ proto's gRPC and gateway stubs. Generating the flat record's service stubs
+ into a separate package would let the boundary test forbid gRPC for every
+ goip user; `reconcile` is already gRPC-free. Boundary rule carries the TODO.
+ Needs the service in its own `.proto` with a separate `go_package` (a buf
+ `PACKAGE_SAME_GO_PACKAGE` exception keeps the wire method names) and a
+ networked `regen-protos`.
+- Evidence windows travel as ClickHouse URL parameters. At 10,000 agents the
+ `agents` and `sessions` arrays approach ClickHouse's default 1 MiB
+ `http_max_uri_size`; move them to external data in the request body before
+ fleets that large.
+- `ipmeta-bootstrap -help` exits 1; return 0 on `flag.ErrHelp` and add it to
+ the help smoke list.
+- Regenerate all protos with the pinned generators in one commit so the
+ committed `gen/` matches `regen-protos` again.
diff --git a/docs/tcp-controller-testing.md b/docs/tcp-controller-testing.md
new file mode 100644
index 000000000..b3589dd86
--- /dev/null
+++ b/docs/tcp-controller-testing.md
@@ -0,0 +1,137 @@
+# TCP controller test and benchmark audit
+
+Audit date: 2026-10-25. All test drivers and benchmarks are Go. Nix provisions
+fixtures; no Python driver is involved.
+
+## Reproduce
+
+```sh
+nix build path:.#test-tcp-controller-unit --no-link --print-out-paths
+nix build path:.#test-tcp-controller-race --no-link --print-out-paths
+nix build path:.#bench-tcp-controller --no-link --print-out-paths
+```
+
+The first two targets are also flake checks, `tcp-controller-unit` and
+`tcp-controller-race`. Their implementation is in
+[`nix/tests/tcp-controller/quality.nix`](../nix/tests/tcp-controller/quality.nix).
+They create a disposable PostgreSQL cluster using only a Unix socket and run
+ClickHouse locally. They require the database tests to pass rather than silently
+skip. No host routes are changed. Logs and coverage are retained in the output
+store directory; benchmarks produce `benchmarks.txt`.
+
+The race target runs the feature suite and route-planning tests three times.
+The benchmark target runs five one-second samples per case. Benchmark times are
+observations, not CI thresholds: shared-machine load makes timing assertions
+unreliable. Allocation counts are reported with `-benchmem`.
+
+For fast iteration without database fixtures:
+
+```sh
+go test -ldflags=-checklinkname=0 ./pkg/treatment/... ./tools/tcp-controller-integration
+CGO_ENABLED=1 go test -race -ldflags=-checklinkname=0 -count=10 \
+ -run 'Concurrent|Notification|JournalConcurrent|AgentRun' ./pkg/treatment/...
+go test -ldflags=-checklinkname=0 -run '^$' -bench . -benchmem ./pkg/treatment/...
+```
+
+Without `XTCP_CONTROLLER_TEST_DSN`, direct Go commands skip the PostgreSQL
+tests; without a `clickhouse` binary on `PATH` they skip the ClickHouse SQL
+test. The Nix targets supply both automatically.
+
+## Coverage and test contracts
+
+New contract tables carry a description and expected outcome: an error substring,
+gRPC/HTTP status, decision outcome, or explicit state/boolean values. Every case
+gets a fresh fixture. Coverage includes positive, negative, boundary and corner
+cases; it is not based only on happy-path workflows.
+
+| Area | Cases and assertions |
+| --- | --- |
+| Validation | Nil inputs, identifier length/characters, IPv4/IPv6 host scope, DCTCP/ECN prerequisites, explicit false versus absent metrics, inclusive RTO/window limits, duplicate identities/destinations, predecessor scope, stable/trial leases, 4,096 assignments and 10,000 hosts, NaN/infinite/negative measurements, timestamp validity, provenance and policy limits. |
+| Decisions | Every evaluation outcome, observation/freshness/clock-skew boundaries, minimum samples, missing hosts/exposure, treated and control harm, small cohorts, full-fleet safety, reviewed transitions, input immutability and exact RTT guard boundaries. |
+| Persistence and reconciliation | Intent before mutation, crash recovery, stale/conflicting revisions and generations, expiry at the exact deadline, predecessor restoration, holds/tombstones, failed plan/install/verify/remove/enable, recovery after failure, corrupt/oversized journals, symlink rejection and competing writer exclusion. |
+| Agent | Config defaults and malformed input, attribution versus actual algorithm exposure, IPv4/IPv6 and padded addresses, namespace separation, expiry and holds, immutable snapshots, concurrent publish/stamp/state reads, wake coalescing, connected/offline cancellation and identity inspection failure. |
+| Controller | mTLS role and enrollment boundaries, authenticated status/readiness, desired-state watch cancellation, notification coalescing/reconnects, HTTP failures/body closure/size limits, SQL counter deltas/resets, real transaction/review races, durable holds, discovery ASN/prefix filters and cooldown across controller restart. |
+| Route planning | Opt-in and private resource bounds, unsupported forwarding attributes, IPv6 encoding, explicit ECN/quickack enable/disable, preservation of unrelated metrics/locks, complete nearby profile and baseline immutability. |
+
+The table below is generated, not hand-collected:
+`nix build .#test-tcp-controller-unit` writes it to `result/coverage-table.md`
+from the unit run's `go test -cover` lines (PostgreSQL and ClickHouse fixtures
+enabled, no skips), and `result/coverage.txt` holds the per-function figures.
+`internal/goip/actuate` runs only its `TestTreatment*` tests there. The race
+target (`test-tcp-controller-race`) runs the same packages three times under
+`-race` and reports no coverage.
+
+| Package | Statements covered |
+| --- | ---: |
+| `pkg/treatment` | 56.0% |
+| `pkg/treatment/agent` | 62.2% |
+| `pkg/treatment/attribution` | 88.1% |
+| `pkg/treatment/controller` | 74.4% |
+| `pkg/treatment/controller/evidence` | 100.0% |
+| `pkg/treatment/controller/evidence/clickhouse` | 93.9% |
+| `pkg/treatment/controller/store/memory` | 95.9% |
+| `pkg/treatment/controller/store/postgres` | 85.0% |
+| `pkg/treatment/experiment` | 93.8% |
+| `pkg/treatment/identity` | 90.5% |
+| `pkg/treatment/local` | 70.5% |
+| `pkg/treatment/reconcile` | 87.2% |
+| `pkg/treatment/wire` | 86.2% |
+| `tools/tcp-controller-integration` | 4.0% |
+| `internal/goip/actuate` | 22.1% |
+
+`HealthyEvidence` and the treatment, TCP-settings, policy, evidence, proposal
+and report validators reach 100% statement coverage; `Evaluate` 94.7%,
+`ValidateDesired` 91.7%, socket stamping 100%, discovery 89.4%, the agent's
+`Run` 97.4%, the reconciler's `Run` 85.0% and the attribution watcher's `Run`
+84.8%. `pkg/treatment` reads lower than before the split because coverage is per
+package (no `-coverpkg`): its enum, `Clone` and `Equal` methods are exercised
+by the `wire`, store and controller tests, which do not count toward it.
+Statement coverage is not branch coverage or a proof of correctness.
+
+Remaining gaps include some filesystem/syscall error paths, live namespace
+inspection, TLS client construction, reconnect/backoff timing, and all
+combinations of controller database failures. Kernel route mutation and network
+behavior remain the responsibility of the existing disposable-namespace and
+seven-guest VM tests. The integration harness itself has low unit coverage
+(4.0%); most of its code only executes inside those VMs. This audit did not rerun
+the 30-minute soak; the previous three-cycle soak passed before these changes.
+
+The new RTT boundary regression exposed floating-point cancellation: `5.5/5-1`
+can be slightly greater than `0.1`. Safety checks now compute the relative
+change from the difference; evaluation uses `Log1p` and compares in log space.
+Tests accept exactly 10% and reject a measurable increase above it, including
+fleet-size cases. Policy limits themselves are unchanged.
+
+## Benchmark review
+
+Host: AMD Ryzen Threadripper PRO 3945WX, Linux/amd64, Go 1.27.0. These are medians
+of three 300ms samples from the direct Go commands, not the separate Nix run.
+Raw results are retained in [before.txt](benchmarks/tcp-controller/before.txt) and
+[after.txt](benchmarks/tcp-controller/after.txt). The later run includes additional
+snapshot-publication and route-planning benchmarks that had no earlier baseline.
+
+| Operation, 10,000 hosts | Before | After | Bytes/op before → after | Allocs/op before → after |
+| --- | ---: | ---: | ---: | ---: |
+| Validate evidence | 3.40 ms | 2.72 ms | 874,017 → 437,242 | 79 → 33 |
+| Fast safety gate | 5.90 ms | 4.06 ms | 2,621,904 → 1,311,648 | 239 → 99 |
+| Evaluate experiment | 7.48 ms | 4.60 ms | 3,391,637 → 1,557,578 | 317 → 106 |
+
+The straightforward improvement was reserving map and slice capacity from known
+population sizes. Evaluation time fell about 39% and allocated bytes about 54%
+in these samples. There are no new caches, synchronization or retained mutable
+state. Tests exercise the same decision contracts before and after allocation
+changes.
+
+The per-socket hot path was already cheap: with 4,096 routes, a matched stamp
+measured 36.6ns and a miss 23.9ns, both zero allocations. Snapshot rebuilding at
+4,096 routes measured 0.69ms and 652KB; it occurs during reconciliation rather
+than per socket. Full-profile route planning measured 1.12µs and 756 bytes per
+operation. Notification benchmarks cover complete 100/1,000/10,000-host fanout,
+including coalescing for slow readers. Their first publication initializes the
+revision map, so reported bytes/op include that amortized startup cost.
+
+No additional optimization was justified for stamping or route encoding. The
+controller microbenchmarks exclude database/network latency and cannot establish
+fleet-wide throughput. Future scaling work should measure ClickHouse queries,
+PostgreSQL transaction contention and journal fsync latency under realistic
+fleet traffic before adding complexity to these in-memory paths.
diff --git a/docs/tcp-controller.md b/docs/tcp-controller.md
new file mode 100644
index 000000000..e4c571719
--- /dev/null
+++ b/docs/tcp-controller.md
@@ -0,0 +1,745 @@
+# Reviewed TCP route treatments
+
+xtcp2 can now opt into a separate controller that proposes TCP route treatments,
+rolls them out after human review, and withdraws failed trials. Ordinary xtcp2
+collection and the goip CLI retain their existing behavior. The agent runs
+either inside xtcp2 (`-treatmentConfig`, a build with the `treatment` tag) or
+as the standalone `xtcp2-treatment-agent` beside an xtcp2 that only reads its
+journal (`-treatmentAttribution`); see [Agent deployment](#agent-deployment).
+Route application requires `enable_apply: true` in the agent configuration in
+either arrangement.
+
+## Components and authority
+
+```mermaid
+flowchart LR
+ D[xtcp2 socket collection] --> K[ClickHouse telemetry]
+ K --> A[Candidate discovery and evidence queries]
+ A --> C[xtcp2-controller]
+ H[Human operator via mTLS] --> C
+ C <--> P[(PostgreSQL experiments, assignments, holds, audit)]
+ C -->|revision notification| D
+ D -->|check-in and observed state| C
+ D --> J[Atomic protobuf-text journal]
+ J --> R[goip actuator, internal/goip/actuate]
+ R --> L[Owned Linux routes and TCP lookup rules]
+ W[Independent local lease watchdog] --> J
+```
+
+The implementation lives under [pkg/treatment](../pkg/treatment), split by
+audience so that each binary links only the half of the contract it needs, with
+a typed [protobuf contract](../proto/xtcp_treatment/v1/) (`xtcp_treatment.v1`: `treatment.proto` types, `agent.proto`, `operator.proto`) and a separate
+[journal file format](../proto/xtcp_treatment_journal/v1/journal.proto) (`xtcp_treatment_journal.v1`) that the host side reads and writes without the RPC stubs:
+
+| Package | Used by | Contents |
+| --- | --- | --- |
+| `pkg/treatment` | everyone | the domain model (`Treatment`, `Experiment`, `Evidence`, `DesiredState`, enums), limits and validators; proto-free |
+| `pkg/treatment/wire` | gRPC boundary | domain ↔ generated proto conversion; `Parse*` fails closed on unknown enums and invalid timestamps |
+| `pkg/treatment/identity` | agent, controller, tools | SPIFFE URI identity, mTLS configuration, gRPC peer resolution, `Policy` interceptors that resolve the caller once per call |
+| `pkg/treatment/reconcile` | agent, watchdog | intent journal (`State`, `Record`, the `xtcp_treatment_journal.v1` file format), reconciler, `Backend` interface, `Mode` (full or expiry-only); domain types only, no RPC proto, no gRPC |
+| `pkg/treatment/local` | agent, watchdog, `treatmentctl` | the shared `controller-agent.json` config and the goip-backed reconciler built from it; no TLS, no controller |
+| `internal/goip/actuate` | `local` | the route actuator: owned table, rule priority and protocol, baseline copy with TCP metrics, ownership and readback checks; requests come from `xtcpnl`'s typed `RouteWrite` and `RuleWrite` builders and reach the kernel only through `goip.NetlinkSource.ApplyRouteControl`, the one live-write path in goip |
+| `pkg/treatment/attribution` | `xtcp2`, agent | the exposure index built from a journal snapshot and the hot-path telemetry stamp; the same code serves the embedded agent and a telemetry-only daemon |
+| `pkg/treatment/experiment` | controller | evaluation statistics, cohort allocation, phase advancement, state machine; pure functions over domain types |
+| `pkg/treatment/agent` | `xtcp2`, agent binary | check-in loop, watch stream, capabilities, over `local` and `attribution`; a library with two front ends |
+| `pkg/treatment/controller` | `xtcp2-controller` | gRPC handlers, maintenance and discovery over the store and evidence ports |
+| `pkg/treatment/controller/store` | controller | repository interfaces (`Agents`, `Experiments`, `Evidence`, `Holds`, `Audit`, `Metrics`) and `Store.Tx` |
+| `pkg/treatment/controller/evidence` | controller | warehouse ports: `Source` (measure a `Window`), `CandidateSource` (scan a location), `Warehouse` (both); `WindowFor` is the controller's window policy |
+| `pkg/treatment/controller/evidence/clickhouse` | `xtcp2-controller` | the one warehouse adapter: `analysis.sql` and `discovery.sql` over the ClickHouse HTTP interface, parameterized, 8 MiB response cap |
+| `pkg/treatment/controller/store/postgres` | `xtcp2-controller` | the only package with SQL: relational schema, pgx through `database/sql`, advisory-lock transactions |
+| `pkg/treatment/controller/store/memory` | handler tests | map-backed store that passes the same conformance suite (`store/storetest`) |
+
+The generated protobuf types are wire-only. The controller works on the Go
+domain types and converts at the gRPC boundary; PostgreSQL holds a relational
+schema (one column per field, `cidr` destinations, evidence stored once and
+referenced by ID), so a proto field rename can never break SQL or an index. The
+only JSON column is the append-only audit payload.
+
+`pkg/treatment/boundaries_test.go` enforces the layering: `xtcp2` and the agent
+never link the controller, a SQL driver or the ClickHouse client; the domain
+and experiment packages never import the proto or gRPC; the reconcile package
+never imports the RPC proto or gRPC; the watchdog never links TLS identity, the
+agent or the RPC proto; SQL lives only in the postgres store; the controller
+never links the host-side reconcile, local or attribution packages or goip.
+The binaries are:
+
+| Binary | Responsibility |
+| --- | --- |
+| `xtcp2-controller` | PostgreSQL state, discovery, analysis, review gates, leases, gRPC, status and metrics |
+| `xtcp2-controllerctl` | Authenticated `propose`, `analyze`, `review`, `control`, and `inspect` requests |
+| `xtcp2` | Telemetry attribution from the journal (always); the embedded agent with `-treatmentConfig` when built with the `treatment` tag |
+| `xtcp2-treatment-agent` | The same agent as a standalone process: controller connection, journal and kernel reconciliation; pairs with `-treatmentAttribution` |
+| `xtcp2-treatmentctl` | Local status, suspension, resume, reconciliation, independent watchdog |
+
+ClickHouse is an evidence source; PostgreSQL is the authority for desired state.
+Every control mutation commits the experiment, affected assignments and audit
+events in one transaction. A transaction-level advisory lock fences replicas.
+Request IDs make operator retries idempotent; reusing an ID with a different
+request is rejected. Reviews also require the expected experiment revision.
+Agents consume complete revisioned snapshots, so missed notifications are safe.
+A shared two-second notification scan coalesces updates; jittered check-ins run
+approximately every thirty seconds. No message broker is required.
+
+The scan is incremental. Every desired-state write stamps the agent row with
+the database clock (`clock_timestamp()`, taken after the advisory lock, so
+stamps commit in lock order), and each scan reads only rows stamped at or
+after the previous scan's newest stamp less a one-second margin, through the
+`desired_updated_at` index. The first scan after a restart reads every row so
+late subscribers learn the current revision; the hub drops repeated revisions.
+A check-in writes one agent row: the record and algorithm rows are rewritten
+only when a digest of the report's content changes, so a steady fleet costs
+one single-row update per heartbeat. Maintenance and candidate discovery run
+under a session-level advisory lease (`pg_try_advisory_lock` on a dedicated
+connection) that one replica holds for the pass; the others log that they are
+skipping. The lease is about cost, not correctness: every write is still fenced
+by the transaction-level mutation lock.
+
+## Trust boundaries and threat model
+
+The control plane has four kinds of principal. What each can do is decided by
+the certificate it presents or the host it runs on, never by a request field.
+
+| Principal | Credential | Can | Cannot |
+| --- | --- | --- | --- |
+| Operator | mTLS certificate with `spiffe://xtcp/operator/` | propose, analyze, review, control, inspect; every action is audited under that ID | act as an agent; reuse a request ID with a different body |
+| Agent | mTLS certificate with `spiffe://xtcp/agent//` | check in, fetch and watch its own desired state | speak for another agent, call an operator RPC, move to another location, or receive a route no operator reviewed |
+| Controller replica | PostgreSQL and ClickHouse credentials | everything above on the operators' behalf | nothing is withheld; replicas are peers and fully trusted |
+| Host root | the journal directory and the netlink socket | run the agent, the watchdog and `xtcp2-treatmentctl`; suspend locally | change another host; the actuator only touches its own table, rule priority and route protocol |
+
+The route itself is defended in depth: the controller cannot install anything
+without an operator review, the actuator refuses routes it does not own on
+readback, trials carry leases the watchdog enforces without the controller, and
+a local suspension or a withdrawn desired state removes routes without any
+network dependency.
+
+Evidence is the weakest boundary and the one to understand. Every telemetry
+record carries the agent ID, location, boot ID, collection nonce and exposure
+fields that the host itself stamped, and reaches ClickHouse through the
+existing telemetry pipeline (Kafka or NSQ, then ClickHouse), which carries no
+per-host authentication. The controller therefore trusts the warehouse to tell
+it which host produced a record. A compromised or misconfigured host can emit
+records that name another enrolled agent in its location and shift that host's
+measured goodput, retransmission ratio or RTT. It cannot make the controller
+issue a route (that needs an operator), but it can push a running trial into an
+automatic rollback by faking harm, or mask real harm on a host it impersonates.
+
+What limits that today: evidence queries filter by the experiment's location
+and the frozen cohort's agent IDs, so records naming hosts outside the cohort
+are never read. Within the cohort, evidence is bound to sessions: each agent
+process draws a 16-byte collection nonce, writes it into its journal header
+(where a telemetry-only daemon reads it) and reports it with its boot ID on
+every mTLS check-in. The controller keeps every `(agent_id, boot_id,
+collection_id)` it has heard (`xtcp_treatment_agent_sessions`, pruned after
+eight days), passes the population's sessions for the window into the
+analysis query, and measures only records stamped with one of them. Records
+that name a cohort agent under any other boot or nonce are excluded from
+every metric and counted per host as `unbound_sockets`, which `Analyze` and
+`Inspect` return with the evidence a reviewer approves. Discovery proposes
+only cohorts of enrolled agents, because only they have sessions.
+
+Per-host sample minimums and the two-minute freshness window bound how little
+data can swing a verdict; every expansion and completion is a human review of
+typed evidence, and completed experiments only ever request review on drift;
+evidence rows are immutable once stored, keyed by ID and digest, and every
+decision is in the audit log with the operator's identity.
+
+What binding does not stop: the nonce and boot ID travel in the same
+unauthenticated telemetry they protect, so a principal that can read the
+topic (or the warehouse) can copy a live session and forge records that bind.
+It raises the bar from "know an agent ID" to "read the telemetry stream", and
+it turns stale records from a previous boot or agent process into visible
+unbound counts instead of evidence. A compromised host can still misreport
+its own sockets; nothing short of signing records at the source would stop
+that.
+
+Inside the controller, the advisory mutation lock and the housekeeping lease
+order work and bound cost; neither is an authorization mechanism. Request IDs
+make an operator's own retries idempotent; they are no defence against a
+principal holding an operator certificate, who is an operator.
+
+## Names and surfaces
+
+One feature name, `treatment`, is used for everything the host side and the
+contract share: the Go packages under `pkg/treatment`, the proto packages
+`xtcp_treatment.v1` and `xtcp_treatment_journal.v1`, the journal, the
+`treatment` build tag, the daemon flags `-treatmentConfig` and
+`-treatmentAttribution`, and the NixOS options under
+`services.xtcp2.treatments`. `controller` names the server role, so the server
+binary is `xtcp2-controller` and its operator client is `xtcp2-controllerctl`.
+`route` is reserved for the kernel object the actuator manages and appears in
+`internal/goip/actuate` and in prose, not in a binary or package name.
+
+`xtcp2-treatmentctl` stays separate from the daemon's `xtcp2ctl` on purpose:
+it works on the journal directory as root, has no network path and must keep
+working, as the watchdog, when the daemon and the controller are both down.
+Folding it into a daemon-side CLI would make the independent withdrawal path
+depend on the process it is meant to outlive.
+
+There are three configuration surfaces, one per audience. Operators configure
+`xtcp2-controller` with flags, a DSN file and an optional discovery-template
+JSON file, all read at start. Hosts share one `controller-agent.json` between
+the agent, the watchdog and `xtcp2-treatmentctl`, so all three agree on the
+journal directory and route table. Operator requests are the RPC messages
+themselves in protobuf text, which `xtcp2-controllerctl -file` sends without
+a schema of its own.
+
+## Supported routes and TCP semantics
+
+The first actuator supports IPv4 `/32` and IPv6 `/128` destinations in the host
+network namespace, with ordinary local/main/default routing and a unique simple
+unicast baseline route. It refuses policy-routing configurations, VRFs, ECMP,
+nexthop objects and unsupported forwarding attributes. Run it on the host, not
+inside a private PID/network namespace. Its `/proc/1/ns/net` check detects an
+ordinary namespace mismatch; it cannot prove that a container's PID 1 is the
+physical host's PID 1.
+
+The default reserved resources are table **10002**, rule priority **30000**, and
+route/rule protocol **242**. The actuator copies the baseline gateway, interface,
+preferred source and supported metrics into a destination override. TCP rules
+with `iif lo` select locally originated traffic. The rule is built from fields
+with `xtcpnl.RuleWrite`, not from `ip rule` keywords; `TestRuleWriteTypedMatchesArgv`
+in `internal/goip` keeps it byte for byte what `ip rule add table 10002 priority
+30000 ipproto tcp iif lo protocol 242` sends. Unmatched traffic falls through
+to the normal tables. Main-table routes are never rewritten. These reserved
+resources must have one owner; every mutation checks ownership and readback,
+and refuses to overwrite or delete a changed/foreign route. Link, address, route
+and rule notifications trigger replanning, with periodic reconciliation as a
+fallback. A changed forwarding path invalidates the old override.
+
+Settings include congestion algorithm and optional lock, minimum RTO in ms,
+initial send/receive windows in segments, quick ACK and ECN. Bounds are enforced
+in [validate.go](../pkg/treatment/validate.go). Algorithms must already be loaded.
+DCTCP requires explicit ECN and an operator assertion that the fabric has been
+independently verified; a low RTT alone does not establish that requirement.
+There is no setting to disable TCP slow start.
+
+The nearby-traffic template in
+[controller-discovery.json](examples/controller-discovery.json) requests CUBIC,
+`rto_min=5ms`, `quickack=1`, `initcwnd=100`, and `initrwnd=100`. These are explicit
+route overrides for the discovered destination, including nearby NFS traffic;
+they do not depend on matching an application port. The initial windows are in
+segments. Discovery preserves these settings in the proposal, and the daemon
+persists them in its protobuf-text journal before applying them through goip.
+Omitting an optional metric preserves the baseline route's setting. The short
+and soak VM tests verify all five installed metrics, including after journal
+replay in the short test.
+
+A route treatment is destination-scoped, not socket-scoped, even though socket
+data discovers it. Established connections may retain previous TCP settings.
+The controller does not call `setsockopt` on application sockets or restart
+applications. Withdrawing a route does not immediately undo an algorithm already
+selected by a live socket. Long-lived NFS connections can therefore delay an
+experiment or make it inconclusive. Initial-window exposure is not inferable
+from an established socket's current congestion window. First-release experiments
+require a congestion algorithm so the evaluator can observe actual algorithm
+exposure; other settings may accompany it, but separate changes are easier to
+interpret.
+
+## Experiments and evidence
+
+Candidate templates search per data center, using RTT, retransmission ratio and
+optional destination prefixes/ASN filters. RTT/ASN conditions propose a
+hypothesis; they do not prove that CUBIC or BBR will help. Existing ASN enrichment
+identifies provider mappings, not verified BGP origins. Discovery runs every
+thirty minutes with a one-hour lookback and never approves its own proposals.
+`-discoveryInterval` (1m..24h) and `-discoveryWindow` (1m..168h) configure these;
+discovery is checked on one-minute maintenance ticks. Short windows are useful
+for integration testing but change the population and stability of the evidence.
+Templates may set `maximum_rtt_increase` as a fractional increase in the range
+0..1; omission uses the production default of 0.1 (10%). This policy value is
+frozen in each proposal for operator review. The VM soak fixture uses 1.0 to
+tolerate small timing variations at 5 ms while testing a jump to 180 ms.
+Initially only one proposed,
+running or held experiment is allowed per data center.
+
+Each proposal freezes a host population and baseline. Allocation is deterministic
+from the experiment ID and interleaved across kernel-version strata. The operator
+reviews that population before approving the first host. Eligibility and algorithm
+availability are checked again before a newly selected host is assigned.
+
+The default sequence doubles `1, 2, 4, 8, ...`, retains at least two untreated
+hosts before the last phase, and then reaches 100% of the **frozen eligible
+population**. For eight hosts it is `1, 2, 4, 6, 8`. Newly enrolled hosts do not
+silently join an approved experiment. Every expansion and final completion needs
+another human review. Minimum observation defaults to thirty minutes **after
+verified application**, not merely thirty minutes after sending a command.
+
+| Default policy | Value |
+| --- | --- |
+| Minimum observation | 30 minutes |
+| Maximum phase lifetime | 24 hours |
+| Maximum evidence age | 2 minutes |
+| Minimum samples per host | 30 sockets and 1 MiB acknowledged |
+| Minimum treated hosts for benefit inference | 4 |
+| Required lower-bound improvement | 5% |
+| Retransmission guardrail | increase of 0.005 in retransmitted/sent byte ratio |
+| RTT guardrail | 10% increase in per-host p95 socket RTT |
+| Trial lease / renewal interval | 1 hour / 5 minutes |
+
+The first seven values are configurable in the experiment policy. Leases are
+currently controller constants. Maintenance runs each minute and may renew the
+current cohort with fresh healthy evidence, or roll it back for harm/expiry;
+maintenance cannot promote it. A pause stops renewal and promotion, so existing
+trial leases eventually expire. Stable assignments have no lease. Completed
+experiments receive hourly drift analysis; regressions request operator review
+instead of automatically changing approved stable routes.
+
+### Lifecycle
+
+An experiment's status only changes through the transition table in
+[`experiment.Transition`](../pkg/treatment/experiment/statemachine.go); Review,
+Control and maintenance all apply a named event to the current status, and any
+pair outside the table fails with `FailedPrecondition`. `TestTransitionExhaustive`
+pins every status and event pair.
+
+| From | Event | To |
+| --- | --- | --- |
+| PROPOSED | approve | RUNNING |
+| RUNNING | approve (cohorts remain) | RUNNING, next phase issued |
+| RUNNING | approve_final (100% phase) | COMPLETE |
+| RUNNING | pause | PAUSED (routes stay, leases run down) |
+| PROPOSED, RUNNING, PAUSED, COMPLETE | suspend | SUSPENDED (routes withdrawn) |
+| PAUSED, SUSPENDED | resume | RUNNING with a fresh phase of the same size |
+| PAUSED, SUSPENDED | resume_stable (last phase was FINAL_SAFETY) | COMPLETE |
+| RUNNING, PAUSED | expire | ROLLED_BACK |
+| RUNNING | harm | ROLLED_BACK |
+| any non-terminal | reject, retire | RETIRED |
+| any non-terminal | rollback | ROLLED_BACK |
+
+RETIRED and ROLLED_BACK are terminal; propose a new experiment instead.
+
+Evaluation results are the `Outcome` enum in `treatment.proto`, mirrored by
+`experiment.Outcome`. Only `BENEFICIAL`, `SAFETY_ONLY` and `FINAL_SAFETY` can
+promote a phase, and only through a review; `HARMFUL` and `EXPIRED` withdraw
+automatically; `STALE` and `INSUFFICIENT_DATA` cannot renew a lease. `OBSERVING`
+means every treated host has verified the assignment and the window is open.
+An assignment is identified by its `experiment_id`; one experiment never issues
+two concurrent assignments to the same host.
+
+[analysis.sql](../pkg/treatment/controller/evidence/clickhouse/analysis.sql) computes whole-window
+counter deltas per boot, host, namespace and socket cookie, deduplicates poll
+timestamps, then aggregates per host. It rejects negative endpoint deltas and
+collection gaps over thirty seconds. Require normal collection at ten seconds
+or faster. This is not a complete exporter-health detector: lost short flows,
+resets followed by recovery within the window, and traffic missing altogether
+still require external collector-health monitoring.
+
+The controller never names ClickHouse. `Maintain` and `Analyze` take an
+`evidence.Source` and ask for `evidence.WindowFor(experiment, now)`; candidate
+discovery takes an `evidence.Warehouse`, asks for `Candidates` within the
+template's RTT and retransmission bounds, applies the template's ASN and prefix
+allow-lists, then takes a baseline `Evidence` for each candidate before
+proposing. `Evidence.artifact_sha256` is the digest of the raw response bytes
+the summary was decoded from; the response is not archived, so reproducing a
+measurement means re-running `query_version` over the same window. Handler
+tests use in-memory fakes of both ports; the adapter has its own contract
+tests plus a real-SQL test under `clickhouse local`.
+
+The host is the experimental unit. Evaluation compares each host's log goodput
+change with contemporaneous controls and uses a conservative Welch interval
+budgeted over planned phases and minute-level looks. Tiny cohorts are safety
+canaries, not evidence of causal benefit. The final 100% phase checks safety after
+benefit has been established with controls. RTT/retransmission guardrails protect
+both treated and control hosts; insufficient, stale or unexposed data blocks
+promotion. Arbitrary repeated operator analyses, adaptive populations, workload
+shifts and shared bottlenecks limit statistical interpretation. This is a review
+aid, not a guarantee of causality or application-level benefit. Validate NFS/RPC
+latency, errors and throughput alongside socket measurements before approval.
+
+Evidence includes analysis/window times, query version, a result digest and
+per-host measurements, stored immutably in PostgreSQL. The digest identifies the
+query result; the raw ClickHouse response is not archived as an external artifact.
+Reviewed phases retain their evidence, reviewer, reason, issue time, observation
+start and decision time. New maintenance evidence never overwrites the approved
+phase record.
+
+This release uses scheduled whole-window queries against `xtcp_flat_records_v2`.
+The existing ingestion materialized view carries the additive attribution fields.
+It deliberately does not compute counter deltas in an insert-triggered MV: socket
+samples cross insert blocks. A future aggregating-state MV must preserve boundary
+samples and deduplication before replacing this query. Benchmark query cost and
+end-to-end delivery latency on representative data before enabling many data
+centers or approaching 5–10k hosts. The 10k-host notification/cohort tests are not
+a production fleet load test.
+
+## PostgreSQL lookup costs and discovery reservations
+
+Discovery first checks the one-active-experiment budget for the data center.
+If it is occupied, that template's ClickHouse scan is skipped. Otherwise each
+candidate is checked in PostgreSQL by `(location, destination)` before fetching
+baseline evidence. PROPOSED, RUNNING, PAUSED, SUSPENDED and COMPLETE experiments
+reserve their destinations. RETIRED and ROLLED_BACK experiments reserve them until
+24 hours after `updated_at`; at exactly 24 hours they become eligible again.
+COMPLETE represents a stable treatment, so it does not expire out of this check.
+
+These checks use experiment state, not a fresh read of every machine's kernel
+routes. Desired assignments describe the controller's intent, agent reports
+describe verified application, and reconciliation repairs divergence. Drift
+monitoring of a completed treatment can request operator review; automatic
+discovery does not replace it. An explicit operator proposal may replace a stable
+treatment using the existing reviewed predecessor/rollback mechanism.
+
+The early lookup is an optimization. The proposal transaction repeats the
+destination check under the existing advisory lock, and repeats the DC budget
+check, so concurrent controllers or changes during ClickHouse analysis cannot
+insert competing automatic proposals. A database lookup failure stops discovery.
+
+Two B-tree indexes on plain columns support these paths:
+
+| Index | Keys | Purpose |
+| --- | --- | --- |
+| `xtcp_treatment_experiments_destination` | location, treatment destination (`cidr`), updated_at | Existing-treatment and cooldown lookup without scanning unrelated history. |
+| `xtcp_treatment_experiments_location_status` | location, experiment status | DC budget lookup and status-based maintenance selection. |
+
+The budget query uses `EXISTS` rather than counting every match. Evidence host
+rows live in `xtcp_treatment_evidence_hosts`, keyed by evidence ID, so an
+experiment row stays small no matter how many hosts were measured. Agent
+primary-key and location indexes cover their lookups; the notification scan
+reads through `xtcp_treatment_agents_desired_updated` with a watermark, so it
+touches the rows that changed since the last scan rather than the fleet.
+`TestPostgresObserveRewritesOnlyChangedReports` checks, through row `xmin`
+values, that an unchanged report leaves the record and algorithm rows alone.
+
+`TestPostgresExperimentQueryIndexes` (in `store/postgres`) loads 100,000 retired
+experiments and five active experiments, runs `ANALYZE`, and compares
+`EXPLAIN (ANALYZE, BUFFERS)` with and without these indexes. It checks that
+PostgreSQL chooses an appropriate index without disabling sequential scans;
+execution times are logged, not used as brittle pass/fail thresholds. The store
+conformance suite (`store/storetest`, run against both PostgreSQL and the
+in-memory store) covers all lifecycle states, cooldown boundaries and
+location/destination isolation. Concurrent proposal tests verify that only one
+automatic proposal is persisted.
+
+On the Nix PostgreSQL 18.6 fixture (`nix build .#bench-tcp-controller-postgres-indexes`),
+three repeated runs measured a median 22.27 ms without indexes versus 0.023 ms
+with them for an old destination's cooldown lookup. These are synthetic query
+execution times, not end-to-end production latency. [Raw query-plan timing results](benchmarks/tcp-controller/postgres-indexes.txt)
+also include missing destinations and active/idle data-center budget checks.
+
+Startup migration creates missing indexes idempotently. For an existing busy
+database, prebuild these indexes before restarting controllers:
+
+```sql
+-- Run outside a transaction, using the controller database/schema.
+CREATE INDEX CONCURRENTLY IF NOT EXISTS xtcp_treatment_experiments_destination
+ ON xtcp_treatment_experiments (location, treatment_destination, updated_at);
+CREATE INDEX CONCURRENTLY IF NOT EXISTS xtcp_treatment_experiments_location_status
+ ON xtcp_treatment_experiments (location, status);
+```
+
+Normal index creation blocks writes while building; PostgreSQL's
+[concurrent index creation](https://www.postgresql.org/docs/current/sql-createindex.html#SQL-CREATEINDEX-CONCURRENTLY)
+avoids that write-blocking build. If a concurrent build fails, inspect and remove
+its invalid index before retrying: `IF NOT EXISTS` does not repair an invalid
+index. The startup migration uses ordinary index creation, not concurrent DDL.
+
+Further scaling work should measure per-host SQL round trips during review and
+lease renewal, large experiment-document rewrites, and evidence/audit
+retention. Those need batching or data-layout changes, not blanket indexes on
+every field. Discovery currently considers the ten busiest candidate
+destinations per template before the PostgreSQL destination filter; pagination
+or earlier exclusion would be needed to avoid already-treated destinations
+occupying all ten slots.
+
+## Persistence, restart and withdrawal
+
+`/var/lib/xtcp2/routes/state.textproto` is the authoritative atomic snapshot:
+prototext of `xtcp_treatment_journal.v1.Journal`, a file format of its own with
+a header naming the writing agent, location and boot. It is converted to and
+from the domain types on every pass and validated on every load; a snapshot in
+any other shape (including the pre-rework `LocalState` text) fails closed.
+`assignment-.textproto` files are readable projections containing receipt,
+attempt, application, verification and removal times. Projection files are never
+replayed independently. A private directory, file lock, temp-file rename and file
+and directory fsync serialize the daemon, watchdog and local commands. The lock
+waits rather than fails: each pass is bounded by its caller's context (15 s for
+the agent's check-in, 25 s for a watchdog pass, 30 s for `treatmentctl
+suspend`/`resume`), and at the deadline the caller gets "treatment journal busy"
+without having read or written anything. A holder that dies releases the lock,
+and the next holder sweeps the half-written temporary file it left.
+`treatmentctl status` reads the snapshot without the lock and never waits.
+Intent is persisted before kernel mutation; kernel readback precedes success
+reporting. Do not hand-edit projections to change desired state.
+
+Startup, periodic work and SIGHUP reconcile the snapshot. Boot IDs prevent stale
+kernel fingerprints from being treated as current installations after reboot.
+Stable assignments are restored without a controller round trip. Trial expiry is
+latched locally: a delayed renewal of the same generation cannot resurrect it.
+An explicit approved reactivation increments the generation. A trial replacing a
+stable treatment stores a predecessor; expiry/rollback restores that predecessor
+when it can be safely replanned. Permanent retirement removes the override.
+
+Run the independent watchdog even when xtcp2 itself stops. It checks every thirty
+seconds and withdraws expired trials or persistent holds; it cannot accept new
+desired state. Local time synchronization and monitoring of both processes are
+required. If both processes are stopped, userspace cannot enforce the lease.
+Corrupt journals fail closed for new application and require operator recovery;
+they cannot prove ownership of routes already installed.
+
+| Operation | Result |
+| --- | --- |
+| Experiment `PAUSE` | Freeze promotion and renewal; existing leases run out |
+| Experiment/host/DC/fleet `SUSPEND` | Persist a hold and withdraw owned overrides |
+| Experiment `RESUME` | Explicitly reactivate the same cohort with a new generation and observation window |
+| Host/DC/fleet `RESUME` | Remove that scope's hold; broader and local holds still win |
+| Experiment `ROLLBACK` | End the experiment; restore a saved stable predecessor when present |
+| Experiment `RETIRE` | End the experiment and remove its overrides |
+| Local `suspend` | Offline persistent hold that controller requests cannot clear |
+
+Broad holds are inherited by new enrollments. A narrower resume cannot clear a
+broader hold. Expired trials remain latched after a broad hold is lifted; pause
+then explicitly resume the experiment, or retire it and propose a new one.
+Suspending a completed experiment and resuming it preserves its stable approval.
+Withdrawals affect future route/connection behavior; allow existing connections
+to turn over before interpreting a temporary baseline test. Disconnected agents
+cannot receive an immediate remote hold; use the local command or wait for trial
+expiry. Stable routes intentionally persist during controller outages.
+
+Before disabling `enable_apply`, removing `-treatmentConfig`, stopping a
+standalone agent for good, or uninstalling the watchdog, suspend the treatments
+and verify withdrawal. Disabling the
+actuator prevents further writes; it does not itself delete existing kernel
+routes. Keep the journal through cleanup so ownership can be checked.
+
+## Agent deployment
+
+The agent is a library (`pkg/treatment/agent`) with two front ends. Pick one per
+host; xtcp2 refuses both flags together.
+
+| Arrangement | xtcp2 flag | Who owns the journal and routes | When |
+| --- | --- | --- | --- |
+| Embedded | `-treatmentConfig=/etc/xtcp2/controller-agent.json` | xtcp2 itself | the fat `xtcp2` build (Nix: every attribute with the full destination set carries the `treatment` tag); one process to run and one journal writer |
+| Standalone | `-treatmentAttribution=/var/lib/xtcp2/routes` | `xtcp2-treatment-agent -config=/etc/xtcp2/controller-agent.json` | slim xtcp2 flavors (`xtcp2-min`, `xtcp2-kafka`, ...), which do not embed the agent, or wherever the controller connection and kernel writes should restart independently of collection |
+
+In both arrangements the daemon stamps every record from the same exposure
+index (`pkg/treatment/attribution`): agent, boot, collection nonce, desired
+revision and, for sockets whose destination has a verified route in the host
+namespace, the experiment, generation, application time and whether the
+observed congestion algorithm matches. Embedded, the index is rebuilt after
+every reconcile pass. Standalone, xtcp2 watches the journal directory
+(inotify on the atomic rename of `state.textproto`, a 30 s poll as fallback,
+SIGHUP to re-read now) and rebuilds it from the snapshot; a missing or invalid
+snapshot clears attribution rather than stamping stale state. The collection
+nonce is the agent's in both arrangements: the agent writes it into the
+journal header on its first pass after starting, the watchdog preserves it,
+and a journal without one (written by an older agent) is stamped without a
+nonce, which the controller counts as unbound, and logged once.
+
+Location follows one rule in both arrangements, because the agent's location
+is certificate-bound and evidence queries filter by it. A daemon started
+without `-location`/`LOCATION` adopts the agent's location for its records and
+logs that once. A daemon with its own label keeps it: embedded, an agent whose
+location differs refuses to start with a message naming both labels (socket
+telemetry continues without the agent); standalone, the watcher keeps the
+daemon's label and logs the disagreement once. No label is rewritten silently.
+`agent.New` likewise refuses a config whose `location`/`agent_id` differ from
+the certificate's URI SAN, naming both.
+
+SIGHUP means "reconcile now" on the host side, and nothing else. In `xtcp2`
+it wakes the embedded agent (check in, then reconcile) or the journal watcher
+(re-read the snapshot); it never rebaselines link state, which is SIGUSR1, and
+never reloads configuration or restarts collection. The standalone agent
+handles SIGHUP the same way. The daemon has no admin RPC surface today, so a
+signal is the only in-process nudge; the
+[network-control gRPC design](design-network-control-grpc.md) describes a
+future admin API, and when it lands "reconcile now" becomes a method there with
+SIGHUP kept as its signal equivalent. `xtcp2-treatmentctl -mode=reconcile`
+is different: it runs one full reconcile pass from the journal through the
+actuator in its own process, without the controller, and prints the resulting
+snapshot, which is the tool for a host whose agent is stopped.
+
+A build without the `treatment` tag rejects `-treatmentConfig` at startup with
+a message naming both remedies, the same way a slim build rejects an enricher
+it lacks: a missing build tag is a property of the artifact and must not
+degrade silently. `go test ./cmd/xtcp2` covers the untagged daemon;
+`nix build .#test-focused-xtcp-treatment` (or
+`go test -tags treatment ./cmd/xtcp2 ./cmd/xtcp2-treatment-agent`) covers the
+embedded path. The watchdog, `xtcp2-treatmentctl -mode=watchdog`, is a
+separate process in both arrangements and builds on `pkg/treatment/local` and
+`pkg/treatment/reconcile` only.
+
+## Deployment
+
+1. Build the controller, client, treatmentctl, the standalone agent if you
+ use it, and your normal xtcp2 build flavor. Nix exposes
+ `.#xtcp2-controller`, `.#xtcp2-controllerctl`, `.#xtcp2-treatment-agent`
+ and `.#xtcp2-treatmentctl`; all of them also build with ordinary `go build`.
+2. Provision PostgreSQL with backups and a restricted database identity. The
+ controller's `-migrate` applies the additive schema; use it during controlled
+ deployment, then remove it from the long-running command. Back up audit and
+ evidence tables together. Restoring an older database can yield revisions
+ older than daemon journals: stop mutations and reconcile state explicitly;
+ do not reset daemon revisions to make the errors disappear.
+3. Update the ClickHouse protobuf format schema and apply
+ [xtcp_treatment_migration.sql](../build/containers/clickhouse/initdb.d/sql/xtcp_treatment_migration.sql)
+ to an existing deployment before enabling agents. Fresh-install DDL already
+ contains the new columns. Preserve the telemetry tables and Kafka offsets.
+4. Provision mutually authenticated TLS. The controller needs a server DNS SAN;
+ agents have exactly one URI SAN `spiffe://xtcp/agent//`;
+ operators have exactly one URI SAN `spiffe://xtcp/operator/`.
+ Agent IDs are globally unique and location is certificate-bound. Agent
+ certificates cannot invoke operator RPCs or fetch another agent's state.
+ Use protected key files; restart processes to load rotated certificates.
+ There is no online certificate revocation service in this release.
+
+ Authorization is declared, not hand-rolled. Every RPC in `agent.proto` and
+ `operator.proto` carries an `(xtcp_treatment.v1.role)` option; the
+ controller builds an `identity.Policy` from those options at startup and
+ installs unary and stream interceptors that resolve the peer certificate
+ once, refuse the wrong role, refuse any method without a declaration
+ (fail closed), and for agent RPCs refuse a request whose `agent_id` or
+ `location` is not the certificate's. Handlers read the resolved identity
+ from the context; the same `identity.Agent`/`identity.Operator` checks
+ remain in the handlers so a direct call behaves identically. A test in
+ `pkg/treatment/controller` tries every served method with an agent
+ certificate, an operator certificate and none, and fails if a method has
+ no declaration.
+5. Configure explicit protected prefixes for management, DNS, telemetry,
+ controller dependencies and any infrastructure that must not be experimented
+ on. The agent also protects controller addresses resolved at startup. DNS
+ changes are why configured management prefixes remain necessary.
+6. Start the controller near ClickHouse/PostgreSQL, enable agents with application
+ disabled first, validate identity/telemetry, then enable the actuator on a
+ small test population and deploy the independent watchdog.
+
+Example controller invocation (secrets remain outside the command line):
+
+```sh
+xtcp2-controller -listen=:9443 -statusListen=127.0.0.1:9444 \
+ -cert=/etc/xtcp2/controller.crt -key=/etc/xtcp2/controller.key \
+ -ca=/etc/xtcp2/clients-ca.crt -databaseDSNFile=/etc/xtcp2/postgres.dsn \
+ -clickhouse=https://clickhouse.example.net:8443 \
+ -discoveryTemplates=/etc/xtcp2/discovery.json
+```
+
+ClickHouse credentials use `XTCP_CLICKHOUSE_USER` and
+`XTCP_CLICKHOUSE_PASSWORD`. Without `-clickhouse`, analysis and lease renewal are
+disabled; manual safety controls remain available. The example
+[agent configuration](examples/controller-agent.json) is intentionally disabled;
+replace its documentation addresses and protected prefixes before use. The
+[discovery templates](examples/controller-discovery.json) are examples of
+hypotheses, not recommended network-wide tuning defaults.
+
+On NixOS, set `services.xtcp2.treatments.enable = true`, its `configFile`, and
+`watchdogPackage`. `treatments.mode` selects the arrangement: `embedded` (the
+default; `package` must be a build with the `treatment` tag) passes
+`-treatmentConfig`, `standalone` runs `agentPackage`'s
+`xtcp2-treatment-agent` as its own service and passes
+`-treatmentAttribution=` to xtcp2. The module creates an
+independent watchdog service in both modes; the example
+[standalone agent unit](examples/xtcp2-treatment-agent.service) is the
+non-NixOS equivalent. A runtime
+JSON file and private keys should remain outside the Nix store. The existing
+`systemctl reload xtcp2` sends SIGUSR1 for link-monitor baseline relearning;
+use `kill -HUP ` for route reconciliation. Other systems can use the
+[example watchdog unit](examples/xtcp2-treatment-watchdog.service).
+
+## Operator workflow
+
+Every CLI request is protobuf text, following the messages in the contract.
+Supply `-controller`, `-serverName`, `-cert`, `-key` and `-ca` on each invocation.
+Use `-method=inspect` to find proposals and their revisions. Discovery creates
+proposals automatically when configured; `-method=propose` accepts a manually
+constructed `ProposeRequest` with a complete baseline and policy.
+
+Before approval, refresh and inspect evidence with `-method=analyze`:
+
+```protobuf
+experiment_id: "hyp-example"
+expected_revision: 1
+```
+
+The result is an `AnalyzeResponse` containing `evidence { ... }` and `outcome`.
+Copy the evidence block into a `ReviewRequest`, retaining its exact ID and values:
+
+```protobuf
+experiment_id: "hyp-example"
+expected_revision: 1
+approve: true
+reason: "Reviewed baseline, eligible hosts and route scope"
+request_id: "review-hyp-example-1"
+# evidence { ...exact evidence returned by Analyze... }
+```
+
+Invoke `-method=review -file=review.textproto`. Subsequent reviews require fresh
+evidence covering the observation window. Reuse the same request ID and exact
+body after a network timeout; use a new ID for a new decision. Stale revision,
+evidence, missing exposure, incomplete host reports or failed guards block review.
+An operator may reject a proposal or stop a trial with `approve: false`.
+
+For an emergency fleet hold, use `-method=control` with:
+
+```protobuf
+fleet: true
+action: CONTROL_ACTION_SUSPEND
+reason: "Temporary baseline comparison for incident 123"
+request_id: "incident-123-fleet-hold"
+```
+
+The same message with a **new** ID and `CONTROL_ACTION_RESUME` lifts that fleet
+hold. Substitute exactly one of `location`, `agent_id` or `experiment_id` for
+`fleet` to narrow the scope. Offline local withdrawal:
+
+```sh
+xtcp2-treatmentctl -config=/etc/xtcp2/controller-agent.json \
+ -mode=suspend -reason='Local baseline comparison for incident 123'
+xtcp2-treatmentctl -config=/etc/xtcp2/controller-agent.json -mode=status
+xtcp2-treatmentctl -config=/etc/xtcp2/controller-agent.json \
+ -mode=resume -reason='Comparison finished'
+```
+
+The optional status listener provides operator-mTLS-protected `/readyz`, `/status`
+and `/metrics`. Monitor controller/agent availability, failed and expired route
+records, holds, growing pending experiments, evidence freshness and watchdog
+logs. `/status` is a JSON dashboard feed, not a graphical UI. A stopped controller
+does not disable the ordinary xtcp2 collection service.
+
+## Validation and remaining extensions
+
+See the [test and benchmark audit](tcp-controller-testing.md) for table-driven
+contracts, race coverage, measured performance, coverage limits, and reproducible
+Nix unit/race/benchmark targets with isolated PostgreSQL and ClickHouse fixtures.
+
+Tests cover durable intent/crash recovery, stale generations, predecessor expiry,
+local/broad holds, concurrent controller reviews, full human-reviewed rollout,
+early safety withdrawal, actual algorithm attribution, 10k-host cohort and
+notification behavior, the incremental notification watermark, the heartbeat
+split and the housekeeping lease. Optional tests exercise real PostgreSQL, ClickHouse SQL,
+and IPv4/IPv6 netlink mutation in a disposable namespace:
+
+```sh
+go test ./pkg/treatment/... ./internal/goip/...
+XTCP_CONTROLLER_TEST_DSN='host=... dbname=... user=... sslmode=...' \
+ go test ./pkg/treatment/controller/...
+PATH=/path/to/clickhouse/bin:$PATH \
+ go test ./pkg/treatment/controller/evidence/clickhouse -run ClickHouse
+XTCP_TREATMENT_LIVE_TEST=1 go test ./internal/goip/actuate -run '^TestTreatmentLiveNamespace$'
+```
+
+Every controller handler test runs twice, as `/memory` and
+`/postgres`; without the DSN the PostgreSQL half skips. The store
+conformance suite runs the same way from `store/memory` and `store/postgres`.
+The PostgreSQL tests create and drop only unique test schemas. The route test
+creates its own user/network namespace and verifies that it differs from the
+parent namespace before any write. It requires `ip`, `unshare` and a kernel that
+permits unprivileged user namespaces. Existing daemon tests need this repository's
+`-ldflags=-checklinkname=0` flag for giouring.
+
+The [Go-driven controller VM integration test](integration-testing.md#tcp-controller-integration)
+uses the existing TCP load tools, six agent guests, real PostgreSQL/ClickHouse,
+and `tc netem` latency bands. Run `nix run path:.#test-tcp-controller-vm`;
+the cached target is `checks.x86_64-linux.vm-tcp-controller`. It checks reviewed
+1→2 canaries, actual socket algorithm exposure, restart persistence, holds,
+automatic rollback after injected harm, and independent watchdog lease expiry.
+The longer `test-tcp-controller-soak-vm` target varies RTT every three minutes,
+checks repeated scheduled discovery and automatic rollback, and verifies the
+destination cooldown. Its test operator explicitly approves each new canary.
+
+Future work includes application SLO inputs, richer workload/fabric stratification,
+aggregated analytical storage, provider-feed provenance, enrollment reconciliation
+for new hosts, multi-experiment scheduling, automated withdrawal experiments,
+and a graphical review dashboard. A future automated/LLM reviewer can consume the
+same typed evidence and decision interface, but the deterministic authorization,
+ownership, budget, freshness and guardrail checks must remain mandatory. This
+release does not autonomously promote treatments or claim that a successful
+small test has optimized an entire production fleet.
diff --git a/flake.nix b/flake.nix
index 018dffdba..2ae77da5e 100644
--- a/flake.nix
+++ b/flake.nix
@@ -33,6 +33,15 @@
# See ./nix/README.md for individual targets, logs and Nix policy checks.
#
# Quick references:
+# nix run path:.#test-tcp-controller-vm -- --accel=auto
+# nix run path:.#test-tcp-controller-soak-vm -- --cycles=3 --interval=3m
+# nix build path:.#test-tcp-controller-unit path:.#test-tcp-controller-race
+# nix build path:.#bench-tcp-controller
+# Repeated RTT changes, automatic discovery, test-operator approval,
+# automatic rollback and cooldown checks (~30 minutes by default).
+# Seven guests: TCP load, netem RTT bands, ClickHouse/PostgreSQL, reviewed
+# canary, withdrawal and independent expiry. Also checks.vm-tcp-controller,
+# checks.vm-all, and integration-all (nix/tests/tcp-controller).
# nix develop # dev shell
# nix build .#xtcp2 # main binary
# nix build .#xtcp2-all # every cmd/* binary
diff --git a/gen/cpp/xtcp_treatment/v1/agent.grpc.pb.cc b/gen/cpp/xtcp_treatment/v1/agent.grpc.pb.cc
new file mode 100644
index 000000000..75c16bd26
--- /dev/null
+++ b/gen/cpp/xtcp_treatment/v1/agent.grpc.pb.cc
@@ -0,0 +1,167 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: xtcp_treatment/v1/agent.proto
+
+#include "xtcp_treatment/v1/agent.pb.h"
+#include "xtcp_treatment/v1/agent.grpc.pb.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+namespace xtcp_treatment {
+namespace v1 {
+
+static const char* AgentControlService_method_names[] = {
+ "/xtcp_treatment.v1.AgentControlService/CheckIn",
+ "/xtcp_treatment.v1.AgentControlService/GetDesiredState",
+ "/xtcp_treatment.v1.AgentControlService/WatchDesiredState",
+};
+
+std::unique_ptr< AgentControlService::Stub> AgentControlService::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
+ (void)options;
+ std::unique_ptr< AgentControlService::Stub> stub(new AgentControlService::Stub(channel, options));
+ return stub;
+}
+
+AgentControlService::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options)
+ : channel_(channel), rpcmethod_CheckIn_(AgentControlService_method_names[0], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+ , rpcmethod_GetDesiredState_(AgentControlService_method_names[1], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+ , rpcmethod_WatchDesiredState_(AgentControlService_method_names[2], options.suffix_for_stats(),::grpc::internal::RpcMethod::SERVER_STREAMING, channel)
+ {}
+
+::grpc::Status AgentControlService::Stub::CheckIn(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest& request, ::xtcp_treatment::v1::CheckInResponse* response) {
+ return ::grpc::internal::BlockingUnaryCall< ::xtcp_treatment::v1::CheckInRequest, ::xtcp_treatment::v1::CheckInResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_CheckIn_, context, request, response);
+}
+
+void AgentControlService::Stub::async::CheckIn(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest* request, ::xtcp_treatment::v1::CheckInResponse* response, std::function f) {
+ ::grpc::internal::CallbackUnaryCall< ::xtcp_treatment::v1::CheckInRequest, ::xtcp_treatment::v1::CheckInResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_CheckIn_, context, request, response, std::move(f));
+}
+
+void AgentControlService::Stub::async::CheckIn(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest* request, ::xtcp_treatment::v1::CheckInResponse* response, ::grpc::ClientUnaryReactor* reactor) {
+ ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_CheckIn_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::CheckInResponse>* AgentControlService::Stub::PrepareAsyncCheckInRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest& request, ::grpc::CompletionQueue* cq) {
+ return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::xtcp_treatment::v1::CheckInResponse, ::xtcp_treatment::v1::CheckInRequest, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_CheckIn_, context, request);
+}
+
+::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::CheckInResponse>* AgentControlService::Stub::AsyncCheckInRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest& request, ::grpc::CompletionQueue* cq) {
+ auto* result =
+ this->PrepareAsyncCheckInRaw(context, request, cq);
+ result->StartCall();
+ return result;
+}
+
+::grpc::Status AgentControlService::Stub::GetDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest& request, ::xtcp_treatment::v1::GetDesiredStateResponse* response) {
+ return ::grpc::internal::BlockingUnaryCall< ::xtcp_treatment::v1::GetDesiredStateRequest, ::xtcp_treatment::v1::GetDesiredStateResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_GetDesiredState_, context, request, response);
+}
+
+void AgentControlService::Stub::async::GetDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest* request, ::xtcp_treatment::v1::GetDesiredStateResponse* response, std::function f) {
+ ::grpc::internal::CallbackUnaryCall< ::xtcp_treatment::v1::GetDesiredStateRequest, ::xtcp_treatment::v1::GetDesiredStateResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_GetDesiredState_, context, request, response, std::move(f));
+}
+
+void AgentControlService::Stub::async::GetDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest* request, ::xtcp_treatment::v1::GetDesiredStateResponse* response, ::grpc::ClientUnaryReactor* reactor) {
+ ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_GetDesiredState_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::GetDesiredStateResponse>* AgentControlService::Stub::PrepareAsyncGetDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest& request, ::grpc::CompletionQueue* cq) {
+ return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::xtcp_treatment::v1::GetDesiredStateResponse, ::xtcp_treatment::v1::GetDesiredStateRequest, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_GetDesiredState_, context, request);
+}
+
+::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::GetDesiredStateResponse>* AgentControlService::Stub::AsyncGetDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest& request, ::grpc::CompletionQueue* cq) {
+ auto* result =
+ this->PrepareAsyncGetDesiredStateRaw(context, request, cq);
+ result->StartCall();
+ return result;
+}
+
+::grpc::ClientReader< ::xtcp_treatment::v1::WatchDesiredStateResponse>* AgentControlService::Stub::WatchDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request) {
+ return ::grpc::internal::ClientReaderFactory< ::xtcp_treatment::v1::WatchDesiredStateResponse>::Create(channel_.get(), rpcmethod_WatchDesiredState_, context, request);
+}
+
+void AgentControlService::Stub::async::WatchDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest* request, ::grpc::ClientReadReactor< ::xtcp_treatment::v1::WatchDesiredStateResponse>* reactor) {
+ ::grpc::internal::ClientCallbackReaderFactory< ::xtcp_treatment::v1::WatchDesiredStateResponse>::Create(stub_->channel_.get(), stub_->rpcmethod_WatchDesiredState_, context, request, reactor);
+}
+
+::grpc::ClientAsyncReader< ::xtcp_treatment::v1::WatchDesiredStateResponse>* AgentControlService::Stub::AsyncWatchDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+ return ::grpc::internal::ClientAsyncReaderFactory< ::xtcp_treatment::v1::WatchDesiredStateResponse>::Create(channel_.get(), cq, rpcmethod_WatchDesiredState_, context, request, true, tag);
+}
+
+::grpc::ClientAsyncReader< ::xtcp_treatment::v1::WatchDesiredStateResponse>* AgentControlService::Stub::PrepareAsyncWatchDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request, ::grpc::CompletionQueue* cq) {
+ return ::grpc::internal::ClientAsyncReaderFactory< ::xtcp_treatment::v1::WatchDesiredStateResponse>::Create(channel_.get(), cq, rpcmethod_WatchDesiredState_, context, request, false, nullptr);
+}
+
+AgentControlService::Service::Service() {
+ AddMethod(new ::grpc::internal::RpcServiceMethod(
+ AgentControlService_method_names[0],
+ ::grpc::internal::RpcMethod::NORMAL_RPC,
+ new ::grpc::internal::RpcMethodHandler< AgentControlService::Service, ::xtcp_treatment::v1::CheckInRequest, ::xtcp_treatment::v1::CheckInResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
+ [](AgentControlService::Service* service,
+ ::grpc::ServerContext* ctx,
+ const ::xtcp_treatment::v1::CheckInRequest* req,
+ ::xtcp_treatment::v1::CheckInResponse* resp) {
+ return service->CheckIn(ctx, req, resp);
+ }, this)));
+ AddMethod(new ::grpc::internal::RpcServiceMethod(
+ AgentControlService_method_names[1],
+ ::grpc::internal::RpcMethod::NORMAL_RPC,
+ new ::grpc::internal::RpcMethodHandler< AgentControlService::Service, ::xtcp_treatment::v1::GetDesiredStateRequest, ::xtcp_treatment::v1::GetDesiredStateResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
+ [](AgentControlService::Service* service,
+ ::grpc::ServerContext* ctx,
+ const ::xtcp_treatment::v1::GetDesiredStateRequest* req,
+ ::xtcp_treatment::v1::GetDesiredStateResponse* resp) {
+ return service->GetDesiredState(ctx, req, resp);
+ }, this)));
+ AddMethod(new ::grpc::internal::RpcServiceMethod(
+ AgentControlService_method_names[2],
+ ::grpc::internal::RpcMethod::SERVER_STREAMING,
+ new ::grpc::internal::ServerStreamingHandler< AgentControlService::Service, ::xtcp_treatment::v1::WatchDesiredStateRequest, ::xtcp_treatment::v1::WatchDesiredStateResponse>(
+ [](AgentControlService::Service* service,
+ ::grpc::ServerContext* ctx,
+ const ::xtcp_treatment::v1::WatchDesiredStateRequest* req,
+ ::grpc::ServerWriter<::xtcp_treatment::v1::WatchDesiredStateResponse>* writer) {
+ return service->WatchDesiredState(ctx, req, writer);
+ }, this)));
+}
+
+AgentControlService::Service::~Service() {
+}
+
+::grpc::Status AgentControlService::Service::CheckIn(::grpc::ServerContext* context, const ::xtcp_treatment::v1::CheckInRequest* request, ::xtcp_treatment::v1::CheckInResponse* response) {
+ (void) context;
+ (void) request;
+ (void) response;
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status AgentControlService::Service::GetDesiredState(::grpc::ServerContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest* request, ::xtcp_treatment::v1::GetDesiredStateResponse* response) {
+ (void) context;
+ (void) request;
+ (void) response;
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status AgentControlService::Service::WatchDesiredState(::grpc::ServerContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest* request, ::grpc::ServerWriter< ::xtcp_treatment::v1::WatchDesiredStateResponse>* writer) {
+ (void) context;
+ (void) request;
+ (void) writer;
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+
+} // namespace xtcp_treatment
+} // namespace v1
+#include
+
diff --git a/gen/cpp/xtcp_treatment/v1/agent.grpc.pb.h b/gen/cpp/xtcp_treatment/v1/agent.grpc.pb.h
new file mode 100644
index 000000000..6a60c3880
--- /dev/null
+++ b/gen/cpp/xtcp_treatment/v1/agent.grpc.pb.h
@@ -0,0 +1,566 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: xtcp_treatment/v1/agent.proto
+// Original file comments:
+//
+// xTCP - treatment agent service
+//
+// The outbound-only RPC surface an agent uses: check in with observed state,
+// fetch the authoritative desired state, and watch for revision hints. Every
+// method requires an agent certificate whose SPIFFE id matches agent_id and
+// whose location matches the request; see pkg/treatment/identity.
+//
+#ifndef GRPC_xtcp_5ftreatment_2fv1_2fagent_2eproto__INCLUDED
+#define GRPC_xtcp_5ftreatment_2fv1_2fagent_2eproto__INCLUDED
+
+#include "xtcp_treatment/v1/agent.pb.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace xtcp_treatment {
+namespace v1 {
+
+class AgentControlService final {
+ public:
+ static constexpr char const* service_full_name() {
+ return "xtcp_treatment.v1.AgentControlService";
+ }
+ class StubInterface {
+ public:
+ virtual ~StubInterface() {}
+ virtual ::grpc::Status CheckIn(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest& request, ::xtcp_treatment::v1::CheckInResponse* response) = 0;
+ std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::CheckInResponse>> AsyncCheckIn(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::CheckInResponse>>(AsyncCheckInRaw(context, request, cq));
+ }
+ std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::CheckInResponse>> PrepareAsyncCheckIn(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::CheckInResponse>>(PrepareAsyncCheckInRaw(context, request, cq));
+ }
+ virtual ::grpc::Status GetDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest& request, ::xtcp_treatment::v1::GetDesiredStateResponse* response) = 0;
+ std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::GetDesiredStateResponse>> AsyncGetDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::GetDesiredStateResponse>>(AsyncGetDesiredStateRaw(context, request, cq));
+ }
+ std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::GetDesiredStateResponse>> PrepareAsyncGetDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::GetDesiredStateResponse>>(PrepareAsyncGetDesiredStateRaw(context, request, cq));
+ }
+ std::unique_ptr< ::grpc::ClientReaderInterface< ::xtcp_treatment::v1::WatchDesiredStateResponse>> WatchDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request) {
+ return std::unique_ptr< ::grpc::ClientReaderInterface< ::xtcp_treatment::v1::WatchDesiredStateResponse>>(WatchDesiredStateRaw(context, request));
+ }
+ std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::xtcp_treatment::v1::WatchDesiredStateResponse>> AsyncWatchDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+ return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::xtcp_treatment::v1::WatchDesiredStateResponse>>(AsyncWatchDesiredStateRaw(context, request, cq, tag));
+ }
+ std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::xtcp_treatment::v1::WatchDesiredStateResponse>> PrepareAsyncWatchDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::xtcp_treatment::v1::WatchDesiredStateResponse>>(PrepareAsyncWatchDesiredStateRaw(context, request, cq));
+ }
+ class async_interface {
+ public:
+ virtual ~async_interface() {}
+ virtual void CheckIn(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest* request, ::xtcp_treatment::v1::CheckInResponse* response, std::function) = 0;
+ virtual void CheckIn(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest* request, ::xtcp_treatment::v1::CheckInResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+ virtual void GetDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest* request, ::xtcp_treatment::v1::GetDesiredStateResponse* response, std::function) = 0;
+ virtual void GetDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest* request, ::xtcp_treatment::v1::GetDesiredStateResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+ virtual void WatchDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest* request, ::grpc::ClientReadReactor< ::xtcp_treatment::v1::WatchDesiredStateResponse>* reactor) = 0;
+ };
+ typedef class async_interface experimental_async_interface;
+ virtual class async_interface* async() { return nullptr; }
+ class async_interface* experimental_async() { return async(); }
+ private:
+ virtual ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::CheckInResponse>* AsyncCheckInRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest& request, ::grpc::CompletionQueue* cq) = 0;
+ virtual ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::CheckInResponse>* PrepareAsyncCheckInRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest& request, ::grpc::CompletionQueue* cq) = 0;
+ virtual ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::GetDesiredStateResponse>* AsyncGetDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest& request, ::grpc::CompletionQueue* cq) = 0;
+ virtual ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::GetDesiredStateResponse>* PrepareAsyncGetDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest& request, ::grpc::CompletionQueue* cq) = 0;
+ virtual ::grpc::ClientReaderInterface< ::xtcp_treatment::v1::WatchDesiredStateResponse>* WatchDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request) = 0;
+ virtual ::grpc::ClientAsyncReaderInterface< ::xtcp_treatment::v1::WatchDesiredStateResponse>* AsyncWatchDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request, ::grpc::CompletionQueue* cq, void* tag) = 0;
+ virtual ::grpc::ClientAsyncReaderInterface< ::xtcp_treatment::v1::WatchDesiredStateResponse>* PrepareAsyncWatchDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request, ::grpc::CompletionQueue* cq) = 0;
+ };
+ class Stub final : public StubInterface {
+ public:
+ Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
+ ::grpc::Status CheckIn(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest& request, ::xtcp_treatment::v1::CheckInResponse* response) override;
+ std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::CheckInResponse>> AsyncCheckIn(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::CheckInResponse>>(AsyncCheckInRaw(context, request, cq));
+ }
+ std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::CheckInResponse>> PrepareAsyncCheckIn(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::CheckInResponse>>(PrepareAsyncCheckInRaw(context, request, cq));
+ }
+ ::grpc::Status GetDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest& request, ::xtcp_treatment::v1::GetDesiredStateResponse* response) override;
+ std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::GetDesiredStateResponse>> AsyncGetDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::GetDesiredStateResponse>>(AsyncGetDesiredStateRaw(context, request, cq));
+ }
+ std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::GetDesiredStateResponse>> PrepareAsyncGetDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::GetDesiredStateResponse>>(PrepareAsyncGetDesiredStateRaw(context, request, cq));
+ }
+ std::unique_ptr< ::grpc::ClientReader< ::xtcp_treatment::v1::WatchDesiredStateResponse>> WatchDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request) {
+ return std::unique_ptr< ::grpc::ClientReader< ::xtcp_treatment::v1::WatchDesiredStateResponse>>(WatchDesiredStateRaw(context, request));
+ }
+ std::unique_ptr< ::grpc::ClientAsyncReader< ::xtcp_treatment::v1::WatchDesiredStateResponse>> AsyncWatchDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request, ::grpc::CompletionQueue* cq, void* tag) {
+ return std::unique_ptr< ::grpc::ClientAsyncReader< ::xtcp_treatment::v1::WatchDesiredStateResponse>>(AsyncWatchDesiredStateRaw(context, request, cq, tag));
+ }
+ std::unique_ptr< ::grpc::ClientAsyncReader< ::xtcp_treatment::v1::WatchDesiredStateResponse>> PrepareAsyncWatchDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncReader< ::xtcp_treatment::v1::WatchDesiredStateResponse>>(PrepareAsyncWatchDesiredStateRaw(context, request, cq));
+ }
+ class async final :
+ public StubInterface::async_interface {
+ public:
+ void CheckIn(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest* request, ::xtcp_treatment::v1::CheckInResponse* response, std::function) override;
+ void CheckIn(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest* request, ::xtcp_treatment::v1::CheckInResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+ void GetDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest* request, ::xtcp_treatment::v1::GetDesiredStateResponse* response, std::function) override;
+ void GetDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest* request, ::xtcp_treatment::v1::GetDesiredStateResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+ void WatchDesiredState(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest* request, ::grpc::ClientReadReactor< ::xtcp_treatment::v1::WatchDesiredStateResponse>* reactor) override;
+ private:
+ friend class Stub;
+ explicit async(Stub* stub): stub_(stub) { }
+ Stub* stub() { return stub_; }
+ Stub* stub_;
+ };
+ class async* async() override { return &async_stub_; }
+
+ private:
+ std::shared_ptr< ::grpc::ChannelInterface> channel_;
+ class async async_stub_{this};
+ ::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::CheckInResponse>* AsyncCheckInRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest& request, ::grpc::CompletionQueue* cq) override;
+ ::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::CheckInResponse>* PrepareAsyncCheckInRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::CheckInRequest& request, ::grpc::CompletionQueue* cq) override;
+ ::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::GetDesiredStateResponse>* AsyncGetDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest& request, ::grpc::CompletionQueue* cq) override;
+ ::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::GetDesiredStateResponse>* PrepareAsyncGetDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest& request, ::grpc::CompletionQueue* cq) override;
+ ::grpc::ClientReader< ::xtcp_treatment::v1::WatchDesiredStateResponse>* WatchDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request) override;
+ ::grpc::ClientAsyncReader< ::xtcp_treatment::v1::WatchDesiredStateResponse>* AsyncWatchDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request, ::grpc::CompletionQueue* cq, void* tag) override;
+ ::grpc::ClientAsyncReader< ::xtcp_treatment::v1::WatchDesiredStateResponse>* PrepareAsyncWatchDesiredStateRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest& request, ::grpc::CompletionQueue* cq) override;
+ const ::grpc::internal::RpcMethod rpcmethod_CheckIn_;
+ const ::grpc::internal::RpcMethod rpcmethod_GetDesiredState_;
+ const ::grpc::internal::RpcMethod rpcmethod_WatchDesiredState_;
+ };
+ static std::unique_ptr NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
+
+ class Service : public ::grpc::Service {
+ public:
+ Service();
+ virtual ~Service();
+ virtual ::grpc::Status CheckIn(::grpc::ServerContext* context, const ::xtcp_treatment::v1::CheckInRequest* request, ::xtcp_treatment::v1::CheckInResponse* response);
+ virtual ::grpc::Status GetDesiredState(::grpc::ServerContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest* request, ::xtcp_treatment::v1::GetDesiredStateResponse* response);
+ virtual ::grpc::Status WatchDesiredState(::grpc::ServerContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest* request, ::grpc::ServerWriter< ::xtcp_treatment::v1::WatchDesiredStateResponse>* writer);
+ };
+ template
+ class WithAsyncMethod_CheckIn : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithAsyncMethod_CheckIn() {
+ ::grpc::Service::MarkMethodAsync(0);
+ }
+ ~WithAsyncMethod_CheckIn() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status CheckIn(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::CheckInRequest* /*request*/, ::xtcp_treatment::v1::CheckInResponse* /*response*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ void RequestCheckIn(::grpc::ServerContext* context, ::xtcp_treatment::v1::CheckInRequest* request, ::grpc::ServerAsyncResponseWriter< ::xtcp_treatment::v1::CheckInResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+ ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
+ }
+ };
+ template
+ class WithAsyncMethod_GetDesiredState : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithAsyncMethod_GetDesiredState() {
+ ::grpc::Service::MarkMethodAsync(1);
+ }
+ ~WithAsyncMethod_GetDesiredState() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status GetDesiredState(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::GetDesiredStateRequest* /*request*/, ::xtcp_treatment::v1::GetDesiredStateResponse* /*response*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ void RequestGetDesiredState(::grpc::ServerContext* context, ::xtcp_treatment::v1::GetDesiredStateRequest* request, ::grpc::ServerAsyncResponseWriter< ::xtcp_treatment::v1::GetDesiredStateResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+ ::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag);
+ }
+ };
+ template
+ class WithAsyncMethod_WatchDesiredState : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithAsyncMethod_WatchDesiredState() {
+ ::grpc::Service::MarkMethodAsync(2);
+ }
+ ~WithAsyncMethod_WatchDesiredState() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status WatchDesiredState(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::WatchDesiredStateRequest* /*request*/, ::grpc::ServerWriter< ::xtcp_treatment::v1::WatchDesiredStateResponse>* /*writer*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ void RequestWatchDesiredState(::grpc::ServerContext* context, ::xtcp_treatment::v1::WatchDesiredStateRequest* request, ::grpc::ServerAsyncWriter< ::xtcp_treatment::v1::WatchDesiredStateResponse>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+ ::grpc::Service::RequestAsyncServerStreaming(2, context, request, writer, new_call_cq, notification_cq, tag);
+ }
+ };
+ typedef WithAsyncMethod_CheckIn > > AsyncService;
+ template
+ class WithCallbackMethod_CheckIn : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithCallbackMethod_CheckIn() {
+ ::grpc::Service::MarkMethodCallback(0,
+ new ::grpc::internal::CallbackUnaryHandler< ::xtcp_treatment::v1::CheckInRequest, ::xtcp_treatment::v1::CheckInResponse>(
+ [this](
+ ::grpc::CallbackServerContext* context, const ::xtcp_treatment::v1::CheckInRequest* request, ::xtcp_treatment::v1::CheckInResponse* response) { return this->CheckIn(context, request, response); }));}
+ void SetMessageAllocatorFor_CheckIn(
+ ::grpc::MessageAllocator< ::xtcp_treatment::v1::CheckInRequest, ::xtcp_treatment::v1::CheckInResponse>* allocator) {
+ ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(0);
+ static_cast<::grpc::internal::CallbackUnaryHandler< ::xtcp_treatment::v1::CheckInRequest, ::xtcp_treatment::v1::CheckInResponse>*>(handler)
+ ->SetMessageAllocator(allocator);
+ }
+ ~WithCallbackMethod_CheckIn() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status CheckIn(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::CheckInRequest* /*request*/, ::xtcp_treatment::v1::CheckInResponse* /*response*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ virtual ::grpc::ServerUnaryReactor* CheckIn(
+ ::grpc::CallbackServerContext* /*context*/, const ::xtcp_treatment::v1::CheckInRequest* /*request*/, ::xtcp_treatment::v1::CheckInResponse* /*response*/) { return nullptr; }
+ };
+ template
+ class WithCallbackMethod_GetDesiredState : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithCallbackMethod_GetDesiredState() {
+ ::grpc::Service::MarkMethodCallback(1,
+ new ::grpc::internal::CallbackUnaryHandler< ::xtcp_treatment::v1::GetDesiredStateRequest, ::xtcp_treatment::v1::GetDesiredStateResponse>(
+ [this](
+ ::grpc::CallbackServerContext* context, const ::xtcp_treatment::v1::GetDesiredStateRequest* request, ::xtcp_treatment::v1::GetDesiredStateResponse* response) { return this->GetDesiredState(context, request, response); }));}
+ void SetMessageAllocatorFor_GetDesiredState(
+ ::grpc::MessageAllocator< ::xtcp_treatment::v1::GetDesiredStateRequest, ::xtcp_treatment::v1::GetDesiredStateResponse>* allocator) {
+ ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(1);
+ static_cast<::grpc::internal::CallbackUnaryHandler< ::xtcp_treatment::v1::GetDesiredStateRequest, ::xtcp_treatment::v1::GetDesiredStateResponse>*>(handler)
+ ->SetMessageAllocator(allocator);
+ }
+ ~WithCallbackMethod_GetDesiredState() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status GetDesiredState(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::GetDesiredStateRequest* /*request*/, ::xtcp_treatment::v1::GetDesiredStateResponse* /*response*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ virtual ::grpc::ServerUnaryReactor* GetDesiredState(
+ ::grpc::CallbackServerContext* /*context*/, const ::xtcp_treatment::v1::GetDesiredStateRequest* /*request*/, ::xtcp_treatment::v1::GetDesiredStateResponse* /*response*/) { return nullptr; }
+ };
+ template
+ class WithCallbackMethod_WatchDesiredState : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithCallbackMethod_WatchDesiredState() {
+ ::grpc::Service::MarkMethodCallback(2,
+ new ::grpc::internal::CallbackServerStreamingHandler< ::xtcp_treatment::v1::WatchDesiredStateRequest, ::xtcp_treatment::v1::WatchDesiredStateResponse>(
+ [this](
+ ::grpc::CallbackServerContext* context, const ::xtcp_treatment::v1::WatchDesiredStateRequest* request) { return this->WatchDesiredState(context, request); }));
+ }
+ ~WithCallbackMethod_WatchDesiredState() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status WatchDesiredState(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::WatchDesiredStateRequest* /*request*/, ::grpc::ServerWriter< ::xtcp_treatment::v1::WatchDesiredStateResponse>* /*writer*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ virtual ::grpc::ServerWriteReactor< ::xtcp_treatment::v1::WatchDesiredStateResponse>* WatchDesiredState(
+ ::grpc::CallbackServerContext* /*context*/, const ::xtcp_treatment::v1::WatchDesiredStateRequest* /*request*/) { return nullptr; }
+ };
+ typedef WithCallbackMethod_CheckIn > > CallbackService;
+ typedef CallbackService ExperimentalCallbackService;
+ template
+ class WithGenericMethod_CheckIn : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithGenericMethod_CheckIn() {
+ ::grpc::Service::MarkMethodGeneric(0);
+ }
+ ~WithGenericMethod_CheckIn() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status CheckIn(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::CheckInRequest* /*request*/, ::xtcp_treatment::v1::CheckInResponse* /*response*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ };
+ template
+ class WithGenericMethod_GetDesiredState : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithGenericMethod_GetDesiredState() {
+ ::grpc::Service::MarkMethodGeneric(1);
+ }
+ ~WithGenericMethod_GetDesiredState() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status GetDesiredState(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::GetDesiredStateRequest* /*request*/, ::xtcp_treatment::v1::GetDesiredStateResponse* /*response*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ };
+ template
+ class WithGenericMethod_WatchDesiredState : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithGenericMethod_WatchDesiredState() {
+ ::grpc::Service::MarkMethodGeneric(2);
+ }
+ ~WithGenericMethod_WatchDesiredState() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status WatchDesiredState(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::WatchDesiredStateRequest* /*request*/, ::grpc::ServerWriter< ::xtcp_treatment::v1::WatchDesiredStateResponse>* /*writer*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ };
+ template
+ class WithRawMethod_CheckIn : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithRawMethod_CheckIn() {
+ ::grpc::Service::MarkMethodRaw(0);
+ }
+ ~WithRawMethod_CheckIn() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status CheckIn(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::CheckInRequest* /*request*/, ::xtcp_treatment::v1::CheckInResponse* /*response*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ void RequestCheckIn(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+ ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
+ }
+ };
+ template
+ class WithRawMethod_GetDesiredState : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithRawMethod_GetDesiredState() {
+ ::grpc::Service::MarkMethodRaw(1);
+ }
+ ~WithRawMethod_GetDesiredState() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status GetDesiredState(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::GetDesiredStateRequest* /*request*/, ::xtcp_treatment::v1::GetDesiredStateResponse* /*response*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ void RequestGetDesiredState(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+ ::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag);
+ }
+ };
+ template
+ class WithRawMethod_WatchDesiredState : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithRawMethod_WatchDesiredState() {
+ ::grpc::Service::MarkMethodRaw(2);
+ }
+ ~WithRawMethod_WatchDesiredState() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status WatchDesiredState(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::WatchDesiredStateRequest* /*request*/, ::grpc::ServerWriter< ::xtcp_treatment::v1::WatchDesiredStateResponse>* /*writer*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ void RequestWatchDesiredState(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncWriter< ::grpc::ByteBuffer>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+ ::grpc::Service::RequestAsyncServerStreaming(2, context, request, writer, new_call_cq, notification_cq, tag);
+ }
+ };
+ template
+ class WithRawCallbackMethod_CheckIn : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithRawCallbackMethod_CheckIn() {
+ ::grpc::Service::MarkMethodRawCallback(0,
+ new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+ [this](
+ ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->CheckIn(context, request, response); }));
+ }
+ ~WithRawCallbackMethod_CheckIn() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status CheckIn(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::CheckInRequest* /*request*/, ::xtcp_treatment::v1::CheckInResponse* /*response*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ virtual ::grpc::ServerUnaryReactor* CheckIn(
+ ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/) { return nullptr; }
+ };
+ template
+ class WithRawCallbackMethod_GetDesiredState : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithRawCallbackMethod_GetDesiredState() {
+ ::grpc::Service::MarkMethodRawCallback(1,
+ new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+ [this](
+ ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->GetDesiredState(context, request, response); }));
+ }
+ ~WithRawCallbackMethod_GetDesiredState() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status GetDesiredState(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::GetDesiredStateRequest* /*request*/, ::xtcp_treatment::v1::GetDesiredStateResponse* /*response*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ virtual ::grpc::ServerUnaryReactor* GetDesiredState(
+ ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/) { return nullptr; }
+ };
+ template
+ class WithRawCallbackMethod_WatchDesiredState : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithRawCallbackMethod_WatchDesiredState() {
+ ::grpc::Service::MarkMethodRawCallback(2,
+ new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+ [this](
+ ::grpc::CallbackServerContext* context, const::grpc::ByteBuffer* request) { return this->WatchDesiredState(context, request); }));
+ }
+ ~WithRawCallbackMethod_WatchDesiredState() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable synchronous version of this method
+ ::grpc::Status WatchDesiredState(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::WatchDesiredStateRequest* /*request*/, ::grpc::ServerWriter< ::xtcp_treatment::v1::WatchDesiredStateResponse>* /*writer*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ virtual ::grpc::ServerWriteReactor< ::grpc::ByteBuffer>* WatchDesiredState(
+ ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/) { return nullptr; }
+ };
+ template
+ class WithStreamedUnaryMethod_CheckIn : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithStreamedUnaryMethod_CheckIn() {
+ ::grpc::Service::MarkMethodStreamed(0,
+ new ::grpc::internal::StreamedUnaryHandler<
+ ::xtcp_treatment::v1::CheckInRequest, ::xtcp_treatment::v1::CheckInResponse>(
+ [this](::grpc::ServerContext* context,
+ ::grpc::ServerUnaryStreamer<
+ ::xtcp_treatment::v1::CheckInRequest, ::xtcp_treatment::v1::CheckInResponse>* streamer) {
+ return this->StreamedCheckIn(context,
+ streamer);
+ }));
+ }
+ ~WithStreamedUnaryMethod_CheckIn() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable regular version of this method
+ ::grpc::Status CheckIn(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::CheckInRequest* /*request*/, ::xtcp_treatment::v1::CheckInResponse* /*response*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ // replace default version of method with streamed unary
+ virtual ::grpc::Status StreamedCheckIn(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::xtcp_treatment::v1::CheckInRequest,::xtcp_treatment::v1::CheckInResponse>* server_unary_streamer) = 0;
+ };
+ template
+ class WithStreamedUnaryMethod_GetDesiredState : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithStreamedUnaryMethod_GetDesiredState() {
+ ::grpc::Service::MarkMethodStreamed(1,
+ new ::grpc::internal::StreamedUnaryHandler<
+ ::xtcp_treatment::v1::GetDesiredStateRequest, ::xtcp_treatment::v1::GetDesiredStateResponse>(
+ [this](::grpc::ServerContext* context,
+ ::grpc::ServerUnaryStreamer<
+ ::xtcp_treatment::v1::GetDesiredStateRequest, ::xtcp_treatment::v1::GetDesiredStateResponse>* streamer) {
+ return this->StreamedGetDesiredState(context,
+ streamer);
+ }));
+ }
+ ~WithStreamedUnaryMethod_GetDesiredState() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable regular version of this method
+ ::grpc::Status GetDesiredState(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::GetDesiredStateRequest* /*request*/, ::xtcp_treatment::v1::GetDesiredStateResponse* /*response*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ // replace default version of method with streamed unary
+ virtual ::grpc::Status StreamedGetDesiredState(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::xtcp_treatment::v1::GetDesiredStateRequest,::xtcp_treatment::v1::GetDesiredStateResponse>* server_unary_streamer) = 0;
+ };
+ typedef WithStreamedUnaryMethod_CheckIn > StreamedUnaryService;
+ template
+ class WithSplitStreamingMethod_WatchDesiredState : public BaseClass {
+ private:
+ void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+ public:
+ WithSplitStreamingMethod_WatchDesiredState() {
+ ::grpc::Service::MarkMethodStreamed(2,
+ new ::grpc::internal::SplitServerStreamingHandler<
+ ::xtcp_treatment::v1::WatchDesiredStateRequest, ::xtcp_treatment::v1::WatchDesiredStateResponse>(
+ [this](::grpc::ServerContext* context,
+ ::grpc::ServerSplitStreamer<
+ ::xtcp_treatment::v1::WatchDesiredStateRequest, ::xtcp_treatment::v1::WatchDesiredStateResponse>* streamer) {
+ return this->StreamedWatchDesiredState(context,
+ streamer);
+ }));
+ }
+ ~WithSplitStreamingMethod_WatchDesiredState() override {
+ BaseClassMustBeDerivedFromService(this);
+ }
+ // disable regular version of this method
+ ::grpc::Status WatchDesiredState(::grpc::ServerContext* /*context*/, const ::xtcp_treatment::v1::WatchDesiredStateRequest* /*request*/, ::grpc::ServerWriter< ::xtcp_treatment::v1::WatchDesiredStateResponse>* /*writer*/) override {
+ abort();
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+ }
+ // replace default version of method with split streamed
+ virtual ::grpc::Status StreamedWatchDesiredState(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::xtcp_treatment::v1::WatchDesiredStateRequest,::xtcp_treatment::v1::WatchDesiredStateResponse>* server_split_streamer) = 0;
+ };
+ typedef WithSplitStreamingMethod_WatchDesiredState SplitStreamedService;
+ typedef WithStreamedUnaryMethod_CheckIn > > StreamedService;
+};
+
+} // namespace v1
+} // namespace xtcp_treatment
+
+
+#include
+#endif // GRPC_xtcp_5ftreatment_2fv1_2fagent_2eproto__INCLUDED
diff --git a/gen/cpp/xtcp_treatment/v1/agent.pb.cc b/gen/cpp/xtcp_treatment/v1/agent.pb.cc
new file mode 100644
index 000000000..61f3a1def
--- /dev/null
+++ b/gen/cpp/xtcp_treatment/v1/agent.pb.cc
@@ -0,0 +1,2576 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// NO CHECKED-IN PROTOBUF GENCODE
+// source: xtcp_treatment/v1/agent.proto
+// Protobuf C++ Version: 7.36.2
+
+#include "xtcp_treatment/v1/agent.pb.h"
+
+#include
+#include
+#include "google/protobuf/io/coded_stream.h"
+#include "google/protobuf/generated_message_tctable_impl.h"
+#include "google/protobuf/internal_visibility.h"
+#include "google/protobuf/extension_set.h"
+#include "google/protobuf/generated_message_util.h"
+#include "google/protobuf/wire_format_lite.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/generated_message_reflection.h"
+#include "google/protobuf/reflection_ops.h"
+#include "google/protobuf/wire_format.h"
+// @@protoc_insertion_point(includes)
+
+// Must be included last.
+#include "google/protobuf/port_def.inc"
+PROTOBUF_PRAGMA_INIT_SEG
+namespace _pb = ::google::protobuf;
+namespace _pbi = ::google::protobuf::internal;
+namespace _fl = ::google::protobuf::internal::field_layout;
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+namespace {
+PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData
+ file_reflection_data[] = {
+ // ::xtcp_treatment::v1::CheckInRequest
+ {&::_pbi::kDescriptorMethods, &::descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto, /* tracker*/ nullptr,},
+ // ::xtcp_treatment::v1::CheckInResponse
+ {&::_pbi::kDescriptorMethods, &::descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto, /* tracker*/ nullptr,},
+ // ::xtcp_treatment::v1::GetDesiredStateRequest
+ {&::_pbi::kDescriptorMethods, &::descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto, /* tracker*/ nullptr,},
+ // ::xtcp_treatment::v1::GetDesiredStateResponse
+ {&::_pbi::kDescriptorMethods, &::descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto, /* tracker*/ nullptr,},
+ // ::xtcp_treatment::v1::WatchDesiredStateRequest
+ {&::_pbi::kDescriptorMethods, &::descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto, /* tracker*/ nullptr,},
+ // ::xtcp_treatment::v1::WatchDesiredStateResponse
+ {&::_pbi::kDescriptorMethods, &::descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto, /* tracker*/ nullptr,},
+};
+} // namespace
+#endif
+namespace xtcp_treatment {
+namespace v1 {
+class WatchDesiredStateResponse::_Internal {
+ public:
+ using HasBits = decltype(::std::declval()._impl_._has_bits_);
+ static constexpr ::int32_t kHasBitsOffset =
+ 8 * PROTOBUF_FIELD_OFFSET(WatchDesiredStateResponse, _impl_._has_bits_);
+};
+
+constexpr WatchDesiredStateResponse::ParseTableT_ WatchDesiredStateResponse::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) {
+ return ParseTableT_{
+ {
+ PROTOBUF_FIELD_OFFSET(WatchDesiredStateResponse, _impl_._has_bits_),
+ 0, // no _extensions_
+ 1, 0, // max_field_number, fast_idx_mask
+ offsetof(ParseTableT_, field_lookup_table),
+ 4294967294, // skipmap
+ offsetof(ParseTableT_, field_entries),
+ 1, // num_field_entries
+ 0, // num_aux_entries
+ offsetof(ParseTableT_, field_names), // no aux_entries
+ class_data,
+ nullptr, // post_loop_handler
+ ::_pbi::TcParser::MpUnknownFields, // fallback
+ #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
+ ::_pbi::TcParser::GetTable<::xtcp_treatment::v1::WatchDesiredStateResponse>(), // to_prefetch
+ #endif // PROTOBUF_PREFETCH_PARSE_TABLE
+ }, {{
+ // uint64 revision = 1 [json_name = "revision"];
+ {::_pbi::TcParser::SingularVarintNoZag1<::uint64_t, offsetof(WatchDesiredStateResponse, _impl_.revision_), 0>(),
+ {8, 0, 0,
+ PROTOBUF_FIELD_OFFSET(WatchDesiredStateResponse, _impl_.revision_)}},
+ }}, {{
+ 65535, 65535
+ }}, {{
+ // uint64 revision = 1 [json_name = "revision"];
+ {PROTOBUF_FIELD_OFFSET(WatchDesiredStateResponse, _impl_.revision_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kUInt64)},
+ }},
+ // no aux_entries
+ {{
+ }},
+ };
+}
+
+
+inline constexpr WatchDesiredStateResponse::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ ::_pbi::ConstantInitialized) noexcept
+ : revision_{::uint64_t{0u}} {}
+
+template
+constexpr WatchDesiredStateResponse::WatchDesiredStateResponse(::_pbi::ConstantInitialized,
+ const ::_pbi::ClassData* PROTOBUF_NONNULL class_data)
+ : Super_(
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ class_data
+#endif // PROTOBUF_CUSTOM_VTABLE
+ ),
+ _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) {
+}
+inline void* PROTOBUF_NONNULL WatchDesiredStateResponse::PlacementNew_(
+ const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {
+ return ::new (mem) WatchDesiredStateResponse(arena);
+}
+constexpr auto WatchDesiredStateResponse::InternalNewImpl_() {
+ return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(WatchDesiredStateResponse), alignof(WatchDesiredStateResponse));
+}
+constexpr auto WatchDesiredStateResponse::InternalGenerateClassData_(
+ const MessageLite& prototype,
+ const ::google::protobuf::internal::TcParseTableBase* tc_table) {
+ return ::google::protobuf::internal::ClassDataFull{
+ ::google::protobuf::internal::ClassData{
+ &prototype,
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+ &_table_.header,
+#else
+ tc_table,
+#endif
+ nullptr, // IsInitialized
+ &WatchDesiredStateResponse::MergeImpl,
+ Super_::GetNewImpl(),
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ &WatchDesiredStateResponse::SharedDtor,
+ Super_::GetClearImpl(), &WatchDesiredStateResponse::ByteSizeLong,
+ &WatchDesiredStateResponse::_InternalSerialize,
+#endif // PROTOBUF_CUSTOM_VTABLE
+ PROTOBUF_FIELD_OFFSET(WatchDesiredStateResponse, _impl_._cached_size_),
+ false,
+ },
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ &file_reflection_data[5],
+#else // !PROTOBUF_MESSAGE_GLOBALS
+ &::_pbi::kDescriptorMethods,
+ &descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto,
+ nullptr, // tracker
+#endif // PROTOBUF_MESSAGE_GLOBALS
+ };
+}
+struct WatchDesiredStateResponseGlobalsTypeInternal : ::_pbi::MessageGlobalsBase {
+ constexpr WatchDesiredStateResponseGlobalsTypeInternal()
+ :
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+ _default(::_pbi::ConstantInitialized{},
+ WatchDesiredStateResponse_class_data_.base())
+#else // !PROTOBUF_MESSAGE_GLOBALS
+ MessageGlobalsBase(WatchDesiredStateResponse::InternalGenerateClassData_(
+ _default, &WatchDesiredStateResponse_globals_._table.header)),
+ _default(::_pbi::ConstantInitialized{}, GetClassData()),
+ _table(::_pbi::PrivateAccess::GenerateParseTable(
+ GetClassData()))
+#endif // PROTOBUF_MESSAGE_GLOBALS
+ {
+ }
+ ~WatchDesiredStateResponseGlobalsTypeInternal() {}
+ union {
+ alignas(::_pbi::kMaxMessageAlignment) WatchDesiredStateResponse _default;
+ };
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ decltype(::_pbi::PrivateAccess::GenerateParseTable(
+ ::std::declval())) _table;
+#endif
+};
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+static_assert(PROTOBUF_FIELD_OFFSET(WatchDesiredStateResponseGlobalsTypeInternal, _default) ==
+ ::_pbi::MessageGlobalsBase::OffsetToDefault());
+#endif // PROTOBUF_MESSAGE_GLOBALS
+
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
+ PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST WatchDesiredStateResponseGlobalsTypeInternal WatchDesiredStateResponse_globals_
+ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro);
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+namespace {
+const ::_pbi::ClassData* WatchDesiredStateResponse_get_class_data() {
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ return WatchDesiredStateResponse_globals_.GetClassData();
+#else
+ return WatchDesiredStateResponse_class_data_.base();
+#endif // PROTOBUF_MESSAGE_GLOBALS
+}
+} // namespace
+#endif // PROTOBUF_CUSTOM_VTABLE
+class WatchDesiredStateRequest::_Internal {
+ public:
+ using HasBits = decltype(::std::declval()._impl_._has_bits_);
+ static constexpr ::int32_t kHasBitsOffset =
+ 8 * PROTOBUF_FIELD_OFFSET(WatchDesiredStateRequest, _impl_._has_bits_);
+};
+
+constexpr WatchDesiredStateRequest::ParseTableT_ WatchDesiredStateRequest::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) {
+ return ParseTableT_{
+ {
+ PROTOBUF_FIELD_OFFSET(WatchDesiredStateRequest, _impl_._has_bits_),
+ 0, // no _extensions_
+ 2, 8, // max_field_number, fast_idx_mask
+ offsetof(ParseTableT_, field_lookup_table),
+ 4294967292, // skipmap
+ offsetof(ParseTableT_, field_entries),
+ 2, // num_field_entries
+ 0, // num_aux_entries
+ offsetof(ParseTableT_, field_names), // no aux_entries
+ class_data,
+ nullptr, // post_loop_handler
+ ::_pbi::TcParser::MpUnknownFields, // fallback
+ #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
+ ::_pbi::TcParser::GetTable<::xtcp_treatment::v1::WatchDesiredStateRequest>(), // to_prefetch
+ #endif // PROTOBUF_PREFETCH_PARSE_TABLE
+ }, {{
+ // uint64 after_revision = 2 [json_name = "afterRevision"];
+ {::_pbi::TcParser::SingularVarintNoZag1<::uint64_t, offsetof(WatchDesiredStateRequest, _impl_.after_revision_), 1>(),
+ {16, 1, 0,
+ PROTOBUF_FIELD_OFFSET(WatchDesiredStateRequest, _impl_.after_revision_)}},
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ {::_pbi::TcParser::FastUS1,
+ {10, 0, 0,
+ PROTOBUF_FIELD_OFFSET(WatchDesiredStateRequest, _impl_.agent_id_)}},
+ }}, {{
+ 65535, 65535
+ }}, {{
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ {PROTOBUF_FIELD_OFFSET(WatchDesiredStateRequest, _impl_.agent_id_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kUtf8String | ::_fl::kRepAString)},
+ // uint64 after_revision = 2 [json_name = "afterRevision"];
+ {PROTOBUF_FIELD_OFFSET(WatchDesiredStateRequest, _impl_.after_revision_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kUInt64)},
+ }},
+ // no aux_entries
+ {{
+ "\52\10\0\0\0\0\0\0"
+ "xtcp_treatment.v1.WatchDesiredStateRequest"
+ "agent_id"
+ }},
+ };
+}
+
+
+inline constexpr WatchDesiredStateRequest::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ ::_pbi::ConstantInitialized) noexcept
+ : agent_id_(
+ &::google::protobuf::internal::fixed_address_empty_string,
+ ::_pbi::ConstantInitialized()),
+ after_revision_{::uint64_t{0u}} {}
+
+template
+constexpr WatchDesiredStateRequest::WatchDesiredStateRequest(::_pbi::ConstantInitialized,
+ const ::_pbi::ClassData* PROTOBUF_NONNULL class_data)
+ : Super_(
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ class_data
+#endif // PROTOBUF_CUSTOM_VTABLE
+ ),
+ _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) {
+}
+inline void* PROTOBUF_NONNULL WatchDesiredStateRequest::PlacementNew_(
+ const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {
+ return ::new (mem) WatchDesiredStateRequest(arena);
+}
+constexpr auto WatchDesiredStateRequest::InternalNewImpl_() {
+ return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(WatchDesiredStateRequest), alignof(WatchDesiredStateRequest));
+}
+constexpr auto WatchDesiredStateRequest::InternalGenerateClassData_(
+ const MessageLite& prototype,
+ const ::google::protobuf::internal::TcParseTableBase* tc_table) {
+ return ::google::protobuf::internal::ClassDataFull{
+ ::google::protobuf::internal::ClassData{
+ &prototype,
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+ &_table_.header,
+#else
+ tc_table,
+#endif
+ nullptr, // IsInitialized
+ &WatchDesiredStateRequest::MergeImpl,
+ Super_::GetNewImpl(),
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ &WatchDesiredStateRequest::SharedDtor,
+ Super_::GetClearImpl(), &WatchDesiredStateRequest::ByteSizeLong,
+ &WatchDesiredStateRequest::_InternalSerialize,
+#endif // PROTOBUF_CUSTOM_VTABLE
+ PROTOBUF_FIELD_OFFSET(WatchDesiredStateRequest, _impl_._cached_size_),
+ false,
+ },
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ &file_reflection_data[4],
+#else // !PROTOBUF_MESSAGE_GLOBALS
+ &::_pbi::kDescriptorMethods,
+ &descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto,
+ nullptr, // tracker
+#endif // PROTOBUF_MESSAGE_GLOBALS
+ };
+}
+struct WatchDesiredStateRequestGlobalsTypeInternal : ::_pbi::MessageGlobalsBase {
+ constexpr WatchDesiredStateRequestGlobalsTypeInternal()
+ :
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+ _default(::_pbi::ConstantInitialized{},
+ WatchDesiredStateRequest_class_data_.base())
+#else // !PROTOBUF_MESSAGE_GLOBALS
+ MessageGlobalsBase(WatchDesiredStateRequest::InternalGenerateClassData_(
+ _default, &WatchDesiredStateRequest_globals_._table.header)),
+ _default(::_pbi::ConstantInitialized{}, GetClassData()),
+ _table(::_pbi::PrivateAccess::GenerateParseTable(
+ GetClassData()))
+#endif // PROTOBUF_MESSAGE_GLOBALS
+ {
+ }
+ ~WatchDesiredStateRequestGlobalsTypeInternal() {}
+ union {
+ alignas(::_pbi::kMaxMessageAlignment) WatchDesiredStateRequest _default;
+ };
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ decltype(::_pbi::PrivateAccess::GenerateParseTable(
+ ::std::declval())) _table;
+#endif
+};
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+static_assert(PROTOBUF_FIELD_OFFSET(WatchDesiredStateRequestGlobalsTypeInternal, _default) ==
+ ::_pbi::MessageGlobalsBase::OffsetToDefault());
+#endif // PROTOBUF_MESSAGE_GLOBALS
+
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
+ PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST WatchDesiredStateRequestGlobalsTypeInternal WatchDesiredStateRequest_globals_
+ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro);
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+namespace {
+const ::_pbi::ClassData* WatchDesiredStateRequest_get_class_data() {
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ return WatchDesiredStateRequest_globals_.GetClassData();
+#else
+ return WatchDesiredStateRequest_class_data_.base();
+#endif // PROTOBUF_MESSAGE_GLOBALS
+}
+} // namespace
+#endif // PROTOBUF_CUSTOM_VTABLE
+class GetDesiredStateRequest::_Internal {
+ public:
+ using HasBits = decltype(::std::declval()._impl_._has_bits_);
+ static constexpr ::int32_t kHasBitsOffset =
+ 8 * PROTOBUF_FIELD_OFFSET(GetDesiredStateRequest, _impl_._has_bits_);
+};
+
+constexpr GetDesiredStateRequest::ParseTableT_ GetDesiredStateRequest::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) {
+ return ParseTableT_{
+ {
+ PROTOBUF_FIELD_OFFSET(GetDesiredStateRequest, _impl_._has_bits_),
+ 0, // no _extensions_
+ 1, 0, // max_field_number, fast_idx_mask
+ offsetof(ParseTableT_, field_lookup_table),
+ 4294967294, // skipmap
+ offsetof(ParseTableT_, field_entries),
+ 1, // num_field_entries
+ 0, // num_aux_entries
+ offsetof(ParseTableT_, field_names), // no aux_entries
+ class_data,
+ nullptr, // post_loop_handler
+ ::_pbi::TcParser::MpUnknownFields, // fallback
+ #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
+ ::_pbi::TcParser::GetTable<::xtcp_treatment::v1::GetDesiredStateRequest>(), // to_prefetch
+ #endif // PROTOBUF_PREFETCH_PARSE_TABLE
+ }, {{
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ {::_pbi::TcParser::FastUS1,
+ {10, 0, 0,
+ PROTOBUF_FIELD_OFFSET(GetDesiredStateRequest, _impl_.agent_id_)}},
+ }}, {{
+ 65535, 65535
+ }}, {{
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ {PROTOBUF_FIELD_OFFSET(GetDesiredStateRequest, _impl_.agent_id_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kUtf8String | ::_fl::kRepAString)},
+ }},
+ // no aux_entries
+ {{
+ "\50\10\0\0\0\0\0\0"
+ "xtcp_treatment.v1.GetDesiredStateRequest"
+ "agent_id"
+ }},
+ };
+}
+
+
+inline constexpr GetDesiredStateRequest::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ ::_pbi::ConstantInitialized) noexcept
+ : agent_id_(
+ &::google::protobuf::internal::fixed_address_empty_string,
+ ::_pbi::ConstantInitialized()) {}
+
+template
+constexpr GetDesiredStateRequest::GetDesiredStateRequest(::_pbi::ConstantInitialized,
+ const ::_pbi::ClassData* PROTOBUF_NONNULL class_data)
+ : Super_(
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ class_data
+#endif // PROTOBUF_CUSTOM_VTABLE
+ ),
+ _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) {
+}
+inline void* PROTOBUF_NONNULL GetDesiredStateRequest::PlacementNew_(
+ const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {
+ return ::new (mem) GetDesiredStateRequest(arena);
+}
+constexpr auto GetDesiredStateRequest::InternalNewImpl_() {
+ return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(GetDesiredStateRequest), alignof(GetDesiredStateRequest));
+}
+constexpr auto GetDesiredStateRequest::InternalGenerateClassData_(
+ const MessageLite& prototype,
+ const ::google::protobuf::internal::TcParseTableBase* tc_table) {
+ return ::google::protobuf::internal::ClassDataFull{
+ ::google::protobuf::internal::ClassData{
+ &prototype,
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+ &_table_.header,
+#else
+ tc_table,
+#endif
+ nullptr, // IsInitialized
+ &GetDesiredStateRequest::MergeImpl,
+ Super_::GetNewImpl(),
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ &GetDesiredStateRequest::SharedDtor,
+ Super_::GetClearImpl(), &GetDesiredStateRequest::ByteSizeLong,
+ &GetDesiredStateRequest::_InternalSerialize,
+#endif // PROTOBUF_CUSTOM_VTABLE
+ PROTOBUF_FIELD_OFFSET(GetDesiredStateRequest, _impl_._cached_size_),
+ false,
+ },
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ &file_reflection_data[2],
+#else // !PROTOBUF_MESSAGE_GLOBALS
+ &::_pbi::kDescriptorMethods,
+ &descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto,
+ nullptr, // tracker
+#endif // PROTOBUF_MESSAGE_GLOBALS
+ };
+}
+struct GetDesiredStateRequestGlobalsTypeInternal : ::_pbi::MessageGlobalsBase {
+ constexpr GetDesiredStateRequestGlobalsTypeInternal()
+ :
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+ _default(::_pbi::ConstantInitialized{},
+ GetDesiredStateRequest_class_data_.base())
+#else // !PROTOBUF_MESSAGE_GLOBALS
+ MessageGlobalsBase(GetDesiredStateRequest::InternalGenerateClassData_(
+ _default, &GetDesiredStateRequest_globals_._table.header)),
+ _default(::_pbi::ConstantInitialized{}, GetClassData()),
+ _table(::_pbi::PrivateAccess::GenerateParseTable(
+ GetClassData()))
+#endif // PROTOBUF_MESSAGE_GLOBALS
+ {
+ }
+ ~GetDesiredStateRequestGlobalsTypeInternal() {}
+ union {
+ alignas(::_pbi::kMaxMessageAlignment) GetDesiredStateRequest _default;
+ };
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ decltype(::_pbi::PrivateAccess::GenerateParseTable(
+ ::std::declval())) _table;
+#endif
+};
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+static_assert(PROTOBUF_FIELD_OFFSET(GetDesiredStateRequestGlobalsTypeInternal, _default) ==
+ ::_pbi::MessageGlobalsBase::OffsetToDefault());
+#endif // PROTOBUF_MESSAGE_GLOBALS
+
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
+ PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST GetDesiredStateRequestGlobalsTypeInternal GetDesiredStateRequest_globals_
+ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro);
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+namespace {
+const ::_pbi::ClassData* GetDesiredStateRequest_get_class_data() {
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ return GetDesiredStateRequest_globals_.GetClassData();
+#else
+ return GetDesiredStateRequest_class_data_.base();
+#endif // PROTOBUF_MESSAGE_GLOBALS
+}
+} // namespace
+#endif // PROTOBUF_CUSTOM_VTABLE
+class GetDesiredStateResponse::_Internal {
+ public:
+ using HasBits = decltype(::std::declval()._impl_._has_bits_);
+ static constexpr ::int32_t kHasBitsOffset =
+ 8 * PROTOBUF_FIELD_OFFSET(GetDesiredStateResponse, _impl_._has_bits_);
+};
+
+constexpr GetDesiredStateResponse::ParseTableT_ GetDesiredStateResponse::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) {
+ return ParseTableT_{
+ {
+ PROTOBUF_FIELD_OFFSET(GetDesiredStateResponse, _impl_._has_bits_),
+ 0, // no _extensions_
+ 1, 0, // max_field_number, fast_idx_mask
+ offsetof(ParseTableT_, field_lookup_table),
+ 4294967294, // skipmap
+ offsetof(ParseTableT_, field_entries),
+ 1, // num_field_entries
+ 1, // num_aux_entries
+ offsetof(ParseTableT_, aux_entries),
+ class_data,
+ nullptr, // post_loop_handler
+ ::_pbi::TcParser::MpUnknownFields, // fallback
+ #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
+ ::_pbi::TcParser::GetTable<::xtcp_treatment::v1::GetDesiredStateResponse>(), // to_prefetch
+ #endif // PROTOBUF_PREFETCH_PARSE_TABLE
+ }, {{
+ // .xtcp_treatment.v1.DesiredState desired = 1 [json_name = "desired"];
+ {::_pbi::TcParser::FastMtS1,
+ {10, 0, 0,
+ PROTOBUF_FIELD_OFFSET(GetDesiredStateResponse, _impl_.desired_)}},
+ }}, {{
+ 65535, 65535
+ }}, {{
+ // .xtcp_treatment.v1.DesiredState desired = 1 [json_name = "desired"];
+ {PROTOBUF_FIELD_OFFSET(GetDesiredStateResponse, _impl_.desired_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)},
+ }},
+ {{
+ #ifndef PROTOBUF_MESSAGE_GLOBALS
+ {::_pbi::TcParser::GetTable<::xtcp_treatment::v1::DesiredState>()},
+ #else
+ {::_pbi::FieldAuxMessageGlobals(), &::xtcp_treatment::v1::DesiredState_globals_},
+ #endif
+ }},
+ {{
+ }},
+ };
+}
+
+
+inline constexpr GetDesiredStateResponse::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ ::_pbi::ConstantInitialized) noexcept
+ : desired_{nullptr} {}
+
+template
+constexpr GetDesiredStateResponse::GetDesiredStateResponse(::_pbi::ConstantInitialized,
+ const ::_pbi::ClassData* PROTOBUF_NONNULL class_data)
+ : Super_(
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ class_data
+#endif // PROTOBUF_CUSTOM_VTABLE
+ ),
+ _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) {
+}
+inline void* PROTOBUF_NONNULL GetDesiredStateResponse::PlacementNew_(
+ const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {
+ return ::new (mem) GetDesiredStateResponse(arena);
+}
+constexpr auto GetDesiredStateResponse::InternalNewImpl_() {
+ return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(GetDesiredStateResponse), alignof(GetDesiredStateResponse));
+}
+constexpr auto GetDesiredStateResponse::InternalGenerateClassData_(
+ const MessageLite& prototype,
+ const ::google::protobuf::internal::TcParseTableBase* tc_table) {
+ return ::google::protobuf::internal::ClassDataFull{
+ ::google::protobuf::internal::ClassData{
+ &prototype,
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+ &_table_.header,
+#else
+ tc_table,
+#endif
+ nullptr, // IsInitialized
+ &GetDesiredStateResponse::MergeImpl,
+ Super_::GetNewImpl(),
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ &GetDesiredStateResponse::SharedDtor,
+ Super_::GetClearImpl(), &GetDesiredStateResponse::ByteSizeLong,
+ &GetDesiredStateResponse::_InternalSerialize,
+#endif // PROTOBUF_CUSTOM_VTABLE
+ PROTOBUF_FIELD_OFFSET(GetDesiredStateResponse, _impl_._cached_size_),
+ false,
+ },
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ &file_reflection_data[3],
+#else // !PROTOBUF_MESSAGE_GLOBALS
+ &::_pbi::kDescriptorMethods,
+ &descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto,
+ nullptr, // tracker
+#endif // PROTOBUF_MESSAGE_GLOBALS
+ };
+}
+struct GetDesiredStateResponseGlobalsTypeInternal : ::_pbi::MessageGlobalsBase {
+ constexpr GetDesiredStateResponseGlobalsTypeInternal()
+ :
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+ _default(::_pbi::ConstantInitialized{},
+ GetDesiredStateResponse_class_data_.base())
+#else // !PROTOBUF_MESSAGE_GLOBALS
+ MessageGlobalsBase(GetDesiredStateResponse::InternalGenerateClassData_(
+ _default, &GetDesiredStateResponse_globals_._table.header)),
+ _default(::_pbi::ConstantInitialized{}, GetClassData()),
+ _table(::_pbi::PrivateAccess::GenerateParseTable(
+ GetClassData()))
+#endif // PROTOBUF_MESSAGE_GLOBALS
+ {
+ }
+ ~GetDesiredStateResponseGlobalsTypeInternal() {}
+ union {
+ alignas(::_pbi::kMaxMessageAlignment) GetDesiredStateResponse _default;
+ };
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ decltype(::_pbi::PrivateAccess::GenerateParseTable(
+ ::std::declval())) _table;
+#endif
+};
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+static_assert(PROTOBUF_FIELD_OFFSET(GetDesiredStateResponseGlobalsTypeInternal, _default) ==
+ ::_pbi::MessageGlobalsBase::OffsetToDefault());
+#endif // PROTOBUF_MESSAGE_GLOBALS
+
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
+ PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST GetDesiredStateResponseGlobalsTypeInternal GetDesiredStateResponse_globals_
+ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro);
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+namespace {
+const ::_pbi::ClassData* GetDesiredStateResponse_get_class_data() {
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ return GetDesiredStateResponse_globals_.GetClassData();
+#else
+ return GetDesiredStateResponse_class_data_.base();
+#endif // PROTOBUF_MESSAGE_GLOBALS
+}
+} // namespace
+#endif // PROTOBUF_CUSTOM_VTABLE
+class CheckInResponse::_Internal {
+ public:
+ using HasBits = decltype(::std::declval()._impl_._has_bits_);
+ static constexpr ::int32_t kHasBitsOffset =
+ 8 * PROTOBUF_FIELD_OFFSET(CheckInResponse, _impl_._has_bits_);
+};
+
+constexpr CheckInResponse::ParseTableT_ CheckInResponse::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) {
+ return ParseTableT_{
+ {
+ PROTOBUF_FIELD_OFFSET(CheckInResponse, _impl_._has_bits_),
+ 0, // no _extensions_
+ 1, 0, // max_field_number, fast_idx_mask
+ offsetof(ParseTableT_, field_lookup_table),
+ 4294967294, // skipmap
+ offsetof(ParseTableT_, field_entries),
+ 1, // num_field_entries
+ 1, // num_aux_entries
+ offsetof(ParseTableT_, aux_entries),
+ class_data,
+ nullptr, // post_loop_handler
+ ::_pbi::TcParser::MpUnknownFields, // fallback
+ #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
+ ::_pbi::TcParser::GetTable<::xtcp_treatment::v1::CheckInResponse>(), // to_prefetch
+ #endif // PROTOBUF_PREFETCH_PARSE_TABLE
+ }, {{
+ // .xtcp_treatment.v1.DesiredState desired = 1 [json_name = "desired"];
+ {::_pbi::TcParser::FastMtS1,
+ {10, 0, 0,
+ PROTOBUF_FIELD_OFFSET(CheckInResponse, _impl_.desired_)}},
+ }}, {{
+ 65535, 65535
+ }}, {{
+ // .xtcp_treatment.v1.DesiredState desired = 1 [json_name = "desired"];
+ {PROTOBUF_FIELD_OFFSET(CheckInResponse, _impl_.desired_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)},
+ }},
+ {{
+ #ifndef PROTOBUF_MESSAGE_GLOBALS
+ {::_pbi::TcParser::GetTable<::xtcp_treatment::v1::DesiredState>()},
+ #else
+ {::_pbi::FieldAuxMessageGlobals(), &::xtcp_treatment::v1::DesiredState_globals_},
+ #endif
+ }},
+ {{
+ }},
+ };
+}
+
+
+inline constexpr CheckInResponse::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ ::_pbi::ConstantInitialized) noexcept
+ : desired_{nullptr} {}
+
+template
+constexpr CheckInResponse::CheckInResponse(::_pbi::ConstantInitialized,
+ const ::_pbi::ClassData* PROTOBUF_NONNULL class_data)
+ : Super_(
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ class_data
+#endif // PROTOBUF_CUSTOM_VTABLE
+ ),
+ _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) {
+}
+inline void* PROTOBUF_NONNULL CheckInResponse::PlacementNew_(
+ const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {
+ return ::new (mem) CheckInResponse(arena);
+}
+constexpr auto CheckInResponse::InternalNewImpl_() {
+ return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(CheckInResponse), alignof(CheckInResponse));
+}
+constexpr auto CheckInResponse::InternalGenerateClassData_(
+ const MessageLite& prototype,
+ const ::google::protobuf::internal::TcParseTableBase* tc_table) {
+ return ::google::protobuf::internal::ClassDataFull{
+ ::google::protobuf::internal::ClassData{
+ &prototype,
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+ &_table_.header,
+#else
+ tc_table,
+#endif
+ nullptr, // IsInitialized
+ &CheckInResponse::MergeImpl,
+ Super_::GetNewImpl(),
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ &CheckInResponse::SharedDtor,
+ Super_::GetClearImpl(), &CheckInResponse::ByteSizeLong,
+ &CheckInResponse::_InternalSerialize,
+#endif // PROTOBUF_CUSTOM_VTABLE
+ PROTOBUF_FIELD_OFFSET(CheckInResponse, _impl_._cached_size_),
+ false,
+ },
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ &file_reflection_data[1],
+#else // !PROTOBUF_MESSAGE_GLOBALS
+ &::_pbi::kDescriptorMethods,
+ &descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto,
+ nullptr, // tracker
+#endif // PROTOBUF_MESSAGE_GLOBALS
+ };
+}
+struct CheckInResponseGlobalsTypeInternal : ::_pbi::MessageGlobalsBase {
+ constexpr CheckInResponseGlobalsTypeInternal()
+ :
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+ _default(::_pbi::ConstantInitialized{},
+ CheckInResponse_class_data_.base())
+#else // !PROTOBUF_MESSAGE_GLOBALS
+ MessageGlobalsBase(CheckInResponse::InternalGenerateClassData_(
+ _default, &CheckInResponse_globals_._table.header)),
+ _default(::_pbi::ConstantInitialized{}, GetClassData()),
+ _table(::_pbi::PrivateAccess::GenerateParseTable(
+ GetClassData()))
+#endif // PROTOBUF_MESSAGE_GLOBALS
+ {
+ }
+ ~CheckInResponseGlobalsTypeInternal() {}
+ union {
+ alignas(::_pbi::kMaxMessageAlignment) CheckInResponse _default;
+ };
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ decltype(::_pbi::PrivateAccess::GenerateParseTable(
+ ::std::declval())) _table;
+#endif
+};
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+static_assert(PROTOBUF_FIELD_OFFSET(CheckInResponseGlobalsTypeInternal, _default) ==
+ ::_pbi::MessageGlobalsBase::OffsetToDefault());
+#endif // PROTOBUF_MESSAGE_GLOBALS
+
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
+ PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST CheckInResponseGlobalsTypeInternal CheckInResponse_globals_
+ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro);
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+namespace {
+const ::_pbi::ClassData* CheckInResponse_get_class_data() {
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ return CheckInResponse_globals_.GetClassData();
+#else
+ return CheckInResponse_class_data_.base();
+#endif // PROTOBUF_MESSAGE_GLOBALS
+}
+} // namespace
+#endif // PROTOBUF_CUSTOM_VTABLE
+class CheckInRequest::_Internal {
+ public:
+ using HasBits = decltype(::std::declval()._impl_._has_bits_);
+ static constexpr ::int32_t kHasBitsOffset =
+ 8 * PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_._has_bits_);
+};
+
+constexpr CheckInRequest::ParseTableT_ CheckInRequest::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) {
+ return ParseTableT_{
+ {
+ PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_._has_bits_),
+ 0, // no _extensions_
+ 6, 56, // max_field_number, fast_idx_mask
+ offsetof(ParseTableT_, field_lookup_table),
+ 4294967232, // skipmap
+ offsetof(ParseTableT_, field_entries),
+ 6, // num_field_entries
+ 2, // num_aux_entries
+ offsetof(ParseTableT_, aux_entries),
+ class_data,
+ nullptr, // post_loop_handler
+ ::_pbi::TcParser::MpUnknownFields, // fallback
+ #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
+ ::_pbi::TcParser::GetTable<::xtcp_treatment::v1::CheckInRequest>(), // to_prefetch
+ #endif // PROTOBUF_PREFETCH_PARSE_TABLE
+ }, {{
+ {::_pbi::TcParser::MiniParse, {}},
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ {::_pbi::TcParser::FastUS1,
+ {10, 1, 0,
+ PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_.agent_id_)}},
+ // string location = 2 [json_name = "location", (.buf.validate.field) = {
+ {::_pbi::TcParser::FastUS1,
+ {18, 2, 0,
+ PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_.location_)}},
+ // .xtcp_treatment.v1.Capabilities capabilities = 3 [json_name = "capabilities", (.buf.validate.field) = {
+ {::_pbi::TcParser::FastMtS1,
+ {26, 3, 0,
+ PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_.capabilities_)}},
+ // uint64 desired_revision = 4 [json_name = "desiredRevision"];
+ {::_pbi::TcParser::SingularVarintNoZag1<::uint64_t, offsetof(CheckInRequest, _impl_.desired_revision_), 4>(),
+ {32, 4, 0,
+ PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_.desired_revision_)}},
+ // repeated .xtcp_treatment.v1.ApplicationRecord records = 5 [json_name = "records", (.buf.validate.field) = {
+ {::_pbi::TcParser::FastMtR1,
+ {42, 0, 1,
+ PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_.records_)}},
+ // bool locally_suspended = 6 [json_name = "locallySuspended"];
+ {::_pbi::TcParser::SingularVarintNoZag1(),
+ {48, 5, 0,
+ PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_.locally_suspended_)}},
+ {::_pbi::TcParser::MiniParse, {}},
+ }}, {{
+ 65535, 65535
+ }}, {{
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ {PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_.agent_id_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kUtf8String | ::_fl::kRepAString)},
+ // string location = 2 [json_name = "location", (.buf.validate.field) = {
+ {PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_.location_), _Internal::kHasBitsOffset + 2, 0, (0 | ::_fl::kFcOptional | ::_fl::kUtf8String | ::_fl::kRepAString)},
+ // .xtcp_treatment.v1.Capabilities capabilities = 3 [json_name = "capabilities", (.buf.validate.field) = {
+ {PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_.capabilities_), _Internal::kHasBitsOffset + 3, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)},
+ // uint64 desired_revision = 4 [json_name = "desiredRevision"];
+ {PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_.desired_revision_), _Internal::kHasBitsOffset + 4, 0, (0 | ::_fl::kFcOptional | ::_fl::kUInt64)},
+ // repeated .xtcp_treatment.v1.ApplicationRecord records = 5 [json_name = "records", (.buf.validate.field) = {
+ {PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_.records_), _Internal::kHasBitsOffset + 0, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)},
+ // bool locally_suspended = 6 [json_name = "locallySuspended"];
+ {PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_.locally_suspended_), _Internal::kHasBitsOffset + 5, 0, (0 | ::_fl::kFcOptional | ::_fl::kBool)},
+ }},
+ {{
+ #ifndef PROTOBUF_MESSAGE_GLOBALS
+ {::_pbi::TcParser::GetTable<::xtcp_treatment::v1::Capabilities>()},
+ #else
+ {::_pbi::FieldAuxMessageGlobals(), &::xtcp_treatment::v1::Capabilities_globals_},
+ #endif
+ #ifndef PROTOBUF_MESSAGE_GLOBALS
+ {::_pbi::TcParser::GetTable<::xtcp_treatment::v1::ApplicationRecord>()},
+ #else
+ {::_pbi::FieldAuxMessageGlobals(), &::xtcp_treatment::v1::ApplicationRecord_globals_},
+ #endif
+ }},
+ {{
+ "\40\10\10\0\0\0\0\0"
+ "xtcp_treatment.v1.CheckInRequest"
+ "agent_id"
+ "location"
+ }},
+ };
+}
+
+
+inline constexpr CheckInRequest::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ ::_pbi::ConstantInitialized) noexcept
+ : records_ { visibility, ::_pbi::InternalMetadataOffset::Build<
+ ::xtcp_treatment::v1::CheckInRequest,
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::CheckInRequest, _impl_.records_)>()
+ }
+ ,
+ agent_id_(
+ &::google::protobuf::internal::fixed_address_empty_string,
+ ::_pbi::ConstantInitialized()),
+ location_(
+ &::google::protobuf::internal::fixed_address_empty_string,
+ ::_pbi::ConstantInitialized()),
+ capabilities_{nullptr},
+ desired_revision_{::uint64_t{0u}},
+ locally_suspended_{false} {}
+
+template
+constexpr CheckInRequest::CheckInRequest(::_pbi::ConstantInitialized,
+ const ::_pbi::ClassData* PROTOBUF_NONNULL class_data)
+ : Super_(
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ class_data
+#endif // PROTOBUF_CUSTOM_VTABLE
+ ),
+ _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) {
+}
+inline void* PROTOBUF_NONNULL CheckInRequest::PlacementNew_(
+ const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {
+ return ::new (mem) CheckInRequest(arena);
+}
+constexpr auto CheckInRequest::InternalNewImpl_() {
+ return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(CheckInRequest), alignof(CheckInRequest));
+}
+constexpr auto CheckInRequest::InternalGenerateClassData_(
+ const MessageLite& prototype,
+ const ::google::protobuf::internal::TcParseTableBase* tc_table) {
+ return ::google::protobuf::internal::ClassDataFull{
+ ::google::protobuf::internal::ClassData{
+ &prototype,
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+ &_table_.header,
+#else
+ tc_table,
+#endif
+ nullptr, // IsInitialized
+ &CheckInRequest::MergeImpl,
+ Super_::GetNewImpl(),
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ &CheckInRequest::SharedDtor,
+ Super_::GetClearImpl(), &CheckInRequest::ByteSizeLong,
+ &CheckInRequest::_InternalSerialize,
+#endif // PROTOBUF_CUSTOM_VTABLE
+ PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_._cached_size_),
+ false,
+ },
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ &file_reflection_data[0],
+#else // !PROTOBUF_MESSAGE_GLOBALS
+ &::_pbi::kDescriptorMethods,
+ &descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto,
+ nullptr, // tracker
+#endif // PROTOBUF_MESSAGE_GLOBALS
+ };
+}
+struct CheckInRequestGlobalsTypeInternal : ::_pbi::MessageGlobalsBase {
+ constexpr CheckInRequestGlobalsTypeInternal()
+ :
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+ _default(::_pbi::ConstantInitialized{},
+ CheckInRequest_class_data_.base())
+#else // !PROTOBUF_MESSAGE_GLOBALS
+ MessageGlobalsBase(CheckInRequest::InternalGenerateClassData_(
+ _default, &CheckInRequest_globals_._table.header)),
+ _default(::_pbi::ConstantInitialized{}, GetClassData()),
+ _table(::_pbi::PrivateAccess::GenerateParseTable(
+ GetClassData()))
+#endif // PROTOBUF_MESSAGE_GLOBALS
+ {
+ }
+ ~CheckInRequestGlobalsTypeInternal() {}
+ union {
+ alignas(::_pbi::kMaxMessageAlignment) CheckInRequest _default;
+ };
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ decltype(::_pbi::PrivateAccess::GenerateParseTable(
+ ::std::declval())) _table;
+#endif
+};
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+static_assert(PROTOBUF_FIELD_OFFSET(CheckInRequestGlobalsTypeInternal, _default) ==
+ ::_pbi::MessageGlobalsBase::OffsetToDefault());
+#endif // PROTOBUF_MESSAGE_GLOBALS
+
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT
+ PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST CheckInRequestGlobalsTypeInternal CheckInRequest_globals_
+ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro);
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+namespace {
+const ::_pbi::ClassData* CheckInRequest_get_class_data() {
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ return CheckInRequest_globals_.GetClassData();
+#else
+ return CheckInRequest_class_data_.base();
+#endif // PROTOBUF_MESSAGE_GLOBALS
+}
+} // namespace
+#endif // PROTOBUF_CUSTOM_VTABLE
+} // namespace v1
+} // namespace xtcp_treatment
+static constexpr const ::_pb::EnumDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE
+ file_level_enum_descriptors_xtcp_5ftreatment_2fv1_2fagent_2eproto = nullptr;
+static constexpr const ::_pb::ServiceDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE
+ file_level_service_descriptors_xtcp_5ftreatment_2fv1_2fagent_2eproto = nullptr;
+const ::uint32_t
+ TableStruct_xtcp_5ftreatment_2fv1_2fagent_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE(
+ protodesc_cold) = {
+ 0x081, // bitmap
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::CheckInRequest, _impl_._has_bits_),
+ 9, // hasbit index offset
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::CheckInRequest, _impl_.agent_id_),
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::CheckInRequest, _impl_.location_),
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::CheckInRequest, _impl_.capabilities_),
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::CheckInRequest, _impl_.desired_revision_),
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::CheckInRequest, _impl_.records_),
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::CheckInRequest, _impl_.locally_suspended_),
+ 1,
+ 2,
+ 3,
+ 4,
+ 0,
+ 5,
+ 0x081, // bitmap
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::CheckInResponse, _impl_._has_bits_),
+ 4, // hasbit index offset
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::CheckInResponse, _impl_.desired_),
+ 0,
+ 0x081, // bitmap
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::GetDesiredStateRequest, _impl_._has_bits_),
+ 4, // hasbit index offset
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::GetDesiredStateRequest, _impl_.agent_id_),
+ 0,
+ 0x081, // bitmap
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::GetDesiredStateResponse, _impl_._has_bits_),
+ 4, // hasbit index offset
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::GetDesiredStateResponse, _impl_.desired_),
+ 0,
+ 0x081, // bitmap
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::WatchDesiredStateRequest, _impl_._has_bits_),
+ 5, // hasbit index offset
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::WatchDesiredStateRequest, _impl_.agent_id_),
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::WatchDesiredStateRequest, _impl_.after_revision_),
+ 0,
+ 1,
+ 0x081, // bitmap
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::WatchDesiredStateResponse, _impl_._has_bits_),
+ 4, // hasbit index offset
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::WatchDesiredStateResponse, _impl_.revision_),
+ 0,
+};
+
+static const ::_pbi::MigrationSchema
+ schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ {0, sizeof(::xtcp_treatment::v1::CheckInRequest)},
+ {15, sizeof(::xtcp_treatment::v1::CheckInResponse)},
+ {20, sizeof(::xtcp_treatment::v1::GetDesiredStateRequest)},
+ {25, sizeof(::xtcp_treatment::v1::GetDesiredStateResponse)},
+ {30, sizeof(::xtcp_treatment::v1::WatchDesiredStateRequest)},
+ {37, sizeof(::xtcp_treatment::v1::WatchDesiredStateResponse)},
+};
+static const ::_pbi::MessageGlobalsBase* PROTOBUF_NONNULL const
+ file_message_globals[] = {
+ &::xtcp_treatment::v1::CheckInRequest_globals_,
+ &::xtcp_treatment::v1::CheckInResponse_globals_,
+ &::xtcp_treatment::v1::GetDesiredStateRequest_globals_,
+ &::xtcp_treatment::v1::GetDesiredStateResponse_globals_,
+ &::xtcp_treatment::v1::WatchDesiredStateRequest_globals_,
+ &::xtcp_treatment::v1::WatchDesiredStateResponse_globals_,
+};
+const char descriptor_table_protodef_xtcp_5ftreatment_2fv1_2fagent_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE(
+ protodesc_cold) = {
+ "\n\035xtcp_treatment/v1/agent.proto\022\021xtcp_tr"
+ "eatment.v1\032\033buf/validate/validate.proto\032"
+ "!xtcp_treatment/v1/treatment.proto\"\215\003\n\016C"
+ "heckInRequest\022D\n\010agent_id\030\001 \001(\tB)\272H&r$2\""
+ "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$R\007agen"
+ "tId\022E\n\010location\030\002 \001(\tB)\272H&r$2\"^[a-zA-Z0-"
+ "9][a-zA-Z0-9_.-]{0,127}$R\010location\022K\n\014ca"
+ "pabilities\030\003 \001(\0132\037.xtcp_treatment.v1.Cap"
+ "abilitiesB\006\272H\003\310\001\001R\014capabilities\022)\n\020desir"
+ "ed_revision\030\004 \001(\004R\017desiredRevision\022I\n\007re"
+ "cords\030\005 \003(\0132$.xtcp_treatment.v1.Applicat"
+ "ionRecordB\t\272H\006\222\001\003\020\200@R\007records\022+\n\021locally"
+ "_suspended\030\006 \001(\010R\020locallySuspended\"L\n\017Ch"
+ "eckInResponse\0229\n\007desired\030\001 \001(\0132\037.xtcp_tr"
+ "eatment.v1.DesiredStateR\007desired\"^\n\026GetD"
+ "esiredStateRequest\022D\n\010agent_id\030\001 \001(\tB)\272H"
+ "&r$2\"^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$R"
+ "\007agentId\"T\n\027GetDesiredStateResponse\0229\n\007d"
+ "esired\030\001 \001(\0132\037.xtcp_treatment.v1.Desired"
+ "StateR\007desired\"\207\001\n\030WatchDesiredStateRequ"
+ "est\022D\n\010agent_id\030\001 \001(\tB)\272H&r$2\"^[a-zA-Z0-"
+ "9][a-zA-Z0-9_.-]{0,127}$R\007agentId\022%\n\016aft"
+ "er_revision\030\002 \001(\004R\rafterRevision\"7\n\031Watc"
+ "hDesiredStateResponse\022\032\n\010revision\030\001 \001(\004R"
+ "\010revision2\325\002\n\023AgentControlService\022V\n\007Che"
+ "ckIn\022!.xtcp_treatment.v1.CheckInRequest\032"
+ "\".xtcp_treatment.v1.CheckInResponse\"\004\320\363\030"
+ "\001\022n\n\017GetDesiredState\022).xtcp_treatment.v1"
+ ".GetDesiredStateRequest\032*.xtcp_treatment"
+ ".v1.GetDesiredStateResponse\"\004\320\363\030\001\022v\n\021Wat"
+ "chDesiredState\022+.xtcp_treatment.v1.Watch"
+ "DesiredStateRequest\032,.xtcp_treatment.v1."
+ "WatchDesiredStateResponse\"\004\320\363\030\0010\001B\274\001\n\025co"
+ "m.xtcp_treatment.v1B\nAgentProtoP\001Z6githu"
+ "b.com/randomizedcoder/xtcp2/gen/go/xtcp_"
+ "treatment\242\002\003XXX\252\002\020XtcpTreatment.V1\312\002\020Xtc"
+ "pTreatment\\V1\342\002\034XtcpTreatment\\V1\\GPBMeta"
+ "data\352\002\021XtcpTreatment::V1b\006proto3"
+};
+static const ::_pbi::DescriptorTable* PROTOBUF_NONNULL const
+ descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto_deps[2] = {
+ &::descriptor_table_buf_2fvalidate_2fvalidate_2eproto,
+ &::descriptor_table_xtcp_5ftreatment_2fv1_2ftreatment_2eproto,
+};
+static ::absl::once_flag descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto_once;
+PROTOBUF_CONSTINIT const ::_pbi::DescriptorTable descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto = {
+ false,
+ false,
+ 1512,
+ descriptor_table_protodef_xtcp_5ftreatment_2fv1_2fagent_2eproto,
+ "xtcp_treatment/v1/agent.proto",
+ &descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto_once,
+ descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto_deps,
+ 2,
+ 6,
+ schemas,
+ file_message_globals,
+ TableStruct_xtcp_5ftreatment_2fv1_2fagent_2eproto::offsets,
+ file_level_enum_descriptors_xtcp_5ftreatment_2fv1_2fagent_2eproto,
+ file_level_service_descriptors_xtcp_5ftreatment_2fv1_2fagent_2eproto,
+};
+namespace xtcp_treatment {
+namespace v1 {
+// ===================================================================
+
+void CheckInRequest::clear_capabilities() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (_impl_.capabilities_ != nullptr) _impl_.capabilities_->Clear();
+ ClearHasBit(_impl_._has_bits_[0], 0x00000008U);
+}
+void CheckInRequest::clear_records() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.records_.Clear();
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+}
+CheckInRequest::CheckInRequest(::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ : Super_(arena, CheckInRequest_get_class_data()) {
+#else // PROTOBUF_CUSTOM_VTABLE
+ : Super_(arena) {
+#endif // PROTOBUF_CUSTOM_VTABLE
+ SharedCtor(arena);
+ // @@protoc_insertion_point(arena_constructor:xtcp_treatment.v1.CheckInRequest)
+}
+PROTOBUF_NDEBUG_INLINE CheckInRequest::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,
+ [[maybe_unused]] const ::xtcp_treatment::v1::CheckInRequest& from_msg)
+ : _has_bits_{from._has_bits_},
+ records_ {
+ visibility, ::_pbi::InternalMetadataOffset::Build<
+ ::xtcp_treatment::v1::CheckInRequest,
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::CheckInRequest, _impl_.records_)>()
+ , arena, from.records_
+ }
+ ,
+ agent_id_(arena, from.agent_id_),
+ location_(arena, from.location_) {}
+
+CheckInRequest::CheckInRequest(
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena,
+ const CheckInRequest& from)
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ : Super_(arena, CheckInRequest_get_class_data()) {
+
+#else // PROTOBUF_CUSTOM_VTABLE
+ : Super_(arena) {
+#endif // PROTOBUF_CUSTOM_VTABLE
+ CheckInRequest* const _this = this;
+ (void)_this;
+ _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
+ from._internal_metadata_);
+ new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);
+ ::uint32_t cached_has_bits = _impl_._has_bits_[0];
+ _impl_.capabilities_ = (CheckHasBit(cached_has_bits, 0x00000008U))
+ ? Super_::CopyConstruct(arena, *from._impl_.capabilities_)
+ : nullptr;
+ ::memcpy(reinterpret_cast(&_impl_) +
+ offsetof(Impl_, desired_revision_),
+ reinterpret_cast(&from._impl_) +
+ offsetof(Impl_, desired_revision_),
+ offsetof(Impl_, locally_suspended_) -
+ offsetof(Impl_, desired_revision_) +
+ sizeof(Impl_::locally_suspended_));
+
+ // @@protoc_insertion_point(copy_constructor:xtcp_treatment.v1.CheckInRequest)
+}
+PROTOBUF_NDEBUG_INLINE CheckInRequest::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
+ : records_ { visibility, ::_pbi::InternalMetadataOffset::Build<
+ ::xtcp_treatment::v1::CheckInRequest,
+ PROTOBUF_FIELD_OFFSET(::xtcp_treatment::v1::CheckInRequest, _impl_.records_)>()
+ }
+ ,
+ agent_id_(arena),
+ location_(arena) {}
+
+inline void CheckInRequest::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) {
+ new (&_impl_) Impl_(internal_visibility(), arena);
+ ::memset(reinterpret_cast(&_impl_) +
+ offsetof(Impl_, capabilities_),
+ 0,
+ offsetof(Impl_, locally_suspended_) -
+ offsetof(Impl_, capabilities_) +
+ sizeof(Impl_::locally_suspended_));
+}
+CheckInRequest::~CheckInRequest() {
+ // @@protoc_insertion_point(destructor:xtcp_treatment.v1.CheckInRequest)
+ SharedDtor(*this);
+}
+inline void CheckInRequest::SharedDtor(MessageLite& self) {
+ CheckInRequest& this_ = static_cast(self);
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ this_.CheckHasBitConsistency();
+ }
+ this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
+ ABSL_DCHECK(this_.GetArena() == nullptr);
+ this_._impl_.agent_id_.Destroy();
+ this_._impl_.location_.Destroy();
+ delete this_._impl_.capabilities_;
+ this_._impl_.~Impl_();
+}
+
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const
+ ::google::protobuf::internal::ClassDataFull CheckInRequest_class_data_ =
+ CheckInRequest::InternalGenerateClassData_(CheckInRequest_globals_._default);
+
+PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+CheckInRequest::GetClassData() const {
+ ::google::protobuf::internal::PrefetchToLocalCache(&CheckInRequest_class_data_);
+ ::google::protobuf::internal::PrefetchToLocalCache(CheckInRequest_class_data_.tc_table);
+ return CheckInRequest_class_data_.base();
+}
+#else
+PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+CheckInRequest::GetClassData() const {
+ ::google::protobuf::internal::PrefetchToLocalCache(&CheckInRequest_globals_);
+ ::google::protobuf::internal::PrefetchToLocalCache(
+ ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&CheckInRequest_globals_));
+ return CheckInRequest_globals_.GetClassData();
+}
+#endif // !PROTOBUF_MESSAGE_GLOBALS
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_CONSTINIT
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CheckInRequest::ParseTableT_
+ CheckInRequest::_table_ =
+ CheckInRequest::InternalGenerateParseTable_(CheckInRequest_class_data_.base());
+#endif // !PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_NOINLINE void CheckInRequest::Clear() {
+ auto& this_ [[maybe_unused]] = *this;
+ // @@protoc_insertion_point(message_clear_start:xtcp_treatment.v1.CheckInRequest)
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ ::uint32_t cached_has_bits [[maybe_unused]] = 0;
+
+ cached_has_bits = this_._impl_._has_bits_[0];
+ if (BatchCheckHasBit(cached_has_bits, 0x0000000fU)) {
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ _impl_.records_.Clear();
+ }
+ if (CheckHasBit(cached_has_bits, 0x00000002U)) {
+ this_._impl_.agent_id_.ClearNonDefaultToEmpty();
+ }
+ if (CheckHasBit(cached_has_bits, 0x00000004U)) {
+ this_._impl_.location_.ClearNonDefaultToEmpty();
+ }
+ if (CheckHasBit(cached_has_bits, 0x00000008U)) {
+ ABSL_DCHECK(this_._impl_.capabilities_ != nullptr);
+ this_._impl_.capabilities_->Clear();
+ }
+ }
+ if (BatchCheckHasBit(cached_has_bits, 0x00000030U)) {
+ ::memset(&this_._impl_.desired_revision_, 0,
+ static_cast<::size_t>(
+ reinterpret_cast(&this_._impl_.locally_suspended_) -
+ reinterpret_cast(&this_._impl_.desired_revision_)) +
+ sizeof(_impl_.locally_suspended_));
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
+}
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+::uint8_t* PROTOBUF_NONNULL CheckInRequest::_InternalSerialize(
+ const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) {
+ const CheckInRequest& this_ = static_cast(base);
+#else // PROTOBUF_CUSTOM_VTABLE
+::uint8_t* PROTOBUF_NONNULL CheckInRequest::_InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
+ const CheckInRequest& this_ = *this;
+#endif // PROTOBUF_CUSTOM_VTABLE
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ this_.CheckHasBitConsistency();
+ }
+ // @@protoc_insertion_point(serialize_to_array_start:xtcp_treatment.v1.CheckInRequest)
+ ::uint32_t cached_has_bits = 0;
+ (void)cached_has_bits;
+
+ cached_has_bits = this_._impl_._has_bits_[0];
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ if (CheckHasBit(cached_has_bits, 0x00000002U)) {
+ if (!this_._internal_agent_id().empty()) {
+ const ::std::string& _s = this_._internal_agent_id();
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ _s.data(), static_cast(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "xtcp_treatment.v1.CheckInRequest.agent_id");
+ target = stream->WriteStringMaybeAliased(1, _s, target);
+ }
+ }
+
+ // string location = 2 [json_name = "location", (.buf.validate.field) = {
+ if (CheckHasBit(cached_has_bits, 0x00000004U)) {
+ if (!this_._internal_location().empty()) {
+ const ::std::string& _s = this_._internal_location();
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ _s.data(), static_cast(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "xtcp_treatment.v1.CheckInRequest.location");
+ target = stream->WriteStringMaybeAliased(2, _s, target);
+ }
+ }
+
+ // .xtcp_treatment.v1.Capabilities capabilities = 3 [json_name = "capabilities", (.buf.validate.field) = {
+ if (CheckHasBit(cached_has_bits, 0x00000008U)) {
+ target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
+ 3, *this_._impl_.capabilities_, this_._impl_.capabilities_->GetCachedSize(), target,
+ stream);
+ }
+
+ // uint64 desired_revision = 4 [json_name = "desiredRevision"];
+ if (CheckHasBit(cached_has_bits, 0x00000010U)) {
+ if (this_._internal_desired_revision() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteUInt64ToArray(
+ 4, this_._internal_desired_revision(), target);
+ }
+ }
+
+ // repeated .xtcp_treatment.v1.ApplicationRecord records = 5 [json_name = "records", (.buf.validate.field) = {
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ for (unsigned i = 0, n = static_cast(
+ this_._internal_records_size());
+ i < n; i++) {
+ const auto& repfield = this_._internal_records().Get(i);
+ target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
+ 5, repfield, repfield.GetCachedSize(), target,
+ stream);
+ }
+ }
+
+ // bool locally_suspended = 6 [json_name = "locallySuspended"];
+ if (CheckHasBit(cached_has_bits, 0x00000020U)) {
+ if (this_._internal_locally_suspended() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteBoolToArray(
+ 6, this_._internal_locally_suspended(), target);
+ }
+ }
+
+ if (ABSL_PREDICT_FALSE(this_._internal_metadata_.have_unknown_fields())) {
+ target =
+ ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ this_._internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:xtcp_treatment.v1.CheckInRequest)
+ return target;
+}
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+::size_t CheckInRequest::ByteSizeLong(const MessageLite& base) {
+ const CheckInRequest& this_ = static_cast(base);
+#else // PROTOBUF_CUSTOM_VTABLE
+::size_t CheckInRequest::ByteSizeLong() const {
+ const CheckInRequest& this_ = *this;
+#endif // PROTOBUF_CUSTOM_VTABLE
+ // @@protoc_insertion_point(message_byte_size_start:xtcp_treatment.v1.CheckInRequest)
+ ::size_t total_size = 0;
+
+ ::uint32_t cached_has_bits [[maybe_unused]] = 0;
+
+ ::_pbi::Prefetch5LinesFrom7Lines(&this_);
+ cached_has_bits = this_._impl_._has_bits_[0];
+ if (BatchCheckHasBit(cached_has_bits, 0x0000003fU)) {
+ // repeated .xtcp_treatment.v1.ApplicationRecord records = 5 [json_name = "records", (.buf.validate.field) = {
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ total_size += 1UL * this_._internal_records_size();
+ for (const auto& msg : this_._internal_records()) {
+ total_size += ::google::protobuf::internal::WireFormatLite::MessageSize(msg);
+ }
+ }
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ if (CheckHasBit(cached_has_bits, 0x00000002U)) {
+ if (!this_._internal_agent_id().empty()) {
+ total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
+ this_._internal_agent_id());
+ }
+ }
+ // string location = 2 [json_name = "location", (.buf.validate.field) = {
+ if (CheckHasBit(cached_has_bits, 0x00000004U)) {
+ if (!this_._internal_location().empty()) {
+ total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
+ this_._internal_location());
+ }
+ }
+ // .xtcp_treatment.v1.Capabilities capabilities = 3 [json_name = "capabilities", (.buf.validate.field) = {
+ if (CheckHasBit(cached_has_bits, 0x00000008U)) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSize(*this_._impl_.capabilities_);
+ }
+ // uint64 desired_revision = 4 [json_name = "desiredRevision"];
+ if (CheckHasBit(cached_has_bits, 0x00000010U)) {
+ if (this_._internal_desired_revision() != 0) {
+ total_size += ::_pbi::WireFormatLite::UInt64SizePlusOne(
+ this_._internal_desired_revision());
+ }
+ }
+ // bool locally_suspended = 6 [json_name = "locallySuspended"];
+ if (CheckHasBit(cached_has_bits, 0x00000020U)) {
+ if (this_._internal_locally_suspended() != 0) {
+ total_size += 2;
+ }
+ }
+ }
+ return this_.MaybeComputeUnknownFieldsSize(total_size,
+ &this_._impl_._cached_size_);
+}
+
+void CheckInRequest::MergeImpl(::google::protobuf::MessageLite& to_msg,
+ const ::google::protobuf::MessageLite& from_msg) {
+ auto* const _this = static_cast(&to_msg);
+ auto& from = static_cast(from_msg);
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ from.CheckHasBitConsistency();
+ }
+ ::google::protobuf::Arena* arena = _this->GetArena();
+ // @@protoc_insertion_point(class_specific_merge_from_start:xtcp_treatment.v1.CheckInRequest)
+ ABSL_DCHECK_NE(&from, _this);
+ ::uint32_t cached_has_bits = 0;
+ (void)cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (BatchCheckHasBit(cached_has_bits, 0x0000003fU)) {
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ _this->_internal_mutable_records()->InternalMergeFromWithArena(
+ ::google::protobuf::MessageLite::internal_visibility(), arena,
+ from._internal_records());
+ }
+ if (CheckHasBit(cached_has_bits, 0x00000002U)) {
+ if (!from._internal_agent_id().empty()) {
+ _this->_internal_set_agent_id(from._internal_agent_id());
+ } else {
+ if (_this->_impl_.agent_id_.IsDefault()) {
+ _this->_internal_set_agent_id("");
+ }
+ }
+ }
+ if (CheckHasBit(cached_has_bits, 0x00000004U)) {
+ if (!from._internal_location().empty()) {
+ _this->_internal_set_location(from._internal_location());
+ } else {
+ if (_this->_impl_.location_.IsDefault()) {
+ _this->_internal_set_location("");
+ }
+ }
+ }
+ if (CheckHasBit(cached_has_bits, 0x00000008U)) {
+ ABSL_DCHECK(from._impl_.capabilities_ != nullptr);
+ if (_this->_impl_.capabilities_ == nullptr) {
+ _this->_impl_.capabilities_ = Super_::CopyConstruct(arena, *from._impl_.capabilities_);
+ } else {
+ _this->_impl_.capabilities_->MergeFrom(*from._impl_.capabilities_);
+ }
+ }
+ if (CheckHasBit(cached_has_bits, 0x00000010U)) {
+ if (from._internal_desired_revision() != 0) {
+ _this->_impl_.desired_revision_ = from._impl_.desired_revision_;
+ }
+ }
+ if (CheckHasBit(cached_has_bits, 0x00000020U)) {
+ if (from._internal_locally_suspended() != 0) {
+ _this->_impl_.locally_suspended_ = from._impl_.locally_suspended_;
+ }
+ }
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
+ from._internal_metadata_);
+}
+
+void CheckInRequest::CopyFrom(const CheckInRequest& from) {
+ // @@protoc_insertion_point(class_specific_copy_from_start:xtcp_treatment.v1.CheckInRequest)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+
+void CheckInRequest::InternalSwap(CheckInRequest* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) {
+ using ::std::swap;
+ auto* arena = GetArena();
+ ABSL_DCHECK_EQ(arena, other->GetArena());
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ _impl_.records_.InternalSwap(&other->_impl_.records_);
+ ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.agent_id_, &other->_impl_.agent_id_, arena);
+ ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.location_, &other->_impl_.location_, arena);
+ ::google::protobuf::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_.locally_suspended_)
+ + sizeof(CheckInRequest::_impl_.locally_suspended_)
+ - PROTOBUF_FIELD_OFFSET(CheckInRequest, _impl_.capabilities_)>(
+ reinterpret_cast(&_impl_.capabilities_),
+ reinterpret_cast(&other->_impl_.capabilities_));
+}
+
+::google::protobuf::Metadata CheckInRequest::GetMetadata() const {
+ return Super_::GetMetadataImpl(GetClassData()->full());
+}
+// ===================================================================
+
+void CheckInResponse::clear_desired() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (_impl_.desired_ != nullptr) _impl_.desired_->Clear();
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+}
+CheckInResponse::CheckInResponse(::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ : Super_(arena, CheckInResponse_get_class_data()) {
+#else // PROTOBUF_CUSTOM_VTABLE
+ : Super_(arena) {
+#endif // PROTOBUF_CUSTOM_VTABLE
+ SharedCtor(arena);
+ // @@protoc_insertion_point(arena_constructor:xtcp_treatment.v1.CheckInResponse)
+}
+PROTOBUF_NDEBUG_INLINE CheckInResponse::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,
+ [[maybe_unused]] const ::xtcp_treatment::v1::CheckInResponse& from_msg)
+ : _has_bits_{from._has_bits_} {}
+
+CheckInResponse::CheckInResponse(
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena,
+ const CheckInResponse& from)
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ : Super_(arena, CheckInResponse_get_class_data()) {
+
+#else // PROTOBUF_CUSTOM_VTABLE
+ : Super_(arena) {
+#endif // PROTOBUF_CUSTOM_VTABLE
+ CheckInResponse* const _this = this;
+ (void)_this;
+ _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
+ from._internal_metadata_);
+ new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);
+ ::uint32_t cached_has_bits = _impl_._has_bits_[0];
+ _impl_.desired_ = (CheckHasBit(cached_has_bits, 0x00000001U))
+ ? Super_::CopyConstruct(arena, *from._impl_.desired_)
+ : nullptr;
+
+ // @@protoc_insertion_point(copy_constructor:xtcp_treatment.v1.CheckInResponse)
+}
+PROTOBUF_NDEBUG_INLINE CheckInResponse::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
+ {}
+
+inline void CheckInResponse::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) {
+ new (&_impl_) Impl_(internal_visibility(), arena);
+ _impl_.desired_ = {};
+}
+CheckInResponse::~CheckInResponse() {
+ // @@protoc_insertion_point(destructor:xtcp_treatment.v1.CheckInResponse)
+ SharedDtor(*this);
+}
+inline void CheckInResponse::SharedDtor(MessageLite& self) {
+ CheckInResponse& this_ = static_cast(self);
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ this_.CheckHasBitConsistency();
+ }
+ this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
+ ABSL_DCHECK(this_.GetArena() == nullptr);
+ delete this_._impl_.desired_;
+ this_._impl_.~Impl_();
+}
+
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const
+ ::google::protobuf::internal::ClassDataFull CheckInResponse_class_data_ =
+ CheckInResponse::InternalGenerateClassData_(CheckInResponse_globals_._default);
+
+PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+CheckInResponse::GetClassData() const {
+ ::google::protobuf::internal::PrefetchToLocalCache(&CheckInResponse_class_data_);
+ ::google::protobuf::internal::PrefetchToLocalCache(CheckInResponse_class_data_.tc_table);
+ return CheckInResponse_class_data_.base();
+}
+#else
+PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+CheckInResponse::GetClassData() const {
+ ::google::protobuf::internal::PrefetchToLocalCache(&CheckInResponse_globals_);
+ ::google::protobuf::internal::PrefetchToLocalCache(
+ ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&CheckInResponse_globals_));
+ return CheckInResponse_globals_.GetClassData();
+}
+#endif // !PROTOBUF_MESSAGE_GLOBALS
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_CONSTINIT
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CheckInResponse::ParseTableT_
+ CheckInResponse::_table_ =
+ CheckInResponse::InternalGenerateParseTable_(CheckInResponse_class_data_.base());
+#endif // !PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_NOINLINE void CheckInResponse::Clear() {
+ auto& this_ [[maybe_unused]] = *this;
+ // @@protoc_insertion_point(message_clear_start:xtcp_treatment.v1.CheckInResponse)
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ ::uint32_t cached_has_bits [[maybe_unused]] = 0;
+
+ cached_has_bits = this_._impl_._has_bits_[0];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ ABSL_DCHECK(this_._impl_.desired_ != nullptr);
+ this_._impl_.desired_->Clear();
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
+}
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+::uint8_t* PROTOBUF_NONNULL CheckInResponse::_InternalSerialize(
+ const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) {
+ const CheckInResponse& this_ = static_cast(base);
+#else // PROTOBUF_CUSTOM_VTABLE
+::uint8_t* PROTOBUF_NONNULL CheckInResponse::_InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
+ const CheckInResponse& this_ = *this;
+#endif // PROTOBUF_CUSTOM_VTABLE
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ this_.CheckHasBitConsistency();
+ }
+ // @@protoc_insertion_point(serialize_to_array_start:xtcp_treatment.v1.CheckInResponse)
+ ::uint32_t cached_has_bits = 0;
+ (void)cached_has_bits;
+
+ cached_has_bits = this_._impl_._has_bits_[0];
+ // .xtcp_treatment.v1.DesiredState desired = 1 [json_name = "desired"];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
+ 1, *this_._impl_.desired_, this_._impl_.desired_->GetCachedSize(), target,
+ stream);
+ }
+
+ if (ABSL_PREDICT_FALSE(this_._internal_metadata_.have_unknown_fields())) {
+ target =
+ ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ this_._internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:xtcp_treatment.v1.CheckInResponse)
+ return target;
+}
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+::size_t CheckInResponse::ByteSizeLong(const MessageLite& base) {
+ const CheckInResponse& this_ = static_cast(base);
+#else // PROTOBUF_CUSTOM_VTABLE
+::size_t CheckInResponse::ByteSizeLong() const {
+ const CheckInResponse& this_ = *this;
+#endif // PROTOBUF_CUSTOM_VTABLE
+ // @@protoc_insertion_point(message_byte_size_start:xtcp_treatment.v1.CheckInResponse)
+ ::size_t total_size = 0;
+
+ ::uint32_t cached_has_bits [[maybe_unused]] = 0;
+
+ {
+ // .xtcp_treatment.v1.DesiredState desired = 1 [json_name = "desired"];
+ cached_has_bits = this_._impl_._has_bits_[0];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSize(*this_._impl_.desired_);
+ }
+ }
+ return this_.MaybeComputeUnknownFieldsSize(total_size,
+ &this_._impl_._cached_size_);
+}
+
+void CheckInResponse::MergeImpl(::google::protobuf::MessageLite& to_msg,
+ const ::google::protobuf::MessageLite& from_msg) {
+ auto* const _this = static_cast(&to_msg);
+ auto& from = static_cast(from_msg);
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ from.CheckHasBitConsistency();
+ }
+ ::google::protobuf::Arena* arena = _this->GetArena();
+ // @@protoc_insertion_point(class_specific_merge_from_start:xtcp_treatment.v1.CheckInResponse)
+ ABSL_DCHECK_NE(&from, _this);
+ ::uint32_t cached_has_bits = 0;
+ (void)cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ ABSL_DCHECK(from._impl_.desired_ != nullptr);
+ if (_this->_impl_.desired_ == nullptr) {
+ _this->_impl_.desired_ = Super_::CopyConstruct(arena, *from._impl_.desired_);
+ } else {
+ _this->_impl_.desired_->MergeFrom(*from._impl_.desired_);
+ }
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
+ from._internal_metadata_);
+}
+
+void CheckInResponse::CopyFrom(const CheckInResponse& from) {
+ // @@protoc_insertion_point(class_specific_copy_from_start:xtcp_treatment.v1.CheckInResponse)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+
+void CheckInResponse::InternalSwap(CheckInResponse* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) {
+ using ::std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ swap(_impl_.desired_, other->_impl_.desired_);
+}
+
+::google::protobuf::Metadata CheckInResponse::GetMetadata() const {
+ return Super_::GetMetadataImpl(GetClassData()->full());
+}
+// ===================================================================
+
+GetDesiredStateRequest::GetDesiredStateRequest(::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ : Super_(arena, GetDesiredStateRequest_get_class_data()) {
+#else // PROTOBUF_CUSTOM_VTABLE
+ : Super_(arena) {
+#endif // PROTOBUF_CUSTOM_VTABLE
+ SharedCtor(arena);
+ // @@protoc_insertion_point(arena_constructor:xtcp_treatment.v1.GetDesiredStateRequest)
+}
+PROTOBUF_NDEBUG_INLINE GetDesiredStateRequest::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,
+ [[maybe_unused]] const ::xtcp_treatment::v1::GetDesiredStateRequest& from_msg)
+ : _has_bits_{from._has_bits_},
+ agent_id_(arena, from.agent_id_) {}
+
+GetDesiredStateRequest::GetDesiredStateRequest(
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena,
+ const GetDesiredStateRequest& from)
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ : Super_(arena, GetDesiredStateRequest_get_class_data()) {
+
+#else // PROTOBUF_CUSTOM_VTABLE
+ : Super_(arena) {
+#endif // PROTOBUF_CUSTOM_VTABLE
+ GetDesiredStateRequest* const _this = this;
+ (void)_this;
+ _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
+ from._internal_metadata_);
+ new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);
+
+ // @@protoc_insertion_point(copy_constructor:xtcp_treatment.v1.GetDesiredStateRequest)
+}
+PROTOBUF_NDEBUG_INLINE GetDesiredStateRequest::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
+ : agent_id_(arena) {}
+
+inline void GetDesiredStateRequest::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) {
+ new (&_impl_) Impl_(internal_visibility(), arena);
+}
+GetDesiredStateRequest::~GetDesiredStateRequest() {
+ // @@protoc_insertion_point(destructor:xtcp_treatment.v1.GetDesiredStateRequest)
+ SharedDtor(*this);
+}
+inline void GetDesiredStateRequest::SharedDtor(MessageLite& self) {
+ GetDesiredStateRequest& this_ = static_cast(self);
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ this_.CheckHasBitConsistency();
+ }
+ this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
+ ABSL_DCHECK(this_.GetArena() == nullptr);
+ this_._impl_.agent_id_.Destroy();
+ this_._impl_.~Impl_();
+}
+
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const
+ ::google::protobuf::internal::ClassDataFull GetDesiredStateRequest_class_data_ =
+ GetDesiredStateRequest::InternalGenerateClassData_(GetDesiredStateRequest_globals_._default);
+
+PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+GetDesiredStateRequest::GetClassData() const {
+ ::google::protobuf::internal::PrefetchToLocalCache(&GetDesiredStateRequest_class_data_);
+ ::google::protobuf::internal::PrefetchToLocalCache(GetDesiredStateRequest_class_data_.tc_table);
+ return GetDesiredStateRequest_class_data_.base();
+}
+#else
+PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+GetDesiredStateRequest::GetClassData() const {
+ ::google::protobuf::internal::PrefetchToLocalCache(&GetDesiredStateRequest_globals_);
+ ::google::protobuf::internal::PrefetchToLocalCache(
+ ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&GetDesiredStateRequest_globals_));
+ return GetDesiredStateRequest_globals_.GetClassData();
+}
+#endif // !PROTOBUF_MESSAGE_GLOBALS
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_CONSTINIT
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const GetDesiredStateRequest::ParseTableT_
+ GetDesiredStateRequest::_table_ =
+ GetDesiredStateRequest::InternalGenerateParseTable_(GetDesiredStateRequest_class_data_.base());
+#endif // !PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_NOINLINE void GetDesiredStateRequest::Clear() {
+ auto& this_ [[maybe_unused]] = *this;
+ // @@protoc_insertion_point(message_clear_start:xtcp_treatment.v1.GetDesiredStateRequest)
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ ::uint32_t cached_has_bits [[maybe_unused]] = 0;
+
+ cached_has_bits = this_._impl_._has_bits_[0];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ this_._impl_.agent_id_.ClearNonDefaultToEmpty();
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
+}
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+::uint8_t* PROTOBUF_NONNULL GetDesiredStateRequest::_InternalSerialize(
+ const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) {
+ const GetDesiredStateRequest& this_ = static_cast(base);
+#else // PROTOBUF_CUSTOM_VTABLE
+::uint8_t* PROTOBUF_NONNULL GetDesiredStateRequest::_InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
+ const GetDesiredStateRequest& this_ = *this;
+#endif // PROTOBUF_CUSTOM_VTABLE
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ this_.CheckHasBitConsistency();
+ }
+ // @@protoc_insertion_point(serialize_to_array_start:xtcp_treatment.v1.GetDesiredStateRequest)
+ ::uint32_t cached_has_bits = 0;
+ (void)cached_has_bits;
+
+ cached_has_bits = this_._impl_._has_bits_[0];
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ if (!this_._internal_agent_id().empty()) {
+ const ::std::string& _s = this_._internal_agent_id();
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ _s.data(), static_cast(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "xtcp_treatment.v1.GetDesiredStateRequest.agent_id");
+ target = stream->WriteStringMaybeAliased(1, _s, target);
+ }
+ }
+
+ if (ABSL_PREDICT_FALSE(this_._internal_metadata_.have_unknown_fields())) {
+ target =
+ ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ this_._internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:xtcp_treatment.v1.GetDesiredStateRequest)
+ return target;
+}
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+::size_t GetDesiredStateRequest::ByteSizeLong(const MessageLite& base) {
+ const GetDesiredStateRequest& this_ = static_cast(base);
+#else // PROTOBUF_CUSTOM_VTABLE
+::size_t GetDesiredStateRequest::ByteSizeLong() const {
+ const GetDesiredStateRequest& this_ = *this;
+#endif // PROTOBUF_CUSTOM_VTABLE
+ // @@protoc_insertion_point(message_byte_size_start:xtcp_treatment.v1.GetDesiredStateRequest)
+ ::size_t total_size = 0;
+
+ ::uint32_t cached_has_bits [[maybe_unused]] = 0;
+
+ {
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ cached_has_bits = this_._impl_._has_bits_[0];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ if (!this_._internal_agent_id().empty()) {
+ total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
+ this_._internal_agent_id());
+ }
+ }
+ }
+ return this_.MaybeComputeUnknownFieldsSize(total_size,
+ &this_._impl_._cached_size_);
+}
+
+void GetDesiredStateRequest::MergeImpl(::google::protobuf::MessageLite& to_msg,
+ const ::google::protobuf::MessageLite& from_msg) {
+ auto* const _this = static_cast(&to_msg);
+ auto& from = static_cast(from_msg);
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ from.CheckHasBitConsistency();
+ }
+ // @@protoc_insertion_point(class_specific_merge_from_start:xtcp_treatment.v1.GetDesiredStateRequest)
+ ABSL_DCHECK_NE(&from, _this);
+ ::uint32_t cached_has_bits = 0;
+ (void)cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ if (!from._internal_agent_id().empty()) {
+ _this->_internal_set_agent_id(from._internal_agent_id());
+ } else {
+ if (_this->_impl_.agent_id_.IsDefault()) {
+ _this->_internal_set_agent_id("");
+ }
+ }
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
+ from._internal_metadata_);
+}
+
+void GetDesiredStateRequest::CopyFrom(const GetDesiredStateRequest& from) {
+ // @@protoc_insertion_point(class_specific_copy_from_start:xtcp_treatment.v1.GetDesiredStateRequest)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+
+void GetDesiredStateRequest::InternalSwap(GetDesiredStateRequest* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) {
+ using ::std::swap;
+ auto* arena = GetArena();
+ ABSL_DCHECK_EQ(arena, other->GetArena());
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.agent_id_, &other->_impl_.agent_id_, arena);
+}
+
+::google::protobuf::Metadata GetDesiredStateRequest::GetMetadata() const {
+ return Super_::GetMetadataImpl(GetClassData()->full());
+}
+// ===================================================================
+
+void GetDesiredStateResponse::clear_desired() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (_impl_.desired_ != nullptr) _impl_.desired_->Clear();
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+}
+GetDesiredStateResponse::GetDesiredStateResponse(::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ : Super_(arena, GetDesiredStateResponse_get_class_data()) {
+#else // PROTOBUF_CUSTOM_VTABLE
+ : Super_(arena) {
+#endif // PROTOBUF_CUSTOM_VTABLE
+ SharedCtor(arena);
+ // @@protoc_insertion_point(arena_constructor:xtcp_treatment.v1.GetDesiredStateResponse)
+}
+PROTOBUF_NDEBUG_INLINE GetDesiredStateResponse::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,
+ [[maybe_unused]] const ::xtcp_treatment::v1::GetDesiredStateResponse& from_msg)
+ : _has_bits_{from._has_bits_} {}
+
+GetDesiredStateResponse::GetDesiredStateResponse(
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena,
+ const GetDesiredStateResponse& from)
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ : Super_(arena, GetDesiredStateResponse_get_class_data()) {
+
+#else // PROTOBUF_CUSTOM_VTABLE
+ : Super_(arena) {
+#endif // PROTOBUF_CUSTOM_VTABLE
+ GetDesiredStateResponse* const _this = this;
+ (void)_this;
+ _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
+ from._internal_metadata_);
+ new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);
+ ::uint32_t cached_has_bits = _impl_._has_bits_[0];
+ _impl_.desired_ = (CheckHasBit(cached_has_bits, 0x00000001U))
+ ? Super_::CopyConstruct(arena, *from._impl_.desired_)
+ : nullptr;
+
+ // @@protoc_insertion_point(copy_constructor:xtcp_treatment.v1.GetDesiredStateResponse)
+}
+PROTOBUF_NDEBUG_INLINE GetDesiredStateResponse::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
+ {}
+
+inline void GetDesiredStateResponse::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) {
+ new (&_impl_) Impl_(internal_visibility(), arena);
+ _impl_.desired_ = {};
+}
+GetDesiredStateResponse::~GetDesiredStateResponse() {
+ // @@protoc_insertion_point(destructor:xtcp_treatment.v1.GetDesiredStateResponse)
+ SharedDtor(*this);
+}
+inline void GetDesiredStateResponse::SharedDtor(MessageLite& self) {
+ GetDesiredStateResponse& this_ = static_cast(self);
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ this_.CheckHasBitConsistency();
+ }
+ this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
+ ABSL_DCHECK(this_.GetArena() == nullptr);
+ delete this_._impl_.desired_;
+ this_._impl_.~Impl_();
+}
+
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const
+ ::google::protobuf::internal::ClassDataFull GetDesiredStateResponse_class_data_ =
+ GetDesiredStateResponse::InternalGenerateClassData_(GetDesiredStateResponse_globals_._default);
+
+PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+GetDesiredStateResponse::GetClassData() const {
+ ::google::protobuf::internal::PrefetchToLocalCache(&GetDesiredStateResponse_class_data_);
+ ::google::protobuf::internal::PrefetchToLocalCache(GetDesiredStateResponse_class_data_.tc_table);
+ return GetDesiredStateResponse_class_data_.base();
+}
+#else
+PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+GetDesiredStateResponse::GetClassData() const {
+ ::google::protobuf::internal::PrefetchToLocalCache(&GetDesiredStateResponse_globals_);
+ ::google::protobuf::internal::PrefetchToLocalCache(
+ ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&GetDesiredStateResponse_globals_));
+ return GetDesiredStateResponse_globals_.GetClassData();
+}
+#endif // !PROTOBUF_MESSAGE_GLOBALS
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_CONSTINIT
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const GetDesiredStateResponse::ParseTableT_
+ GetDesiredStateResponse::_table_ =
+ GetDesiredStateResponse::InternalGenerateParseTable_(GetDesiredStateResponse_class_data_.base());
+#endif // !PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_NOINLINE void GetDesiredStateResponse::Clear() {
+ auto& this_ [[maybe_unused]] = *this;
+ // @@protoc_insertion_point(message_clear_start:xtcp_treatment.v1.GetDesiredStateResponse)
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ ::uint32_t cached_has_bits [[maybe_unused]] = 0;
+
+ cached_has_bits = this_._impl_._has_bits_[0];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ ABSL_DCHECK(this_._impl_.desired_ != nullptr);
+ this_._impl_.desired_->Clear();
+ }
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
+}
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+::uint8_t* PROTOBUF_NONNULL GetDesiredStateResponse::_InternalSerialize(
+ const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) {
+ const GetDesiredStateResponse& this_ = static_cast(base);
+#else // PROTOBUF_CUSTOM_VTABLE
+::uint8_t* PROTOBUF_NONNULL GetDesiredStateResponse::_InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
+ const GetDesiredStateResponse& this_ = *this;
+#endif // PROTOBUF_CUSTOM_VTABLE
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ this_.CheckHasBitConsistency();
+ }
+ // @@protoc_insertion_point(serialize_to_array_start:xtcp_treatment.v1.GetDesiredStateResponse)
+ ::uint32_t cached_has_bits = 0;
+ (void)cached_has_bits;
+
+ cached_has_bits = this_._impl_._has_bits_[0];
+ // .xtcp_treatment.v1.DesiredState desired = 1 [json_name = "desired"];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
+ 1, *this_._impl_.desired_, this_._impl_.desired_->GetCachedSize(), target,
+ stream);
+ }
+
+ if (ABSL_PREDICT_FALSE(this_._internal_metadata_.have_unknown_fields())) {
+ target =
+ ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ this_._internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:xtcp_treatment.v1.GetDesiredStateResponse)
+ return target;
+}
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+::size_t GetDesiredStateResponse::ByteSizeLong(const MessageLite& base) {
+ const GetDesiredStateResponse& this_ = static_cast(base);
+#else // PROTOBUF_CUSTOM_VTABLE
+::size_t GetDesiredStateResponse::ByteSizeLong() const {
+ const GetDesiredStateResponse& this_ = *this;
+#endif // PROTOBUF_CUSTOM_VTABLE
+ // @@protoc_insertion_point(message_byte_size_start:xtcp_treatment.v1.GetDesiredStateResponse)
+ ::size_t total_size = 0;
+
+ ::uint32_t cached_has_bits [[maybe_unused]] = 0;
+
+ {
+ // .xtcp_treatment.v1.DesiredState desired = 1 [json_name = "desired"];
+ cached_has_bits = this_._impl_._has_bits_[0];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSize(*this_._impl_.desired_);
+ }
+ }
+ return this_.MaybeComputeUnknownFieldsSize(total_size,
+ &this_._impl_._cached_size_);
+}
+
+void GetDesiredStateResponse::MergeImpl(::google::protobuf::MessageLite& to_msg,
+ const ::google::protobuf::MessageLite& from_msg) {
+ auto* const _this = static_cast(&to_msg);
+ auto& from = static_cast(from_msg);
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ from.CheckHasBitConsistency();
+ }
+ ::google::protobuf::Arena* arena = _this->GetArena();
+ // @@protoc_insertion_point(class_specific_merge_from_start:xtcp_treatment.v1.GetDesiredStateResponse)
+ ABSL_DCHECK_NE(&from, _this);
+ ::uint32_t cached_has_bits = 0;
+ (void)cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ ABSL_DCHECK(from._impl_.desired_ != nullptr);
+ if (_this->_impl_.desired_ == nullptr) {
+ _this->_impl_.desired_ = Super_::CopyConstruct(arena, *from._impl_.desired_);
+ } else {
+ _this->_impl_.desired_->MergeFrom(*from._impl_.desired_);
+ }
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
+ from._internal_metadata_);
+}
+
+void GetDesiredStateResponse::CopyFrom(const GetDesiredStateResponse& from) {
+ // @@protoc_insertion_point(class_specific_copy_from_start:xtcp_treatment.v1.GetDesiredStateResponse)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+
+void GetDesiredStateResponse::InternalSwap(GetDesiredStateResponse* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) {
+ using ::std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ swap(_impl_.desired_, other->_impl_.desired_);
+}
+
+::google::protobuf::Metadata GetDesiredStateResponse::GetMetadata() const {
+ return Super_::GetMetadataImpl(GetClassData()->full());
+}
+// ===================================================================
+
+WatchDesiredStateRequest::WatchDesiredStateRequest(::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ : Super_(arena, WatchDesiredStateRequest_get_class_data()) {
+#else // PROTOBUF_CUSTOM_VTABLE
+ : Super_(arena) {
+#endif // PROTOBUF_CUSTOM_VTABLE
+ SharedCtor(arena);
+ // @@protoc_insertion_point(arena_constructor:xtcp_treatment.v1.WatchDesiredStateRequest)
+}
+PROTOBUF_NDEBUG_INLINE WatchDesiredStateRequest::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,
+ [[maybe_unused]] const ::xtcp_treatment::v1::WatchDesiredStateRequest& from_msg)
+ : _has_bits_{from._has_bits_},
+ agent_id_(arena, from.agent_id_) {}
+
+WatchDesiredStateRequest::WatchDesiredStateRequest(
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena,
+ const WatchDesiredStateRequest& from)
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ : Super_(arena, WatchDesiredStateRequest_get_class_data()) {
+
+#else // PROTOBUF_CUSTOM_VTABLE
+ : Super_(arena) {
+#endif // PROTOBUF_CUSTOM_VTABLE
+ WatchDesiredStateRequest* const _this = this;
+ (void)_this;
+ _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
+ from._internal_metadata_);
+ new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);
+ _impl_.after_revision_ = from._impl_.after_revision_;
+
+ // @@protoc_insertion_point(copy_constructor:xtcp_treatment.v1.WatchDesiredStateRequest)
+}
+PROTOBUF_NDEBUG_INLINE WatchDesiredStateRequest::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
+ : agent_id_(arena) {}
+
+inline void WatchDesiredStateRequest::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) {
+ new (&_impl_) Impl_(internal_visibility(), arena);
+ _impl_.after_revision_ = {};
+}
+WatchDesiredStateRequest::~WatchDesiredStateRequest() {
+ // @@protoc_insertion_point(destructor:xtcp_treatment.v1.WatchDesiredStateRequest)
+ SharedDtor(*this);
+}
+inline void WatchDesiredStateRequest::SharedDtor(MessageLite& self) {
+ WatchDesiredStateRequest& this_ = static_cast(self);
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ this_.CheckHasBitConsistency();
+ }
+ this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
+ ABSL_DCHECK(this_.GetArena() == nullptr);
+ this_._impl_.agent_id_.Destroy();
+ this_._impl_.~Impl_();
+}
+
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const
+ ::google::protobuf::internal::ClassDataFull WatchDesiredStateRequest_class_data_ =
+ WatchDesiredStateRequest::InternalGenerateClassData_(WatchDesiredStateRequest_globals_._default);
+
+PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+WatchDesiredStateRequest::GetClassData() const {
+ ::google::protobuf::internal::PrefetchToLocalCache(&WatchDesiredStateRequest_class_data_);
+ ::google::protobuf::internal::PrefetchToLocalCache(WatchDesiredStateRequest_class_data_.tc_table);
+ return WatchDesiredStateRequest_class_data_.base();
+}
+#else
+PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+WatchDesiredStateRequest::GetClassData() const {
+ ::google::protobuf::internal::PrefetchToLocalCache(&WatchDesiredStateRequest_globals_);
+ ::google::protobuf::internal::PrefetchToLocalCache(
+ ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&WatchDesiredStateRequest_globals_));
+ return WatchDesiredStateRequest_globals_.GetClassData();
+}
+#endif // !PROTOBUF_MESSAGE_GLOBALS
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_CONSTINIT
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const WatchDesiredStateRequest::ParseTableT_
+ WatchDesiredStateRequest::_table_ =
+ WatchDesiredStateRequest::InternalGenerateParseTable_(WatchDesiredStateRequest_class_data_.base());
+#endif // !PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_NOINLINE void WatchDesiredStateRequest::Clear() {
+ auto& this_ [[maybe_unused]] = *this;
+ // @@protoc_insertion_point(message_clear_start:xtcp_treatment.v1.WatchDesiredStateRequest)
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ ::uint32_t cached_has_bits [[maybe_unused]] = 0;
+
+ cached_has_bits = this_._impl_._has_bits_[0];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ this_._impl_.agent_id_.ClearNonDefaultToEmpty();
+ }
+ this_._impl_.after_revision_ = ::uint64_t{0u};
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
+}
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+::uint8_t* PROTOBUF_NONNULL WatchDesiredStateRequest::_InternalSerialize(
+ const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) {
+ const WatchDesiredStateRequest& this_ = static_cast(base);
+#else // PROTOBUF_CUSTOM_VTABLE
+::uint8_t* PROTOBUF_NONNULL WatchDesiredStateRequest::_InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
+ const WatchDesiredStateRequest& this_ = *this;
+#endif // PROTOBUF_CUSTOM_VTABLE
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ this_.CheckHasBitConsistency();
+ }
+ // @@protoc_insertion_point(serialize_to_array_start:xtcp_treatment.v1.WatchDesiredStateRequest)
+ ::uint32_t cached_has_bits = 0;
+ (void)cached_has_bits;
+
+ cached_has_bits = this_._impl_._has_bits_[0];
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ if (!this_._internal_agent_id().empty()) {
+ const ::std::string& _s = this_._internal_agent_id();
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ _s.data(), static_cast(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "xtcp_treatment.v1.WatchDesiredStateRequest.agent_id");
+ target = stream->WriteStringMaybeAliased(1, _s, target);
+ }
+ }
+
+ // uint64 after_revision = 2 [json_name = "afterRevision"];
+ if (CheckHasBit(cached_has_bits, 0x00000002U)) {
+ if (this_._internal_after_revision() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteUInt64ToArray(
+ 2, this_._internal_after_revision(), target);
+ }
+ }
+
+ if (ABSL_PREDICT_FALSE(this_._internal_metadata_.have_unknown_fields())) {
+ target =
+ ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ this_._internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:xtcp_treatment.v1.WatchDesiredStateRequest)
+ return target;
+}
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+::size_t WatchDesiredStateRequest::ByteSizeLong(const MessageLite& base) {
+ const WatchDesiredStateRequest& this_ = static_cast(base);
+#else // PROTOBUF_CUSTOM_VTABLE
+::size_t WatchDesiredStateRequest::ByteSizeLong() const {
+ const WatchDesiredStateRequest& this_ = *this;
+#endif // PROTOBUF_CUSTOM_VTABLE
+ // @@protoc_insertion_point(message_byte_size_start:xtcp_treatment.v1.WatchDesiredStateRequest)
+ ::size_t total_size = 0;
+
+ ::uint32_t cached_has_bits [[maybe_unused]] = 0;
+
+ ::_pbi::Prefetch5LinesFrom7Lines(&this_);
+ cached_has_bits = this_._impl_._has_bits_[0];
+ if (BatchCheckHasBit(cached_has_bits, 0x00000003U)) {
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ if (!this_._internal_agent_id().empty()) {
+ total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
+ this_._internal_agent_id());
+ }
+ }
+ // uint64 after_revision = 2 [json_name = "afterRevision"];
+ if (CheckHasBit(cached_has_bits, 0x00000002U)) {
+ if (this_._internal_after_revision() != 0) {
+ total_size += ::_pbi::WireFormatLite::UInt64SizePlusOne(
+ this_._internal_after_revision());
+ }
+ }
+ }
+ return this_.MaybeComputeUnknownFieldsSize(total_size,
+ &this_._impl_._cached_size_);
+}
+
+void WatchDesiredStateRequest::MergeImpl(::google::protobuf::MessageLite& to_msg,
+ const ::google::protobuf::MessageLite& from_msg) {
+ auto* const _this = static_cast(&to_msg);
+ auto& from = static_cast(from_msg);
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ from.CheckHasBitConsistency();
+ }
+ // @@protoc_insertion_point(class_specific_merge_from_start:xtcp_treatment.v1.WatchDesiredStateRequest)
+ ABSL_DCHECK_NE(&from, _this);
+ ::uint32_t cached_has_bits = 0;
+ (void)cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (BatchCheckHasBit(cached_has_bits, 0x00000003U)) {
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ if (!from._internal_agent_id().empty()) {
+ _this->_internal_set_agent_id(from._internal_agent_id());
+ } else {
+ if (_this->_impl_.agent_id_.IsDefault()) {
+ _this->_internal_set_agent_id("");
+ }
+ }
+ }
+ if (CheckHasBit(cached_has_bits, 0x00000002U)) {
+ if (from._internal_after_revision() != 0) {
+ _this->_impl_.after_revision_ = from._impl_.after_revision_;
+ }
+ }
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
+ from._internal_metadata_);
+}
+
+void WatchDesiredStateRequest::CopyFrom(const WatchDesiredStateRequest& from) {
+ // @@protoc_insertion_point(class_specific_copy_from_start:xtcp_treatment.v1.WatchDesiredStateRequest)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+
+void WatchDesiredStateRequest::InternalSwap(WatchDesiredStateRequest* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) {
+ using ::std::swap;
+ auto* arena = GetArena();
+ ABSL_DCHECK_EQ(arena, other->GetArena());
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.agent_id_, &other->_impl_.agent_id_, arena);
+ swap(_impl_.after_revision_, other->_impl_.after_revision_);
+}
+
+::google::protobuf::Metadata WatchDesiredStateRequest::GetMetadata() const {
+ return Super_::GetMetadataImpl(GetClassData()->full());
+}
+// ===================================================================
+
+WatchDesiredStateResponse::WatchDesiredStateResponse(::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ : Super_(arena, WatchDesiredStateResponse_get_class_data()) {
+#else // PROTOBUF_CUSTOM_VTABLE
+ : Super_(arena) {
+#endif // PROTOBUF_CUSTOM_VTABLE
+ SharedCtor(arena);
+ // @@protoc_insertion_point(arena_constructor:xtcp_treatment.v1.WatchDesiredStateResponse)
+}
+WatchDesiredStateResponse::WatchDesiredStateResponse(
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const WatchDesiredStateResponse& from)
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ : Super_(arena, WatchDesiredStateResponse_get_class_data()),
+#else // PROTOBUF_CUSTOM_VTABLE
+ : Super_(arena),
+#endif // PROTOBUF_CUSTOM_VTABLE
+ _impl_(from._impl_) {
+ _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
+ from._internal_metadata_);
+}
+PROTOBUF_NDEBUG_INLINE WatchDesiredStateResponse::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
+ {}
+
+inline void WatchDesiredStateResponse::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) {
+ new (&_impl_) Impl_(internal_visibility(), arena);
+ _impl_.revision_ = {};
+}
+WatchDesiredStateResponse::~WatchDesiredStateResponse() {
+ // @@protoc_insertion_point(destructor:xtcp_treatment.v1.WatchDesiredStateResponse)
+ SharedDtor(*this);
+}
+inline void WatchDesiredStateResponse::SharedDtor(MessageLite& self) {
+ WatchDesiredStateResponse& this_ = static_cast(self);
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ this_.CheckHasBitConsistency();
+ }
+ this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
+ ABSL_DCHECK(this_.GetArena() == nullptr);
+ this_._impl_.~Impl_();
+}
+
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const
+ ::google::protobuf::internal::ClassDataFull WatchDesiredStateResponse_class_data_ =
+ WatchDesiredStateResponse::InternalGenerateClassData_(WatchDesiredStateResponse_globals_._default);
+
+PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+WatchDesiredStateResponse::GetClassData() const {
+ ::google::protobuf::internal::PrefetchToLocalCache(&WatchDesiredStateResponse_class_data_);
+ ::google::protobuf::internal::PrefetchToLocalCache(WatchDesiredStateResponse_class_data_.tc_table);
+ return WatchDesiredStateResponse_class_data_.base();
+}
+#else
+PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+WatchDesiredStateResponse::GetClassData() const {
+ ::google::protobuf::internal::PrefetchToLocalCache(&WatchDesiredStateResponse_globals_);
+ ::google::protobuf::internal::PrefetchToLocalCache(
+ ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&WatchDesiredStateResponse_globals_));
+ return WatchDesiredStateResponse_globals_.GetClassData();
+}
+#endif // !PROTOBUF_MESSAGE_GLOBALS
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_CONSTINIT
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const WatchDesiredStateResponse::ParseTableT_
+ WatchDesiredStateResponse::_table_ =
+ WatchDesiredStateResponse::InternalGenerateParseTable_(WatchDesiredStateResponse_class_data_.base());
+#endif // !PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_NOINLINE void WatchDesiredStateResponse::Clear() {
+ auto& this_ [[maybe_unused]] = *this;
+ // @@protoc_insertion_point(message_clear_start:xtcp_treatment.v1.WatchDesiredStateResponse)
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ ::uint32_t cached_has_bits [[maybe_unused]] = 0;
+
+ this_._impl_.revision_ = ::uint64_t{0u};
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
+}
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+::uint8_t* PROTOBUF_NONNULL WatchDesiredStateResponse::_InternalSerialize(
+ const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) {
+ const WatchDesiredStateResponse& this_ = static_cast(base);
+#else // PROTOBUF_CUSTOM_VTABLE
+::uint8_t* PROTOBUF_NONNULL WatchDesiredStateResponse::_InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
+ const WatchDesiredStateResponse& this_ = *this;
+#endif // PROTOBUF_CUSTOM_VTABLE
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ this_.CheckHasBitConsistency();
+ }
+ // @@protoc_insertion_point(serialize_to_array_start:xtcp_treatment.v1.WatchDesiredStateResponse)
+ ::uint32_t cached_has_bits = 0;
+ (void)cached_has_bits;
+
+ cached_has_bits = this_._impl_._has_bits_[0];
+ // uint64 revision = 1 [json_name = "revision"];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ if (this_._internal_revision() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteUInt64ToArray(
+ 1, this_._internal_revision(), target);
+ }
+ }
+
+ if (ABSL_PREDICT_FALSE(this_._internal_metadata_.have_unknown_fields())) {
+ target =
+ ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ this_._internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:xtcp_treatment.v1.WatchDesiredStateResponse)
+ return target;
+}
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+::size_t WatchDesiredStateResponse::ByteSizeLong(const MessageLite& base) {
+ const WatchDesiredStateResponse& this_ = static_cast(base);
+#else // PROTOBUF_CUSTOM_VTABLE
+::size_t WatchDesiredStateResponse::ByteSizeLong() const {
+ const WatchDesiredStateResponse& this_ = *this;
+#endif // PROTOBUF_CUSTOM_VTABLE
+ // @@protoc_insertion_point(message_byte_size_start:xtcp_treatment.v1.WatchDesiredStateResponse)
+ ::size_t total_size = 0;
+
+ ::uint32_t cached_has_bits [[maybe_unused]] = 0;
+
+ {
+ // uint64 revision = 1 [json_name = "revision"];
+ cached_has_bits = this_._impl_._has_bits_[0];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ if (this_._internal_revision() != 0) {
+ total_size += ::_pbi::WireFormatLite::UInt64SizePlusOne(
+ this_._internal_revision());
+ }
+ }
+ }
+ return this_.MaybeComputeUnknownFieldsSize(total_size,
+ &this_._impl_._cached_size_);
+}
+
+void WatchDesiredStateResponse::MergeImpl(::google::protobuf::MessageLite& to_msg,
+ const ::google::protobuf::MessageLite& from_msg) {
+ auto* const _this = static_cast(&to_msg);
+ auto& from = static_cast(from_msg);
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ from.CheckHasBitConsistency();
+ }
+ // @@protoc_insertion_point(class_specific_merge_from_start:xtcp_treatment.v1.WatchDesiredStateResponse)
+ ABSL_DCHECK_NE(&from, _this);
+ ::uint32_t cached_has_bits = 0;
+ (void)cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ if (from._internal_revision() != 0) {
+ _this->_impl_.revision_ = from._impl_.revision_;
+ }
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
+ from._internal_metadata_);
+}
+
+void WatchDesiredStateResponse::CopyFrom(const WatchDesiredStateResponse& from) {
+ // @@protoc_insertion_point(class_specific_copy_from_start:xtcp_treatment.v1.WatchDesiredStateResponse)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+
+void WatchDesiredStateResponse::InternalSwap(WatchDesiredStateResponse* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) {
+ using ::std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ swap(_impl_.revision_, other->_impl_.revision_);
+}
+
+::google::protobuf::Metadata WatchDesiredStateResponse::GetMetadata() const {
+ return Super_::GetMetadataImpl(GetClassData()->full());
+}
+// @@protoc_insertion_point(namespace_scope)
+} // namespace v1
+} // namespace xtcp_treatment
+namespace google {
+namespace protobuf {
+} // namespace protobuf
+} // namespace google
+// @@protoc_insertion_point(global_scope)
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::std::false_type
+ _static_init2_ [[maybe_unused]] =
+ (::_pbi::AddDescriptors(&descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto),
+ ::std::false_type{});
+#include "google/protobuf/port_undef.inc"
diff --git a/gen/cpp/xtcp_treatment/v1/agent.pb.h b/gen/cpp/xtcp_treatment/v1/agent.pb.h
new file mode 100644
index 000000000..0bdc0ce88
--- /dev/null
+++ b/gen/cpp/xtcp_treatment/v1/agent.pb.h
@@ -0,0 +1,2167 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// NO CHECKED-IN PROTOBUF GENCODE
+// source: xtcp_treatment/v1/agent.proto
+// Protobuf C++ Version: 7.36.2
+
+#ifndef xtcp_5ftreatment_2fv1_2fagent_2eproto_2epb_2eh
+#define xtcp_5ftreatment_2fv1_2fagent_2eproto_2epb_2eh
+
+#include
+#include
+#include
+#include
+
+// clang-format off
+#include "google/protobuf/runtime_version.h"
+#if PROTOBUF_VERSION != 7036002
+#error "Protobuf C++ gencode is built with an incompatible version of"
+#error "Protobuf C++ headers/runtime. See"
+#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
+#endif
+#include "google/protobuf/io/coded_stream.h"
+#include "google/protobuf/arena.h"
+#include "google/protobuf/arenastring.h"
+#include "google/protobuf/generated_message_tctable_decl.h"
+#include "google/protobuf/generated_message_util.h"
+#include "google/protobuf/metadata_lite.h"
+#include "google/protobuf/generated_message_reflection.h"
+#include "google/protobuf/message.h"
+#include "google/protobuf/message_lite.h"
+#include "google/protobuf/repeated_field.h" // IWYU pragma: export
+#include "google/protobuf/extension_set.h" // IWYU pragma: export
+#include "google/protobuf/unknown_field_set.h"
+#include "buf/validate/validate.pb.h"
+#include "xtcp_treatment/v1/treatment.pb.h"
+// @@protoc_insertion_point(includes)
+
+// Must be included last.
+#include "google/protobuf/port_def.inc"
+
+#define PROTOBUF_INTERNAL_EXPORT_xtcp_5ftreatment_2fv1_2fagent_2eproto
+
+// Internal implementation detail -- do not use these members.
+struct TableStruct_xtcp_5ftreatment_2fv1_2fagent_2eproto {
+ static const ::uint32_t offsets[];
+};
+extern "C" {
+extern const ::google::protobuf::internal::DescriptorTable descriptor_table_xtcp_5ftreatment_2fv1_2fagent_2eproto;
+} // extern "C"
+namespace xtcp_treatment {
+namespace v1 {
+class CheckInRequest;
+struct CheckInRequestGlobalsTypeInternal;
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+extern CheckInRequestGlobalsTypeInternal CheckInRequest_globals_;
+extern const ::google::protobuf::internal::ClassDataFull CheckInRequest_class_data_;
+#else
+extern const CheckInRequestGlobalsTypeInternal CheckInRequest_globals_;
+#endif // PROTOBUF_MESSAGE_GLOBALS
+class CheckInResponse;
+struct CheckInResponseGlobalsTypeInternal;
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+extern CheckInResponseGlobalsTypeInternal CheckInResponse_globals_;
+extern const ::google::protobuf::internal::ClassDataFull CheckInResponse_class_data_;
+#else
+extern const CheckInResponseGlobalsTypeInternal CheckInResponse_globals_;
+#endif // PROTOBUF_MESSAGE_GLOBALS
+class GetDesiredStateRequest;
+struct GetDesiredStateRequestGlobalsTypeInternal;
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+extern GetDesiredStateRequestGlobalsTypeInternal GetDesiredStateRequest_globals_;
+extern const ::google::protobuf::internal::ClassDataFull GetDesiredStateRequest_class_data_;
+#else
+extern const GetDesiredStateRequestGlobalsTypeInternal GetDesiredStateRequest_globals_;
+#endif // PROTOBUF_MESSAGE_GLOBALS
+class GetDesiredStateResponse;
+struct GetDesiredStateResponseGlobalsTypeInternal;
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+extern GetDesiredStateResponseGlobalsTypeInternal GetDesiredStateResponse_globals_;
+extern const ::google::protobuf::internal::ClassDataFull GetDesiredStateResponse_class_data_;
+#else
+extern const GetDesiredStateResponseGlobalsTypeInternal GetDesiredStateResponse_globals_;
+#endif // PROTOBUF_MESSAGE_GLOBALS
+class WatchDesiredStateRequest;
+struct WatchDesiredStateRequestGlobalsTypeInternal;
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+extern WatchDesiredStateRequestGlobalsTypeInternal WatchDesiredStateRequest_globals_;
+extern const ::google::protobuf::internal::ClassDataFull WatchDesiredStateRequest_class_data_;
+#else
+extern const WatchDesiredStateRequestGlobalsTypeInternal WatchDesiredStateRequest_globals_;
+#endif // PROTOBUF_MESSAGE_GLOBALS
+class WatchDesiredStateResponse;
+struct WatchDesiredStateResponseGlobalsTypeInternal;
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+extern WatchDesiredStateResponseGlobalsTypeInternal WatchDesiredStateResponse_globals_;
+extern const ::google::protobuf::internal::ClassDataFull WatchDesiredStateResponse_class_data_;
+#else
+extern const WatchDesiredStateResponseGlobalsTypeInternal WatchDesiredStateResponse_globals_;
+#endif // PROTOBUF_MESSAGE_GLOBALS
+} // namespace v1
+} // namespace xtcp_treatment
+namespace google {
+namespace protobuf {
+} // namespace protobuf
+} // namespace google
+
+namespace xtcp_treatment {
+namespace v1 {
+
+// ===================================================================
+
+
+// -------------------------------------------------------------------
+
+class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED WatchDesiredStateResponse final : public ::google::protobuf::Message
+/* @@protoc_insertion_point(class_definition:xtcp_treatment.v1.WatchDesiredStateResponse) */ {
+ using Super_ = ::google::protobuf::Message;
+
+ public:
+ inline WatchDesiredStateResponse() : WatchDesiredStateResponse(nullptr) {}
+ ~WatchDesiredStateResponse() PROTOBUF_FINAL;
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ void operator delete(WatchDesiredStateResponse* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) {
+ SharedDtor(*msg);
+ ::google::protobuf::internal::SizedDelete(msg, sizeof(WatchDesiredStateResponse));
+ }
+#endif
+
+ template
+ explicit constexpr WatchDesiredStateResponse(::google::protobuf::internal::ConstantInitialized,
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+ class_data);
+
+ inline WatchDesiredStateResponse(const WatchDesiredStateResponse& from) : WatchDesiredStateResponse(nullptr, from) {}
+ inline WatchDesiredStateResponse(WatchDesiredStateResponse&& from) noexcept : WatchDesiredStateResponse(nullptr, ::std::move(from)) {}
+ inline WatchDesiredStateResponse& operator=(const WatchDesiredStateResponse& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline WatchDesiredStateResponse& operator=(WatchDesiredStateResponse&& from) noexcept {
+ if (this == &from) return *this;
+ if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ [[nodiscard]] inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance);
+ }
+ [[nodiscard]] inline ::google::protobuf::UnknownFieldSet* PROTOBUF_NONNULL
+ mutable_unknown_fields() ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>();
+ }
+
+ [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() {
+ return GetDescriptor();
+ }
+ [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL
+ GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ [[nodiscard]] static const ::google::protobuf::Reflection* PROTOBUF_NONNULL GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ [[nodiscard]] static const WatchDesiredStateResponse& default_instance() {
+ return *::google::protobuf::internal::MessageGlobalsBase::ToDefaultInstance(&WatchDesiredStateResponse_globals_);
+ }
+ static constexpr int kIndexInFileMessages = 5;
+ friend void swap(WatchDesiredStateResponse& a, WatchDesiredStateResponse& b) { a.Swap(&b); }
+ inline void Swap(WatchDesiredStateResponse* PROTOBUF_NONNULL other) {
+ if (other == this) return;
+ if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) {
+ InternalSwap(other);
+ } else {
+ ::google::protobuf::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(WatchDesiredStateResponse* PROTOBUF_NONNULL other) {
+ if (other == this) return;
+ ABSL_DCHECK(GetArena() == other->GetArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ [[nodiscard]] WatchDesiredStateResponse* PROTOBUF_NONNULL
+ New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const {
+ return Super_::DefaultConstruct(arena);
+ }
+ using Super_::CopyFrom;
+ void CopyFrom(const WatchDesiredStateResponse& from);
+ using Super_::MergeFrom;
+ void MergeFrom(const WatchDesiredStateResponse& from) { WatchDesiredStateResponse::MergeImpl(*this, from); }
+
+ private:
+ static void MergeImpl(::google::protobuf::MessageLite& to_msg,
+ const ::google::protobuf::MessageLite& from_msg);
+
+ public:
+ [[nodiscard]] bool IsInitialized() const {
+ return true;
+ }
+ ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
+ #if defined(PROTOBUF_CUSTOM_VTABLE)
+ private:
+ [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg);
+ [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream);
+
+ public:
+ [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); }
+ [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
+ return _InternalSerialize(*this, target, stream);
+ }
+ #else // PROTOBUF_CUSTOM_VTABLE
+ [[nodiscard]] ::size_t ByteSizeLong() const final;
+ [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final;
+ #endif // PROTOBUF_CUSTOM_VTABLE
+ [[nodiscard]] int GetCachedSize() const {
+ return _impl_._cached_size_.Get();
+ }
+
+ private:
+ void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ static void SharedDtor(MessageLite& self);
+ void InternalSwap(WatchDesiredStateResponse* PROTOBUF_NONNULL other);
+ private:
+ static ::absl::string_view FullMessageName() { return "xtcp_treatment.v1.WatchDesiredStateResponse"; }
+
+ explicit WatchDesiredStateResponse(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ WatchDesiredStateResponse(::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const WatchDesiredStateResponse& from);
+ WatchDesiredStateResponse(
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, WatchDesiredStateResponse&& from) noexcept
+ : WatchDesiredStateResponse(arena) {
+ *this = ::std::move(from);
+ }
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL;
+ static void* PROTOBUF_NONNULL PlacementNew_(
+ const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ static constexpr auto InternalNewImpl_();
+
+ public:
+ static constexpr auto InternalGenerateClassData_(
+ const MessageLite& prototype,
+ const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr);
+
+ [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const;
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+ enum : int {
+ kRevisionFieldNumber = 1,
+ };
+ // uint64 revision = 1 [json_name = "revision"];
+ void clear_revision() ;
+ [[nodiscard]] ::uint64_t revision() const;
+ void set_revision(::uint64_t value);
+
+ private:
+ ::uint64_t _internal_revision() const;
+ void _internal_set_revision(::uint64_t value);
+
+ public:
+ // @@protoc_insertion_point(class_scope:xtcp_treatment.v1.WatchDesiredStateResponse)
+ private:
+ class _Internal;
+ using ParseTableT_ =
+ ::google::protobuf::internal::TcParseTable<0, 1,
+ 0, 0,
+ 2>;
+ static constexpr ParseTableT_ InternalGenerateParseTable_(
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data);
+ friend class ::google::protobuf::internal::TcParser;
+ #ifndef PROTOBUF_MESSAGE_GLOBALS
+ static const ParseTableT_ _table_;
+ #endif
+
+ friend class ::google::protobuf::MessageLite;
+ friend class ::google::protobuf::Arena;
+ friend ::google::protobuf::internal::PrivateAccess;
+ template
+ friend class ::google::protobuf::Arena::InternalHelper;
+ using InternalArenaConstructable_ = void;
+ using DestructorSkippable_ = void;
+ struct Impl_ {
+ inline explicit constexpr Impl_(::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::internal::ConstantInitialized) noexcept;
+ inline explicit Impl_(
+ ::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ inline explicit Impl_(
+ ::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,
+ const WatchDesiredStateResponse& from_msg);
+ ::google::protobuf::internal::HasBits<1> _has_bits_;
+ ::google::protobuf::internal::CachedSize _cached_size_;
+ ::uint64_t revision_;
+ PROTOBUF_TSAN_DECLARE_MEMBER
+ };
+ union { Impl_ _impl_; };
+ friend struct ::TableStruct_xtcp_5ftreatment_2fv1_2fagent_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED WatchDesiredStateRequest final : public ::google::protobuf::Message
+/* @@protoc_insertion_point(class_definition:xtcp_treatment.v1.WatchDesiredStateRequest) */ {
+ using Super_ = ::google::protobuf::Message;
+
+ public:
+ inline WatchDesiredStateRequest() : WatchDesiredStateRequest(nullptr) {}
+ ~WatchDesiredStateRequest() PROTOBUF_FINAL;
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ void operator delete(WatchDesiredStateRequest* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) {
+ SharedDtor(*msg);
+ ::google::protobuf::internal::SizedDelete(msg, sizeof(WatchDesiredStateRequest));
+ }
+#endif
+
+ template
+ explicit constexpr WatchDesiredStateRequest(::google::protobuf::internal::ConstantInitialized,
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+ class_data);
+
+ inline WatchDesiredStateRequest(const WatchDesiredStateRequest& from) : WatchDesiredStateRequest(nullptr, from) {}
+ inline WatchDesiredStateRequest(WatchDesiredStateRequest&& from) noexcept : WatchDesiredStateRequest(nullptr, ::std::move(from)) {}
+ inline WatchDesiredStateRequest& operator=(const WatchDesiredStateRequest& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline WatchDesiredStateRequest& operator=(WatchDesiredStateRequest&& from) noexcept {
+ if (this == &from) return *this;
+ if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ [[nodiscard]] inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance);
+ }
+ [[nodiscard]] inline ::google::protobuf::UnknownFieldSet* PROTOBUF_NONNULL
+ mutable_unknown_fields() ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>();
+ }
+
+ [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() {
+ return GetDescriptor();
+ }
+ [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL
+ GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ [[nodiscard]] static const ::google::protobuf::Reflection* PROTOBUF_NONNULL GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ [[nodiscard]] static const WatchDesiredStateRequest& default_instance() {
+ return *::google::protobuf::internal::MessageGlobalsBase::ToDefaultInstance(&WatchDesiredStateRequest_globals_);
+ }
+ static constexpr int kIndexInFileMessages = 4;
+ friend void swap(WatchDesiredStateRequest& a, WatchDesiredStateRequest& b) { a.Swap(&b); }
+ inline void Swap(WatchDesiredStateRequest* PROTOBUF_NONNULL other) {
+ if (other == this) return;
+ if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) {
+ InternalSwap(other);
+ } else {
+ ::google::protobuf::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(WatchDesiredStateRequest* PROTOBUF_NONNULL other) {
+ if (other == this) return;
+ ABSL_DCHECK(GetArena() == other->GetArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ [[nodiscard]] WatchDesiredStateRequest* PROTOBUF_NONNULL
+ New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const {
+ return Super_::DefaultConstruct(arena);
+ }
+ using Super_::CopyFrom;
+ void CopyFrom(const WatchDesiredStateRequest& from);
+ using Super_::MergeFrom;
+ void MergeFrom(const WatchDesiredStateRequest& from) { WatchDesiredStateRequest::MergeImpl(*this, from); }
+
+ private:
+ static void MergeImpl(::google::protobuf::MessageLite& to_msg,
+ const ::google::protobuf::MessageLite& from_msg);
+
+ public:
+ [[nodiscard]] bool IsInitialized() const {
+ return true;
+ }
+ ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
+ #if defined(PROTOBUF_CUSTOM_VTABLE)
+ private:
+ [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg);
+ [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream);
+
+ public:
+ [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); }
+ [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
+ return _InternalSerialize(*this, target, stream);
+ }
+ #else // PROTOBUF_CUSTOM_VTABLE
+ [[nodiscard]] ::size_t ByteSizeLong() const final;
+ [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final;
+ #endif // PROTOBUF_CUSTOM_VTABLE
+ [[nodiscard]] int GetCachedSize() const {
+ return _impl_._cached_size_.Get();
+ }
+
+ private:
+ void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ static void SharedDtor(MessageLite& self);
+ void InternalSwap(WatchDesiredStateRequest* PROTOBUF_NONNULL other);
+ private:
+ static ::absl::string_view FullMessageName() { return "xtcp_treatment.v1.WatchDesiredStateRequest"; }
+
+ explicit WatchDesiredStateRequest(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ WatchDesiredStateRequest(::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const WatchDesiredStateRequest& from);
+ WatchDesiredStateRequest(
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, WatchDesiredStateRequest&& from) noexcept
+ : WatchDesiredStateRequest(arena) {
+ *this = ::std::move(from);
+ }
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL;
+ static void* PROTOBUF_NONNULL PlacementNew_(
+ const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ static constexpr auto InternalNewImpl_();
+
+ public:
+ static constexpr auto InternalGenerateClassData_(
+ const MessageLite& prototype,
+ const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr);
+
+ [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const;
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+ enum : int {
+ kAgentIdFieldNumber = 1,
+ kAfterRevisionFieldNumber = 2,
+ };
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ void clear_agent_id() ;
+ [[nodiscard]] const ::std::string& agent_id() const;
+ template
+ void set_agent_id(Arg_&& arg, Args_... args);
+ ::std::string* PROTOBUF_NONNULL mutable_agent_id();
+ [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_agent_id();
+ void set_allocated_agent_id(::std::string* PROTOBUF_NULLABLE value);
+
+ private:
+ const ::std::string& _internal_agent_id() const;
+ PROTOBUF_ALWAYS_INLINE void _internal_set_agent_id(const ::std::string& value);
+ ::std::string* PROTOBUF_NONNULL _internal_mutable_agent_id();
+
+ public:
+ // uint64 after_revision = 2 [json_name = "afterRevision"];
+ void clear_after_revision() ;
+ [[nodiscard]] ::uint64_t after_revision() const;
+ void set_after_revision(::uint64_t value);
+
+ private:
+ ::uint64_t _internal_after_revision() const;
+ void _internal_set_after_revision(::uint64_t value);
+
+ public:
+ // @@protoc_insertion_point(class_scope:xtcp_treatment.v1.WatchDesiredStateRequest)
+ private:
+ class _Internal;
+ using ParseTableT_ =
+ ::google::protobuf::internal::TcParseTable<1, 2,
+ 0, 59,
+ 2>;
+ static constexpr ParseTableT_ InternalGenerateParseTable_(
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data);
+ friend class ::google::protobuf::internal::TcParser;
+ #ifndef PROTOBUF_MESSAGE_GLOBALS
+ static const ParseTableT_ _table_;
+ #endif
+
+ friend class ::google::protobuf::MessageLite;
+ friend class ::google::protobuf::Arena;
+ friend ::google::protobuf::internal::PrivateAccess;
+ template
+ friend class ::google::protobuf::Arena::InternalHelper;
+ using InternalArenaConstructable_ = void;
+ using DestructorSkippable_ = void;
+ struct Impl_ {
+ inline explicit constexpr Impl_(::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::internal::ConstantInitialized) noexcept;
+ inline explicit Impl_(
+ ::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ inline explicit Impl_(
+ ::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,
+ const WatchDesiredStateRequest& from_msg);
+ ::google::protobuf::internal::HasBits<1> _has_bits_;
+ ::google::protobuf::internal::CachedSize _cached_size_;
+ ::google::protobuf::internal::ArenaStringPtr agent_id_;
+ ::uint64_t after_revision_;
+ PROTOBUF_TSAN_DECLARE_MEMBER
+ };
+ union { Impl_ _impl_; };
+ friend struct ::TableStruct_xtcp_5ftreatment_2fv1_2fagent_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GetDesiredStateRequest final : public ::google::protobuf::Message
+/* @@protoc_insertion_point(class_definition:xtcp_treatment.v1.GetDesiredStateRequest) */ {
+ using Super_ = ::google::protobuf::Message;
+
+ public:
+ inline GetDesiredStateRequest() : GetDesiredStateRequest(nullptr) {}
+ ~GetDesiredStateRequest() PROTOBUF_FINAL;
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ void operator delete(GetDesiredStateRequest* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) {
+ SharedDtor(*msg);
+ ::google::protobuf::internal::SizedDelete(msg, sizeof(GetDesiredStateRequest));
+ }
+#endif
+
+ template
+ explicit constexpr GetDesiredStateRequest(::google::protobuf::internal::ConstantInitialized,
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+ class_data);
+
+ inline GetDesiredStateRequest(const GetDesiredStateRequest& from) : GetDesiredStateRequest(nullptr, from) {}
+ inline GetDesiredStateRequest(GetDesiredStateRequest&& from) noexcept : GetDesiredStateRequest(nullptr, ::std::move(from)) {}
+ inline GetDesiredStateRequest& operator=(const GetDesiredStateRequest& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline GetDesiredStateRequest& operator=(GetDesiredStateRequest&& from) noexcept {
+ if (this == &from) return *this;
+ if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ [[nodiscard]] inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance);
+ }
+ [[nodiscard]] inline ::google::protobuf::UnknownFieldSet* PROTOBUF_NONNULL
+ mutable_unknown_fields() ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>();
+ }
+
+ [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() {
+ return GetDescriptor();
+ }
+ [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL
+ GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ [[nodiscard]] static const ::google::protobuf::Reflection* PROTOBUF_NONNULL GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ [[nodiscard]] static const GetDesiredStateRequest& default_instance() {
+ return *::google::protobuf::internal::MessageGlobalsBase::ToDefaultInstance(&GetDesiredStateRequest_globals_);
+ }
+ static constexpr int kIndexInFileMessages = 2;
+ friend void swap(GetDesiredStateRequest& a, GetDesiredStateRequest& b) { a.Swap(&b); }
+ inline void Swap(GetDesiredStateRequest* PROTOBUF_NONNULL other) {
+ if (other == this) return;
+ if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) {
+ InternalSwap(other);
+ } else {
+ ::google::protobuf::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(GetDesiredStateRequest* PROTOBUF_NONNULL other) {
+ if (other == this) return;
+ ABSL_DCHECK(GetArena() == other->GetArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ [[nodiscard]] GetDesiredStateRequest* PROTOBUF_NONNULL
+ New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const {
+ return Super_::DefaultConstruct(arena);
+ }
+ using Super_::CopyFrom;
+ void CopyFrom(const GetDesiredStateRequest& from);
+ using Super_::MergeFrom;
+ void MergeFrom(const GetDesiredStateRequest& from) { GetDesiredStateRequest::MergeImpl(*this, from); }
+
+ private:
+ static void MergeImpl(::google::protobuf::MessageLite& to_msg,
+ const ::google::protobuf::MessageLite& from_msg);
+
+ public:
+ [[nodiscard]] bool IsInitialized() const {
+ return true;
+ }
+ ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
+ #if defined(PROTOBUF_CUSTOM_VTABLE)
+ private:
+ [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg);
+ [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream);
+
+ public:
+ [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); }
+ [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
+ return _InternalSerialize(*this, target, stream);
+ }
+ #else // PROTOBUF_CUSTOM_VTABLE
+ [[nodiscard]] ::size_t ByteSizeLong() const final;
+ [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final;
+ #endif // PROTOBUF_CUSTOM_VTABLE
+ [[nodiscard]] int GetCachedSize() const {
+ return _impl_._cached_size_.Get();
+ }
+
+ private:
+ void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ static void SharedDtor(MessageLite& self);
+ void InternalSwap(GetDesiredStateRequest* PROTOBUF_NONNULL other);
+ private:
+ static ::absl::string_view FullMessageName() { return "xtcp_treatment.v1.GetDesiredStateRequest"; }
+
+ explicit GetDesiredStateRequest(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ GetDesiredStateRequest(::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const GetDesiredStateRequest& from);
+ GetDesiredStateRequest(
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, GetDesiredStateRequest&& from) noexcept
+ : GetDesiredStateRequest(arena) {
+ *this = ::std::move(from);
+ }
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL;
+ static void* PROTOBUF_NONNULL PlacementNew_(
+ const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ static constexpr auto InternalNewImpl_();
+
+ public:
+ static constexpr auto InternalGenerateClassData_(
+ const MessageLite& prototype,
+ const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr);
+
+ [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const;
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+ enum : int {
+ kAgentIdFieldNumber = 1,
+ };
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ void clear_agent_id() ;
+ [[nodiscard]] const ::std::string& agent_id() const;
+ template
+ void set_agent_id(Arg_&& arg, Args_... args);
+ ::std::string* PROTOBUF_NONNULL mutable_agent_id();
+ [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_agent_id();
+ void set_allocated_agent_id(::std::string* PROTOBUF_NULLABLE value);
+
+ private:
+ const ::std::string& _internal_agent_id() const;
+ PROTOBUF_ALWAYS_INLINE void _internal_set_agent_id(const ::std::string& value);
+ ::std::string* PROTOBUF_NONNULL _internal_mutable_agent_id();
+
+ public:
+ // @@protoc_insertion_point(class_scope:xtcp_treatment.v1.GetDesiredStateRequest)
+ private:
+ class _Internal;
+ using ParseTableT_ =
+ ::google::protobuf::internal::TcParseTable<0, 1,
+ 0, 57,
+ 2>;
+ static constexpr ParseTableT_ InternalGenerateParseTable_(
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data);
+ friend class ::google::protobuf::internal::TcParser;
+ #ifndef PROTOBUF_MESSAGE_GLOBALS
+ static const ParseTableT_ _table_;
+ #endif
+
+ friend class ::google::protobuf::MessageLite;
+ friend class ::google::protobuf::Arena;
+ friend ::google::protobuf::internal::PrivateAccess;
+ template
+ friend class ::google::protobuf::Arena::InternalHelper;
+ using InternalArenaConstructable_ = void;
+ using DestructorSkippable_ = void;
+ struct Impl_ {
+ inline explicit constexpr Impl_(::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::internal::ConstantInitialized) noexcept;
+ inline explicit Impl_(
+ ::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ inline explicit Impl_(
+ ::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,
+ const GetDesiredStateRequest& from_msg);
+ ::google::protobuf::internal::HasBits<1> _has_bits_;
+ ::google::protobuf::internal::CachedSize _cached_size_;
+ ::google::protobuf::internal::ArenaStringPtr agent_id_;
+ PROTOBUF_TSAN_DECLARE_MEMBER
+ };
+ union { Impl_ _impl_; };
+ friend struct ::TableStruct_xtcp_5ftreatment_2fv1_2fagent_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GetDesiredStateResponse final : public ::google::protobuf::Message
+/* @@protoc_insertion_point(class_definition:xtcp_treatment.v1.GetDesiredStateResponse) */ {
+ using Super_ = ::google::protobuf::Message;
+
+ public:
+ inline GetDesiredStateResponse() : GetDesiredStateResponse(nullptr) {}
+ ~GetDesiredStateResponse() PROTOBUF_FINAL;
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ void operator delete(GetDesiredStateResponse* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) {
+ SharedDtor(*msg);
+ ::google::protobuf::internal::SizedDelete(msg, sizeof(GetDesiredStateResponse));
+ }
+#endif
+
+ template
+ explicit constexpr GetDesiredStateResponse(::google::protobuf::internal::ConstantInitialized,
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+ class_data);
+
+ inline GetDesiredStateResponse(const GetDesiredStateResponse& from) : GetDesiredStateResponse(nullptr, from) {}
+ inline GetDesiredStateResponse(GetDesiredStateResponse&& from) noexcept : GetDesiredStateResponse(nullptr, ::std::move(from)) {}
+ inline GetDesiredStateResponse& operator=(const GetDesiredStateResponse& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline GetDesiredStateResponse& operator=(GetDesiredStateResponse&& from) noexcept {
+ if (this == &from) return *this;
+ if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ [[nodiscard]] inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance);
+ }
+ [[nodiscard]] inline ::google::protobuf::UnknownFieldSet* PROTOBUF_NONNULL
+ mutable_unknown_fields() ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>();
+ }
+
+ [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() {
+ return GetDescriptor();
+ }
+ [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL
+ GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ [[nodiscard]] static const ::google::protobuf::Reflection* PROTOBUF_NONNULL GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ [[nodiscard]] static const GetDesiredStateResponse& default_instance() {
+ return *::google::protobuf::internal::MessageGlobalsBase::ToDefaultInstance(&GetDesiredStateResponse_globals_);
+ }
+ static constexpr int kIndexInFileMessages = 3;
+ friend void swap(GetDesiredStateResponse& a, GetDesiredStateResponse& b) { a.Swap(&b); }
+ inline void Swap(GetDesiredStateResponse* PROTOBUF_NONNULL other) {
+ if (other == this) return;
+ if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) {
+ InternalSwap(other);
+ } else {
+ ::google::protobuf::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(GetDesiredStateResponse* PROTOBUF_NONNULL other) {
+ if (other == this) return;
+ ABSL_DCHECK(GetArena() == other->GetArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ [[nodiscard]] GetDesiredStateResponse* PROTOBUF_NONNULL
+ New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const {
+ return Super_::DefaultConstruct(arena);
+ }
+ using Super_::CopyFrom;
+ void CopyFrom(const GetDesiredStateResponse& from);
+ using Super_::MergeFrom;
+ void MergeFrom(const GetDesiredStateResponse& from) { GetDesiredStateResponse::MergeImpl(*this, from); }
+
+ private:
+ static void MergeImpl(::google::protobuf::MessageLite& to_msg,
+ const ::google::protobuf::MessageLite& from_msg);
+
+ public:
+ [[nodiscard]] bool IsInitialized() const {
+ return true;
+ }
+ ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
+ #if defined(PROTOBUF_CUSTOM_VTABLE)
+ private:
+ [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg);
+ [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream);
+
+ public:
+ [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); }
+ [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
+ return _InternalSerialize(*this, target, stream);
+ }
+ #else // PROTOBUF_CUSTOM_VTABLE
+ [[nodiscard]] ::size_t ByteSizeLong() const final;
+ [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final;
+ #endif // PROTOBUF_CUSTOM_VTABLE
+ [[nodiscard]] int GetCachedSize() const {
+ return _impl_._cached_size_.Get();
+ }
+
+ private:
+ void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ static void SharedDtor(MessageLite& self);
+ void InternalSwap(GetDesiredStateResponse* PROTOBUF_NONNULL other);
+ private:
+ static ::absl::string_view FullMessageName() { return "xtcp_treatment.v1.GetDesiredStateResponse"; }
+
+ explicit GetDesiredStateResponse(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ GetDesiredStateResponse(::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const GetDesiredStateResponse& from);
+ GetDesiredStateResponse(
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, GetDesiredStateResponse&& from) noexcept
+ : GetDesiredStateResponse(arena) {
+ *this = ::std::move(from);
+ }
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL;
+ static void* PROTOBUF_NONNULL PlacementNew_(
+ const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ static constexpr auto InternalNewImpl_();
+
+ public:
+ static constexpr auto InternalGenerateClassData_(
+ const MessageLite& prototype,
+ const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr);
+
+ [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const;
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+ enum : int {
+ kDesiredFieldNumber = 1,
+ };
+ // .xtcp_treatment.v1.DesiredState desired = 1 [json_name = "desired"];
+ [[nodiscard]] bool has_desired() const;
+ void clear_desired() ;
+ [[nodiscard]] const ::xtcp_treatment::v1::DesiredState& desired() const;
+ [[nodiscard]] ::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE release_desired();
+ ::xtcp_treatment::v1::DesiredState* PROTOBUF_NONNULL mutable_desired();
+ void set_allocated_desired(::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE value);
+ void unsafe_arena_set_allocated_desired(::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE value);
+ ::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE unsafe_arena_release_desired();
+
+ private:
+ const ::xtcp_treatment::v1::DesiredState& _internal_desired() const;
+ ::xtcp_treatment::v1::DesiredState* PROTOBUF_NONNULL _internal_mutable_desired();
+
+ public:
+ // @@protoc_insertion_point(class_scope:xtcp_treatment.v1.GetDesiredStateResponse)
+ private:
+ class _Internal;
+ using ParseTableT_ =
+ ::google::protobuf::internal::TcParseTable<0, 1,
+ 1, 0,
+ 2>;
+ static constexpr ParseTableT_ InternalGenerateParseTable_(
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data);
+ friend class ::google::protobuf::internal::TcParser;
+ #ifndef PROTOBUF_MESSAGE_GLOBALS
+ static const ParseTableT_ _table_;
+ #endif
+
+ friend class ::google::protobuf::MessageLite;
+ friend class ::google::protobuf::Arena;
+ friend ::google::protobuf::internal::PrivateAccess;
+ template
+ friend class ::google::protobuf::Arena::InternalHelper;
+ using InternalArenaConstructable_ = void;
+ using DestructorSkippable_ = void;
+ struct Impl_ {
+ inline explicit constexpr Impl_(::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::internal::ConstantInitialized) noexcept;
+ inline explicit Impl_(
+ ::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ inline explicit Impl_(
+ ::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,
+ const GetDesiredStateResponse& from_msg);
+ ::google::protobuf::internal::HasBits<1> _has_bits_;
+ ::google::protobuf::internal::CachedSize _cached_size_;
+ ::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE desired_;
+ PROTOBUF_TSAN_DECLARE_MEMBER
+ };
+ union { Impl_ _impl_; };
+ friend struct ::TableStruct_xtcp_5ftreatment_2fv1_2fagent_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CheckInResponse final : public ::google::protobuf::Message
+/* @@protoc_insertion_point(class_definition:xtcp_treatment.v1.CheckInResponse) */ {
+ using Super_ = ::google::protobuf::Message;
+
+ public:
+ inline CheckInResponse() : CheckInResponse(nullptr) {}
+ ~CheckInResponse() PROTOBUF_FINAL;
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ void operator delete(CheckInResponse* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) {
+ SharedDtor(*msg);
+ ::google::protobuf::internal::SizedDelete(msg, sizeof(CheckInResponse));
+ }
+#endif
+
+ template
+ explicit constexpr CheckInResponse(::google::protobuf::internal::ConstantInitialized,
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+ class_data);
+
+ inline CheckInResponse(const CheckInResponse& from) : CheckInResponse(nullptr, from) {}
+ inline CheckInResponse(CheckInResponse&& from) noexcept : CheckInResponse(nullptr, ::std::move(from)) {}
+ inline CheckInResponse& operator=(const CheckInResponse& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline CheckInResponse& operator=(CheckInResponse&& from) noexcept {
+ if (this == &from) return *this;
+ if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ [[nodiscard]] inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance);
+ }
+ [[nodiscard]] inline ::google::protobuf::UnknownFieldSet* PROTOBUF_NONNULL
+ mutable_unknown_fields() ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>();
+ }
+
+ [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() {
+ return GetDescriptor();
+ }
+ [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL
+ GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ [[nodiscard]] static const ::google::protobuf::Reflection* PROTOBUF_NONNULL GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ [[nodiscard]] static const CheckInResponse& default_instance() {
+ return *::google::protobuf::internal::MessageGlobalsBase::ToDefaultInstance(&CheckInResponse_globals_);
+ }
+ static constexpr int kIndexInFileMessages = 1;
+ friend void swap(CheckInResponse& a, CheckInResponse& b) { a.Swap(&b); }
+ inline void Swap(CheckInResponse* PROTOBUF_NONNULL other) {
+ if (other == this) return;
+ if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) {
+ InternalSwap(other);
+ } else {
+ ::google::protobuf::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(CheckInResponse* PROTOBUF_NONNULL other) {
+ if (other == this) return;
+ ABSL_DCHECK(GetArena() == other->GetArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ [[nodiscard]] CheckInResponse* PROTOBUF_NONNULL
+ New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const {
+ return Super_::DefaultConstruct(arena);
+ }
+ using Super_::CopyFrom;
+ void CopyFrom(const CheckInResponse& from);
+ using Super_::MergeFrom;
+ void MergeFrom(const CheckInResponse& from) { CheckInResponse::MergeImpl(*this, from); }
+
+ private:
+ static void MergeImpl(::google::protobuf::MessageLite& to_msg,
+ const ::google::protobuf::MessageLite& from_msg);
+
+ public:
+ [[nodiscard]] bool IsInitialized() const {
+ return true;
+ }
+ ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
+ #if defined(PROTOBUF_CUSTOM_VTABLE)
+ private:
+ [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg);
+ [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream);
+
+ public:
+ [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); }
+ [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
+ return _InternalSerialize(*this, target, stream);
+ }
+ #else // PROTOBUF_CUSTOM_VTABLE
+ [[nodiscard]] ::size_t ByteSizeLong() const final;
+ [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final;
+ #endif // PROTOBUF_CUSTOM_VTABLE
+ [[nodiscard]] int GetCachedSize() const {
+ return _impl_._cached_size_.Get();
+ }
+
+ private:
+ void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ static void SharedDtor(MessageLite& self);
+ void InternalSwap(CheckInResponse* PROTOBUF_NONNULL other);
+ private:
+ static ::absl::string_view FullMessageName() { return "xtcp_treatment.v1.CheckInResponse"; }
+
+ explicit CheckInResponse(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ CheckInResponse(::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const CheckInResponse& from);
+ CheckInResponse(
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, CheckInResponse&& from) noexcept
+ : CheckInResponse(arena) {
+ *this = ::std::move(from);
+ }
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL;
+ static void* PROTOBUF_NONNULL PlacementNew_(
+ const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ static constexpr auto InternalNewImpl_();
+
+ public:
+ static constexpr auto InternalGenerateClassData_(
+ const MessageLite& prototype,
+ const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr);
+
+ [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const;
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+ enum : int {
+ kDesiredFieldNumber = 1,
+ };
+ // .xtcp_treatment.v1.DesiredState desired = 1 [json_name = "desired"];
+ [[nodiscard]] bool has_desired() const;
+ void clear_desired() ;
+ [[nodiscard]] const ::xtcp_treatment::v1::DesiredState& desired() const;
+ [[nodiscard]] ::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE release_desired();
+ ::xtcp_treatment::v1::DesiredState* PROTOBUF_NONNULL mutable_desired();
+ void set_allocated_desired(::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE value);
+ void unsafe_arena_set_allocated_desired(::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE value);
+ ::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE unsafe_arena_release_desired();
+
+ private:
+ const ::xtcp_treatment::v1::DesiredState& _internal_desired() const;
+ ::xtcp_treatment::v1::DesiredState* PROTOBUF_NONNULL _internal_mutable_desired();
+
+ public:
+ // @@protoc_insertion_point(class_scope:xtcp_treatment.v1.CheckInResponse)
+ private:
+ class _Internal;
+ using ParseTableT_ =
+ ::google::protobuf::internal::TcParseTable<0, 1,
+ 1, 0,
+ 2>;
+ static constexpr ParseTableT_ InternalGenerateParseTable_(
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data);
+ friend class ::google::protobuf::internal::TcParser;
+ #ifndef PROTOBUF_MESSAGE_GLOBALS
+ static const ParseTableT_ _table_;
+ #endif
+
+ friend class ::google::protobuf::MessageLite;
+ friend class ::google::protobuf::Arena;
+ friend ::google::protobuf::internal::PrivateAccess;
+ template
+ friend class ::google::protobuf::Arena::InternalHelper;
+ using InternalArenaConstructable_ = void;
+ using DestructorSkippable_ = void;
+ struct Impl_ {
+ inline explicit constexpr Impl_(::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::internal::ConstantInitialized) noexcept;
+ inline explicit Impl_(
+ ::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ inline explicit Impl_(
+ ::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,
+ const CheckInResponse& from_msg);
+ ::google::protobuf::internal::HasBits<1> _has_bits_;
+ ::google::protobuf::internal::CachedSize _cached_size_;
+ ::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE desired_;
+ PROTOBUF_TSAN_DECLARE_MEMBER
+ };
+ union { Impl_ _impl_; };
+ friend struct ::TableStruct_xtcp_5ftreatment_2fv1_2fagent_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CheckInRequest final : public ::google::protobuf::Message
+/* @@protoc_insertion_point(class_definition:xtcp_treatment.v1.CheckInRequest) */ {
+ using Super_ = ::google::protobuf::Message;
+
+ public:
+ inline CheckInRequest() : CheckInRequest(nullptr) {}
+ ~CheckInRequest() PROTOBUF_FINAL;
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ void operator delete(CheckInRequest* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) {
+ SharedDtor(*msg);
+ ::google::protobuf::internal::SizedDelete(msg, sizeof(CheckInRequest));
+ }
+#endif
+
+ template
+ explicit constexpr CheckInRequest(::google::protobuf::internal::ConstantInitialized,
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+ class_data);
+
+ inline CheckInRequest(const CheckInRequest& from) : CheckInRequest(nullptr, from) {}
+ inline CheckInRequest(CheckInRequest&& from) noexcept : CheckInRequest(nullptr, ::std::move(from)) {}
+ inline CheckInRequest& operator=(const CheckInRequest& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline CheckInRequest& operator=(CheckInRequest&& from) noexcept {
+ if (this == &from) return *this;
+ if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ [[nodiscard]] inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance);
+ }
+ [[nodiscard]] inline ::google::protobuf::UnknownFieldSet* PROTOBUF_NONNULL
+ mutable_unknown_fields() ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>();
+ }
+
+ [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() {
+ return GetDescriptor();
+ }
+ [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL
+ GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ [[nodiscard]] static const ::google::protobuf::Reflection* PROTOBUF_NONNULL GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ [[nodiscard]] static const CheckInRequest& default_instance() {
+ return *::google::protobuf::internal::MessageGlobalsBase::ToDefaultInstance(&CheckInRequest_globals_);
+ }
+ static constexpr int kIndexInFileMessages = 0;
+ friend void swap(CheckInRequest& a, CheckInRequest& b) { a.Swap(&b); }
+ inline void Swap(CheckInRequest* PROTOBUF_NONNULL other) {
+ if (other == this) return;
+ if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) {
+ InternalSwap(other);
+ } else {
+ ::google::protobuf::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(CheckInRequest* PROTOBUF_NONNULL other) {
+ if (other == this) return;
+ ABSL_DCHECK(GetArena() == other->GetArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ [[nodiscard]] CheckInRequest* PROTOBUF_NONNULL
+ New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const {
+ return Super_::DefaultConstruct(arena);
+ }
+ using Super_::CopyFrom;
+ void CopyFrom(const CheckInRequest& from);
+ using Super_::MergeFrom;
+ void MergeFrom(const CheckInRequest& from) { CheckInRequest::MergeImpl(*this, from); }
+
+ private:
+ static void MergeImpl(::google::protobuf::MessageLite& to_msg,
+ const ::google::protobuf::MessageLite& from_msg);
+
+ public:
+ [[nodiscard]] bool IsInitialized() const {
+ return true;
+ }
+ ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
+ #if defined(PROTOBUF_CUSTOM_VTABLE)
+ private:
+ [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg);
+ [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream);
+
+ public:
+ [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); }
+ [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
+ return _InternalSerialize(*this, target, stream);
+ }
+ #else // PROTOBUF_CUSTOM_VTABLE
+ [[nodiscard]] ::size_t ByteSizeLong() const final;
+ [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final;
+ #endif // PROTOBUF_CUSTOM_VTABLE
+ [[nodiscard]] int GetCachedSize() const {
+ return _impl_._cached_size_.Get();
+ }
+
+ private:
+ void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ static void SharedDtor(MessageLite& self);
+ void InternalSwap(CheckInRequest* PROTOBUF_NONNULL other);
+ private:
+ static ::absl::string_view FullMessageName() { return "xtcp_treatment.v1.CheckInRequest"; }
+
+ explicit CheckInRequest(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ CheckInRequest(::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const CheckInRequest& from);
+ CheckInRequest(
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, CheckInRequest&& from) noexcept
+ : CheckInRequest(arena) {
+ *this = ::std::move(from);
+ }
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL;
+ static void* PROTOBUF_NONNULL PlacementNew_(
+ const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ static constexpr auto InternalNewImpl_();
+
+ public:
+ static constexpr auto InternalGenerateClassData_(
+ const MessageLite& prototype,
+ const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr);
+
+ [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const;
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+ enum : int {
+ kRecordsFieldNumber = 5,
+ kAgentIdFieldNumber = 1,
+ kLocationFieldNumber = 2,
+ kCapabilitiesFieldNumber = 3,
+ kDesiredRevisionFieldNumber = 4,
+ kLocallySuspendedFieldNumber = 6,
+ };
+ // repeated .xtcp_treatment.v1.ApplicationRecord records = 5 [json_name = "records", (.buf.validate.field) = {
+ [[nodiscard]] int records_size() const;
+ private:
+ int _internal_records_size() const;
+
+ public:
+ void clear_records() ;
+ [[nodiscard]] const ::xtcp_treatment::v1::ApplicationRecord& records(int index) const;
+ [[nodiscard]] ::xtcp_treatment::v1::ApplicationRecord* PROTOBUF_NONNULL mutable_records(int index);
+ ::xtcp_treatment::v1::ApplicationRecord* PROTOBUF_NONNULL add_records();
+ [[nodiscard]] const ::google::protobuf::RepeatedPtrField<::xtcp_treatment::v1::ApplicationRecord>&
+ records() const;
+ [[nodiscard]] ::google::protobuf::RepeatedPtrField<::xtcp_treatment::v1::ApplicationRecord>* PROTOBUF_NONNULL
+ mutable_records();
+
+ private:
+ const ::google::protobuf::RepeatedPtrField<::xtcp_treatment::v1::ApplicationRecord>& _internal_records() const;
+ ::google::protobuf::RepeatedPtrField<::xtcp_treatment::v1::ApplicationRecord>* PROTOBUF_NONNULL _internal_mutable_records();
+
+ public:
+ // string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+ void clear_agent_id() ;
+ [[nodiscard]] const ::std::string& agent_id() const;
+ template
+ void set_agent_id(Arg_&& arg, Args_... args);
+ ::std::string* PROTOBUF_NONNULL mutable_agent_id();
+ [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_agent_id();
+ void set_allocated_agent_id(::std::string* PROTOBUF_NULLABLE value);
+
+ private:
+ const ::std::string& _internal_agent_id() const;
+ PROTOBUF_ALWAYS_INLINE void _internal_set_agent_id(const ::std::string& value);
+ ::std::string* PROTOBUF_NONNULL _internal_mutable_agent_id();
+
+ public:
+ // string location = 2 [json_name = "location", (.buf.validate.field) = {
+ void clear_location() ;
+ [[nodiscard]] const ::std::string& location() const;
+ template
+ void set_location(Arg_&& arg, Args_... args);
+ ::std::string* PROTOBUF_NONNULL mutable_location();
+ [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_location();
+ void set_allocated_location(::std::string* PROTOBUF_NULLABLE value);
+
+ private:
+ const ::std::string& _internal_location() const;
+ PROTOBUF_ALWAYS_INLINE void _internal_set_location(const ::std::string& value);
+ ::std::string* PROTOBUF_NONNULL _internal_mutable_location();
+
+ public:
+ // .xtcp_treatment.v1.Capabilities capabilities = 3 [json_name = "capabilities", (.buf.validate.field) = {
+ [[nodiscard]] bool has_capabilities() const;
+ void clear_capabilities() ;
+ [[nodiscard]] const ::xtcp_treatment::v1::Capabilities& capabilities() const;
+ [[nodiscard]] ::xtcp_treatment::v1::Capabilities* PROTOBUF_NULLABLE release_capabilities();
+ ::xtcp_treatment::v1::Capabilities* PROTOBUF_NONNULL mutable_capabilities();
+ void set_allocated_capabilities(::xtcp_treatment::v1::Capabilities* PROTOBUF_NULLABLE value);
+ void unsafe_arena_set_allocated_capabilities(::xtcp_treatment::v1::Capabilities* PROTOBUF_NULLABLE value);
+ ::xtcp_treatment::v1::Capabilities* PROTOBUF_NULLABLE unsafe_arena_release_capabilities();
+
+ private:
+ const ::xtcp_treatment::v1::Capabilities& _internal_capabilities() const;
+ ::xtcp_treatment::v1::Capabilities* PROTOBUF_NONNULL _internal_mutable_capabilities();
+
+ public:
+ // uint64 desired_revision = 4 [json_name = "desiredRevision"];
+ void clear_desired_revision() ;
+ [[nodiscard]] ::uint64_t desired_revision() const;
+ void set_desired_revision(::uint64_t value);
+
+ private:
+ ::uint64_t _internal_desired_revision() const;
+ void _internal_set_desired_revision(::uint64_t value);
+
+ public:
+ // bool locally_suspended = 6 [json_name = "locallySuspended"];
+ void clear_locally_suspended() ;
+ [[nodiscard]] bool locally_suspended() const;
+ void set_locally_suspended(bool value);
+
+ private:
+ bool _internal_locally_suspended() const;
+ void _internal_set_locally_suspended(bool value);
+
+ public:
+ // @@protoc_insertion_point(class_scope:xtcp_treatment.v1.CheckInRequest)
+ private:
+ class _Internal;
+ using ParseTableT_ =
+ ::google::protobuf::internal::TcParseTable<3, 6,
+ 2, 57,
+ 2>;
+ static constexpr ParseTableT_ InternalGenerateParseTable_(
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data);
+ friend class ::google::protobuf::internal::TcParser;
+ #ifndef PROTOBUF_MESSAGE_GLOBALS
+ static const ParseTableT_ _table_;
+ #endif
+
+ friend class ::google::protobuf::MessageLite;
+ friend class ::google::protobuf::Arena;
+ friend ::google::protobuf::internal::PrivateAccess;
+ template
+ friend class ::google::protobuf::Arena::InternalHelper;
+ using InternalArenaConstructable_ = void;
+ using DestructorSkippable_ = void;
+ struct Impl_ {
+ inline explicit constexpr Impl_(::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::internal::ConstantInitialized) noexcept;
+ inline explicit Impl_(
+ ::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ inline explicit Impl_(
+ ::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,
+ const CheckInRequest& from_msg);
+ ::google::protobuf::internal::HasBits<1> _has_bits_;
+ ::google::protobuf::internal::CachedSize _cached_size_;
+ ::google::protobuf::RepeatedPtrField< ::xtcp_treatment::v1::ApplicationRecord > records_;
+ ::google::protobuf::internal::ArenaStringPtr agent_id_;
+ ::google::protobuf::internal::ArenaStringPtr location_;
+ ::xtcp_treatment::v1::Capabilities* PROTOBUF_NULLABLE capabilities_;
+ ::uint64_t desired_revision_;
+ bool locally_suspended_;
+ PROTOBUF_TSAN_DECLARE_MEMBER
+ };
+ union { Impl_ _impl_; };
+ friend struct ::TableStruct_xtcp_5ftreatment_2fv1_2fagent_2eproto;
+};
+
+// ===================================================================
+
+
+
+
+// ===================================================================
+
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// -------------------------------------------------------------------
+
+// CheckInRequest
+
+// string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+inline void CheckInRequest::clear_agent_id() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.agent_id_.ClearToEmpty();
+ ClearHasBit(_impl_._has_bits_[0], 0x00000002U);
+}
+inline const ::std::string& CheckInRequest::agent_id() const
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ // @@protoc_insertion_point(field_get:xtcp_treatment.v1.CheckInRequest.agent_id)
+ return _internal_agent_id();
+}
+template
+PROTOBUF_ALWAYS_INLINE void CheckInRequest::set_agent_id(Arg_&& arg, Args_... args) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ SetHasBit(_impl_._has_bits_[0], 0x00000002U);
+ _impl_.agent_id_.Set(static_cast(arg), args..., GetArena());
+ // @@protoc_insertion_point(field_set:xtcp_treatment.v1.CheckInRequest.agent_id)
+}
+inline ::std::string* PROTOBUF_NONNULL CheckInRequest::mutable_agent_id()
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ SetHasBit(_impl_._has_bits_[0], 0x00000002U);
+ ::std::string* _s = _internal_mutable_agent_id();
+ // @@protoc_insertion_point(field_mutable:xtcp_treatment.v1.CheckInRequest.agent_id)
+ return _s;
+}
+inline const ::std::string& CheckInRequest::_internal_agent_id() const {
+ ::google::protobuf::internal::TSanRead(&_impl_);
+ return _impl_.agent_id_.Get();
+}
+inline void CheckInRequest::_internal_set_agent_id(const ::std::string& value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.agent_id_.Set(value, GetArena());
+}
+inline ::std::string* PROTOBUF_NONNULL CheckInRequest::_internal_mutable_agent_id() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ return _impl_.agent_id_.Mutable( GetArena());
+}
+inline ::std::string* PROTOBUF_NULLABLE CheckInRequest::release_agent_id() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ // @@protoc_insertion_point(field_release:xtcp_treatment.v1.CheckInRequest.agent_id)
+ if (!CheckHasBit(_impl_._has_bits_[0], 0x00000002U)) {
+ return nullptr;
+ }
+ ClearHasBit(_impl_._has_bits_[0], 0x00000002U);
+ auto* released = _impl_.agent_id_.Release();
+ if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) {
+ _impl_.agent_id_.Set("", GetArena());
+ }
+ return released;
+}
+inline void CheckInRequest::set_allocated_agent_id(::std::string* PROTOBUF_NULLABLE value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (value != nullptr) {
+ SetHasBit(_impl_._has_bits_[0], 0x00000002U);
+ } else {
+ ClearHasBit(_impl_._has_bits_[0], 0x00000002U);
+ }
+ _impl_.agent_id_.SetAllocated(value, GetArena());
+ if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.agent_id_.IsDefault()) {
+ _impl_.agent_id_.Set("", GetArena());
+ }
+ // @@protoc_insertion_point(field_set_allocated:xtcp_treatment.v1.CheckInRequest.agent_id)
+}
+
+// string location = 2 [json_name = "location", (.buf.validate.field) = {
+inline void CheckInRequest::clear_location() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.location_.ClearToEmpty();
+ ClearHasBit(_impl_._has_bits_[0], 0x00000004U);
+}
+inline const ::std::string& CheckInRequest::location() const
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ // @@protoc_insertion_point(field_get:xtcp_treatment.v1.CheckInRequest.location)
+ return _internal_location();
+}
+template
+PROTOBUF_ALWAYS_INLINE void CheckInRequest::set_location(Arg_&& arg, Args_... args) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ SetHasBit(_impl_._has_bits_[0], 0x00000004U);
+ _impl_.location_.Set(static_cast(arg), args..., GetArena());
+ // @@protoc_insertion_point(field_set:xtcp_treatment.v1.CheckInRequest.location)
+}
+inline ::std::string* PROTOBUF_NONNULL CheckInRequest::mutable_location()
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ SetHasBit(_impl_._has_bits_[0], 0x00000004U);
+ ::std::string* _s = _internal_mutable_location();
+ // @@protoc_insertion_point(field_mutable:xtcp_treatment.v1.CheckInRequest.location)
+ return _s;
+}
+inline const ::std::string& CheckInRequest::_internal_location() const {
+ ::google::protobuf::internal::TSanRead(&_impl_);
+ return _impl_.location_.Get();
+}
+inline void CheckInRequest::_internal_set_location(const ::std::string& value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.location_.Set(value, GetArena());
+}
+inline ::std::string* PROTOBUF_NONNULL CheckInRequest::_internal_mutable_location() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ return _impl_.location_.Mutable( GetArena());
+}
+inline ::std::string* PROTOBUF_NULLABLE CheckInRequest::release_location() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ // @@protoc_insertion_point(field_release:xtcp_treatment.v1.CheckInRequest.location)
+ if (!CheckHasBit(_impl_._has_bits_[0], 0x00000004U)) {
+ return nullptr;
+ }
+ ClearHasBit(_impl_._has_bits_[0], 0x00000004U);
+ auto* released = _impl_.location_.Release();
+ if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) {
+ _impl_.location_.Set("", GetArena());
+ }
+ return released;
+}
+inline void CheckInRequest::set_allocated_location(::std::string* PROTOBUF_NULLABLE value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (value != nullptr) {
+ SetHasBit(_impl_._has_bits_[0], 0x00000004U);
+ } else {
+ ClearHasBit(_impl_._has_bits_[0], 0x00000004U);
+ }
+ _impl_.location_.SetAllocated(value, GetArena());
+ if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.location_.IsDefault()) {
+ _impl_.location_.Set("", GetArena());
+ }
+ // @@protoc_insertion_point(field_set_allocated:xtcp_treatment.v1.CheckInRequest.location)
+}
+
+// .xtcp_treatment.v1.Capabilities capabilities = 3 [json_name = "capabilities", (.buf.validate.field) = {
+inline bool CheckInRequest::has_capabilities() const {
+ bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000008U);
+ PROTOBUF_ASSUME(!value || _impl_.capabilities_ != nullptr);
+ return value;
+}
+inline const ::xtcp_treatment::v1::Capabilities& CheckInRequest::_internal_capabilities() const {
+ ::google::protobuf::internal::TSanRead(&_impl_);
+ const ::xtcp_treatment::v1::Capabilities* p = _impl_.capabilities_;
+ return p != nullptr ? *p : *::google::protobuf::internal::MessageGlobalsBase::ToDefaultInstance<::xtcp_treatment::v1::Capabilities>(&::xtcp_treatment::v1::Capabilities_globals_);
+}
+inline const ::xtcp_treatment::v1::Capabilities& CheckInRequest::capabilities() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ // @@protoc_insertion_point(field_get:xtcp_treatment.v1.CheckInRequest.capabilities)
+ return _internal_capabilities();
+}
+inline void CheckInRequest::unsafe_arena_set_allocated_capabilities(
+ ::xtcp_treatment::v1::Capabilities* PROTOBUF_NULLABLE value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (GetArena() == nullptr) {
+ delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.capabilities_);
+ }
+ _impl_.capabilities_ = reinterpret_cast<::xtcp_treatment::v1::Capabilities*>(value);
+ if (value != nullptr) {
+ SetHasBit(_impl_._has_bits_[0], 0x00000008U);
+ } else {
+ ClearHasBit(_impl_._has_bits_[0], 0x00000008U);
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:xtcp_treatment.v1.CheckInRequest.capabilities)
+}
+inline ::xtcp_treatment::v1::Capabilities* PROTOBUF_NULLABLE CheckInRequest::release_capabilities() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+
+ ClearHasBit(_impl_._has_bits_[0], 0x00000008U);
+ ::xtcp_treatment::v1::Capabilities* released = _impl_.capabilities_;
+ _impl_.capabilities_ = nullptr;
+ if (::google::protobuf::internal::DebugHardenForceCopyInRelease()) {
+ auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
+ released = ::google::protobuf::internal::DuplicateIfNonNull(released);
+ if (GetArena() == nullptr) {
+ delete old;
+ }
+ } else {
+ if (GetArena() != nullptr) {
+ released = ::google::protobuf::internal::DuplicateIfNonNull(released);
+ }
+ }
+ return released;
+}
+inline ::xtcp_treatment::v1::Capabilities* PROTOBUF_NULLABLE CheckInRequest::unsafe_arena_release_capabilities() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ // @@protoc_insertion_point(field_release:xtcp_treatment.v1.CheckInRequest.capabilities)
+
+ ClearHasBit(_impl_._has_bits_[0], 0x00000008U);
+ ::xtcp_treatment::v1::Capabilities* temp = _impl_.capabilities_;
+ _impl_.capabilities_ = nullptr;
+ return temp;
+}
+inline ::xtcp_treatment::v1::Capabilities* PROTOBUF_NONNULL CheckInRequest::_internal_mutable_capabilities() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (_impl_.capabilities_ == nullptr) {
+ auto* p = Super_::DefaultConstruct<::xtcp_treatment::v1::Capabilities>(GetArena());
+ _impl_.capabilities_ = reinterpret_cast<::xtcp_treatment::v1::Capabilities*>(p);
+ }
+ return _impl_.capabilities_;
+}
+inline ::xtcp_treatment::v1::Capabilities* PROTOBUF_NONNULL CheckInRequest::mutable_capabilities()
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ SetHasBit(_impl_._has_bits_[0], 0x00000008U);
+ ::xtcp_treatment::v1::Capabilities* _msg = _internal_mutable_capabilities();
+ // @@protoc_insertion_point(field_mutable:xtcp_treatment.v1.CheckInRequest.capabilities)
+ return _msg;
+}
+inline void CheckInRequest::set_allocated_capabilities(::xtcp_treatment::v1::Capabilities* PROTOBUF_NULLABLE value) {
+ ::google::protobuf::Arena* message_arena = GetArena();
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (message_arena == nullptr) {
+ delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.capabilities_);
+ }
+
+ if (value != nullptr) {
+ ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::Message*>(value)->GetArena();
+ if (message_arena != submessage_arena) {
+ value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
+ }
+ SetHasBit(_impl_._has_bits_[0], 0x00000008U);
+ } else {
+ ClearHasBit(_impl_._has_bits_[0], 0x00000008U);
+ }
+
+ _impl_.capabilities_ = reinterpret_cast<::xtcp_treatment::v1::Capabilities*>(value);
+ // @@protoc_insertion_point(field_set_allocated:xtcp_treatment.v1.CheckInRequest.capabilities)
+}
+
+// uint64 desired_revision = 4 [json_name = "desiredRevision"];
+inline void CheckInRequest::clear_desired_revision() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.desired_revision_ = ::uint64_t{0u};
+ ClearHasBit(_impl_._has_bits_[0], 0x00000010U);
+}
+inline ::uint64_t CheckInRequest::desired_revision() const {
+ // @@protoc_insertion_point(field_get:xtcp_treatment.v1.CheckInRequest.desired_revision)
+ return _internal_desired_revision();
+}
+inline void CheckInRequest::set_desired_revision(::uint64_t value) {
+ _internal_set_desired_revision(value);
+ SetHasBit(_impl_._has_bits_[0], 0x00000010U);
+ // @@protoc_insertion_point(field_set:xtcp_treatment.v1.CheckInRequest.desired_revision)
+}
+inline ::uint64_t CheckInRequest::_internal_desired_revision() const {
+ ::google::protobuf::internal::TSanRead(&_impl_);
+ return _impl_.desired_revision_;
+}
+inline void CheckInRequest::_internal_set_desired_revision(::uint64_t value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.desired_revision_ = value;
+}
+
+// repeated .xtcp_treatment.v1.ApplicationRecord records = 5 [json_name = "records", (.buf.validate.field) = {
+inline int CheckInRequest::_internal_records_size() const {
+ return _internal_records().size();
+}
+inline int CheckInRequest::records_size() const {
+ return _internal_records_size();
+}
+inline const ::xtcp_treatment::v1::ApplicationRecord& CheckInRequest::records(int index) const
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ // @@protoc_insertion_point(field_get:xtcp_treatment.v1.CheckInRequest.records)
+ return _internal_records().Get(index);
+}
+inline ::xtcp_treatment::v1::ApplicationRecord* PROTOBUF_NONNULL CheckInRequest::mutable_records(int index)
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ // @@protoc_insertion_point(field_mutable:xtcp_treatment.v1.CheckInRequest.records)
+ return _internal_mutable_records()->Mutable(index);
+}
+inline ::xtcp_treatment::v1::ApplicationRecord* PROTOBUF_NONNULL CheckInRequest::add_records()
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ ::xtcp_treatment::v1::ApplicationRecord* _add =
+ _internal_mutable_records()->InternalAddWithArena(
+ ::google::protobuf::MessageLite::internal_visibility(), GetArena());
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ // @@protoc_insertion_point(field_add:xtcp_treatment.v1.CheckInRequest.records)
+ return _add;
+}
+inline const ::google::protobuf::RepeatedPtrField<::xtcp_treatment::v1::ApplicationRecord>& CheckInRequest::records() const
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ // @@protoc_insertion_point(field_list:xtcp_treatment.v1.CheckInRequest.records)
+ return _internal_records();
+}
+inline ::google::protobuf::RepeatedPtrField<::xtcp_treatment::v1::ApplicationRecord>* PROTOBUF_NONNULL
+CheckInRequest::mutable_records() ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ // @@protoc_insertion_point(field_mutable_list:xtcp_treatment.v1.CheckInRequest.records)
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ return _internal_mutable_records();
+}
+inline const ::google::protobuf::RepeatedPtrField<::xtcp_treatment::v1::ApplicationRecord>&
+CheckInRequest::_internal_records() const {
+ ::google::protobuf::internal::TSanRead(&_impl_);
+ return _impl_.records_;
+}
+inline ::google::protobuf::RepeatedPtrField<::xtcp_treatment::v1::ApplicationRecord>* PROTOBUF_NONNULL
+CheckInRequest::_internal_mutable_records() {
+ ::google::protobuf::internal::TSanRead(&_impl_);
+ return &_impl_.records_;
+}
+
+// bool locally_suspended = 6 [json_name = "locallySuspended"];
+inline void CheckInRequest::clear_locally_suspended() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.locally_suspended_ = false;
+ ClearHasBit(_impl_._has_bits_[0], 0x00000020U);
+}
+inline bool CheckInRequest::locally_suspended() const {
+ // @@protoc_insertion_point(field_get:xtcp_treatment.v1.CheckInRequest.locally_suspended)
+ return _internal_locally_suspended();
+}
+inline void CheckInRequest::set_locally_suspended(bool value) {
+ _internal_set_locally_suspended(value);
+ SetHasBit(_impl_._has_bits_[0], 0x00000020U);
+ // @@protoc_insertion_point(field_set:xtcp_treatment.v1.CheckInRequest.locally_suspended)
+}
+inline bool CheckInRequest::_internal_locally_suspended() const {
+ ::google::protobuf::internal::TSanRead(&_impl_);
+ return _impl_.locally_suspended_;
+}
+inline void CheckInRequest::_internal_set_locally_suspended(bool value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.locally_suspended_ = value;
+}
+
+// -------------------------------------------------------------------
+
+// CheckInResponse
+
+// .xtcp_treatment.v1.DesiredState desired = 1 [json_name = "desired"];
+inline bool CheckInResponse::has_desired() const {
+ bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000001U);
+ PROTOBUF_ASSUME(!value || _impl_.desired_ != nullptr);
+ return value;
+}
+inline const ::xtcp_treatment::v1::DesiredState& CheckInResponse::_internal_desired() const {
+ ::google::protobuf::internal::TSanRead(&_impl_);
+ const ::xtcp_treatment::v1::DesiredState* p = _impl_.desired_;
+ return p != nullptr ? *p : *::google::protobuf::internal::MessageGlobalsBase::ToDefaultInstance<::xtcp_treatment::v1::DesiredState>(&::xtcp_treatment::v1::DesiredState_globals_);
+}
+inline const ::xtcp_treatment::v1::DesiredState& CheckInResponse::desired() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ // @@protoc_insertion_point(field_get:xtcp_treatment.v1.CheckInResponse.desired)
+ return _internal_desired();
+}
+inline void CheckInResponse::unsafe_arena_set_allocated_desired(
+ ::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (GetArena() == nullptr) {
+ delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.desired_);
+ }
+ _impl_.desired_ = reinterpret_cast<::xtcp_treatment::v1::DesiredState*>(value);
+ if (value != nullptr) {
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ } else {
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:xtcp_treatment.v1.CheckInResponse.desired)
+}
+inline ::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE CheckInResponse::release_desired() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+ ::xtcp_treatment::v1::DesiredState* released = _impl_.desired_;
+ _impl_.desired_ = nullptr;
+ if (::google::protobuf::internal::DebugHardenForceCopyInRelease()) {
+ auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
+ released = ::google::protobuf::internal::DuplicateIfNonNull(released);
+ if (GetArena() == nullptr) {
+ delete old;
+ }
+ } else {
+ if (GetArena() != nullptr) {
+ released = ::google::protobuf::internal::DuplicateIfNonNull(released);
+ }
+ }
+ return released;
+}
+inline ::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE CheckInResponse::unsafe_arena_release_desired() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ // @@protoc_insertion_point(field_release:xtcp_treatment.v1.CheckInResponse.desired)
+
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+ ::xtcp_treatment::v1::DesiredState* temp = _impl_.desired_;
+ _impl_.desired_ = nullptr;
+ return temp;
+}
+inline ::xtcp_treatment::v1::DesiredState* PROTOBUF_NONNULL CheckInResponse::_internal_mutable_desired() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (_impl_.desired_ == nullptr) {
+ auto* p = Super_::DefaultConstruct<::xtcp_treatment::v1::DesiredState>(GetArena());
+ _impl_.desired_ = reinterpret_cast<::xtcp_treatment::v1::DesiredState*>(p);
+ }
+ return _impl_.desired_;
+}
+inline ::xtcp_treatment::v1::DesiredState* PROTOBUF_NONNULL CheckInResponse::mutable_desired()
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ ::xtcp_treatment::v1::DesiredState* _msg = _internal_mutable_desired();
+ // @@protoc_insertion_point(field_mutable:xtcp_treatment.v1.CheckInResponse.desired)
+ return _msg;
+}
+inline void CheckInResponse::set_allocated_desired(::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE value) {
+ ::google::protobuf::Arena* message_arena = GetArena();
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (message_arena == nullptr) {
+ delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.desired_);
+ }
+
+ if (value != nullptr) {
+ ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::Message*>(value)->GetArena();
+ if (message_arena != submessage_arena) {
+ value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
+ }
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ } else {
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+ }
+
+ _impl_.desired_ = reinterpret_cast<::xtcp_treatment::v1::DesiredState*>(value);
+ // @@protoc_insertion_point(field_set_allocated:xtcp_treatment.v1.CheckInResponse.desired)
+}
+
+// -------------------------------------------------------------------
+
+// GetDesiredStateRequest
+
+// string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+inline void GetDesiredStateRequest::clear_agent_id() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.agent_id_.ClearToEmpty();
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+}
+inline const ::std::string& GetDesiredStateRequest::agent_id() const
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ // @@protoc_insertion_point(field_get:xtcp_treatment.v1.GetDesiredStateRequest.agent_id)
+ return _internal_agent_id();
+}
+template
+PROTOBUF_ALWAYS_INLINE void GetDesiredStateRequest::set_agent_id(Arg_&& arg, Args_... args) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ _impl_.agent_id_.Set(static_cast(arg), args..., GetArena());
+ // @@protoc_insertion_point(field_set:xtcp_treatment.v1.GetDesiredStateRequest.agent_id)
+}
+inline ::std::string* PROTOBUF_NONNULL GetDesiredStateRequest::mutable_agent_id()
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ ::std::string* _s = _internal_mutable_agent_id();
+ // @@protoc_insertion_point(field_mutable:xtcp_treatment.v1.GetDesiredStateRequest.agent_id)
+ return _s;
+}
+inline const ::std::string& GetDesiredStateRequest::_internal_agent_id() const {
+ ::google::protobuf::internal::TSanRead(&_impl_);
+ return _impl_.agent_id_.Get();
+}
+inline void GetDesiredStateRequest::_internal_set_agent_id(const ::std::string& value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.agent_id_.Set(value, GetArena());
+}
+inline ::std::string* PROTOBUF_NONNULL GetDesiredStateRequest::_internal_mutable_agent_id() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ return _impl_.agent_id_.Mutable( GetArena());
+}
+inline ::std::string* PROTOBUF_NULLABLE GetDesiredStateRequest::release_agent_id() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ // @@protoc_insertion_point(field_release:xtcp_treatment.v1.GetDesiredStateRequest.agent_id)
+ if (!CheckHasBit(_impl_._has_bits_[0], 0x00000001U)) {
+ return nullptr;
+ }
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+ auto* released = _impl_.agent_id_.Release();
+ if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) {
+ _impl_.agent_id_.Set("", GetArena());
+ }
+ return released;
+}
+inline void GetDesiredStateRequest::set_allocated_agent_id(::std::string* PROTOBUF_NULLABLE value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (value != nullptr) {
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ } else {
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+ }
+ _impl_.agent_id_.SetAllocated(value, GetArena());
+ if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.agent_id_.IsDefault()) {
+ _impl_.agent_id_.Set("", GetArena());
+ }
+ // @@protoc_insertion_point(field_set_allocated:xtcp_treatment.v1.GetDesiredStateRequest.agent_id)
+}
+
+// -------------------------------------------------------------------
+
+// GetDesiredStateResponse
+
+// .xtcp_treatment.v1.DesiredState desired = 1 [json_name = "desired"];
+inline bool GetDesiredStateResponse::has_desired() const {
+ bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000001U);
+ PROTOBUF_ASSUME(!value || _impl_.desired_ != nullptr);
+ return value;
+}
+inline const ::xtcp_treatment::v1::DesiredState& GetDesiredStateResponse::_internal_desired() const {
+ ::google::protobuf::internal::TSanRead(&_impl_);
+ const ::xtcp_treatment::v1::DesiredState* p = _impl_.desired_;
+ return p != nullptr ? *p : *::google::protobuf::internal::MessageGlobalsBase::ToDefaultInstance<::xtcp_treatment::v1::DesiredState>(&::xtcp_treatment::v1::DesiredState_globals_);
+}
+inline const ::xtcp_treatment::v1::DesiredState& GetDesiredStateResponse::desired() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ // @@protoc_insertion_point(field_get:xtcp_treatment.v1.GetDesiredStateResponse.desired)
+ return _internal_desired();
+}
+inline void GetDesiredStateResponse::unsafe_arena_set_allocated_desired(
+ ::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (GetArena() == nullptr) {
+ delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.desired_);
+ }
+ _impl_.desired_ = reinterpret_cast<::xtcp_treatment::v1::DesiredState*>(value);
+ if (value != nullptr) {
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ } else {
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:xtcp_treatment.v1.GetDesiredStateResponse.desired)
+}
+inline ::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE GetDesiredStateResponse::release_desired() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+ ::xtcp_treatment::v1::DesiredState* released = _impl_.desired_;
+ _impl_.desired_ = nullptr;
+ if (::google::protobuf::internal::DebugHardenForceCopyInRelease()) {
+ auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
+ released = ::google::protobuf::internal::DuplicateIfNonNull(released);
+ if (GetArena() == nullptr) {
+ delete old;
+ }
+ } else {
+ if (GetArena() != nullptr) {
+ released = ::google::protobuf::internal::DuplicateIfNonNull(released);
+ }
+ }
+ return released;
+}
+inline ::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE GetDesiredStateResponse::unsafe_arena_release_desired() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ // @@protoc_insertion_point(field_release:xtcp_treatment.v1.GetDesiredStateResponse.desired)
+
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+ ::xtcp_treatment::v1::DesiredState* temp = _impl_.desired_;
+ _impl_.desired_ = nullptr;
+ return temp;
+}
+inline ::xtcp_treatment::v1::DesiredState* PROTOBUF_NONNULL GetDesiredStateResponse::_internal_mutable_desired() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (_impl_.desired_ == nullptr) {
+ auto* p = Super_::DefaultConstruct<::xtcp_treatment::v1::DesiredState>(GetArena());
+ _impl_.desired_ = reinterpret_cast<::xtcp_treatment::v1::DesiredState*>(p);
+ }
+ return _impl_.desired_;
+}
+inline ::xtcp_treatment::v1::DesiredState* PROTOBUF_NONNULL GetDesiredStateResponse::mutable_desired()
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ ::xtcp_treatment::v1::DesiredState* _msg = _internal_mutable_desired();
+ // @@protoc_insertion_point(field_mutable:xtcp_treatment.v1.GetDesiredStateResponse.desired)
+ return _msg;
+}
+inline void GetDesiredStateResponse::set_allocated_desired(::xtcp_treatment::v1::DesiredState* PROTOBUF_NULLABLE value) {
+ ::google::protobuf::Arena* message_arena = GetArena();
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (message_arena == nullptr) {
+ delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.desired_);
+ }
+
+ if (value != nullptr) {
+ ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::Message*>(value)->GetArena();
+ if (message_arena != submessage_arena) {
+ value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
+ }
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ } else {
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+ }
+
+ _impl_.desired_ = reinterpret_cast<::xtcp_treatment::v1::DesiredState*>(value);
+ // @@protoc_insertion_point(field_set_allocated:xtcp_treatment.v1.GetDesiredStateResponse.desired)
+}
+
+// -------------------------------------------------------------------
+
+// WatchDesiredStateRequest
+
+// string agent_id = 1 [json_name = "agentId", (.buf.validate.field) = {
+inline void WatchDesiredStateRequest::clear_agent_id() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.agent_id_.ClearToEmpty();
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+}
+inline const ::std::string& WatchDesiredStateRequest::agent_id() const
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ // @@protoc_insertion_point(field_get:xtcp_treatment.v1.WatchDesiredStateRequest.agent_id)
+ return _internal_agent_id();
+}
+template
+PROTOBUF_ALWAYS_INLINE void WatchDesiredStateRequest::set_agent_id(Arg_&& arg, Args_... args) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ _impl_.agent_id_.Set(static_cast(arg), args..., GetArena());
+ // @@protoc_insertion_point(field_set:xtcp_treatment.v1.WatchDesiredStateRequest.agent_id)
+}
+inline ::std::string* PROTOBUF_NONNULL WatchDesiredStateRequest::mutable_agent_id()
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ ::std::string* _s = _internal_mutable_agent_id();
+ // @@protoc_insertion_point(field_mutable:xtcp_treatment.v1.WatchDesiredStateRequest.agent_id)
+ return _s;
+}
+inline const ::std::string& WatchDesiredStateRequest::_internal_agent_id() const {
+ ::google::protobuf::internal::TSanRead(&_impl_);
+ return _impl_.agent_id_.Get();
+}
+inline void WatchDesiredStateRequest::_internal_set_agent_id(const ::std::string& value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.agent_id_.Set(value, GetArena());
+}
+inline ::std::string* PROTOBUF_NONNULL WatchDesiredStateRequest::_internal_mutable_agent_id() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ return _impl_.agent_id_.Mutable( GetArena());
+}
+inline ::std::string* PROTOBUF_NULLABLE WatchDesiredStateRequest::release_agent_id() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ // @@protoc_insertion_point(field_release:xtcp_treatment.v1.WatchDesiredStateRequest.agent_id)
+ if (!CheckHasBit(_impl_._has_bits_[0], 0x00000001U)) {
+ return nullptr;
+ }
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+ auto* released = _impl_.agent_id_.Release();
+ if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) {
+ _impl_.agent_id_.Set("", GetArena());
+ }
+ return released;
+}
+inline void WatchDesiredStateRequest::set_allocated_agent_id(::std::string* PROTOBUF_NULLABLE value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ if (value != nullptr) {
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ } else {
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+ }
+ _impl_.agent_id_.SetAllocated(value, GetArena());
+ if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.agent_id_.IsDefault()) {
+ _impl_.agent_id_.Set("", GetArena());
+ }
+ // @@protoc_insertion_point(field_set_allocated:xtcp_treatment.v1.WatchDesiredStateRequest.agent_id)
+}
+
+// uint64 after_revision = 2 [json_name = "afterRevision"];
+inline void WatchDesiredStateRequest::clear_after_revision() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.after_revision_ = ::uint64_t{0u};
+ ClearHasBit(_impl_._has_bits_[0], 0x00000002U);
+}
+inline ::uint64_t WatchDesiredStateRequest::after_revision() const {
+ // @@protoc_insertion_point(field_get:xtcp_treatment.v1.WatchDesiredStateRequest.after_revision)
+ return _internal_after_revision();
+}
+inline void WatchDesiredStateRequest::set_after_revision(::uint64_t value) {
+ _internal_set_after_revision(value);
+ SetHasBit(_impl_._has_bits_[0], 0x00000002U);
+ // @@protoc_insertion_point(field_set:xtcp_treatment.v1.WatchDesiredStateRequest.after_revision)
+}
+inline ::uint64_t WatchDesiredStateRequest::_internal_after_revision() const {
+ ::google::protobuf::internal::TSanRead(&_impl_);
+ return _impl_.after_revision_;
+}
+inline void WatchDesiredStateRequest::_internal_set_after_revision(::uint64_t value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.after_revision_ = value;
+}
+
+// -------------------------------------------------------------------
+
+// WatchDesiredStateResponse
+
+// uint64 revision = 1 [json_name = "revision"];
+inline void WatchDesiredStateResponse::clear_revision() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.revision_ = ::uint64_t{0u};
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+}
+inline ::uint64_t WatchDesiredStateResponse::revision() const {
+ // @@protoc_insertion_point(field_get:xtcp_treatment.v1.WatchDesiredStateResponse.revision)
+ return _internal_revision();
+}
+inline void WatchDesiredStateResponse::set_revision(::uint64_t value) {
+ _internal_set_revision(value);
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ // @@protoc_insertion_point(field_set:xtcp_treatment.v1.WatchDesiredStateResponse.revision)
+}
+inline ::uint64_t WatchDesiredStateResponse::_internal_revision() const {
+ ::google::protobuf::internal::TSanRead(&_impl_);
+ return _impl_.revision_;
+}
+inline void WatchDesiredStateResponse::_internal_set_revision(::uint64_t value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.revision_ = value;
+}
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif // __GNUC__
+
+// @@protoc_insertion_point(namespace_scope)
+} // namespace v1
+} // namespace xtcp_treatment
+
+
+// @@protoc_insertion_point(global_scope)
+
+#include "google/protobuf/port_undef.inc"
+// clang-format on
+
+#endif // xtcp_5ftreatment_2fv1_2fagent_2eproto_2epb_2eh
diff --git a/gen/cpp/xtcp_treatment/v1/operator.grpc.pb.cc b/gen/cpp/xtcp_treatment/v1/operator.grpc.pb.cc
new file mode 100644
index 000000000..8d58c1a0a
--- /dev/null
+++ b/gen/cpp/xtcp_treatment/v1/operator.grpc.pb.cc
@@ -0,0 +1,258 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: xtcp_treatment/v1/operator.proto
+
+#include "xtcp_treatment/v1/operator.pb.h"
+#include "xtcp_treatment/v1/operator.grpc.pb.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+namespace xtcp_treatment {
+namespace v1 {
+
+static const char* OperatorService_method_names[] = {
+ "/xtcp_treatment.v1.OperatorService/Propose",
+ "/xtcp_treatment.v1.OperatorService/Analyze",
+ "/xtcp_treatment.v1.OperatorService/Review",
+ "/xtcp_treatment.v1.OperatorService/Control",
+ "/xtcp_treatment.v1.OperatorService/Inspect",
+};
+
+std::unique_ptr< OperatorService::Stub> OperatorService::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
+ (void)options;
+ std::unique_ptr< OperatorService::Stub> stub(new OperatorService::Stub(channel, options));
+ return stub;
+}
+
+OperatorService::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options)
+ : channel_(channel), rpcmethod_Propose_(OperatorService_method_names[0], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+ , rpcmethod_Analyze_(OperatorService_method_names[1], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+ , rpcmethod_Review_(OperatorService_method_names[2], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+ , rpcmethod_Control_(OperatorService_method_names[3], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+ , rpcmethod_Inspect_(OperatorService_method_names[4], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+ {}
+
+::grpc::Status OperatorService::Stub::Propose(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ProposeRequest& request, ::xtcp_treatment::v1::ProposeResponse* response) {
+ return ::grpc::internal::BlockingUnaryCall< ::xtcp_treatment::v1::ProposeRequest, ::xtcp_treatment::v1::ProposeResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_Propose_, context, request, response);
+}
+
+void OperatorService::Stub::async::Propose(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ProposeRequest* request, ::xtcp_treatment::v1::ProposeResponse* response, std::function f) {
+ ::grpc::internal::CallbackUnaryCall< ::xtcp_treatment::v1::ProposeRequest, ::xtcp_treatment::v1::ProposeResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_Propose_, context, request, response, std::move(f));
+}
+
+void OperatorService::Stub::async::Propose(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ProposeRequest* request, ::xtcp_treatment::v1::ProposeResponse* response, ::grpc::ClientUnaryReactor* reactor) {
+ ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_Propose_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::ProposeResponse>* OperatorService::Stub::PrepareAsyncProposeRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ProposeRequest& request, ::grpc::CompletionQueue* cq) {
+ return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::xtcp_treatment::v1::ProposeResponse, ::xtcp_treatment::v1::ProposeRequest, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_Propose_, context, request);
+}
+
+::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::ProposeResponse>* OperatorService::Stub::AsyncProposeRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ProposeRequest& request, ::grpc::CompletionQueue* cq) {
+ auto* result =
+ this->PrepareAsyncProposeRaw(context, request, cq);
+ result->StartCall();
+ return result;
+}
+
+::grpc::Status OperatorService::Stub::Analyze(::grpc::ClientContext* context, const ::xtcp_treatment::v1::AnalyzeRequest& request, ::xtcp_treatment::v1::AnalyzeResponse* response) {
+ return ::grpc::internal::BlockingUnaryCall< ::xtcp_treatment::v1::AnalyzeRequest, ::xtcp_treatment::v1::AnalyzeResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_Analyze_, context, request, response);
+}
+
+void OperatorService::Stub::async::Analyze(::grpc::ClientContext* context, const ::xtcp_treatment::v1::AnalyzeRequest* request, ::xtcp_treatment::v1::AnalyzeResponse* response, std::function f) {
+ ::grpc::internal::CallbackUnaryCall< ::xtcp_treatment::v1::AnalyzeRequest, ::xtcp_treatment::v1::AnalyzeResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_Analyze_, context, request, response, std::move(f));
+}
+
+void OperatorService::Stub::async::Analyze(::grpc::ClientContext* context, const ::xtcp_treatment::v1::AnalyzeRequest* request, ::xtcp_treatment::v1::AnalyzeResponse* response, ::grpc::ClientUnaryReactor* reactor) {
+ ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_Analyze_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::AnalyzeResponse>* OperatorService::Stub::PrepareAsyncAnalyzeRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::AnalyzeRequest& request, ::grpc::CompletionQueue* cq) {
+ return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::xtcp_treatment::v1::AnalyzeResponse, ::xtcp_treatment::v1::AnalyzeRequest, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_Analyze_, context, request);
+}
+
+::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::AnalyzeResponse>* OperatorService::Stub::AsyncAnalyzeRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::AnalyzeRequest& request, ::grpc::CompletionQueue* cq) {
+ auto* result =
+ this->PrepareAsyncAnalyzeRaw(context, request, cq);
+ result->StartCall();
+ return result;
+}
+
+::grpc::Status OperatorService::Stub::Review(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ReviewRequest& request, ::xtcp_treatment::v1::ReviewResponse* response) {
+ return ::grpc::internal::BlockingUnaryCall< ::xtcp_treatment::v1::ReviewRequest, ::xtcp_treatment::v1::ReviewResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_Review_, context, request, response);
+}
+
+void OperatorService::Stub::async::Review(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ReviewRequest* request, ::xtcp_treatment::v1::ReviewResponse* response, std::function f) {
+ ::grpc::internal::CallbackUnaryCall< ::xtcp_treatment::v1::ReviewRequest, ::xtcp_treatment::v1::ReviewResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_Review_, context, request, response, std::move(f));
+}
+
+void OperatorService::Stub::async::Review(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ReviewRequest* request, ::xtcp_treatment::v1::ReviewResponse* response, ::grpc::ClientUnaryReactor* reactor) {
+ ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_Review_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::ReviewResponse>* OperatorService::Stub::PrepareAsyncReviewRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ReviewRequest& request, ::grpc::CompletionQueue* cq) {
+ return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::xtcp_treatment::v1::ReviewResponse, ::xtcp_treatment::v1::ReviewRequest, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_Review_, context, request);
+}
+
+::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::ReviewResponse>* OperatorService::Stub::AsyncReviewRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ReviewRequest& request, ::grpc::CompletionQueue* cq) {
+ auto* result =
+ this->PrepareAsyncReviewRaw(context, request, cq);
+ result->StartCall();
+ return result;
+}
+
+::grpc::Status OperatorService::Stub::Control(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ControlRequest& request, ::xtcp_treatment::v1::ControlResponse* response) {
+ return ::grpc::internal::BlockingUnaryCall< ::xtcp_treatment::v1::ControlRequest, ::xtcp_treatment::v1::ControlResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_Control_, context, request, response);
+}
+
+void OperatorService::Stub::async::Control(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ControlRequest* request, ::xtcp_treatment::v1::ControlResponse* response, std::function f) {
+ ::grpc::internal::CallbackUnaryCall< ::xtcp_treatment::v1::ControlRequest, ::xtcp_treatment::v1::ControlResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_Control_, context, request, response, std::move(f));
+}
+
+void OperatorService::Stub::async::Control(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ControlRequest* request, ::xtcp_treatment::v1::ControlResponse* response, ::grpc::ClientUnaryReactor* reactor) {
+ ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_Control_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::ControlResponse>* OperatorService::Stub::PrepareAsyncControlRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ControlRequest& request, ::grpc::CompletionQueue* cq) {
+ return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::xtcp_treatment::v1::ControlResponse, ::xtcp_treatment::v1::ControlRequest, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_Control_, context, request);
+}
+
+::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::ControlResponse>* OperatorService::Stub::AsyncControlRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ControlRequest& request, ::grpc::CompletionQueue* cq) {
+ auto* result =
+ this->PrepareAsyncControlRaw(context, request, cq);
+ result->StartCall();
+ return result;
+}
+
+::grpc::Status OperatorService::Stub::Inspect(::grpc::ClientContext* context, const ::xtcp_treatment::v1::InspectRequest& request, ::xtcp_treatment::v1::InspectResponse* response) {
+ return ::grpc::internal::BlockingUnaryCall< ::xtcp_treatment::v1::InspectRequest, ::xtcp_treatment::v1::InspectResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_Inspect_, context, request, response);
+}
+
+void OperatorService::Stub::async::Inspect(::grpc::ClientContext* context, const ::xtcp_treatment::v1::InspectRequest* request, ::xtcp_treatment::v1::InspectResponse* response, std::function f) {
+ ::grpc::internal::CallbackUnaryCall< ::xtcp_treatment::v1::InspectRequest, ::xtcp_treatment::v1::InspectResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_Inspect_, context, request, response, std::move(f));
+}
+
+void OperatorService::Stub::async::Inspect(::grpc::ClientContext* context, const ::xtcp_treatment::v1::InspectRequest* request, ::xtcp_treatment::v1::InspectResponse* response, ::grpc::ClientUnaryReactor* reactor) {
+ ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_Inspect_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::InspectResponse>* OperatorService::Stub::PrepareAsyncInspectRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::InspectRequest& request, ::grpc::CompletionQueue* cq) {
+ return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::xtcp_treatment::v1::InspectResponse, ::xtcp_treatment::v1::InspectRequest, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_Inspect_, context, request);
+}
+
+::grpc::ClientAsyncResponseReader< ::xtcp_treatment::v1::InspectResponse>* OperatorService::Stub::AsyncInspectRaw(::grpc::ClientContext* context, const ::xtcp_treatment::v1::InspectRequest& request, ::grpc::CompletionQueue* cq) {
+ auto* result =
+ this->PrepareAsyncInspectRaw(context, request, cq);
+ result->StartCall();
+ return result;
+}
+
+OperatorService::Service::Service() {
+ AddMethod(new ::grpc::internal::RpcServiceMethod(
+ OperatorService_method_names[0],
+ ::grpc::internal::RpcMethod::NORMAL_RPC,
+ new ::grpc::internal::RpcMethodHandler< OperatorService::Service, ::xtcp_treatment::v1::ProposeRequest, ::xtcp_treatment::v1::ProposeResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
+ [](OperatorService::Service* service,
+ ::grpc::ServerContext* ctx,
+ const ::xtcp_treatment::v1::ProposeRequest* req,
+ ::xtcp_treatment::v1::ProposeResponse* resp) {
+ return service->Propose(ctx, req, resp);
+ }, this)));
+ AddMethod(new ::grpc::internal::RpcServiceMethod(
+ OperatorService_method_names[1],
+ ::grpc::internal::RpcMethod::NORMAL_RPC,
+ new ::grpc::internal::RpcMethodHandler< OperatorService::Service, ::xtcp_treatment::v1::AnalyzeRequest, ::xtcp_treatment::v1::AnalyzeResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
+ [](OperatorService::Service* service,
+ ::grpc::ServerContext* ctx,
+ const ::xtcp_treatment::v1::AnalyzeRequest* req,
+ ::xtcp_treatment::v1::AnalyzeResponse* resp) {
+ return service->Analyze(ctx, req, resp);
+ }, this)));
+ AddMethod(new ::grpc::internal::RpcServiceMethod(
+ OperatorService_method_names[2],
+ ::grpc::internal::RpcMethod::NORMAL_RPC,
+ new ::grpc::internal::RpcMethodHandler< OperatorService::Service, ::xtcp_treatment::v1::ReviewRequest, ::xtcp_treatment::v1::ReviewResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
+ [](OperatorService::Service* service,
+ ::grpc::ServerContext* ctx,
+ const ::xtcp_treatment::v1::ReviewRequest* req,
+ ::xtcp_treatment::v1::ReviewResponse* resp) {
+ return service->Review(ctx, req, resp);
+ }, this)));
+ AddMethod(new ::grpc::internal::RpcServiceMethod(
+ OperatorService_method_names[3],
+ ::grpc::internal::RpcMethod::NORMAL_RPC,
+ new ::grpc::internal::RpcMethodHandler< OperatorService::Service, ::xtcp_treatment::v1::ControlRequest, ::xtcp_treatment::v1::ControlResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
+ [](OperatorService::Service* service,
+ ::grpc::ServerContext* ctx,
+ const ::xtcp_treatment::v1::ControlRequest* req,
+ ::xtcp_treatment::v1::ControlResponse* resp) {
+ return service->Control(ctx, req, resp);
+ }, this)));
+ AddMethod(new ::grpc::internal::RpcServiceMethod(
+ OperatorService_method_names[4],
+ ::grpc::internal::RpcMethod::NORMAL_RPC,
+ new ::grpc::internal::RpcMethodHandler< OperatorService::Service, ::xtcp_treatment::v1::InspectRequest, ::xtcp_treatment::v1::InspectResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
+ [](OperatorService::Service* service,
+ ::grpc::ServerContext* ctx,
+ const ::xtcp_treatment::v1::InspectRequest* req,
+ ::xtcp_treatment::v1::InspectResponse* resp) {
+ return service->Inspect(ctx, req, resp);
+ }, this)));
+}
+
+OperatorService::Service::~Service() {
+}
+
+::grpc::Status OperatorService::Service::Propose(::grpc::ServerContext* context, const ::xtcp_treatment::v1::ProposeRequest* request, ::xtcp_treatment::v1::ProposeResponse* response) {
+ (void) context;
+ (void) request;
+ (void) response;
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status OperatorService::Service::Analyze(::grpc::ServerContext* context, const ::xtcp_treatment::v1::AnalyzeRequest* request, ::xtcp_treatment::v1::AnalyzeResponse* response) {
+ (void) context;
+ (void) request;
+ (void) response;
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status OperatorService::Service::Review(::grpc::ServerContext* context, const ::xtcp_treatment::v1::ReviewRequest* request, ::xtcp_treatment::v1::ReviewResponse* response) {
+ (void) context;
+ (void) request;
+ (void) response;
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status OperatorService::Service::Control(::grpc::ServerContext* context, const ::xtcp_treatment::v1::ControlRequest* request, ::xtcp_treatment::v1::ControlResponse* response) {
+ (void) context;
+ (void) request;
+ (void) response;
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status OperatorService::Service::Inspect(::grpc::ServerContext* context, const ::xtcp_treatment::v1::InspectRequest* request, ::xtcp_treatment::v1::InspectResponse* response) {
+ (void) context;
+ (void) request;
+ (void) response;
+ return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+
+} // namespace xtcp_treatment
+} // namespace v1
+#include
+
diff --git a/gen/cpp/xtcp_treatment/v1/operator.grpc.pb.h b/gen/cpp/xtcp_treatment/v1/operator.grpc.pb.h
new file mode 100644
index 000000000..72df21c03
--- /dev/null
+++ b/gen/cpp/xtcp_treatment/v1/operator.grpc.pb.h
@@ -0,0 +1,881 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: xtcp_treatment/v1/operator.proto
+// Original file comments:
+//
+// xTCP - treatment operator service
+//
+// The authenticated review surface. Every mutation carries a request_id;
+// repeating one with the same body replays the original response, repeating
+// it with a different body is refused. Reviews also fence on the experiment
+// revision the operator last saw.
+//
+#ifndef GRPC_xtcp_5ftreatment_2fv1_2foperator_2eproto__INCLUDED
+#define GRPC_xtcp_5ftreatment_2fv1_2foperator_2eproto__INCLUDED
+
+#include "xtcp_treatment/v1/operator.pb.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace xtcp_treatment {
+namespace v1 {
+
+class OperatorService final {
+ public:
+ static constexpr char const* service_full_name() {
+ return "xtcp_treatment.v1.OperatorService";
+ }
+ class StubInterface {
+ public:
+ virtual ~StubInterface() {}
+ virtual ::grpc::Status Propose(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ProposeRequest& request, ::xtcp_treatment::v1::ProposeResponse* response) = 0;
+ std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::ProposeResponse>> AsyncPropose(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ProposeRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::ProposeResponse>>(AsyncProposeRaw(context, request, cq));
+ }
+ std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::ProposeResponse>> PrepareAsyncPropose(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ProposeRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::ProposeResponse>>(PrepareAsyncProposeRaw(context, request, cq));
+ }
+ virtual ::grpc::Status Analyze(::grpc::ClientContext* context, const ::xtcp_treatment::v1::AnalyzeRequest& request, ::xtcp_treatment::v1::AnalyzeResponse* response) = 0;
+ std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::AnalyzeResponse>> AsyncAnalyze(::grpc::ClientContext* context, const ::xtcp_treatment::v1::AnalyzeRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::AnalyzeResponse>>(AsyncAnalyzeRaw(context, request, cq));
+ }
+ std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::AnalyzeResponse>> PrepareAsyncAnalyze(::grpc::ClientContext* context, const ::xtcp_treatment::v1::AnalyzeRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::AnalyzeResponse>>(PrepareAsyncAnalyzeRaw(context, request, cq));
+ }
+ virtual ::grpc::Status Review(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ReviewRequest& request, ::xtcp_treatment::v1::ReviewResponse* response) = 0;
+ std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::ReviewResponse>> AsyncReview(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ReviewRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::ReviewResponse>>(AsyncReviewRaw(context, request, cq));
+ }
+ std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::ReviewResponse>> PrepareAsyncReview(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ReviewRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::ReviewResponse>>(PrepareAsyncReviewRaw(context, request, cq));
+ }
+ virtual ::grpc::Status Control(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ControlRequest& request, ::xtcp_treatment::v1::ControlResponse* response) = 0;
+ std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::ControlResponse>> AsyncControl(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ControlRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::ControlResponse>>(AsyncControlRaw(context, request, cq));
+ }
+ std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::ControlResponse>> PrepareAsyncControl(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ControlRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::ControlResponse>>(PrepareAsyncControlRaw(context, request, cq));
+ }
+ virtual ::grpc::Status Inspect(::grpc::ClientContext* context, const ::xtcp_treatment::v1::InspectRequest& request, ::xtcp_treatment::v1::InspectResponse* response) = 0;
+ std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::InspectResponse>> AsyncInspect(::grpc::ClientContext* context, const ::xtcp_treatment::v1::InspectRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::InspectResponse>>(AsyncInspectRaw(context, request, cq));
+ }
+ std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::InspectResponse>> PrepareAsyncInspect(::grpc::ClientContext* context, const ::xtcp_treatment::v1::InspectRequest& request, ::grpc::CompletionQueue* cq) {
+ return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::xtcp_treatment::v1::InspectResponse>>(PrepareAsyncInspectRaw(context, request, cq));
+ }
+ class async_interface {
+ public:
+ virtual ~async_interface() {}
+ virtual void Propose(::grpc::ClientContext* context, const ::xtcp_treatment::v1::ProposeRequest* request, ::xtcp_treatment::v1::ProposeResponse* response, std::function