ZooKeeperQuorumServer.cc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with this
  4. * work for additional information regarding copyright ownership. The ASF
  5. * licenses this file to you under the Apache License, Version 2.0 (the
  6. * "License"); you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  13. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  14. * License for the specific language governing permissions and limitations under
  15. * the License.
  16. */
  17. #include "ZooKeeperQuorumServer.h"
  18. #include <cassert>
  19. #include <cstdio>
  20. #include <cstdlib>
  21. #include <fstream>
  22. #include <sstream>
  23. ZooKeeperQuorumServer::
  24. ZooKeeperQuorumServer(uint32_t id, uint32_t numServers) :
  25. id_(id),
  26. numServers_(numServers) {
  27. const char* root = getenv("ZKROOT");
  28. if (root == NULL) {
  29. assert(!"Environment variable 'ZKROOT' is not set");
  30. }
  31. root_ = root;
  32. createConfigFile();
  33. createDataDirectory();
  34. start();
  35. }
  36. ZooKeeperQuorumServer::
  37. ~ZooKeeperQuorumServer() {
  38. stop();
  39. }
  40. std::string ZooKeeperQuorumServer::
  41. getHostPort() {
  42. std::stringstream ss;
  43. ss << "localhost:" << getClientPort();
  44. return ss.str();
  45. }
  46. uint32_t ZooKeeperQuorumServer::
  47. getClientPort() {
  48. return CLIENT_PORT_BASE + id_;
  49. }
  50. void ZooKeeperQuorumServer::
  51. start() {
  52. std::string command = root_ + "/bin/zkServer.sh start " +
  53. getConfigFileName();
  54. assert(system(command.c_str()) == 0);
  55. }
  56. void ZooKeeperQuorumServer::
  57. stop() {
  58. std::string command = root_ + "/bin/zkServer.sh stop " +
  59. getConfigFileName();
  60. assert(system(command.c_str()) == 0);
  61. }
  62. std::string ZooKeeperQuorumServer::
  63. getMode() {
  64. char buf[1024];
  65. std::string result;
  66. std::string command = root_ + "/bin/zkServer.sh status " +
  67. getConfigFileName();
  68. FILE* output = popen(command.c_str(), "r");
  69. do {
  70. if (fgets(buf, 1024, output) != NULL) {
  71. result += buf;
  72. }
  73. } while (!feof(output));
  74. pclose(output);
  75. if (result.find("Mode: leader") != std::string::npos) {
  76. return "leader";
  77. } else if (result.find("Mode: follower") != std::string::npos) {
  78. return "follower";
  79. } else {
  80. printf("%s\n", result.c_str());
  81. assert(!"unknown mode");
  82. }
  83. }
  84. bool ZooKeeperQuorumServer::
  85. isLeader() {
  86. return getMode() == "leader";
  87. }
  88. bool ZooKeeperQuorumServer::
  89. isFollower() {
  90. return getMode() == "follower";
  91. }
  92. void ZooKeeperQuorumServer::
  93. createConfigFile() {
  94. std::string command = "mkdir -p " + root_ + "/build/test/test-cppunit/conf";
  95. assert(system(command.c_str()) == 0);
  96. std::ofstream confFile;
  97. std::stringstream ss;
  98. ss << id_ << ".conf";
  99. std::string fileName = root_ + "/build/test/test-cppunit/conf/" + ss.str();
  100. confFile.open(fileName.c_str());
  101. confFile << "tickTime=2000\n";
  102. confFile << "clientPort=" << getClientPort() << "\n";
  103. confFile << "initLimit=5\n";
  104. confFile << "syncLimit=2\n";
  105. confFile << "dataDir=" << getDataDirectory() << "\n";
  106. for (int i = 0; i < numServers_; i++) {
  107. confFile << getServerString(i) << "\n";
  108. }
  109. confFile.close();
  110. }
  111. std::string ZooKeeperQuorumServer::
  112. getConfigFileName() {
  113. std::stringstream ss;
  114. ss << id_ << ".conf";
  115. return root_ + "/build/test/test-cppunit/conf/" + ss.str();
  116. }
  117. void ZooKeeperQuorumServer::
  118. createDataDirectory() {
  119. std::string dataDirectory = getDataDirectory();
  120. std::string command = "rm -rf " + dataDirectory;
  121. assert(system(command.c_str()) == 0);
  122. command = "mkdir -p " + dataDirectory;
  123. assert(system(command.c_str()) == 0);
  124. std::ofstream myidFile;
  125. std::string fileName = dataDirectory + "/myid";
  126. myidFile.open(fileName.c_str());
  127. myidFile << id_ << "\n";
  128. myidFile.close();
  129. setenv("ZOO_LOG_DIR", dataDirectory.c_str(), true);
  130. }
  131. std::string ZooKeeperQuorumServer::
  132. getServerString() {
  133. return getServerString(id_);
  134. }
  135. std::string ZooKeeperQuorumServer::
  136. getServerString(uint32_t id) {
  137. std::stringstream ss;
  138. ss << "server." << id << "=localhost:" << SERVER_PORT_BASE + id <<
  139. ":" << ELECTION_PORT_BASE + id << ":participant;localhost:" <<
  140. CLIENT_PORT_BASE + id;
  141. return ss.str();
  142. }
  143. std::string ZooKeeperQuorumServer::
  144. getDataDirectory() {
  145. std::stringstream ss;
  146. ss << "data" << id_;
  147. return root_ + "/build/test/test-cppunit/" + ss.str();
  148. }
  149. std::vector<ZooKeeperQuorumServer*> ZooKeeperQuorumServer::
  150. getCluster(uint32_t numServers) {
  151. std::vector<ZooKeeperQuorumServer*> cluster;
  152. for (int i = 0; i < numServers; i++) {
  153. cluster.push_back(new ZooKeeperQuorumServer(i, numServers));
  154. }
  155. return cluster;
  156. }