1 // Copyright (c) 2017 Nuxi, https://nuxi.nl/ 2 // 3 // This file is distributed under a 2-clause BSD license. 4 // See the LICENSE file for details. 5 6 #include <cstdlib> 7 #include <ostream> 8 9 #include <arpc++/arpc++.h> 10 11 #include <flower/ls/configuration.ad.h> 12 #include <flower/ls/start.h> 13 #include <flower/protocol/switchboard.ad.h> 14 #include <flower/util/fd_streambuf.h> 15 #include <flower/util/label_map.h> 16 #include <flower/util/logger.h> 17 #include <flower/util/null_streambuf.h> 18 19 using arpc::Channel; 20 using arpc::ClientContext; 21 using arpc::ClientReader; 22 using arpc::Status; 23 using flower::protocol::switchboard::ListRequest; 24 using flower::protocol::switchboard::ListResponse; 25 using flower::protocol::switchboard::Switchboard; 26 using flower::util::LabelMapToJson; 27 using flower::util::Logger; 28 using flower::util::fd_streambuf; 29 using flower::util::null_streambuf; 30 Start(const Configuration & configuration)31void flower::ls::Start(const Configuration& configuration) { 32 // Make logging work. 33 std::unique_ptr<std::streambuf> logger_streambuf; 34 if (const auto& logger_output = configuration.logger_output(); 35 logger_output) { 36 logger_streambuf = std::make_unique<fd_streambuf>(logger_output); 37 } else { 38 logger_streambuf = std::make_unique<null_streambuf>(); 39 } 40 Logger logger(logger_streambuf.get()); 41 42 // Check that all required fields are present. 43 const auto& switchboard_socket = configuration.switchboard_socket(); 44 if (!switchboard_socket) { 45 logger.Log() << "Cannot start without a switchboard socket"; 46 std::exit(1); 47 } 48 const auto& list_output_fd = configuration.list_output(); 49 if (!list_output_fd) { 50 logger.Log() << "Cannot start without an descriptor for listing output"; 51 std::exit(1); 52 } 53 fd_streambuf list_output_streambuf(list_output_fd); 54 std::ostream list_output(&list_output_streambuf); 55 56 // Request a list of registered targets from the Switchboard. 57 std::shared_ptr<Channel> channel = CreateChannel(switchboard_socket); 58 std::unique_ptr<Switchboard::Stub> stub = Switchboard::NewStub(channel); 59 ClientContext context; 60 ListRequest request; 61 std::unique_ptr<ClientReader<ListResponse>> reader = 62 stub->List(&context, request); 63 64 // Print the targets. 65 for (ListResponse response; reader->Read(&response);) { 66 LabelMapToJson(response.labels(), &list_output); 67 list_output << std::endl; 68 } 69 70 if (Status status = reader->Finish(); !status.ok()) { 71 logger.Log() << "Cannot start without a switchboard socket"; 72 std::exit(1); 73 } 74 std::exit(0); 75 } 76