From eb3b6db63ae548e4b8ffeba5e6e7edb868f27b72 Mon Sep 17 00:00:00 2001 From: JUN Date: Fri, 8 Nov 2024 13:47:27 +0800 Subject: [PATCH] [#5477] improvement(cli): display audit information on Catalog, Schema, Table (#5509) ### What changes were proposed in this pull request? Add the `--audit` option to display audit information on Catalog, Schema, Table ### Why are the changes needed? This change allows users to retrieve additional audit information on Catalog/Schema/Table, providing more insights. Close: #5477 ### Does this PR introduce _any_ user-facing change? Yes, it adds the `--audit` option to `CommandEntities.CATALOG/SCHEMA/TABLE`. ### How was this patch tested? 1. Follow the instructions in the [cli README](https://github.com/apache/gravitino/tree/main/clients/cli) to build the CLI sub-project. 2. Start the Gravitino Playground. To test, use a command like the following: ``` gcli metalake details --metalake metalake_demo --audit gcli catalog details --metalake metalake_demo --name catalog_postgres --audit gcli schema details --metalake metalake_demo --name catalog_postgres.hr --audit gcli table details --metalake metalake_demo --name catalog_postgres.hr.departments --audit ``` Check that the output matches the expected audit information. ![2024-11-08 002032](https://github.com/user-attachments/assets/636e9abf-fdf3-46f0-9e03-d3b485a06de9) --- .../gravitino/cli/GravitinoCommandLine.java | 25 ++++-- .../gravitino/cli/commands/AuditCommand.java | 56 +++++++++++++ .../gravitino/cli/commands/CatalogAudit.java | 69 ++++++++++++++++ ...alakeAuditInfo.java => MetalakeAudit.java} | 17 +--- .../gravitino/cli/commands/SchemaAudit.java | 78 +++++++++++++++++++ .../gravitino/cli/commands/TableAudit.java | 68 ++++++++++++++++ .../gravitino/cli/commands/TableCommand.java | 2 +- docs/cli.md | 25 ++++++ 8 files changed, 320 insertions(+), 20 deletions(-) create mode 100644 clients/cli/src/main/java/org/apache/gravitino/cli/commands/AuditCommand.java create mode 100644 clients/cli/src/main/java/org/apache/gravitino/cli/commands/CatalogAudit.java rename clients/cli/src/main/java/org/apache/gravitino/cli/commands/{MetalakeAuditInfo.java => MetalakeAudit.java} (79%) create mode 100644 clients/cli/src/main/java/org/apache/gravitino/cli/commands/SchemaAudit.java create mode 100644 clients/cli/src/main/java/org/apache/gravitino/cli/commands/TableAudit.java diff --git a/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoCommandLine.java b/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoCommandLine.java index 566ff88e94d..d14ec4755ae 100644 --- a/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoCommandLine.java +++ b/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoCommandLine.java @@ -23,6 +23,7 @@ import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; +import org.apache.gravitino.cli.commands.CatalogAudit; import org.apache.gravitino.cli.commands.CatalogDetails; import org.apache.gravitino.cli.commands.ClientVersion; import org.apache.gravitino.cli.commands.CreateCatalog; @@ -47,16 +48,18 @@ import org.apache.gravitino.cli.commands.ListSchemaProperties; import org.apache.gravitino.cli.commands.ListTables; import org.apache.gravitino.cli.commands.ListUsers; -import org.apache.gravitino.cli.commands.MetalakeAuditInfo; +import org.apache.gravitino.cli.commands.MetalakeAudit; import org.apache.gravitino.cli.commands.MetalakeDetails; import org.apache.gravitino.cli.commands.RemoveCatalogProperty; import org.apache.gravitino.cli.commands.RemoveMetalakeProperty; import org.apache.gravitino.cli.commands.RemoveSchemaProperty; +import org.apache.gravitino.cli.commands.SchemaAudit; import org.apache.gravitino.cli.commands.SchemaDetails; import org.apache.gravitino.cli.commands.ServerVersion; import org.apache.gravitino.cli.commands.SetCatalogProperty; import org.apache.gravitino.cli.commands.SetMetalakeProperty; import org.apache.gravitino.cli.commands.SetSchemaProperty; +import org.apache.gravitino.cli.commands.TableAudit; import org.apache.gravitino.cli.commands.TableDetails; import org.apache.gravitino.cli.commands.UpdateCatalogComment; import org.apache.gravitino.cli.commands.UpdateCatalogName; @@ -177,7 +180,7 @@ private void handleMetalakeCommand() { if (CommandActions.DETAILS.equals(command)) { if (line.hasOption(GravitinoOptions.AUDIT)) { - new MetalakeAuditInfo(url, ignore, metalake).handle(); + new MetalakeAudit(url, ignore, metalake).handle(); } else { new MetalakeDetails(url, ignore, metalake).handle(); } @@ -225,7 +228,11 @@ private void handleCatalogCommand() { String catalog = name.getCatalogName(); if (CommandActions.DETAILS.equals(command)) { - new CatalogDetails(url, ignore, metalake, catalog).handle(); + if (line.hasOption(GravitinoOptions.AUDIT)) { + new CatalogAudit(url, ignore, metalake, catalog).handle(); + } else { + new CatalogDetails(url, ignore, metalake, catalog).handle(); + } } else if (CommandActions.CREATE.equals(command)) { String comment = line.getOptionValue(GravitinoOptions.COMMENT); String provider = line.getOptionValue(GravitinoOptions.PROVIDER); @@ -272,7 +279,11 @@ private void handleSchemaCommand() { String schema = name.getSchemaName(); if (CommandActions.DETAILS.equals(command)) { - new SchemaDetails(url, ignore, metalake, catalog, schema).handle(); + if (line.hasOption(GravitinoOptions.AUDIT)) { + new SchemaAudit(url, ignore, metalake, catalog, schema).handle(); + } else { + new SchemaDetails(url, ignore, metalake, catalog, schema).handle(); + } } else if (CommandActions.CREATE.equals(command)) { String comment = line.getOptionValue(GravitinoOptions.COMMENT); new CreateSchema(url, ignore, metalake, catalog, schema, comment).handle(); @@ -308,7 +319,11 @@ private void handleTableCommand() { String table = name.getTableName(); if (CommandActions.DETAILS.equals(command)) { - new TableDetails(url, ignore, metalake, catalog, schema, table).handle(); + if (line.hasOption(GravitinoOptions.AUDIT)) { + new TableAudit(url, ignore, metalake, catalog, schema, table).handle(); + } else { + new TableDetails(url, ignore, metalake, catalog, schema, table).handle(); + } } else if (CommandActions.CREATE.equals(command)) { // TODO } else if (CommandActions.DELETE.equals(command)) { diff --git a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/AuditCommand.java b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/AuditCommand.java new file mode 100644 index 00000000000..09eee347821 --- /dev/null +++ b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/AuditCommand.java @@ -0,0 +1,56 @@ +/* + * 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. + */ + +package org.apache.gravitino.cli.commands; + +import org.apache.gravitino.Audit; + +public abstract class AuditCommand extends Command { + /** + * @param url The URL of the Gravitino server. + * @param ignoreVersions If true don't check the client/server versions match. + */ + public AuditCommand(String url, boolean ignoreVersions) { + super(url, ignoreVersions); + } + + /* Overridden in parent - do nothing */ + @Override + public void handle() {} + + /** + * Displays audit information for the given audit object. + * + * @param audit from a class that implements the Auditable interface. + */ + public void displayAuditInfo(Audit audit) { + String auditInfo = + "creator,create_time,modified,modified_time" + + System.lineSeparator() + + audit.creator() + + "," + + audit.createTime() + + "," + + audit.lastModifier() + + "," + + audit.lastModifiedTime(); + + System.out.println(auditInfo); + } +} diff --git a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/CatalogAudit.java b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/CatalogAudit.java new file mode 100644 index 00000000000..588d8bf4217 --- /dev/null +++ b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/CatalogAudit.java @@ -0,0 +1,69 @@ +/* + * 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. + */ + +package org.apache.gravitino.cli.commands; + +import org.apache.gravitino.Catalog; +import org.apache.gravitino.cli.ErrorMessages; +import org.apache.gravitino.client.GravitinoClient; +import org.apache.gravitino.exceptions.NoSuchCatalogException; +import org.apache.gravitino.exceptions.NoSuchMetalakeException; + +public class CatalogAudit extends AuditCommand { + + protected final String metalake; + protected final String catalog; + + /** + * Displays the audit information of a catalog. + * + * @param url The URL of the Gravitino server. + * @param ignoreVersions If true don't check the client/server versions match. + * @param metalake The name of the metalake. + * @param catalog The name of the catalog. + */ + public CatalogAudit(String url, boolean ignoreVersions, String metalake, String catalog) { + super(url, ignoreVersions); + this.metalake = metalake; + this.catalog = catalog; + } + + /** Displays the audit information of a specified catalog. */ + @Override + public void handle() { + Catalog result; + + try (GravitinoClient client = buildClient(metalake)) { + result = client.loadCatalog(this.catalog); + } catch (NoSuchMetalakeException err) { + System.err.println(ErrorMessages.UNKNOWN_METALAKE); + return; + } catch (NoSuchCatalogException err) { + System.err.println(ErrorMessages.UNKNOWN_CATALOG); + return; + } catch (Exception exp) { + System.err.println(exp.getMessage()); + return; + } + + if (result != null) { + displayAuditInfo(result.auditInfo()); + } + } +} diff --git a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAudit.java similarity index 79% rename from clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java rename to clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAudit.java index de38078393b..2e4b7c326bd 100644 --- a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java +++ b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAudit.java @@ -25,7 +25,7 @@ import org.apache.gravitino.exceptions.NoSuchMetalakeException; /** Displays the audit information of a metalake. */ -public class MetalakeAuditInfo extends Command { +public class MetalakeAudit extends AuditCommand { protected final String metalake; /** @@ -35,7 +35,7 @@ public class MetalakeAuditInfo extends Command { * @param ignoreVersions If true don't check the client/server versions match. * @param metalake The name of the metalake. */ - public MetalakeAuditInfo(String url, boolean ignoreVersions, String metalake) { + public MetalakeAudit(String url, boolean ignoreVersions, String metalake) { super(url, ignoreVersions); this.metalake = metalake; } @@ -54,17 +54,6 @@ public void handle() { return; } - String auditInfo = - "creator,createTime,lastModifier,lastModifiedTime" - + System.lineSeparator() - + audit.creator() - + "," - + audit.createTime() - + "," - + audit.lastModifier() - + "," - + audit.lastModifiedTime(); - - System.out.println(auditInfo); + displayAuditInfo(audit); } } diff --git a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/SchemaAudit.java b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/SchemaAudit.java new file mode 100644 index 00000000000..b34ab36cfbf --- /dev/null +++ b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/SchemaAudit.java @@ -0,0 +1,78 @@ +/* + * 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. + */ + +package org.apache.gravitino.cli.commands; + +import org.apache.gravitino.Schema; +import org.apache.gravitino.cli.ErrorMessages; +import org.apache.gravitino.client.GravitinoClient; +import org.apache.gravitino.exceptions.NoSuchCatalogException; +import org.apache.gravitino.exceptions.NoSuchMetalakeException; +import org.apache.gravitino.exceptions.NoSuchSchemaException; + +/** Displays the audit information of schema. */ +public class SchemaAudit extends AuditCommand { + + protected final String metalake; + protected final String catalog; + protected final String schema; + + /** + * Displays the audit information of a schema. + * + * @param url The URL of the Gravitino server. + * @param ignoreVersions If true don't check the client/server versions match. + * @param metalake The name of the metalake. + * @param catalog The name of the catalog. + * @param schema The name of the schenma. + */ + public SchemaAudit( + String url, boolean ignoreVersions, String metalake, String catalog, String schema) { + super(url, ignoreVersions); + this.metalake = metalake; + this.catalog = catalog; + this.schema = schema; + } + + /** Displays the audit information of schema. */ + @Override + public void handle() { + Schema result; + + try (GravitinoClient client = buildClient(metalake)) { + result = client.loadCatalog(catalog).asSchemas().loadSchema(this.schema); + } catch (NoSuchMetalakeException err) { + System.err.println(ErrorMessages.UNKNOWN_METALAKE); + return; + } catch (NoSuchCatalogException err) { + System.err.println(ErrorMessages.UNKNOWN_CATALOG); + return; + } catch (NoSuchSchemaException err) { + System.err.println(ErrorMessages.UNKNOWN_SCHEMA); + return; + } catch (Exception exp) { + System.err.println(exp.getMessage()); + return; + } + + if (result != null) { + displayAuditInfo(result.auditInfo()); + } + } +} diff --git a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TableAudit.java b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TableAudit.java new file mode 100644 index 00000000000..8051daf3450 --- /dev/null +++ b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TableAudit.java @@ -0,0 +1,68 @@ +/* + * 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. + */ + +package org.apache.gravitino.cli.commands; + +import org.apache.gravitino.NameIdentifier; +import org.apache.gravitino.rel.Table; + +/** Displays the audit information of a table. */ +public class TableAudit extends TableCommand { + + protected final String schema; + protected final String table; + + /** + * Displays the audit information of a table. + * + * @param url The URL of the Gravitino server. + * @param ignoreVersions If true don't check the client/server versions match. + * @param metalake The name of the metalake. + * @param catalog The name of the catalog. + * @param schema The name of the schenma. + * @param table The name of the table. + */ + public TableAudit( + String url, + boolean ignoreVersions, + String metalake, + String catalog, + String schema, + String table) { + super(url, ignoreVersions, metalake, catalog); + this.schema = schema; + this.table = table; + } + + /** Displays the audit information of a table. */ + @Override + public void handle() { + Table gTable; + + try { + NameIdentifier name = NameIdentifier.of(schema, table); + gTable = tableCatalog().loadTable(name); + } catch (Exception exp) { + System.err.println(exp.getMessage()); + return; + } + + displayAuditInfo(gTable.auditInfo()); + } +} diff --git a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TableCommand.java b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TableCommand.java index a292a2f5b29..f0e89d71ff5 100644 --- a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TableCommand.java +++ b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TableCommand.java @@ -28,7 +28,7 @@ import org.apache.gravitino.rel.TableCatalog; /* Common code for all table commands. */ -public class TableCommand extends Command { +public class TableCommand extends AuditCommand { protected final String metalake; protected final String catalog; diff --git a/docs/cli.md b/docs/cli.md index d54ba2c3379..663a9c6ec66 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -34,6 +34,7 @@ The general structure for running commands with the Gravitino CLI is `gcli entit -h,--help command help information -i,--ignore Ignore client/sever version check -l,--user user name + -a,--audit display audit information -m,--metalake Metalake name -n,--name full entity name (dot separated) -P,--property property name @@ -160,6 +161,12 @@ gcli metalake list gcli metalake details --metalake metalake_demo ``` +#### Show a metalake audit information + +```bash +gcli metalake details --metalake metalake_demo --audit +``` + #### Create a metalake ```bash @@ -216,6 +223,12 @@ gcli catalog list --metalake metalake_demo gcli catalog details --metalake metalake_demo --name catalog_postgres ``` +#### Show a catalog audit information + +```bash +gcli catalog details --metalake metalake_demo --name catalog_postgres --audit +``` + #### Creating a catalog The type of catalog to be created is specified by the `--provider` option. Different catalogs require different properties, for example, a Hive catalog requires a metastore-uri property. @@ -300,6 +313,12 @@ gcli schema list --metalake metalake_demo --name catalog_postgres gcli schema details --metalake metalake_demo --name catalog_postgres.hr ``` +#### Show schema audit information + +```bash +gcli schema details --metalake metalake_demo --name catalog_postgres.hr --audit +``` + #### Create a schema ```bash @@ -328,6 +347,12 @@ gcli table list --metalake metalake_demo --name catalog_postgres.hr gcli column list --metalake metalake_demo --name catalog_postgres.hr.departments ``` +#### Show tables audit information + +```bash +gcli table details --metalake metalake_demo --name catalog_postgres.hr.departments --audit +``` + #### Delete a table ```bash