tkhurana commented on code in PR #2397:
URL: https://github.com/apache/phoenix/pull/2397#discussion_r3060912497
##########
phoenix-core-client/src/main/java/org/apache/phoenix/jdbc/PhoenixHAAdminTool.java:
##########
@@ -780,6 +817,168 @@ private int executeGetClusterRoleRecord(String[] args)
throws Exception {
}
}
+ /**
+ * Creates a new HA group entry in SYSTEM.HA_GROUP. Idempotent: if the group
already exists,
+ * prints a skip message and returns success without modifying the existing
row. The ZK znode is
+ * initialized automatically on first access by HAGroupStoreClient. Run the
same command on both
+ * clusters.
+ */
+ private int executeCreate(String[] args) throws Exception {
+ try {
+ CommandLine cmdLine = new DefaultParser().parse(createCreateOptions(),
args);
+
+ if (cmdLine.hasOption(HELP_OPT.getOpt())) {
+ printCreateHelp();
+ return RET_SUCCESS;
+ }
+
+ String haGroupName = getRequiredOption(cmdLine, HA_GROUP_OPT, "HA group
name");
+ String policy = getRequiredOption(cmdLine, POLICY_OPT, "policy");
+ String zkUrl1 = getRequiredOption(cmdLine, ZK_URL_1_OPT, "ZK URL for
cluster 1");
+ String clusterUrl1 =
+ getRequiredOption(cmdLine, CLUSTER_URL_1_OPT, "cluster URL for cluster
1");
+ String clusterRole1Str =
+ getRequiredOption(cmdLine, CLUSTER_ROLE_1_OPT, "cluster role for
cluster 1");
+ String zkUrl2 = getRequiredOption(cmdLine, ZK_URL_2_OPT, "ZK URL for
cluster 2");
+ String clusterUrl2 =
+ getRequiredOption(cmdLine, CLUSTER_URL_2_OPT, "cluster URL for cluster
2");
+ String clusterRole2Str =
+ getRequiredOption(cmdLine, CLUSTER_ROLE_2_OPT, "cluster role for
cluster 2");
+
+ String hdfsUrl1 = getRequiredOption(cmdLine, HDFS_URL_1_OPT, "HDFS URL
for cluster 1");
+ String hdfsUrl2 = getRequiredOption(cmdLine, HDFS_URL_2_OPT, "HDFS URL
for cluster 2");
+ final boolean dryRun = cmdLine.hasOption(DRY_RUN_OPT.getOpt());
+
+ long adminVersion = 1L;
+ String adminVersionStr =
cmdLine.getOptionValue(ADMIN_VERSION_OPT.getOpt());
+ if (adminVersionStr != null) {
+ adminVersion = Long.parseLong(adminVersionStr);
+ }
+
+ ClusterRole clusterRole1 = parseClusterRole(clusterRole1Str);
+ ClusterRole clusterRole2 = parseClusterRole(clusterRole2Str);
+
+ String localZkUrl = getLocalZkUrl(getConf());
+
+ if (haGroupExistsInSystemTable(haGroupName, localZkUrl)) {
+ System.out.println("HA group '" + haGroupName
+ + "' already exists in SYSTEM.HA_GROUP. Skipping creation. Use
update command to modify it.");
+ return RET_SUCCESS;
+ }
+
+ System.out.println("\n=== HA Group to Create ===\n");
+ System.out.println(String.format(" %-25s: %s", "HA Group Name",
haGroupName));
+ System.out.println(String.format(" %-25s: %s", "Policy", policy));
+ System.out.println(String.format(" %-25s: %s", "ZK URL 1", zkUrl1));
+ System.out.println(String.format(" %-25s: %s", "Cluster URL 1",
clusterUrl1));
+ System.out.println(String.format(" %-25s: %s", "Cluster Role 1",
clusterRole1));
+ System.out.println(String.format(" %-25s: %s", "ZK URL 2", zkUrl2));
+ System.out.println(String.format(" %-25s: %s", "Cluster URL 2",
clusterUrl2));
+ System.out.println(String.format(" %-25s: %s", "Cluster Role 2",
clusterRole2));
+ System.out.println(String.format(" %-25s: %s", "HDFS URL 1", hdfsUrl1));
+ System.out.println(String.format(" %-25s: %s", "HDFS URL 2", hdfsUrl2));
+ System.out.println(String.format(" %-25s: %d", "Admin Version",
adminVersion));
+ System.out.println();
+
+ if (dryRun) {
+ System.out.println("\n\u2713 Dry-run completed. No changes were
applied.");
+ return RET_SUCCESS;
+ }
+
+ insertIntoSystemTable(haGroupName, policy, zkUrl1, clusterUrl1,
clusterRole1, hdfsUrl1,
+ zkUrl2, clusterUrl2, clusterRole2, hdfsUrl2, adminVersion, localZkUrl);
+
+ System.out.println(" \u2713 SYSTEM.HA_GROUP entry created.");
+
+ HAGroupStoreManager manager = HAGroupStoreManager.getInstance(getConf());
+ Optional<HAGroupStoreRecord> record =
manager.getHAGroupStoreRecord(haGroupName);
+ if (record.isPresent()) {
+ System.out
+ .println(" \u2713 Znode initialized (state: " +
record.get().getHAGroupState() + ").");
+ } else {
+ System.err.println(
+ " \u26a0 Znode initialization returned empty record for '" +
haGroupName + "'.");
+ }
+
+ System.out.println("\n\u2713 HA group '" + haGroupName + "' created
successfully.");
+ return RET_SUCCESS;
+
+ } catch (IllegalArgumentException e) {
+ System.err.println("\n\u2717 Invalid argument: " + e.getMessage());
+ return RET_ARGUMENT_ERROR;
+ } catch (Exception e) {
+ System.err.println("\n\u2717 Create failed: " + e.getMessage());
+ LOG.error("Create command failed", e);
+ return RET_UPDATE_ERROR;
+ }
+ }
+
+ /**
+ * Check if an HA group entry already exists in SYSTEM.HA_GROUP.
+ */
+ private boolean haGroupExistsInSystemTable(String haGroupName, String
localZkUrl)
+ throws SQLException {
+ String query =
+ "SELECT COUNT(*) FROM " + SYSTEM_HA_GROUP_NAME + " WHERE " +
HA_GROUP_NAME + " = ?";
+ try (
+ PhoenixConnection conn = (PhoenixConnection) DriverManager
+ .getConnection(JDBC_PROTOCOL_ZK + JDBC_PROTOCOL_SEPARATOR +
localZkUrl);
+ PreparedStatement pstmt = conn.prepareStatement(query)) {
+ pstmt.setString(1, haGroupName);
+ try (ResultSet rs = pstmt.executeQuery()) {
+ if (rs.next()) {
+ return rs.getLong(1) > 0;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Insert a new HA group row into SYSTEM.HA_GROUP using symmetric slot-based
columns.
+ */
+ private void insertIntoSystemTable(String haGroupName, String policy, String
zkUrl1,
+ String clusterUrl1, ClusterRole clusterRole1, String hdfsUrl1, String
zkUrl2,
+ String clusterUrl2, ClusterRole clusterRole2, String hdfsUrl2, long
adminVersion,
+ String localZkUrl) throws SQLException {
+
+ String insertQuery = "UPSERT INTO " + SYSTEM_HA_GROUP_NAME + " (" +
HA_GROUP_NAME + ", "
+ + POLICY + ", " + ZK_URL_1 + ", " + CLUSTER_URL_1 + ", " +
CLUSTER_ROLE_1 + ", " + HDFS_URL_1
+ + ", " + ZK_URL_2 + ", " + CLUSTER_URL_2 + ", " + CLUSTER_ROLE_2 + ", "
+ HDFS_URL_2 + ", "
+ + VERSION + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ try (
+ PhoenixConnection conn = (PhoenixConnection) DriverManager
+ .getConnection(JDBC_PROTOCOL_ZK + JDBC_PROTOCOL_SEPARATOR +
localZkUrl);
Review Comment:
Same as above
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]