123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- /*
- Copyright (c) 2022 Sogou, Inc.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string>
- #include <string.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <dirent.h>
- #include <fcntl.h>
- #include "srpc_controller.h"
- RPCController::RPCController()
- {
- this->config.type = COMMAND_RPC;
- struct file_info info;
- info = { "rpc/CMakeLists.txt", "CMakeLists.txt", rpc_cmake_transform };
- this->default_files.push_back(info);
- info = { "common/config.json", "client.conf", nullptr };
- this->default_files.push_back(info);
- info = { "common/config.json", "server.conf", nullptr };
- this->default_files.push_back(info);
- info = { "common/GNUmakefile", "GNUmakefile", nullptr };
- this->default_files.push_back(info);
- info = { "config/Json.h", "config/Json.h", nullptr };
- this->default_files.push_back(info);
- info = { "config/Json.cc", "config/Json.cc", nullptr };
- this->default_files.push_back(info);
- info = { "config/config_full.h", "config/config.h", nullptr };
- this->default_files.push_back(info);
- info = { "config/config_full.cc", "config/config.cc", nullptr };
- this->default_files.push_back(info);
- info = { "common/config.json", "full.conf", nullptr };
- this->default_files.push_back(info);
- }
- void RPCController::print_usage(const char *name) const
- {
- printf(COLOR_PINK"Usage:\n"
- COLOR_INFO" %s " COLOR_COMMAND "rpc "
- COLOR_INFO"<PROJECT_NAME> " COLOR_FLAG "[FLAGS]\n\n"
- COLOR_PINK"Example:\n"
- COLOR_PURPLE" %s rpc my_rpc_project\n\n"
- COLOR_PINK"Available Flags:\n"
- COLOR_FLAG" -r "
- COLOR_WHITE": rpc type [ SRPC | SRPCHttp | BRPC | Thrift | "
- "ThriftHttp | TRPC | TRPCHttp ] (default: SRPC)\n"
- COLOR_FLAG" -o "
- COLOR_WHITE": project output path (default: CURRENT_PATH)\n"
- COLOR_FLAG" -s "
- COLOR_WHITE": service name (default: PROJECT_NAME)\n"
- COLOR_FLAG" -i "
- COLOR_WHITE": idl type [ protobuf | thrift ] (default: protobuf)\n"
- COLOR_FLAG" -x "
- COLOR_WHITE": data type [ protobuf | thrift | json ] "
- "(default: idl type. json for http)\n"
- COLOR_FLAG" -c "
- COLOR_WHITE": compress type [ gzip | zlib | snappy | lz4 ] "
- "(default: no compression)\n"
- COLOR_FLAG" -d "
- COLOR_WHITE": path of dependencies (default: COMPILE_PATH)\n"
- COLOR_FLAG" -f "
- COLOR_WHITE": specify the idl_file to generate codes "
- "(default: templates/rpc/IDL_FILE)\n"
- COLOR_FLAG" -p "
- COLOR_WHITE": specify the path for idl_file to depend "
- "(default: templates/rpc/)\n"
- COLOR_OFF, name, name);
- }
- bool RPCController::copy_files()
- {
- struct srpc_config *config = &this->config;
- int ret = true;
-
- if (config->specified_idl_file == NULL) // fill the default rpc files
- {
- this->fill_rpc_default_files();
- }
- else
- {
- // copy specified idl file and generate rpc files
- struct GeneratorParams params;
- params.out_dir = config->output_path;
- params.input_dir = config->specified_idl_path;
- if (params.input_dir[params.input_dir.length() - 1] != '/')
- params.input_dir += "/";
- params.idl_file = config->specified_idl_file;
- auto pos = params.idl_file.find_last_of('/');
- if (pos != std::string::npos)
- params.idl_file = params.idl_file.substr(pos + 1);
- std::string out_file = std::string(config->output_path) +
- std::string("/") + params.idl_file;
- if (CommandController::copy_single_file(config->specified_idl_file,
- out_file, nullptr) == false)
- return false;
- ControlGenerator gen(config);
- printf(COLOR_PURPLE"Info: srpc generator begin.\n" COLOR_OFF);
- ret = gen.generate(params);
- if (ret == false)
- {
- printf(COLOR_RED"Error: srpc generator error.\n\n" COLOR_OFF);
- return false;
- }
- printf(COLOR_PURPLE"Info: srpc generator done.\n\n" COLOR_OFF);
- }
- return CommandController::copy_files();
- }
- static bool rpc_get_opt(int argc, const char **argv, struct srpc_config *config)
- {
- int c;
- while ((c = getopt(argc, (char * const *)argv,
- "o:r:i:x:c:s:d:f:p:")) >= 0)
- {
- switch (c)
- {
- case 'o':
- if (sscanf(optarg, "%s", config->output_path) != 1)
- return false;
- break;
- case 'r':
- config->set_rpc_type(optarg);
- break;
- case 'i':
- config->set_idl_type(optarg);
- break;
- case 'x':
- config->set_data_type(optarg);
- break;
- case 'c':
- config->set_compress_type(optarg);
- break;
- case 's':
- config->service_name = optarg;
- break;
- case 'd':
- config->specified_depend_path = true;
- memset(config->depend_path, 0, MAXPATHLEN);
- if (sscanf(optarg, "%s", config->depend_path) != 1)
- return false;
- break;
- case 'f':
- config->specified_idl_file = optarg;
- break;
- case 'p':
- config->specified_idl_path = optarg;
- break;
- default:
- printf(COLOR_RED "Error:\n Unknown args : "
- COLOR_BLUE "%s\n\n" COLOR_OFF, argv[optind - 1]);
- return false;
- }
- }
- return true;
- }
- bool RPCController::get_opt(int argc, const char **argv)
- {
- optind = 2;
- if (rpc_get_opt(argc, argv, &this->config) == false)
- return false;
- if (optind == argc)
- {
- printf(COLOR_RED "Missing: PROJECT_NAME\n\n" COLOR_OFF);
- return false;
- }
- this->config.project_name = argv[optind];
- optind++;
- if (rpc_get_opt(argc, argv, &this->config) == false)
- return false;
- if (this->config.project_name == NULL)
- {
- printf(COLOR_RED "Missing: PROJECT_NAME\n\n" COLOR_OFF);
- return false;
- }
- return true;
- }
- bool RPCController::check_args()
- {
- if (CommandController::check_args() == false)
- return false;
- struct srpc_config *config = &this->config;
- if (config->rpc_type == PROTOCOL_TYPE_MAX ||
- config->idl_type == IDL_TYPE_MAX ||
- config->data_type == DATA_TYPE_MAX ||
- config->compress_type == COMPRESS_TYPE_MAX)
- {
- printf(COLOR_RED"Error:\n Invalid rpc args : -r | -i | -c | -d .\n\n" COLOR_OFF);
- return false;
- }
- switch (config->rpc_type)
- {
- case PROTOCOL_TYPE_THRIFT:
- case PROTOCOL_TYPE_THRIFT_HTTP:
- if (config->idl_type == IDL_TYPE_PROTOBUF ||
- config->data_type == DATA_TYPE_PROTOBUF)
- {
- printf(COLOR_RED"Error:\n "
- COLOR_BLUE"\" %s \" "
- COLOR_RED"does NOT support protobuf as idl or data type.\n\n" COLOR_OFF,
- config->rpc_type_string());
- return false;
- }
- if (config->idl_type == IDL_TYPE_DEFAULT)
- config->idl_type = IDL_TYPE_THRIFT; // as default;
- break;
- case PROTOCOL_TYPE_BRPC:
- case PROTOCOL_TYPE_TRPC:
- case PROTOCOL_TYPE_TRPC_HTTP:
- if (config->idl_type == IDL_TYPE_THRIFT ||
- config->data_type == DATA_TYPE_THRIFT)
- {
- printf(COLOR_RED "Error:\n "
- COLOR_BLUE "\" %s \" "
- COLOR_RED "does NOT support thrift as idl or data type.\n" COLOR_OFF,
- config->rpc_type_string());
- return false;
- }
- default:
- if (config->idl_type == IDL_TYPE_DEFAULT)
- config->idl_type = IDL_TYPE_PROTOBUF; // as default;
- break;
- }
- if (config->prepare_specified_idl_file() == false)
- return false;
- if (config->service_name == NULL)
- config->service_name = config->project_name;
- return true;
- }
- APIController::APIController()
- {
- this->config.type = COMMAND_API;
- this->config.idl_type = IDL_TYPE_PROTOBUF;
- }
- void APIController::print_usage(const char *name) const
- {
- printf(COLOR_PINK"Usage:\n"
- COLOR_INFO" %s " COLOR_COMMAND "api "
- COLOR_INFO"<FILE_NAME> " COLOR_FLAG "[FLAGS]\n\n"
- COLOR_PINK"Example:\n"
- COLOR_PURPLE" %s api my_api\n\n"
- COLOR_PINK"Available Flags:\n"
- COLOR_FLAG" -o "
- COLOR_WHITE": file output path (default: CURRENT_PATH)\n"
- COLOR_FLAG" -i "
- COLOR_WHITE": idl type [ protobuf | thrift ] (default: protobuf)\n"
- COLOR_OFF, name, name);
- }
- static bool api_get_opt(int argc, const char **argv, struct srpc_config *config)
- {
- char c;
- while ((c = getopt(argc, (char * const *)argv, "o:i:")) != -1)
- {
- switch (c)
- {
- case 'o':
- memset(config->output_path, 0, MAXPATHLEN);
- if (sscanf(optarg, "%s", config->output_path) != 1)
- return false;
- break;
- case 'i':
- config->set_idl_type(optarg);
- break;
- default:
- printf(COLOR_RED "Error:\n Unknown args : "
- COLOR_BLUE "%s\n\n" COLOR_OFF, argv[optind - 1]);
- return false;
- }
- }
- return true;
- }
- bool APIController::get_opt(int argc, const char **argv)
- {
- optind = 2;
- getcwd(this->config.output_path, MAXPATHLEN);
- if (api_get_opt(argc, argv, &this->config) == false)
- return false;
- if (optind == argc)
- {
- printf(COLOR_RED "Missing: FILE_NAME\n\n" COLOR_OFF);
- return false;
- }
- this->config.project_name = argv[optind];
- optind++;
- if (api_get_opt(argc, argv, &this->config) == false)
- return false;
- if (this->config.project_name == NULL)
- {
- printf(COLOR_RED "Missing: FILE_NAME\n\n" COLOR_OFF);
- return false;
- }
- this->config.service_name = this->config.project_name;
- return true;
- }
- bool APIController::dependencies_and_dir()
- {
- std::string idl_file_name;
- std::string out_file_name = this->config.project_name;
- if (this->config.idl_type == IDL_TYPE_PROTOBUF)
- {
- out_file_name += ".proto";
- idl_file_name = "rpc/rpc.proto";
- }
- else if (this->config.idl_type == IDL_TYPE_THRIFT)
- {
- out_file_name += ".thrift";
- idl_file_name = "rpc/rpc.thrift";
- }
- std::string abs_file_name = this->config.output_path;
- if (abs_file_name.at(abs_file_name.length() - 1) != '/')
- abs_file_name += "/";
- abs_file_name += out_file_name;
- DIR *dir;
- dir = opendir(this->config.output_path);
- if (dir == NULL)
- {
- if (mkdir_p(this->config.output_path, 0755) != 0)
- {
- perror("Error:\n failed to make output_path ");
- return false;
- }
- }
- else
- {
- closedir(dir);
- struct stat st;
- if (stat(abs_file_name.c_str(), &st) >= 0)
- {
- printf(COLOR_RED"Error:\n file"
- COLOR_BLUE" %s " COLOR_RED "EXISTED in path"
- COLOR_BLUE" %s " COLOR_RED ".\n" COLOR_OFF,
- out_file_name.c_str(), this->config.output_path);
- return false;
- }
- }
- dir = opendir(this->config.template_path);
- if (dir == NULL)
- {
- printf(COLOR_RED"Error:\n template path "
- COLOR_BLUE" %s " COLOR_RED "does NOT exist.\n" COLOR_OFF,
- this->config.template_path);
- return false;
- }
- struct file_info info;
- info = { idl_file_name , out_file_name, rpc_idl_transform };
- this->default_files.push_back(info);
- closedir(dir);
- return true;
- }
- void APIController::print_success_info() const
- {
- std::string file_name = this->config.project_name;
- if (this->config.idl_type == IDL_TYPE_PROTOBUF)
- file_name += ".proto";
- else if (this->config.idl_type == IDL_TYPE_THRIFT)
- file_name += ".thrift";
- printf(COLOR_GREEN"Success:\n Create api file"
- COLOR_BLUE" %s " COLOR_GREEN "at path"
- COLOR_BLUE" %s " COLOR_GREEN "done.\n\n" COLOR_OFF,
- file_name.c_str(), this->config.output_path);
- printf(COLOR_PINK"Suggestions:\n"
- COLOR_WHITE" Modify the api file as you needed.\n"
- " And make rpc project base on this file with the following command:\n\n"
- COLOR_GREEN" ./srpc rpc my_rpc_project -f %s -p %s\n\n" COLOR_OFF,
- file_name.c_str(), this->config.output_path);
- }
|