blob: 1c53b665ac5f29cdf6ea40982f500bd17efaeed4 [file] [log] [blame]
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Implements inventory_service.proto (see proto for details)
package main
import (
"bytes"
"errors"
"io/ioutil"
"log"
"net"
"github.com/golang/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
"go.chromium.org/chromiumos/config/go/test/lab/api"
"google.golang.org/grpc"
)
// InventoryServer implementation of inventory_service.proto
type InventoryServer struct {
logger *log.Logger
dutTopology *api.DutTopology
}
// Optional arguments (passed during startup that control serving behavior)
type Options struct {
DutAddress string
DutPort int
// File path to a serialized jsonproto payload of DutTopology.
// This allows local complex lab setups (e.g. multi-dut) for local testing.
DutTopologyConfigPath string
}
// readJsonpb reads the jsonpb at path into m.
func readJsonpb(path string, m proto.Message) error {
b, err := ioutil.ReadFile(path)
if err != nil {
return err
}
return jsonpb.Unmarshal(bytes.NewReader(b), m)
}
// newInventoryServer creates a new inventory service server to listen to rpc requests.
func newInventoryServer(l net.Listener, logger *log.Logger, options *Options) (*grpc.Server, error) {
dutTopology := &api.DutTopology{}
dutAddress := len(options.DutAddress) != 0
dutTopoConfig := len(options.DutTopologyConfigPath) != 0
if dutAddress && dutTopoConfig {
return nil, errors.New("DutAddress and DutTopologyConfigOptions options are mutally exclusive")
}
if dutTopoConfig {
if err := readJsonpb(options.DutTopologyConfigPath, dutTopology); err != nil {
return nil, err
}
} else if dutAddress {
dutTopology = &api.DutTopology{
Id: &api.DutTopology_Id{
Value: options.DutAddress,
},
Duts: []*api.Dut{
{
Id: &api.Dut_Id{
Value: options.DutAddress,
},
DutType: &api.Dut_Chromeos{
Chromeos: &api.Dut_ChromeOS{
Ssh: &api.IpEndpoint{
Address: options.DutAddress,
Port: int32(options.DutPort),
},
},
},
},
},
}
}
s := &InventoryServer{
logger: logger,
dutTopology: dutTopology,
}
server := grpc.NewServer()
api.RegisterInventoryServiceServer(server, s)
logger.Println("inventoryservice listening to requests at ", l.Addr().String())
return server, nil
}
func (s *InventoryServer) GetDutTopology(req *api.GetDutTopologyRequest, stream api.InventoryService_GetDutTopologyServer) error {
s.logger.Println("Received api.GetDutTopology: ", *req)
return stream.Send(&api.GetDutTopologyResponse{
Result: &api.GetDutTopologyResponse_Success_{
Success: &api.GetDutTopologyResponse_Success{
DutTopology: s.dutTopology,
},
},
})
}