You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by jf...@apache.org on 2018/11/16 19:21:17 UTC
[incubator-pinot] 01/01: Add table config backup tool
This is an automated email from the ASF dual-hosted git repository.
jfim pushed a commit to branch add-config-backup-tool
in repository https://gitbox.apache.org/repos/asf/incubator-pinot.git
commit 5c75eff367043f8db0811e3138dd2d86b8dfc049
Author: Jean-Francois Im <je...@gmail.com>
AuthorDate: Mon Oct 1 09:58:36 2018 -0700
Add table config backup tool
Add a tool that allows saving table configurations to disk using the new
configuration format.
---
.../helix/ControllerRequestURLBuilder.java | 4 +
.../pinot/tools/admin/PinotAdministrator.java | 4 +-
.../admin/command/BackupTableConfigsCommand.java | 125 +++++++++++++++++++++
3 files changed, 132 insertions(+), 1 deletion(-)
diff --git a/pinot-controller/src/main/java/com/linkedin/pinot/controller/helix/ControllerRequestURLBuilder.java b/pinot-controller/src/main/java/com/linkedin/pinot/controller/helix/ControllerRequestURLBuilder.java
index 9a79cc3..cfb4a84 100644
--- a/pinot-controller/src/main/java/com/linkedin/pinot/controller/helix/ControllerRequestURLBuilder.java
+++ b/pinot-controller/src/main/java/com/linkedin/pinot/controller/helix/ControllerRequestURLBuilder.java
@@ -76,6 +76,10 @@ public class ControllerRequestURLBuilder {
return StringUtil.join("/", StringUtils.chomp(_baseUrl, "/"), "instances");
}
+ public String forTableList() {
+ return StringUtil.join("/", StringUtils.chomp(_baseUrl, "/"), "tables");
+ }
+
public String forTablesFromTenant(String tenantName) {
return StringUtil.join("/", StringUtils.chomp(_baseUrl, "/"), TENANTS, tenantName, TABLES);
}
diff --git a/pinot-tools/src/main/java/com/linkedin/pinot/tools/admin/PinotAdministrator.java b/pinot-tools/src/main/java/com/linkedin/pinot/tools/admin/PinotAdministrator.java
index ac5054a..9a6bbeb 100644
--- a/pinot-tools/src/main/java/com/linkedin/pinot/tools/admin/PinotAdministrator.java
+++ b/pinot-tools/src/main/java/com/linkedin/pinot/tools/admin/PinotAdministrator.java
@@ -16,6 +16,7 @@
package com.linkedin.pinot.tools.admin;
import com.linkedin.pinot.tools.admin.command.ApplyTableConfigCommand;
+import com.linkedin.pinot.tools.admin.command.BackupTableConfigsCommand;
import com.linkedin.pinot.tools.admin.command.MoveReplicaGroup;
import com.linkedin.pinot.tools.admin.command.RealtimeProvisioningHelperCommand;
@@ -96,7 +97,8 @@ public class PinotAdministrator {
@SubCommand(name = "BackfillSegmentColumn", impl = BackfillDateTimeColumnCommand.class),
@SubCommand(name = "VerifyClusterState", impl = VerifyClusterStateCommand.class),
@SubCommand(name = "ApplyTableConfig", impl = ApplyTableConfigCommand.class),
- @SubCommand(name = "RealtimeProvisioningHelper", impl = RealtimeProvisioningHelperCommand.class)
+ @SubCommand(name = "RealtimeProvisioningHelper", impl = RealtimeProvisioningHelperCommand.class),
+ @SubCommand(name = "BackupTableConfigs", impl = BackupTableConfigsCommand.class)
})
Command _subCommand;
// @formatter:on
diff --git a/pinot-tools/src/main/java/com/linkedin/pinot/tools/admin/command/BackupTableConfigsCommand.java b/pinot-tools/src/main/java/com/linkedin/pinot/tools/admin/command/BackupTableConfigsCommand.java
new file mode 100644
index 0000000..182aed5
--- /dev/null
+++ b/pinot-tools/src/main/java/com/linkedin/pinot/tools/admin/command/BackupTableConfigsCommand.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright (C) 2014-2016 LinkedIn Corp. (pinot-core@linkedin.com)
+ *
+ * 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.
+ */
+
+package com.linkedin.pinot.tools.admin.command;
+
+import com.google.common.base.Charsets;
+import com.linkedin.pinot.controller.helix.ControllerRequestURLBuilder;
+import com.linkedin.pinot.tools.Command;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.HttpClients;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.kohsuke.args4j.Option;
+
+
+/**
+ * Command to back up table configurations.
+ */
+public class BackupTableConfigsCommand extends AbstractBaseAdminCommand implements Command {
+ @Option(name = "-controllerUrl", required = true, metaVar = "<String>", usage = "Controller URL")
+ private String _controllerUrl;
+
+ @Option(name = "-tableName", required = false, usage = "Table name to back up. Optional, if not specified, defaults to backing up all tables")
+ private String _tableName = null;
+
+ @Option(name = "-outputDir", required = false, usage = "Directory in which table configs are placed. Optional, defaults to the current working directory. Directory is created if it does not exist.")
+ private String _outputDir = ".";
+
+ @Option(name = "-help", required = false, help = true, aliases = { "-h", "--h", "--help" },
+ usage = "Print this message.")
+ private boolean _help = false;
+
+ @Override
+ public boolean execute() throws Exception {
+ // Create the output directory if it does not exist
+ File outputDirectory = new File(_outputDir);
+ if (!outputDirectory.exists()) {
+ outputDirectory.mkdirs();
+ }
+
+ // Populate the list of tables to fetch, if applicable
+ ControllerRequestURLBuilder requestURLBuilder = ControllerRequestURLBuilder.baseUrl(_controllerUrl);
+ HttpClient client = HttpClients.createDefault();
+ List<String> tablesToFetch;
+ if (_tableName != null) {
+ tablesToFetch = Collections.singletonList(_tableName);
+ } else {
+ HttpResponse response = client.execute(new HttpGet(requestURLBuilder.forTableList()));
+ int statusCode = response.getStatusLine().getStatusCode();
+ String responseEntity = IOUtils.toString(response.getEntity().getContent());
+ if (statusCode / 100 == 2) {
+ JSONArray tableNameArray = new JSONObject(responseEntity).getJSONArray("tables");
+ tablesToFetch = new ArrayList<>(tableNameArray.length());
+ for (int i = 0; i < tableNameArray.length(); i++) {
+ tablesToFetch.add(tableNameArray.getString(i));
+ }
+ } else {
+ throw new RuntimeException("Failed to fetch the table list, got HTTP status " + statusCode + ": " + responseEntity);
+ }
+ }
+
+ System.out.println("Will fetch " + tablesToFetch.size() + " table(s)");
+
+ boolean allTablesSuccessful = true;
+ for (String tableName : tablesToFetch) {
+ HttpResponse response = client.execute(new HttpGet(requestURLBuilder.forNewUpdateTableConfig(tableName)));
+ int statusCode = response.getStatusLine().getStatusCode();
+ String responseEntity = IOUtils.toString(response.getEntity().getContent());
+ if (statusCode / 100 == 2) {
+ try {
+ File outputFile = new File(outputDirectory, tableName + ".conf");
+ FileUtils.writeStringToFile(outputFile, responseEntity, Charsets.UTF_8);
+ System.out.println("Saved table configuration for table " + tableName);
+ } catch (IOException e) {
+ System.out.println("Failed to write table configuration for table " + tableName + ", got exception.");
+ e.printStackTrace();
+ allTablesSuccessful = false;
+ }
+ } else {
+ System.out.println("Failed to fetch table configuration for table " + tableName + ", got HTTP status " + statusCode + ": " + responseEntity);
+ allTablesSuccessful = false;
+ }
+ }
+
+ if (allTablesSuccessful) {
+ System.out.println("Successfully backed up " + tablesToFetch.size() + " tables");
+ } else {
+ System.out.println("Some tables failed to back up, see messages above for details.");
+ }
+
+ return allTablesSuccessful;
+ }
+
+ @Override
+ public String description() {
+ return "Backs up table configurations.";
+ }
+
+ @Override
+ public boolean getHelp() {
+ return _help;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org