This is an automated email from the ASF dual-hosted git repository.

harishgokul01 pushed a commit to branch release-bugs
in repository https://gitbox.apache.org/repos/asf/incubator-resilientdb.git


The following commit(s) were added to refs/heads/release-bugs by this push:
     new f7a09830 Add server configuration files and update generation script
f7a09830 is described below

commit f7a0983066badea71cef56fe99aa882c97efce22
Author: harish876 <[email protected]>
AuthorDate: Fri Oct 31 06:44:31 2025 +0000

    Add server configuration files and update generation script
    
    - Introduced `server.config.json` and `server.config` files to define 
server region and replica information.
    - Updated `generate_config.sh` to use the new configuration generation tool 
and ensure proper key generation.
    - Added a new C++ tool `generate_region_config_cc` for generating region 
configuration in JSON format.
    - Modified `start_kv_service.sh` to include the new configuration 
generation step.
---
 server.config.json                                |   1 +
 service/tools/config/generate_config.sh           |  19 ++-
 service/tools/config/interface/service.config     |   3 +-
 service/tools/config/server.config                |   5 +
 service/tools/kv/server_tools/generate_config.sh  |   2 +-
 service/tools/kv/server_tools/start_kv_service.sh |   5 +
 tools/BUILD                                       |   9 ++
 tools/generate_region_config_cc.cpp               | 180 ++++++++++++++++++++++
 8 files changed, 217 insertions(+), 7 deletions(-)

diff --git a/server.config.json b/server.config.json
new file mode 100644
index 00000000..c71f61c8
--- /dev/null
+++ b/server.config.json
@@ -0,0 +1 @@
+{"region":[{"replicaInfo":[{"id":"1","ip":"127.0.0.1","port":20001},{"id":"2","ip":"127.0.0.1","port":20002},{"id":"3","ip":"127.0.0.1","port":20003},{"id":"4","ip":"127.0.0.1","port":20004}]}]}
\ No newline at end of file
diff --git a/service/tools/config/generate_config.sh 
b/service/tools/config/generate_config.sh
index 8d493c55..92aaa490 100755
--- a/service/tools/config/generate_config.sh
+++ b/service/tools/config/generate_config.sh
@@ -40,7 +40,8 @@ ADMIN_PRIVATE_KEY=${admin_key_path}/admin.key.pri
 ADMIN_PUBLIC_KEY=${admin_key_path}/admin.key.pub
 
 CERT_TOOLS_BIN=${base_path}/bazel-bin/tools/certificate_tools
-CONFIG_TOOLS_BIN=${base_path}/bazel-bin/tools/generate_region_config
+CONFIG_TOOLS_BIN=${base_path}/bazel-bin/tools/generate_region_config_cc
+KEYGEN_BIN=${base_path}/bazel-bin/tools/key_generator_tools
 
 USERNAME=ubuntu
 BASE_PORT=${base_port}
@@ -51,7 +52,8 @@ echo "" > client.config
 echo "" > server.config
 
 bazel build //tools:certificate_tools
-bazel build //tools:generate_region_config
+bazel build //tools:key_generator_tools
+bazel build //tools:generate_region_config_cc
 
 idx=1
 tot=0
@@ -65,12 +67,21 @@ echo "node num:"$tot
 echo "base port:"${BASE_PORT}
 echo "client num:" ${CLIENT_NUM}
 
+# Ensure cert output directory exists and use it for node key generation
+mkdir -p ${output_cert_path}
+
+# Generate admin keypair (needed by certificate_tools)
+${KEYGEN_BIN} ${output_cert_path}/admin
+
 for ip in ${iplist[@]};
 do
   port=$((${BASE_PORT}+${idx}))
-  public_key=${key_path}/node${idx}.key.pub 
+  public_key=${output_cert_path}/node${idx}.key.pub 
   echo "get ip:"${ip}
 
+  # generate node key pair for this idx
+  ${KEYGEN_BIN} ${output_cert_path}/node${idx}
+
   # create public key
   # create server config
   # create the public key and certificate
@@ -85,7 +96,7 @@ do
   idx=$(($idx+1))
 done
 
-python3 ${CONFIG_TOOLS_BIN} ./server.config ./server.config.json 
+${CONFIG_TOOLS_BIN} ./server.config ./server.config.json 
 mv server.config.json ${output_path}/server/server.config
 mv client.config ${output_path}/interface/service.config
 echo "config done:" ${output_path}/server/server.config
diff --git a/service/tools/config/interface/service.config 
b/service/tools/config/interface/service.config
index d357ba73..9cda04c0 100644
--- a/service/tools/config/interface/service.config
+++ b/service/tools/config/interface/service.config
@@ -1,3 +1,2 @@
-5 127.0.0.1 10005
-
 
+5 127.0.0.1 10005
diff --git a/service/tools/config/server.config 
b/service/tools/config/server.config
new file mode 100644
index 00000000..a68d1cec
--- /dev/null
+++ b/service/tools/config/server.config
@@ -0,0 +1,5 @@
+
+1 127.0.0.1 10001
+2 127.0.0.1 10002
+3 127.0.0.1 10003
+4 127.0.0.1 10004
diff --git a/service/tools/kv/server_tools/generate_config.sh 
b/service/tools/kv/server_tools/generate_config.sh
index 5f494434..14641d70 100755
--- a/service/tools/kv/server_tools/generate_config.sh
+++ b/service/tools/kv/server_tools/generate_config.sh
@@ -28,7 +28,7 @@ iplist=(
 WORKSPACE=$PWD
 CERT_PATH=$PWD/service/tools/data/cert/
 CONFIG_PATH=$PWD/service/tools/config/
-PORT_BASE=20000
+PORT_BASE=10000
 CLIENT_NUM=1
 
 ./service/tools/config/generate_config.sh ${WORKSPACE} ${CERT_PATH} 
${CERT_PATH} ${CONFIG_PATH} ${CERT_PATH} ${CLIENT_NUM} ${PORT_BASE} 
${iplist[@]} 
diff --git a/service/tools/kv/server_tools/start_kv_service.sh 
b/service/tools/kv/server_tools/start_kv_service.sh
index e0273133..b99d0e46 100755
--- a/service/tools/kv/server_tools/start_kv_service.sh
+++ b/service/tools/kv/server_tools/start_kv_service.sh
@@ -23,6 +23,11 @@ SERVER_CONFIG=service/tools/config/server/server.config
 WORK_PATH=$PWD
 CERT_PATH=${WORK_PATH}/service/tools/data/cert/
 
+./service/tools/kv/server_tools/generate_config.sh || {
+  echo "Failed to generate configs/certificates" 1>&2
+  exit 1
+}
+
 bazel build //service/kv:kv_service $@
 nohup $SERVER_PATH $SERVER_CONFIG $CERT_PATH/node1.key.pri 
$CERT_PATH/cert_1.cert > server0.log &
 nohup $SERVER_PATH $SERVER_CONFIG $CERT_PATH/node2.key.pri 
$CERT_PATH/cert_2.cert > server1.log &
diff --git a/tools/BUILD b/tools/BUILD
index 8d5ca092..13475336 100644
--- a/tools/BUILD
+++ b/tools/BUILD
@@ -77,3 +77,12 @@ py_binary(
         "//platform/proto:replica_info_py_proto",
     ],
 )
+
+cc_binary(
+    name = "generate_region_config_cc",
+    srcs = ["generate_region_config_cc.cpp"],
+    deps = [
+        "//platform/config:resdb_config_utils",
+        "//platform/proto:replica_info_cc_proto",
+    ],
+)
diff --git a/tools/generate_region_config_cc.cpp 
b/tools/generate_region_config_cc.cpp
new file mode 100644
index 00000000..b2147867
--- /dev/null
+++ b/tools/generate_region_config_cc.cpp
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <map>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/util/json_util.h>
+#include "platform/proto/replica_info.pb.h"
+
+namespace {
+
+using google::protobuf::util::JsonStringToMessage;
+using google::protobuf::util::MessageToJsonString;
+using google::protobuf::util::JsonParseOptions;
+using resdb::ResConfigData;
+using resdb::ReplicaInfo;
+using resdb::RegionInfo;
+
+bool readLines(const std::string& path, std::vector<std::string>* lines) {
+  std::ifstream in(path);
+  if (!in.is_open()) {
+    std::cerr << "Failed to open file: " << path << "\n";
+    return false;
+  }
+  std::string line;
+  while (std::getline(in, line)) {
+    lines->push_back(line);
+  }
+  return true;
+}
+
+std::string readFileToString(const std::string& path) {
+  std::ifstream in(path);
+  if (!in.is_open()) {
+    std::cerr << "Failed to open file: " << path << "\n";
+    return "";
+  }
+  std::ostringstream oss;
+  oss << in.rdbuf();
+  return oss.str();
+}
+
+}  // namespace
+
+int main(int argc, char** argv) {
+  if (argc < 3) {
+    std::cerr << "Usage: " << argv[0]
+              << " <server.config input> <output.json> [template.json]\n";
+    return 1;
+  }
+
+  const std::string input_path = argv[1];
+  const std::string output_path = argv[2];
+  const std::string template_path = (argc > 3 ? argv[3] : "");
+
+  std::vector<std::string> lines;
+  if (!readLines(input_path, &lines)) {
+    std::cerr << "Failed to read input file: " << input_path << "\n";
+    return 2;
+  }
+
+  ResConfigData config_data;
+  std::map<std::string, std::vector<ReplicaInfo>> region_to_replicas;
+  
+  for (const std::string& line : lines) {
+    if (line.empty() || line.find_first_not_of(" \t\r\n") == 
std::string::npos) {
+      continue;
+    }
+    
+    std::istringstream iss(line);
+    std::string id_str, ip, port_str, region_id;
+    
+    if (!(iss >> id_str >> ip >> port_str)) {
+      continue;
+    }
+    
+    if (!(iss >> region_id)) {
+      region_id = "0";
+    }
+    
+    int64_t id;
+    int32_t port;
+    try {
+      id = std::stoll(id_str);
+      port = std::stoi(port_str);
+    } catch (const std::exception& e) {
+      std::cerr << "Warning: Failed to parse id or port from line: " << line 
<< "\n";
+      continue;
+    }
+    
+    ReplicaInfo replica;
+    replica.set_id(id);
+    replica.set_ip(ip);
+    replica.set_port(port);
+    
+    region_to_replicas[region_id].push_back(replica);
+  }
+
+  for (auto& [rid, replicas] : region_to_replicas) {
+    RegionInfo* region = config_data.add_region();
+    for (auto& replica : replicas) {
+      *region->add_replica_info() = replica;
+    }
+  }
+
+  std::string output_json;
+  MessageToJsonString(config_data, &output_json);
+  std::cerr << "Generated JSON (before template):\n" << output_json << "\n\n";
+
+  std::ofstream out(output_path);
+  if (!out.is_open()) {
+    std::cerr << "Failed to open output file: " << output_path << "\n";
+    return 4;
+  }
+  out << output_json;
+  out.close();
+
+  if (!template_path.empty()) {
+    std::string base_json = readFileToString(output_path);
+    std::cerr << "Read base config:\n" << base_json << "\n\n";
+    
+    ResConfigData base_config;
+    JsonParseOptions parse_options;
+    auto status = JsonStringToMessage(base_json, &base_config, parse_options);
+    if (!status.ok()) {
+      std::cerr << "Failed to parse generated JSON: " << status.message() << 
"\n";
+      return 5;
+    }
+    
+    std::string template_json_str = readFileToString(template_path);
+    if (template_json_str.empty()) {
+      std::cerr << "Failed to read template file: " << template_path << "\n";
+      return 6;
+    }
+    std::cerr << "Read template config:\n" << template_json_str << "\n\n";
+    
+    ResConfigData template_config;
+    status = JsonStringToMessage(template_json_str, &template_config, 
parse_options);
+    if (!status.ok()) {
+      std::cerr << "Failed to parse template JSON: " << status.message() << 
"\n";
+      return 7;
+    }
+    
+    base_config.MergeFrom(template_config);
+    
+    std::string merged_json;
+    MessageToJsonString(base_config, &merged_json);
+    std::cerr << "Merged JSON (after template):\n" << merged_json << "\n\n";
+    std::ofstream out2(output_path);
+    if (!out2.is_open()) {
+      std::cerr << "Failed to reopen output file for merged config\n";
+      return 8;
+    }
+    out2 << merged_json;
+    out2.close();
+  }
+
+  return 0;
+}

Reply via email to