package rpc import ( "context" "crypto/tls" "fmt" "os" agentpb "git.ipao.vip/rogee/go-sip/gen/agent" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) // Client is a thin generated-stub wrapper. Business retries and reconciliation // remain at the caller; this type never retries an originate automatically. type Client struct { Conn *grpc.ClientConn Agent agentpb.AgentControlServiceClient } func Dial(endpoint string, tlsConfig *tls.Config) (*Client, error) { if endpoint == "" { return nil, fmt.Errorf("gRPC endpoint is required") } if tlsConfig == nil { return nil, fmt.Errorf("mTLS configuration is required") } conn, err := grpc.NewClient(endpoint, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig))) if err != nil { return nil, fmt.Errorf("dial gRPC endpoint: %w", err) } return &Client{Conn: conn, Agent: agentpb.NewAgentControlServiceClient(conn)}, nil } func DialFromFiles(endpoint, caFile, certFile, keyFile, serverName string) (*Client, error) { caPEM, err := readFile(caFile, "CA") if err != nil { return nil, err } certPEM, err := readFile(certFile, "certificate") if err != nil { return nil, err } keyPEM, err := readFile(keyFile, "key") if err != nil { return nil, err } tlsConfig, err := NewClientTLSConfig(caPEM, certPEM, keyPEM, serverName) if err != nil { return nil, err } return Dial(endpoint, tlsConfig) } func readFile(path, label string) ([]byte, error) { if path == "" { return nil, fmt.Errorf("%s file is required", label) } data, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("read %s file: %w", label, err) } return data, nil } func (c *Client) ReportExecutionEvent(ctx context.Context, request *agentpb.ReportExecutionEventRequest) (*agentpb.ReportExecutionEventResponse, error) { if c == nil || c.Agent == nil { return nil, fmt.Errorf("AgentControl client is not initialized") } return c.Agent.ReportExecutionEvent(ctx, request) } func (c *Client) RequestUpload(ctx context.Context, request *agentpb.RequestUploadRequest) (*agentpb.RequestUploadResponse, error) { if c == nil || c.Agent == nil { return nil, fmt.Errorf("AgentControl client is not initialized") } return c.Agent.RequestUpload(ctx, request) } func (c *Client) CompleteUpload(ctx context.Context, request *agentpb.CompleteUploadRequest) (*agentpb.CompleteUploadResponse, error) { if c == nil || c.Agent == nil { return nil, fmt.Errorf("AgentControl client is not initialized") } return c.Agent.CompleteUpload(ctx, request) } func (c *Client) Close() error { if c == nil || c.Conn == nil { return nil } return c.Conn.Close() }