<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alex Yan</title>
    <description>The latest articles on DEV Community by Alex Yan (@alex_yan_163de34c186edd87).</description>
    <link>https://dev.to/alex_yan_163de34c186edd87</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3420051%2F40d2a76d-43fb-4631-8c77-14230b6fe231.png</url>
      <title>DEV Community: Alex Yan</title>
      <link>https://dev.to/alex_yan_163de34c186edd87</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alex_yan_163de34c186edd87"/>
    <language>en</language>
    <item>
      <title>Apache Gravitino 1.0.0 — From Metadata Management to Contextual Engineering</title>
      <dc:creator>Alex Yan</dc:creator>
      <pubDate>Sun, 05 Oct 2025 05:40:44 +0000</pubDate>
      <link>https://dev.to/datastrato/apache-gravitino-100-from-metadata-management-to-contextual-engineering-47kb</link>
      <guid>https://dev.to/datastrato/apache-gravitino-100-from-metadata-management-to-contextual-engineering-47kb</guid>
      <description>&lt;p&gt;Apache Gravitino was designed from day one to provide a unified framework for metadata management across heterogeneous sources, regions, and clouds—what we define as the metadata lake (or metalake). Throughout its evolution, Gravitino has extended support to multiple data modalities, including tabular metadata from Apache Hive, Apache Iceberg, MySQL, and PostgreSQL; unstructured assets from HDFS and S3; streaming and messaging metadata from Apache Kafka; and metadata for machine learning models. To further strengthen governance in Gravitino, we have also integrated advanced capabilities, including tagging, audit logging, and end-to-end lineage capture.&lt;/p&gt;

&lt;p&gt;After all enterprise metadata has been centralized through Gravitino, it forms a data brain: a structured, queryable, and semantically enriched representation of data assets. This enables not only consistent metadata access but also knowledge grounding, contextual reasoning, tool using and others. As we approach the 1.0 milestone, our focus shifts from pure metadata storage to metadata-driven contextual engineering—a foundation we call the Metadata-driven Action System, to provide the building blocks for the contextual engineering.&lt;/p&gt;

&lt;p&gt;The release of Apache Gravitino 1.0.0 marks a significant engineering step forward, with robust APIs, extensible connectors, enhanced governance primitives, improved scalability and reliability in distributed environments. In the following sections, I will dive into the new features and architectural improvements introduced in Gravitino 1.0.0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Metadata-driven action system
&lt;/h2&gt;

&lt;p&gt;In version 1.0.0, we introduced three new components that enable us to build jobs to accomplish metadata-driven actions, such as table compaction, TTL data management, and PII identification. These three new components are: the statistics system, the policy system, and the job system.&lt;/p&gt;

&lt;p&gt;Taking table compaction as an example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firstly, users can define the table compaction policy in Gravitino and associate this policy with the tables that need to be compacted.&lt;/li&gt;
&lt;li&gt;Then, users can save the statistics of the table to Gravitino.&lt;/li&gt;
&lt;li&gt;Also, users can define a job template for the compaction.&lt;/li&gt;
&lt;li&gt;Lastly, users can use the statistics with the defined policy to generate the compaction parameters and use these parameters to trigger a compaction job based on the defined job templates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Statistics system
&lt;/h3&gt;

&lt;p&gt;The statistics system is a new component for the statistics store and retrieval. You can define and store the table/partition level statistics in Gravitino, and also fetch them through Gravitino for different purposes.&lt;/p&gt;

&lt;p&gt;For the details of how we design this component, please see &lt;a href="https://github.com/apache/gravitino/issues/7268" rel="noopener noreferrer"&gt;#7268&lt;/a&gt;. For instructions on using the statistics system, refer to the documentation &lt;a href="https://gravitino.apache.org/docs/1.0.0/manage-statistics-in-gravitino/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Policy system
&lt;/h3&gt;

&lt;p&gt;The policy system enables you to define action rules in Gravitino, like compaction rules or TTL rules. The defined policy can be associated with the metadata, which means these rules will be enforced on the dedicated metadata. Users can leverage these enforced polices to decide how to trigger an action on the dedicated metadata.&lt;/p&gt;

&lt;p&gt;Please refer to the policy system &lt;a href="https://gravitino.apache.org/docs/1.0.0/manage-policies-in-gravitino" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; to know how to use it. For more information on the policy system's implementation details, please refer to &lt;a href="https://github.com/apache/gravitino/issues/7139" rel="noopener noreferrer"&gt;#7139&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Job system
&lt;/h3&gt;

&lt;p&gt;The job system is another feature that allows you to submit and run jobs through Gravitino. Users can register a job template, then trigger a job based on the specific job template. Gravitino will help submit the job to the dedicated job executor, such as Apache Airflow. Gravitino can manage the job lifecycle and save the job status in it. With the job system, users can run a self-defined job to accomplish a metadata-driven action system.&lt;/p&gt;

&lt;p&gt;In version 1.0.0, we have an initial version to support running the jobs as a local process. If you want to know more about the design details, you can follow issue &lt;a href="https://github.com/apache/gravitino/issues/7154" rel="noopener noreferrer"&gt;#7154&lt;/a&gt;. Also, a user-facing documentation can be found &lt;a href="https://gravitino.apache.org/docs/1.0.0/manage-jobs-in-gravitino" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The whole metadata-driven action system is still in an alpha phase for version 1.0.0. The community will continue to evolve the code and take the Iceberg table maintenance as a reference implementation in the next version. Please stay tuned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent-ready through the MCP server
&lt;/h2&gt;

&lt;p&gt;MCP is a powerful protocol to bridge the gap between human languages and machine interfaces. With MCP, users can communicate with the LLM using natural language, and the LLM can understand the context and invoke the appropriate tools.&lt;/p&gt;

&lt;p&gt;In version 1.0.0, the community officially delivered the MCP server for Gravitino. Users can launch it as a remote or local MCP server and connect to various MCP applications, such as Cursor and Claude Desktop. Additionally, we exposed all metadata-related interfaces as tools that MCP clients can call.&lt;/p&gt;

&lt;p&gt;With the Gravitino MCP server, users can manage and govern metadata, as well as perform metadata-driven actions using natural language. Please follow issue &lt;a href="https://github.com/apache/gravitino/issues/7483" rel="noopener noreferrer"&gt;#7483&lt;/a&gt; for more details. Additionally, you can refer to the &lt;a href="https://gravitino.apache.org/docs/1.0.0/gravitino-mcp-server" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for instructions on how to start the MCP server locally or in Docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unified access control framework
&lt;/h2&gt;

&lt;p&gt;Gravitino introduced the RBAC system in the previous version, but it only offers users the ability to grant privileges to roles and users, without enforcing access control when manipulating the secure objects. In 1.0.0, we complete this missing piece in Gravitino.&lt;/p&gt;

&lt;p&gt;Currently, users can set access control policies through our RBAC system and enforce these controls when accessing secure objects. For details, you can refer to the umbrella issue &lt;a href="https://github.com/apache/gravitino/issues/6762" rel="noopener noreferrer"&gt;#6762&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add support for multiple locations model management
&lt;/h2&gt;

&lt;p&gt;The model management is introduced in Gravitino 0.9.0. Users have since requested support for multiple storage locations within a single model version, allowing them to select a model version with a preferred location.&lt;/p&gt;

&lt;p&gt;In 1.0.0, the community added multiple locations for model management. This feature is similar to the fileset’s support for multiple locations. Users can check the document &lt;a href="https://gravitino.apache.org/docs/1.0.0/manage-model-metadata-using-gravitino" rel="noopener noreferrer"&gt;here&lt;/a&gt; for more information. For more information on implementation details, please refer to this issue &lt;a href="https://github.com/apache/gravitino/issues/7363" rel="noopener noreferrer"&gt;#7363&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Support the latest Apache Iceberg and Paimon versions
&lt;/h2&gt;

&lt;p&gt;In Gravitino 1.0.0, we have upgraded the supported Iceberg version to 1.9.0. With the new version, we will add more feature support in the next release. Additionally, we have upgraded the supported Paimon version to 1.2.0, introducing new features for Paimon support.&lt;/p&gt;

&lt;p&gt;You can see the issue &lt;a href="https://github.com/apache/gravitino/issues/6719" rel="noopener noreferrer"&gt;#6719&lt;/a&gt; for Iceberg upgrading and issue &lt;a href="https://github.com/apache/gravitino/issues/8163" rel="noopener noreferrer"&gt;#8163&lt;/a&gt; for Paimon upgrading.&lt;/p&gt;

&lt;h2&gt;
  
  
  Various core features
&lt;/h2&gt;

&lt;p&gt;Core:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the cache system in the Gravitino entity store &lt;a href="https://github.com/apache/gravitino/issues/7175" rel="noopener noreferrer"&gt;#7175&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Add Marquez integration as a lineage sink in Gravitino &lt;a href="https://github.com/apache/gravitino/issues/7396" rel="noopener noreferrer"&gt;#7396&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add Azure AD login support for OAuth authentication &lt;a href="https://github.com/apache/gravitino/issues/7538" rel="noopener noreferrer"&gt;#7538&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Catalogs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support StarRocks catalog management in Gravitino &lt;a href="https://github.com/apache/gravitino/issues/3302" rel="noopener noreferrer"&gt;#3302&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clients:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adds the custom configurations for clients &lt;a href="https://github.com/apache/gravitino/issues/7816" rel="noopener noreferrer"&gt;#7816&lt;/a&gt;, &lt;a href="https://github.com/apache/gravitino/issues/7817" rel="noopener noreferrer"&gt;#7817&lt;/a&gt;, &lt;a href="https://github.com/apache/gravitino/issues/7670" rel="noopener noreferrer"&gt;#7670&lt;/a&gt;, &lt;a href="https://github.com/apache/gravitino/issues/7456" rel="noopener noreferrer"&gt;#7456&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Spark connector:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upgrade the supported Kyubbi version &lt;a href="https://github.com/apache/gravitino/issues/7480" rel="noopener noreferrer"&gt;#7480&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;UI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add web UI for listing files / directories under a fileset &lt;a href="https://github.com/apache/gravitino/issues/7477" rel="noopener noreferrer"&gt;#7477&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add hem char deployment for Iceberg REST catalog &lt;a href="https://github.com/apache/gravitino/issues/7159" rel="noopener noreferrer"&gt;#7159&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Behavior changes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Compatible changes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Rename the Hadoop catalog to fileset catalog &lt;a href="https://github.com/apache/gravitino/issues/7184" rel="noopener noreferrer"&gt;#7184&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Allowing event listener changes Iceberg create table request &lt;a href="https://github.com/apache/gravitino/issues/6486" rel="noopener noreferrer"&gt;#6486&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Support returning aliases when listing model version &lt;a href="https://github.com/apache/gravitino/issues/7307" rel="noopener noreferrer"&gt;#7307&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Breaking changes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Change the supported Java version to JDK 17 for the Gravitino server.&lt;/li&gt;
&lt;li&gt;Remove the Python 3.8 support for the Gravitino Python client &lt;a href="https://github.com/apache/gravitino/issues/7491" rel="noopener noreferrer"&gt;#7491&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Fix the unnecessary double encoding and decoding issue for fileset get location and list files interfaces &lt;a href="https://github.com/apache/gravitino/issues/8335" rel="noopener noreferrer"&gt;#8335&lt;/a&gt;. This change is incompatible with the old version of Java and Python clients. Using old version clients with a new version server will meet a decoding issue in some unexpected scenarios.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Overall
&lt;/h2&gt;

&lt;p&gt;There are still lots of features, improvements, and bug fixes that are not mentioned here. We thank the community for their continued support and valuable contributions.&lt;/p&gt;

&lt;p&gt;Apache Gravitino 1.0.0 opens a new chapter from the data catalog to the smart catalog. We will continue to innovate and build, to add more Data and AI features. Please stay tuned!&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;This release acknowledges the hard work and dedication of all contributors who have helped make this release possible.&lt;/p&gt;

&lt;p&gt;&lt;a href="mailto:1161623489@qq.com"&gt;1161623489@qq.com&lt;/a&gt;, Aamir, Aaryan Kumar Sinha, Ajax, Akshat Tiwari, Akshat kumar gupta, Aman Chandra Kumar, AndreVale69, Ashwil-Colaco, BIN, Ben Coke, Bharath Krishna, Brijesh Thummar, Bryan Maloyer, Cyber Star, Danhua Wang, Daniel, Daniele Carpentiero, Dentalkart399, Drinkaiii, Edie, Eric Chang, FANNG, Gagan B Mishra, George T. C. Lai, Guilherme Santos, Hatim Kagalwala, Jackeyzhe, Jarvis, JeonDaehong, Jerry Shao, Jimmy Lee, Joonha, Joonseo Lee, Joseph C., Justin Mclean, KWON TAE HEON, Kang, KeeProMise, Khawaja Abdullah Ansar, Kwon Taeheon, Kyle Lin, KyleLin0927, Lord of Abyss, MaAng, Mathieu Baurin, Maxspace1024, Mikshakecere, Mini Yu, Minji Kim, Minji Ryu, Nithish Kumar S, Pacman, Peidian li, Praveen, Qian Xia, Qiang-Liu, Qiming Teng, Raj Gupta, Ratnesh Rastogi, Raveendra Pujari, Reuben George, RickyMa, Rory, Sambhavi Pandey, Sébastien Brochet, Shaofeng Shi, Spiritedswordsman, Sua Bae, Surya B, Tarun, Tian Lu, Tianhang, Timur, Viral Kachhadiya, Will Guo, XiaoZ, Xiaojian Sun, Xun, Yftach Zur, Yuhui, Yujiang Zhong, Yunchi Pang, Zhengke Zhou, _.mung, ankamde, arjun, danielyyang, dependabot[bot], fad, fanng, gavin.wang, guow34, jackeyzhe, kaghatim, keepConcentration, kerenpas, kitoha, lipeidian, liuxian, liuxian131, lsyulong, mchades, mingdaoy, predator4ann, qbhan, raveendra11, roryqi, senlizishi, slimtom95, taylor.fan, taylor12805, teo, tian bao, vishnu, yangyang zhong, youngseojeon, yuhui, yunchi, yuqi, zacsun, zhanghan, zhanghan18, 梁自强, 박용현, 배수아, 신동재, 이승주, 이준하&lt;/p&gt;

&lt;p&gt;Apache, Apache Fink, Apache Hive, Apache Hudi, Apache Iceberg, Apache Ranger, Apache Spark, Apache Paimon and Apache Gravitino are either registered trademarks or trademarks of the Apache Software Foundation in the United States and/or other countries.&lt;/p&gt;

</description>
      <category>dataengineering</category>
      <category>opensource</category>
      <category>cloud</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Doris x Gravitino: Unified Metadata Management for Modern Lakehouse Architecture</title>
      <dc:creator>Alex Yan</dc:creator>
      <pubDate>Sun, 28 Sep 2025 21:54:13 +0000</pubDate>
      <link>https://dev.to/datastrato/doris-x-gravitino-unified-metadata-management-for-modern-lakehouse-architecture-1ca8</link>
      <guid>https://dev.to/datastrato/doris-x-gravitino-unified-metadata-management-for-modern-lakehouse-architecture-1ca8</guid>
      <description>&lt;p&gt;With the rapid evolution of data lake technologies, building unified, secure, and efficient lakehouse architectures has become a core challenge for enterprise digital transformation. &lt;a href="https://gravitino.apache.org/" rel="noopener noreferrer"&gt;Apache Gravitino&lt;/a&gt; serves as a next-generation unified metadata management platform, providing comprehensive solutions for data governance in multi-cloud and multi-engine environments. It not only supports unified management of various data sources and compute engines but also ensures secure and controllable data access through its credential management mechanism (Credential Vending).&lt;/p&gt;

&lt;p&gt;This article provides an in-depth introduction to deep integration between &lt;a href="https://doris.apache.org/" rel="noopener noreferrer"&gt;Apache Doris&lt;/a&gt; and Apache Gravitino, building a modern lakehouse architecture based on Iceberg REST Catalog. Through Gravitino's unified metadata management and dynamic credential vending capabilities, we achieve efficient and secure access to Iceberg data stored on S3.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you'll learn from this guide:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS Environment Setup&lt;/strong&gt;: How to create S3 buckets and IAM roles in AWS, configure secure credential management systems for Gravitino, and implement dynamic temporary credential distribution mechanisms.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gravitino Deployment and Configuration&lt;/strong&gt;: How to quickly deploy Gravitino services, configure Iceberg REST Catalog, and enable vended-credentials functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Connecting Doris to Gravitino&lt;/strong&gt;: Detailed explanation of how Doris accesses Iceberg data through Gravitino's REST API, supporting two core storage access modes:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Static Credential Mode: Doris uses fixed AK/SK to directly access S3
2. Dynamic Credential Mode: Gravitino dynamically distributes temporary credentials to Doris via STS AssumeRole
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  About Apache Doris
&lt;/h2&gt;

&lt;p&gt;Apache Doris is the fastest analytical and search database for the AI era.&lt;/p&gt;

&lt;p&gt;It provides high-performance hybrid search capabilities across structured data, semi-structured data (such as JSON), and vector data. It excels at delivering high-concurrency, low-latency queries, while also offering advanced optimization for complex join operations. In addition, Doris can serve as a unified query engine, delivering high-performance analytical services not only on its self-managed internal table format but also on open lakehouse formats such as Iceberg.&lt;/p&gt;

&lt;p&gt;With Doris, users can easily build a real-time lakehouse data platform.&lt;/p&gt;
&lt;h2&gt;
  
  
  About Apache Gravitino
&lt;/h2&gt;

&lt;p&gt;Apache Gravitino is a high-performance, distributed federated metadata lake open-source project designed to manage metadata across different regions and data sources in public and private clouds. It supports various types of data catalogs including Apache Hive, Apache Iceberg, Apache Paimon, Apache Doris, MySQL, PostgreSQL, Fileset (HDFS, S3, GCS, OSS, JuiceFS, etc.), Streaming (Apache Kafka), Models, and more (continuously expanding), providing users with unified metadata access for Data and AI assets.&lt;/p&gt;
&lt;h2&gt;
  
  
  Hands-on Guide
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. AWS Environment Setup
&lt;/h3&gt;

&lt;p&gt;Before we begin, we need to prepare a complete infrastructure on AWS, including S3 buckets and a carefully designed IAM role system, which forms the foundation for building a secure and reliable lakehouse architecture.&lt;/p&gt;
&lt;h4&gt;
  
  
  1.1 Create S3 Bucket
&lt;/h4&gt;

&lt;p&gt;First, create a dedicated S3 bucket to store Iceberg data:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create S3 bucket&lt;/span&gt;
aws s3 mb s3://gravitino-iceberg-demo &lt;span class="nt"&gt;--region&lt;/span&gt; us-west-2
&lt;span class="c"&gt;# Verify bucket creation&lt;/span&gt;
aws s3 &lt;span class="nb"&gt;ls&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;gravitino-iceberg-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  1.2 Design IAM Role Architecture
&lt;/h4&gt;

&lt;p&gt;To implement secure credential management, we need to create an IAM role for Gravitino to use through the STS AssumeRole mechanism. This design follows the principles of least privilege and separation of duties security best practices.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create Data Access Role&lt;/p&gt;

&lt;p&gt;Create trust policy file gravitino-trust-policy.json:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"AWS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::YOUR_ACCOUNT_ID:root"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create IAM Role&lt;/p&gt;

&lt;p&gt;For demonstration simplicity, we'll use AWS managed policies directly. For production environments, we recommend creating more fine-grained permission controls.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create IAM role&lt;/span&gt;
aws iam create-role &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--role-name&lt;/span&gt; gravitino-iceberg-access &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--assume-role-policy-document&lt;/span&gt; file://gravitino-trust-policy.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"Gravitino Iceberg data access role"&lt;/span&gt;

&lt;span class="c"&gt;# Attach S3 full access permissions (for testing; use fine-grained permissions in production)&lt;/span&gt;
aws iam attach-role-policy &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--role-name&lt;/span&gt; gravitino-iceberg-access &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--policy-arn&lt;/span&gt; arn:aws:iam::aws:policy/AmazonS3FullAccess
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify IAM Configuration&lt;/p&gt;

&lt;p&gt;Verify that the role configuration is correct:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test role assumption functionality&lt;/span&gt;
aws sts assume-role &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--role-arn&lt;/span&gt; arn:aws:iam::YOUR_ACCOUNT_ID:role/gravitino-iceberg-access &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--role-session-name&lt;/span&gt; gravitino-test
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Example successful response:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Credentials"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"AccessKeyId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ASIA***************"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"SecretAccessKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"***************************"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"SessionToken"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"IQoJb3JpZ2luX2VjEOj..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-07-23T08:33:30+00:00"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. Gravitino Deployment and Configuration
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Download and Install Gravitino&lt;/p&gt;

&lt;p&gt;We'll use Gravitino's pre-compiled version for quick environment setup:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create working directory&lt;/span&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;gravitino-deployment &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;gravitino-deployment

&lt;span class="c"&gt;# Download Gravitino main program&lt;/span&gt;
wget https://dlcdn.apache.org/gravitino/0.9.1/gravitino-0.9.1-bin.tar.gz

&lt;span class="c"&gt;# Extract and install&lt;/span&gt;
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xzf&lt;/span&gt; gravitino-0.9.1-bin.tar.gz
&lt;span class="nb"&gt;cd &lt;/span&gt;gravitino-0.9.1-bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install Required Dependencies&lt;/p&gt;

&lt;p&gt;To support AWS S3 and credential management functionality, we need to install additional JAR packages:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create necessary directory structure&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; logs
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /tmp/gravitino

&lt;span class="c"&gt;# Download Iceberg AWS bundle&lt;/span&gt;
wget https://repo1.maven.org/maven2/org/apache/iceberg/iceberg-aws-bundle/1.6.1/iceberg-aws-bundle-1.6.1.jar &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-P&lt;/span&gt; catalogs/lakehouse-iceberg/libs/
&lt;span class="nb"&gt;cp &lt;/span&gt;catalogs/lakehouse-iceberg/libs/iceberg-aws-bundle-1.6.1.jar iceberg-rest-server/libs/

&lt;span class="c"&gt;# Download Gravitino AWS support package (core for vended-credentials functionality)&lt;/span&gt;
wget https://repo1.maven.org/maven2/org/apache/gravitino/gravitino-aws/0.9.1/gravitino-aws-0.9.1.jar &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-P&lt;/span&gt; iceberg-rest-server/libs/
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configure Gravitino Service&lt;/p&gt;

&lt;p&gt;Create or edit the conf/gravitino.conf file:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="c"&gt;# Iceberg catalog backend configuration; default memory config is for testing only, should be changed to jdbc
# Using H2 here, MySQL recommended for production:
&lt;/span&gt;&lt;span class="py"&gt;gravitino.iceberg-rest.catalog-backend&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;jdbc&lt;/span&gt;
&lt;span class="py"&gt;gravitino.iceberg-rest.uri&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;jdbc:h2:file:/tmp/gravitino/catalog_iceberg.db;DB_CLOSE_DELAY=-1;MODE=MYSQL&lt;/span&gt;
&lt;span class="py"&gt;gravitino.iceberg-rest.jdbc-driver&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;org.h2.Driver&lt;/span&gt;
&lt;span class="py"&gt;gravitino.iceberg-rest.jdbc-user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;iceberg&lt;/span&gt;
&lt;span class="py"&gt;gravitino.iceberg-rest.jdbc-password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;iceberg123&lt;/span&gt;
&lt;span class="py"&gt;gravitino.iceberg-rest.jdbc-initialize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;gravitino.iceberg-rest.warehouse&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;s3://gravitino-iceberg-demo/warehouse&lt;/span&gt;
&lt;span class="py"&gt;gravitino.iceberg-rest.io-impl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;org.apache.iceberg.aws.s3.S3FileIO&lt;/span&gt;
&lt;span class="py"&gt;gravitino.iceberg-rest.s3-region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;us-west-2&lt;/span&gt;

&lt;span class="c"&gt;# Enable Vended-Credentials functionality
# Note: Gravitino uses these AK/SK to call STS AssumeRole and obtain temporary credentials for client distribution
&lt;/span&gt;&lt;span class="py"&gt;gravitino.iceberg-rest.credential-providers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;s3-token&lt;/span&gt;
&lt;span class="py"&gt;gravitino.iceberg-rest.s3-access-key-id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;YOUR_AWS_ACCESS_KEY_ID&lt;/span&gt;
&lt;span class="py"&gt;gravitino.iceberg-rest.s3-secret-access-key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;YOUR_AWS_SECRET_ACCESS_KEY&lt;/span&gt;
&lt;span class="py"&gt;gravitino.iceberg-rest.s3-role-arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;arn:aws:iam::YOUR_ACCOUNT_ID:role/gravitino-iceberg-access&lt;/span&gt;
&lt;span class="py"&gt;gravitino.iceberg-rest.s3-region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;us-west-2&lt;/span&gt;
&lt;span class="py"&gt;gravitino.iceberg-rest.s3-token-expire-in-secs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;3600&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Please note: Replace the warehouse, s3-region, access key id, secret access key, YOUR_ACCOUNT_ID and other properties in the above configuration with your own values.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Start Services&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start Gravitino service&lt;/span&gt;
./bin/gravitino.sh start

&lt;span class="c"&gt;# Check service status&lt;/span&gt;
./bin/gravitino.sh status

&lt;span class="c"&gt;# View logs&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; logs/gravitino-server.log

&lt;span class="c"&gt;# Verify main service&lt;/span&gt;
curl &lt;span class="nt"&gt;-v&lt;/span&gt; http://localhost:8090/api/version

&lt;span class="c"&gt;# Verify Iceberg REST service&lt;/span&gt;
curl &lt;span class="nt"&gt;-v&lt;/span&gt; http://localhost:9001/iceberg/v1/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create Gravitino Metadata Structure&lt;/p&gt;

&lt;p&gt;Create necessary metadata structures through REST API. &lt;code&gt;MetaLake&lt;/code&gt; is the top level of Gravitino's metadata structure. If you already have one, you can skip this step. Otherwise, we'll create a &lt;code&gt;metalake&lt;/code&gt; named &lt;code&gt;lakehouse&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create MetaLake&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Accept: application/vnd.gravitino.v1+json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "name": "lakehouse",
    "comment": "Gravitino lakehouse for Doris integration",
    "properties": {}
  }'&lt;/span&gt; http://localhost:8090/api/metalakes
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Next, we create an Iceberg Catalog, which can be done through the Web GUI or REST API. For example, here we create a catalog named &lt;code&gt;iceberg_catalog&lt;/code&gt; with &lt;code&gt;JDBC&lt;/code&gt; as the backend metadata storage and the warehouse address pointing to the S3 bucket created earlier:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create Iceberg Catalog&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Accept: application/vnd.gravitino.v1+json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "name": "iceberg_catalog",
    "type": "RELATIONAL",
    "provider": "lakehouse-iceberg",
    "comment": "Iceberg catalog with S3 storage and vended credentials",
    "properties": {
      "catalog-backend": "jdbc",
      "uri": "jdbc:h2:file:/tmp/gravitino/catalog_iceberg.db;DB_CLOSE_DELAY=-1;MODE=MYSQL",
      "jdbc-user": "iceberg",
      "jdbc-password": "iceberg123",
      "jdbc-driver": "org.h2.Driver",
      "jdbc-initialize": "true",
      "warehouse": "s3://gravitino-iceberg-demo/warehouse",
      "io-impl": "org.apache.iceberg.aws.s3.S3FileIO",
      "s3-region": "us-west-2"
    }
  }'&lt;/span&gt; http://localhost:8090/api/metalakes/lakehouse/catalogs
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;At this point, the necessary metadata has been created in Gravitino.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  3. Connecting Doris to Gravitino
&lt;/h2&gt;

&lt;p&gt;Doris can connect to Gravitino and access Iceberg data on S3 through two different approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static Credential Mode: Doris uses pre-configured fixed AK/SK to directly access S3&lt;/li&gt;
&lt;li&gt;Dynamic Credential Mode: Gravitino dynamically distributes temporary credentials to Doris via STS&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Vended Credential Mode (Recommended)&lt;/p&gt;

&lt;p&gt;Enabling vended credential mode is the more secure approach. In this mode, Gravitino dynamically generates temporary credentials and distributes them to clients like Doris, thereby minimizing the risk of credential leakage:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Create Catalog with vended credential mode&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;CATALOG&lt;/span&gt; &lt;span class="n"&gt;gravitino_vending&lt;/span&gt; &lt;span class="n"&gt;PROPERTIES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'type'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'iceberg'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'iceberg.catalog.type'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'rest'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'iceberg.rest.uri'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'http://127.0.0.1:9001/iceberg/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'iceberg.rest.warehouse'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'warehouse'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'iceberg.rest.vended-credentials-enabled'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'true'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'s3.endpoint'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'https://s3.us-west-2.amazonaws.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'s3.region'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'us-west-2'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Static Credential Mode&lt;/p&gt;

&lt;p&gt;In this mode, Doris directly uses fixed AWS credentials to access S3, with Gravitino providing only metadata services:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Create Catalog with static credential mode&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;CATALOG&lt;/span&gt; &lt;span class="n"&gt;gravitino_static&lt;/span&gt; &lt;span class="n"&gt;PROPERTIES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'type'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'iceberg'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'iceberg.catalog.type'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'rest'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'iceberg.rest.uri'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'http://127.0.0.1:9001/iceberg/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'iceberg.rest.warehouse'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'warehouse'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'iceberg.rest.vended-credentials-enabled'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'false'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'s3.endpoint'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'https://s3.us-west-2.amazonaws.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'s3.access_key'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'YOUR_AWS_ACCESS_KEY_ID'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'s3.secret_key'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'YOUR_AWS_SECRET_ACCESS_KEY'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'s3.region'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'us-west-2'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify Connection and Data Operations&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Verify connection&lt;/span&gt;
&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="n"&gt;DATABASES&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;gravitino_vending&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Switch to vended credentials catalog&lt;/span&gt;
&lt;span class="n"&gt;SWITCH&lt;/span&gt; &lt;span class="n"&gt;gravitino_vending&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Create database and table&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;USE&lt;/span&gt; &lt;span class="n"&gt;gravitino_vending&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;gravitino_table&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;STRING&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;PROPERTIES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'write-format'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'parquet'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Insert test data&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;gravitino_table&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Doris'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Gravitino'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Query verification&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;gravitino_table&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Through this guide, you can successfully build a modern lakehouse architecture based on Gravitino and Doris. This architecture not only provides high performance and high availability but also ensures data access security and compliance through advanced security mechanisms. As data scales grow and business requirements evolve, this architecture can flexibly expand to meet various enterprise-level needs. For those interested in these two projects, please star both projects on GitHub: &lt;a href="https://github.com/apache/gravitino" rel="noopener noreferrer"&gt;https://github.com/apache/gravitino&lt;/a&gt; and &lt;a href="https://github.com/apache/doris" rel="noopener noreferrer"&gt;https://github.com/apache/doris&lt;/a&gt;. We look forward to your participation in community issue discussions and PR contributions!&lt;/p&gt;

</description>
      <category>metadata</category>
      <category>apachedoris</category>
      <category>apachegravitino</category>
      <category>ai</category>
    </item>
    <item>
      <title>Why Metadata Matters: The Force Driving Data and AI</title>
      <dc:creator>Alex Yan</dc:creator>
      <pubDate>Sat, 27 Sep 2025 01:47:34 +0000</pubDate>
      <link>https://dev.to/datastrato/why-metadata-matters-the-force-driving-data-and-ai-b48</link>
      <guid>https://dev.to/datastrato/why-metadata-matters-the-force-driving-data-and-ai-b48</guid>
      <description>&lt;p&gt;In a world drowning in data, we often focus on the information itself – the records, the tables, the images, and the videos. What if the most important asset isn't just the data, but also the "data about data"? This is the essence of &lt;strong&gt;metadata&lt;/strong&gt;. Think of it as the DNA of your information, providing context, meaning, and structure.&lt;/p&gt;

&lt;p&gt;While metadata has long been the backbone of traditional data management, its role is now exploding in importance. It is becoming the critical link between human understanding and AI-driven intelligence. Let's explore why metadata is more crucial than ever.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Foundation of Traditional Data Management
&lt;/h2&gt;

&lt;p&gt;In the classic data ecosystem, metadata is the key to creating a single source of truth. Without it, data exists in isolated "silos"—departments have their own databases, and nobody knows what information exists elsewhere. Metadata changes this by acting as a universal translator.&lt;/p&gt;

&lt;p&gt;A well-defined &lt;strong&gt;metadata catalog&lt;/strong&gt; serves as a central library, documenting everything from data ownership and access permissions to data types and refresh schedules. This centralized view eliminates data silos and lays the groundwork for robust &lt;strong&gt;data governance&lt;/strong&gt;. When you have a unified view of your data, you can enforce quality standards, ensure regulatory compliance (like GDPR or HIPAA), and manage sensitive information effectively.&lt;/p&gt;

&lt;p&gt;Furthermore, metadata is the engine behind &lt;strong&gt;data lineage&lt;/strong&gt;. It tracks the journey of data from its source to its final destination, showing every transformation it undergoes and each point of interaction. This is invaluable for troubleshooting data quality issues, auditing processes, and understanding the complete history of your information.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fuel for AI Models: Data for AI
&lt;/h2&gt;

&lt;p&gt;To train a powerful AI model, you need high-quality, relevant data. For large-scale multi-modal models that understand everything from text to images to audio, the challenge is immense. You can't just throw raw data at a model; without context, the data is simply noise.&lt;/p&gt;

&lt;p&gt;This is where metadata shines. For multi-modal AI, metadata acts as the "label" or "tag" that allows the model to interpret the data it's analyzing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Images&lt;/strong&gt;: Annotations that identify objects ("car," "dog") and actions ("running," "jumping").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text&lt;/strong&gt;: Sentiment tags ("positive," "negative"), keywords, and topic classifications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audio&lt;/strong&gt;: Transcriptions, speaker identification, and background noise annotations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without this crucial metadata, a multi-modal model would be blind and deaf. It's the metadata that allows the model to connect a picture of a cat with the word "cat," or an audio clip of a car with the term "vehicle." This process of &lt;strong&gt;data annotation&lt;/strong&gt; and labeling, powered by metadata, is the single most important step in preparing data for effective AI training.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Brain for AI Agents: AI for Data
&lt;/h2&gt;

&lt;p&gt;The most exciting development is the shift from "Data For AI" to "AI For Data." This is where AI models don't just consume data – they actively manage and understand it. Metadata provides the cognitive foundation for this new generation of &lt;strong&gt;data agents&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine an AI that can answer complex business questions like: "What was the total revenue from our top five products in Europe last quarter?" To do this, the AI needs more than just access to a database. It needs metadata to act as its "brain." This metadata helps the model understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Context&lt;/strong&gt;: What does the "revenue" column actually mean? Is it net or gross?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relationships&lt;/strong&gt;: How does the "product" table connect to the "sales" table?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantics&lt;/strong&gt;: What does "Europe" refer to in the context of the data? Is it a country or a region?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the power of &lt;strong&gt;semantic metadata&lt;/strong&gt;, which goes beyond simple descriptions to map the meaning and relationships of data. By integrating metadata with large language models (LLMs) and other tools, we can create data agents that understand the nuance of your business. These agents can autonomously clean data, generate reports, and even orchestrate complex data pipelines—all by using metadata as their guide.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future is Now: From Data Management to Data Intelligence
&lt;/h2&gt;

&lt;p&gt;The journey of metadata is a continuous evolution. We are moving beyond traditional data management – passive registries of information – towards something far more intelligent. This new paradigm is often called &lt;strong&gt;Data Intelligence&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Data intelligence isn't just a data repository; it’s an AI-powered system that automatically understands, enriches, and connects metadata. It can infer relationships, suggest improvements, and serve as the central brain for all your AI-powered data initiatives.&lt;/p&gt;

&lt;p&gt;This vision is at the core of projects like &lt;strong&gt;Apache Gravitino&lt;/strong&gt;. The release of &lt;strong&gt;Apache Gravitino 1.0.0&lt;/strong&gt; marks a major step forward, designed from the ground up to be a modern metadata lake for data and AI. It provides a unified, open-source metadata management solution that is built to support the very transitions we've discussed: from addressing traditional data silos to providing the essential semantic layer that will power the next generation of AI applications. With Apache Gravitino, metadata is no longer a static asset but a dynamic and collaborative force in the data ecosystem.&lt;/p&gt;

&lt;p&gt;Please stay tuned for our follow-up blogs about the Gravitino 1.0.0 technical deep dive.&lt;/p&gt;

</description>
      <category>metadata</category>
      <category>data</category>
      <category>datamanagement</category>
      <category>ai</category>
    </item>
    <item>
      <title>Catalogs as Context: How Metadata is Powering the Next Wave of AI</title>
      <dc:creator>Alex Yan</dc:creator>
      <pubDate>Fri, 19 Sep 2025 23:19:27 +0000</pubDate>
      <link>https://dev.to/datastrato/catalogs-as-context-how-metadata-is-powering-the-next-wave-of-ai-1dem</link>
      <guid>https://dev.to/datastrato/catalogs-as-context-how-metadata-is-powering-the-next-wave-of-ai-1dem</guid>
      <description>&lt;p&gt;The promise of AI and LLMs to revolutionize business is immense, but for many organizations, it's blocked by a significant hurdle: data chaos. While our historic focus on the "3Vs"—Volume, Velocity, and Variety—advanced data architectures, it also created complex silos that trap data, making it difficult to use for effective AI.&lt;/p&gt;

&lt;p&gt;We believe the solution lies not in managing more data, but in understanding it better. The key is context, which is powered by metadata. A unified metadata layer, acting as a central "brain" for your data ecosystem, is the essential component to unlock data for AI, enabling both powerful insights and robust governance.&lt;/p&gt;

&lt;h2&gt;
  
  
  The End of an Era: Why Our Old Data Goals Are Failing Us
&lt;/h2&gt;

&lt;p&gt;The data landscape is fundamentally shifting, and the paradigms that brought us here are beginning to show their limits. We see three major challenges confronting modern data platforms:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Diminishing Returns: With the end of Moore's Law, we can no longer solve data problems simply by adding more hardware.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Crushing Complexity: The modern data stack has become a tangled web of tools, creating massive overhead that slows innovation and increases risk.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Push to Intelligence: Data platforms must evolve beyond simple storage to intelligently understand and act on data, much like cars evolved from speed machines to autonomous vehicles.  &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Metadata: The Key to Unlocking AI
&lt;/h2&gt;

&lt;p&gt;This is where metadata—data about your data—comes in. For too long, it’s been an afterthought. In the AI era, it’s your most critical asset. Think of it as the bridge connecting the powerful brain of an LLM to your specific business data. Without it, AI is flying blind.&lt;/p&gt;

&lt;p&gt;Good metadata management delivers on three key things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Clear Understanding: It's your universal "data dictionary," making sure everyone and every system is on the same page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consistent Governance: It provides a single place to manage security, quality, and compliance rules everywhere.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Smart Automation: It gives AI the context it needs to automate tasks and make decisions correctly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Meet Apache Gravitino: Your Data's Central Brain
&lt;/h2&gt;

&lt;p&gt;That's where Apache Gravitino comes in. We're excited to be building this open-source "catalog of catalogs"—a single place to manage all your metadata. Gravitino doesn't replace your existing systems. Instead, it works with them by providing a unified layer on top, which unlocks several key advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Single Source of Truth: Eliminate ambiguity and ensure everyone—and every system—is working with the same understanding of your data assets.&lt;/li&gt;
&lt;li&gt;Improved Efficiency &amp;amp; Discovery: Radically simplify the process of finding and using the right data for any task.&lt;/li&gt;
&lt;li&gt;Enhanced Data Quality &amp;amp; Governance: Define and enforce data quality rules, access policies, and compliance standards from one central, authoritative place.&lt;/li&gt;
&lt;li&gt;Empowering LLMs: Provide your AI models with the rich, reliable, and well-governed context they need to perform effectively and safely.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Future is Agentic: Putting Your Metadata to Work
&lt;/h2&gt;

&lt;p&gt;Centralizing metadata is the first step. The next is to build systems that can act on it intelligently. The future of data management is "agentic." Our roadmap for Gravitino includes building a framework for specialized AI agents that can automate today's most complex data tasks, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated Data Engineering: Imagine agents that can understand a natural language request, discover the relevant data across your entire ecosystem, and automatically build the necessary data pipelines.&lt;/li&gt;
&lt;li&gt;Automated Data Governance: Picture agents that can automatically scan, classify, and tag sensitive data, applying the correct governance policies without manual intervention.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Build Your Data's Brain Before You Build Your AI
&lt;/h2&gt;

&lt;p&gt;The journey to becoming an AI-driven organization requires a shift in focus—from simply collecting data to truly understanding it. In this new era, a unified metadata catalog isn't a "nice-to-have"; it is a foundational requirement. You cannot build a powerful, trustworthy AI system on a chaotic and poorly understood data foundation.&lt;/p&gt;

&lt;p&gt;The work on Apache Gravitino is just beginning, and we are excited about the future. The project recently graduated to become an Apache Top-Level Project in May 2025, and we invite you to join us on this journey.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explore the project on our official website&lt;/li&gt;
&lt;li&gt;Star and contribute to the code on our Apache Gravitino repository.&lt;/li&gt;
&lt;li&gt;Join the conversation by subscribing to our mailing lists.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, we can build the open standard for the next generation of intelligent, metadata-driven data platforms.&lt;/p&gt;

</description>
      <category>metadata</category>
      <category>ai</category>
      <category>apachegravitino</category>
    </item>
    <item>
      <title>Apache Gravitino: Production-Ready Unified Metadata for Enterprise Data</title>
      <dc:creator>Alex Yan</dc:creator>
      <pubDate>Sat, 23 Aug 2025 05:15:35 +0000</pubDate>
      <link>https://dev.to/datastrato/apache-gravitino-production-ready-unified-metadata-for-enterprise-data-2dem</link>
      <guid>https://dev.to/datastrato/apache-gravitino-production-ready-unified-metadata-for-enterprise-data-2dem</guid>
      <description>&lt;p&gt;&lt;small&gt;Jerry Shao, CTO &amp;amp; Co-founder of Datastrato, explained the vision and capabilities of unified metadata management at &lt;a href="https://www.youtube.com/watch?v=beNdWVPz9-s&amp;amp;t=252s" rel="noopener noreferrer"&gt;Scaling Iceberg Adoption at Pinterest with Gravitino&lt;/a&gt;.&lt;br&gt;
&lt;/small&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Session 1: The Modern Data Challenge - Why "Catalog of Catalogs" Matters
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Enterprise Data Silos Problem
&lt;/h3&gt;

&lt;p&gt;Modern data-driven companies face an inevitable challenge: &lt;strong&gt;data silos everywhere&lt;/strong&gt;. Take a typical enterprise—they'll have a Hadoop-based data lake for ETL and batch processing, a data warehouse for ad hoc analytics, streaming processing stacks for real-time requirements, and machine learning platforms for AI workloads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The result?&lt;/strong&gt; Each system serves its purpose well, but &lt;strong&gt;data becomes fragmented across isolated islands.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Traditional "Unified Data" Approach Falls Short
&lt;/h3&gt;

&lt;p&gt;The conventional wisdom says: "Unify all your data in one storage layer." Lakehouse technologies attempt this, trying to force everything into a single system.&lt;/p&gt;

&lt;p&gt;But here's the problem: &lt;strong&gt;Current lakehouse technologies cannot adequately support streaming analytics AND machine learning AND traditional analytics.&lt;/strong&gt; Each workload has unique requirements that no single system can perfectly address.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apache Gravitino's Revolutionary Insight
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Instead of asking "How do we unify data together?"&lt;br&gt;
We asked: "Can we unify the metadata together?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This shift in thinking is profound. Every data system needs a catalog to manage its metadata. So rather than moving massive amounts of data, &lt;strong&gt;why not create a unified layer that manages the catalogs themselves?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa768tjimmlq3vmhpx7rs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa768tjimmlq3vmhpx7rs.png" alt=" " width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apache Gravitino is a "catalog of catalogs"&lt;/strong&gt; - a metadata management platform that provides unified governance and access across diverse data systems without forcing you to abandon existing investments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Session 2: Gravitino's Architecture - Unification Without Migration
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fktj3qj64533shjhnribi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fktj3qj64533shjhnribi.png" alt=" " width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Generic Metadata Object Model
&lt;/h3&gt;

&lt;p&gt;At Gravitino's core is a &lt;strong&gt;universal metadata framework&lt;/strong&gt; that represents different types of data through consistent interfaces:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unified Table Management&lt;/strong&gt; Tables from Hive, Iceberg, PostgreSQL, and other systems are represented through the same metadata model, enabling consistent operations across platforms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comprehensive Data Type Support&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tables&lt;/strong&gt;: Traditional structured data across any system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filesets&lt;/strong&gt;: Direct file and directory management on HDFS, S3, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Models&lt;/strong&gt;: Machine learning model metadata and versioning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Topics&lt;/strong&gt;: Streaming data topics and configurations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Connection Layer: Universal Data System Integration
&lt;/h3&gt;

&lt;p&gt;Gravitino connects to diverse data systems through specialized connectors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hive Connector&lt;/strong&gt;: Integrates with Hive Metastore ecosystems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JDBC Connector&lt;/strong&gt;: Connects to relational databases&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iceberg Connector&lt;/strong&gt;: Native Apache Iceberg support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Connectors&lt;/strong&gt;: Extensible framework for new systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dual API Strategy: Standards Compliance + Innovation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Gravitino Unified REST APIs&lt;/strong&gt; Generic operations across all data types and systems through consistent interfaces.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Native Iceberg REST APIs&lt;/strong&gt; Full compliance with Iceberg REST specification at &lt;code&gt;/v1/namespaces&lt;/code&gt;, &lt;code&gt;/v1/tables&lt;/code&gt;, supporting standard Iceberg clients while adding enterprise capabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Power of Interoperability&lt;/strong&gt; Both API sets operate on the same underlying data, so operations through one interface are immediately reflected in the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Session 3: Gravitino IRC - Production-Ready Iceberg REST Catalog
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beyond Basic REST Catalog Implementation
&lt;/h3&gt;

&lt;p&gt;While Apache Iceberg provides a reference REST catalog implementation, &lt;strong&gt;Gravitino IRC is built for enterprise production requirements&lt;/strong&gt; with enhanced capabilities that standard implementations lack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Federated Catalog Architecture
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Challenge&lt;/strong&gt;: Organizations use different catalog backends (Hive Metastore, JDBC databases, cloud-native solutions) and don't want to abandon existing investments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gravitino's Solution&lt;/strong&gt;: Build REST endpoints &lt;strong&gt;on top of&lt;/strong&gt; existing catalogs rather than replacing them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq54gmb462snu1306q7it.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq54gmb462snu1306q7it.png" alt=" " width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;User Applications → Iceberg REST Interface → Gravitino IRC → Existing Catalogs&lt;br&gt;
                                                 ├── Hive Metastore&lt;br&gt;
                                                      ├── JDBC Catalog&lt;br&gt;
                                                          └── Future: S3, Polaris&lt;/p&gt;

&lt;h3&gt;
  
  
  Dual API Interoperability
&lt;/h3&gt;

&lt;p&gt;Both Gravitino unified APIs and Iceberg REST APIs operate on the same underlying metadata, enabling seamless interoperability:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7asrbpj24z6vseuxp41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7asrbpj24z6vseuxp41.png" alt=" " width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Production Enhancements Over Standard Implementation
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh13j7hqasy4ypspm69bv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh13j7hqasy4ypspm69bv.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Enterprise Serviceability
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Integrated metrics systems&lt;/strong&gt;: Native Prometheus and Grafana support for comprehensive monitoring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit logging&lt;/strong&gt;: Complete operation tracking for governance and compliance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event framework&lt;/strong&gt;: Pre/post-event hooks for custom business logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Flexible Deployment Options&lt;/strong&gt; Organizations can deploy Gravitino IRC as a unified service alongside other Gravitino APIs, or as a standalone Iceberg-focused service, depending on their architectural preferences.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enhanced Performance and Reliability&lt;/strong&gt; Unlike basic implementations, Gravitino IRC includes intelligent caching, connection pooling, and failover mechanisms designed for enterprise-scale workloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Session 4: Enterprise Security and Governance at Scale
&lt;/h2&gt;

&lt;h3&gt;
  
  
  End-to-End Authentication Architecture
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Client Authentication&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OAuth2&lt;/strong&gt;: Modern web-based authentication for applications and users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kerberos&lt;/strong&gt;: Enterprise directory integration for secure environments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pluggable Framework&lt;/strong&gt;: Custom authentication methods for unique organizational requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Backend Catalog Authentication&lt;/strong&gt; Different catalog systems require different authentication approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hive Catalogs&lt;/strong&gt;: Kerberos and delegation token support with impersonation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JDBC Catalogs&lt;/strong&gt;: Secure username/password management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Catalogs&lt;/strong&gt;: Native cloud identity integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Data Layer Security&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HDFS Integration&lt;/strong&gt;: Kerberos and delegation token support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Storage&lt;/strong&gt;: Secure credential vending that provides temporary, scoped access tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-System&lt;/strong&gt;: Consistent security model regardless of backend storage&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Role-Based Access Control (RBAC)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9s79qvd44xz3v5nozeon.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9s79qvd44xz3v5nozeon.png" alt=" " width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comprehensive Identity Management&lt;/strong&gt; Through Gravitino's unified REST APIs, administrators can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add users and groups to the system&lt;/li&gt;
&lt;li&gt;Create roles with specific privileges on different entities&lt;/li&gt;
&lt;li&gt;Bind roles to users with fine-grained control&lt;/li&gt;
&lt;li&gt;Enforce policies consistently across all connected systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Unified Policy Enforcement&lt;/strong&gt; When users query tables through any connected engine, Gravitino enforces access policies in real-time, checking permissions before allowing read or write operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advanced Data Governance Features
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokr6xtuwiu0eolo6zk3v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokr6xtuwiu0eolo6zk3v.png" alt=" " width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intelligent Data Discovery&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tagging System&lt;/strong&gt;: Classify and organize data assets across systems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search Integration&lt;/strong&gt;: OpenSearch integration for keyword-based data discovery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metadata Enrichment&lt;/strong&gt;: Automatic data profiling and documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Data Lineage Tracking&lt;/strong&gt; Gravitino captures and exposes lineage information, showing how data flows between systems and transforms through different processing stages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Session 5: Expanding Ecosystem Support
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Growing Catalog Backend Support&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current Production Support&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hive Metastore&lt;/strong&gt;: Full integration with existing Hadoop ecosystems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JDBC Catalogs&lt;/strong&gt;: PostgreSQL, MySQL, and other relational database catalogs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Planned Integrations&lt;/strong&gt; We will extend to support more catalog backends like &lt;strong&gt;S3 catalogs and Polaris&lt;/strong&gt; and others, giving organizations even more flexibility in their catalog choices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: The Unified Metadata Future
&lt;/h2&gt;

&lt;p&gt;Apache Gravitino represents a fundamental shift in how enterprises approach data architecture. Rather than forcing organizations to migrate data or abandon existing investments, &lt;strong&gt;Gravitino enables transformation through unification&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The three core principles driving this evolution:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Metadata-First Architecture&lt;/strong&gt;: Unifying metadata management enables data interoperability without data movement&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Federation Over Migration&lt;/strong&gt;: Preserve existing investments while gaining modern capabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standards-Based Innovation&lt;/strong&gt;: Extensible platforms that maintain ecosystem compatibility&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Organizations choosing Gravitino gain:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Immediate integration benefits without migration risk&lt;/li&gt;
&lt;li&gt;Enterprise-grade security and governance capabilities&lt;/li&gt;
&lt;li&gt;Future-proof architecture that evolves with industry standards&lt;/li&gt;
&lt;li&gt;Active community support and continuous innovation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The future of enterprise data architecture isn't about choosing the right system—it's about choosing the right approach to &lt;strong&gt;unified metadata management.&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Introduction to REST Catalogs for Apache Iceberg</title>
      <dc:creator>Alex Yan</dc:creator>
      <pubDate>Wed, 13 Aug 2025 18:54:31 +0000</pubDate>
      <link>https://dev.to/datastrato/introduction-to-rest-catalogs-for-apache-iceberg-5a7l</link>
      <guid>https://dev.to/datastrato/introduction-to-rest-catalogs-for-apache-iceberg-5a7l</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokzfvpgmiybdv96ty4ar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokzfvpgmiybdv96ty4ar.png" alt=" " width="720" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What is the Apache Iceberg Catalog?&lt;br&gt;
While Iceberg primarily concentrates on its role as an open data format for lakehouse implementation, it still needs to use metadata to track its tables by name. The catalog acts as a reference and contains a pointer to the metadata file for a given table and provides atomicity. Different backends (e.g. Hive, Hadoop, AWS Glue) that can serve as the Iceberg catalog will store the current metadata pointer differently. Iceberg catalogs are flexible and can be implemented using almost any backend system. They can be plugged into any Iceberg runtime, and allow any processing engine that supports Iceberg to load the tracked Iceberg tables. Iceberg also comes with several catalog implementations that are ready to use out of the box.&lt;/p&gt;

&lt;p&gt;This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST: a server-side catalog that’s exposed through a REST API, such as Apache Gravitino or Apache Polaris&lt;/li&gt;
&lt;li&gt;Hive Metastore: tracks namespaces and tables using a Hive metastore&lt;/li&gt;
&lt;li&gt;JDBC: tracks namespaces and tables in the JDBC database&lt;/li&gt;
&lt;li&gt;Nessie: a transactional catalog that tracks namespaces and tables in a database with git-like version control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Catalogs are extremely useful at telling us where our Iceberg tables are, and subsequently how we can access them safely. They are the backbone of data governance frameworks and with regards to Iceberg, they are used for tracking tables and allowing external tools to interface with the metadata. For an Iceberg catalog to be production-ready, it must support atomic operations for updating the current metadata pointer. This helps ensure ACID compliance for table operations by making sure all readers and writers see the same state of the table at a given point in time. When there are two concurrent writers, it’s important to ensure that partial writes don’t happen, resulting in data loss.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdfhg7qalnbeg77k2t72.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdfhg7qalnbeg77k2t72.png" alt=" " width="720" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;br&gt;
Image Credit: Iceberg the Definitive Guide.&lt;br&gt;
&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How do catalogs work in Iceberg?
&lt;/h3&gt;

&lt;p&gt;This metastore plays a central role in providing the source of truth for the metadata location of Iceberg tables and task execution like creating, dropping, or renaming tables. By grouping collections of tables into namespaces, the Iceberg catalog can keep track of each table’s current metadata for when you load in a specific table. It is important to note that the purpose of the Iceberg catalog is primarily technical, which means most of its functionality surrounds versioning, table management, and naming — this differs significantly from a product data catalog. To learn more about the difference between technical and product data catalogs, see &lt;a href="https://medium.com/@lisancao/technical-vs-product-data-catalogs-which-one-is-best-for-you-6a54337e1ded" rel="noopener noreferrer"&gt;“Technical vs Product Data Catalogs: Which one is best for you?”&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When you implement Iceberg in your setup, one of the first steps is to initialize and configure the catalog. These catalogs enable the SQL commands that will allow you to manage the tables and load them by name. The catalog will be configured by passing along certain properties to the processing engine at initialization. For instance, a Spark catalog would be set by passing spark.sql.catalog. The Iceberg catalog initialized will be specified based on this property, depending on where you are loading tables from. Examples are spark.sql.catalog.hive, spark.sql.catalog.rest, or spark.sql.catalog.hadoop to name a few. It is important to note that not all engines are configured the same way, so it’s best to always refer to the documentation for best practices.&lt;/p&gt;

&lt;p&gt;Many pluggable services exist for the Iceberg catalog, such as Apache Gravitino or Polaris, which will utilize the REST catalog. Using REST as a defacto, these services are part of an effort to decouple the catalogs from their underlying technologies. This is important because many of the Iceberg catalog clients contain particular logic depending on the source, so moving it to the catalog server instead allows for more flexibility and control. Iceberg 0.14.0 introduced the &lt;a href="https://github.com/apache/iceberg/blob/main/open-api/rest-catalog-open-api.yaml" rel="noopener noreferrer"&gt;REST Open API specification&lt;/a&gt;, allowing server-side logic to be written in any language and use any custom technology as long as the API followed the specification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evolution of Catalogs: From Apache Hive Metastore to REST
&lt;/h3&gt;

&lt;p&gt;Generally, you will find Iceberg catalogs in two flavors: either a Service-based catalog or a File System Catalog. The majority of Service-based catalogs work by running a service that is either self or cloud managed, and use a backing store to maintain all the Iceberg table references, as well as any locking mechanisms to ensure ACID compliance and prevent conflicts. This type of catalog is becoming a more common trend over File System Catalogs, which use a file to track tables instead of a dedicated backing store. These types of catalogs, such as the Apache Hadoop catalog, are compatible with any storage system but as a result are more prone to inconsistencies due to the &lt;a href="https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/filesystem/introduction.html#Core_Expectations_of_a_Hadoop_Compatible_FileSystem" rel="noopener noreferrer"&gt;atomicity guarantee differences&lt;/a&gt; between the many types of storage solutions that exist, and are inherently split-state.&lt;/p&gt;

&lt;p&gt;The Hive Metastore catalog was previously a widely used implementation for managing an Iceberg catalog due to the prevalence of the Hadoop ecosystem. It works by mapping a table’s path to its current metadata file using the location table property in the table’s entry within Hive Metastore. This property specifies the absolute path in the filesystem where the table’s current metadata file is stored. This means that the metastore needs to be synced to the file storage to avoid failures of the metastore being written but not the data, or vice versa. File system catalogs like the Hive Metastore have been used to manage Iceberg, particularly during migrations from Hive to Iceberg, while maintaining both systems. However, these catalogs often encountered locking issues and conflicts that required resolution. For example, when concurrent writes are occurring, the writer that first successfully acquires the lock will swap in its snapshot, while the second writer will retry applying its changes. However, locks may also be occasionally abandoned during a shutdown that failed to be cleaned up.&lt;/p&gt;

&lt;p&gt;As a result, the Iceberg community began exploring alternative lock implementations, though there remained a desire for a less bloated solution than the Hive Metastore. JDBC-based catalogs work by storing the metadata in a dedicated table in the respective relational database it is connected to and then use that table to track changes and manage the iceberg tables. Depending on the implementation, JDBC-based catalogs can be more prone to inconsistencies due to differences in ACID compliance across various storage systems. To address these challenges, the idea of using REST was introduced, where engines would send HTTP requests to a REST endpoint, with conflicts handled server-side. This approach allows users to utilize Iceberg without needing an in-depth understanding of its intricacies.&lt;/p&gt;

&lt;h3&gt;
  
  
  An introduction to REST
&lt;/h3&gt;

&lt;p&gt;A REST API conforms to the principles of the Representational State Transfer (REST) architectural style, making it compatible with RESTful web services. REST is not necessarily a protocol or standard but rather a set of architectural constraints that developers can implement in various ways. When a client makes a request via a RESTful API, it receives a representation of the resource’s state, which is delivered through HTTP in formats including but not limited to JSON, HTML, Python, or plain text.&lt;/p&gt;

&lt;p&gt;Because it would be hard to accommodate everyone’s data infrastructure, and as languages like Java and Python have begun to co-exist, it is important that catalog implementations are consistent. It’s ideal to have a central place to manage all the metadata for all these clients to interact with Iceberg seamlessly. Especially when you have long-running jobs it needs to be backwards and forwards compatible in terms of iceberg versioning. REST catalogs were meant to solve this core issue by shifting a lot of the logic from the client side to the server side.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkw3jywjo8a82elzzurjt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkw3jywjo8a82elzzurjt.png" alt=" " width="720" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Image by mannhowie.com&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Apache Iceberg’s REST implementation
&lt;/h3&gt;

&lt;p&gt;The API Definitions exist in official Iceberg documentation as a specification, but it is not actually implemented. This is what we consider REST compliance, and to fully make use of it we would have to build the service ourselves or use a catalog that provides the REST service for us, like Apache Gravitino. At the very least, such a service requires the implementation of a server, which will need to handle the requests, and a backend which delegates to the catalog to fulfill the requests. We can also extend the functionality of the API at will depending on our needs, which, when compared to Hive Metastore, is a more pluggable approach. The service implementing the REST catalog interface can choose to store the mapping of a table’s path to its current metadata file in any way it chooses. It could even store it in another catalog if it wanted to.&lt;/p&gt;

&lt;p&gt;A REST catalog offers several advantages that make it an appealing choice for many organizations. First, it requires fewer packages and dependencies compared to other catalogs, which simplifies deployment and management. This simplicity is largely due to its reliance on standard HTTP communication. Additionally, the REST catalog provides flexibility because it can be implemented by any service capable of handling RESTful requests and responses, and the service’s data store can vary widely. Another benefit is its support for multi-table transactions, which allows for complex operations across multiple tables. Moreover, a REST catalog is cloud-agnostic, making it suitable for organizations that are currently using a multi-cloud strategy, or plan to do so in the future, or want to avoid cloud vendor lock-in.&lt;/p&gt;

&lt;p&gt;However, there are also some disadvantages to consider. Implementing a REST catalog requires running a process to handle and respond to REST calls from engines and tools. In production environments, this often necessitates an additional data storage service to store the catalog’s state. Furthermore, there is no public implementation of the backend service to support REST catalog endpoints, meaning developers will need to create their own or opt for a hosted service. Another limitation is that not all engines and tools support the REST catalog, though some, like Spark, Trino, PyIceberg, and Snowflake, do at the time of writing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7sknes82gc93uuzos5bo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7sknes82gc93uuzos5bo.png" alt=" " width="720" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Compilation of Iceberg REST Catalogs&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;In terms of use cases, a REST catalog is ideal if you need a flexible, customizable solution that can integrate with a variety of backend data stores, require support for multi-table transactions, or aim to maintain cloud agnosticism. When choosing a catalog, key considerations include whether it is recommended for production, whether it requires an external system and if that system is self-hosted or managed, whether it has broad compatibility with engines and tools, whether it supports multi-table and multi-statement transactions, and whether it is cloud-agnostic. Several examples of catalogs that follow the Iceberg REST Specification and are available for use out of the box are Apache Gravitino, Apache Polaris, Project Nessie, and Unity Catalog.&lt;/p&gt;

&lt;p&gt;The tool with the largest open source ecosystem support and connectors is &lt;a href="https://github.com/apache/gravitino" rel="noopener noreferrer"&gt;Apache Gravitino&lt;/a&gt;. Gravitino implements a metalake approach across data AI assets (although in the next release it will modularize its Iceberg REST service) and can also aggregate from other catalogs. Along with Iceberg, Gravitino also has native connectors to streaming sources, filesets, and relational stores and supports querying with Flink, Trino, Spark, or StarRocks. Learn more about Apache Gravitino &lt;a href="https://gravitino.apache.org/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;br&gt;
Apache, Apache Iceberg, Apache Hive, Apache Hadoop, Apache Polaris and Apache Gravitino are either registered trademarks or trademarks of the Apache Software Foundation in the United States and/or other countries.&lt;br&gt;
&lt;/small&gt;&lt;/p&gt;

</description>
      <category>dataengineering</category>
      <category>apacheiceberg</category>
      <category>datacatalog</category>
      <category>rest</category>
    </item>
    <item>
      <title>Datastrato Announced as an Official OPEA Partner</title>
      <dc:creator>Alex Yan</dc:creator>
      <pubDate>Wed, 13 Aug 2025 18:54:04 +0000</pubDate>
      <link>https://dev.to/datastrato/datastrato-announced-as-an-official-opea-partner-5bgj</link>
      <guid>https://dev.to/datastrato/datastrato-announced-as-an-official-opea-partner-5bgj</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2mrvwoqjbc9uqpxhck0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2mrvwoqjbc9uqpxhck0.png" alt=" " width="720" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’re excited to share that Datastrato has officially become a partner for the &lt;a href="https://opea.dev/" rel="noopener noreferrer"&gt;Open Platform For Enterprise AI&lt;/a&gt; (OPEA), the &lt;a href="https://lfaidata.foundation/" rel="noopener noreferrer"&gt;LF AI &amp;amp; Data Foundation&lt;/a&gt;’s latest Sandbox Project. The pioneering initiative unites industry leaders to champion the development of open, multi-provider, robust, and composable GenAI systems.&lt;/p&gt;

&lt;p&gt;Datastrato was chosen in no small part due to our contributions to &lt;a href="https://gravitino.apache.org/" rel="noopener noreferrer"&gt;Apache (incubating) Gravitino&lt;/a&gt;, an open source metadata lake that can catalog data from unstructured, relational, and streaming data sources. By using a technical data catalog and metadata lake, you can manage access and perform data governance for all your data sources while safely using multiple engines like Spark, Trino, or Flink on multiple formats on different cloud providers.&lt;/p&gt;

&lt;p&gt;The mission drives open source innovation in the AI and data domains by enabling collaboration and the creation of new opportunities for all members of the community. By supporting development of flexible, scalable GenAI systems, OPEA harnesses the best open source innovation from across the ecosystem. As an open source data catalog and metadata lake, we help provide the backbone for enterprise data architectures to streamline their data strategy across both legacy and modern data sources and make it accessible to multiple engines.&lt;/p&gt;

&lt;p&gt;This recognition places us alongside industry leaders like Anyscale, Cloudera, Datastax, Domino Data Lab, Hugging Face, Intel, KX, MariaDB Foundation, Minio, Qdrant, Red Hat, SAS, Yellowbrick Data, and Zilliz, highlighting our strengths in supporting large and diverse data infrastructure through versatility, scalability, and high availability.&lt;/p&gt;

&lt;p&gt;Learn more about OPEA through their &lt;a href="https://opea.dev/" rel="noopener noreferrer"&gt;website&lt;/a&gt;, or attend their upcoming webinar “&lt;a href="https://www.linkedin.com/events/genaiworkflowsolutionsforenterp7223710312330395650/theater/" rel="noopener noreferrer"&gt;GenAI Workflow Solutions for Enterprise: OPEA Demo-palooza&lt;/a&gt;”.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>data</category>
      <category>infrastructure</category>
      <category>generativeaitools</category>
    </item>
    <item>
      <title>Building A Universal Data Agent in 15 Minutes with LlamaIndex and Apache Gravitino (incubating)</title>
      <dc:creator>Alex Yan</dc:creator>
      <pubDate>Wed, 13 Aug 2025 18:53:30 +0000</pubDate>
      <link>https://dev.to/datastrato/building-a-universal-data-agent-in-15-minutes-with-llamaindex-and-apache-gravitino-incubating-213d</link>
      <guid>https://dev.to/datastrato/building-a-universal-data-agent-in-15-minutes-with-llamaindex-and-apache-gravitino-incubating-213d</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7d3parb3s2v5day5w33w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7d3parb3s2v5day5w33w.png" alt=" " width="720" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;br&gt;
Blogpost by Jerry Shao &amp;amp; Lisa N. Cao&lt;br&gt;
&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;In this new, modern era of data and generative intelligence, data infrastructure teams are struggling with getting company data served in a way that is convenient, efficient, and compliant with regulations. This is especially crucial in the development of Large Language Models (LLMs) and Agentic Retrieval-Augmented Generation (RAG), which have taken the analytics world by storm. In this article, we will cover how you can build a data agent from scratch and interact with it using an open source data catalog.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is a LLM Agent?
&lt;/h2&gt;

&lt;p&gt;Before we get started, we should first review the role of Agents in RAG Pipelines. While LLMs themselves lack advanced reasoning capabilities and provide the general ability to understand and generate language, Agents are used to take it a step further by being able to take instructions to perform more complex, domain specific reasoning that then gets fed back into the LLM.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd7ypqen1p4nv81c7l9uw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd7ypqen1p4nv81c7l9uw.png" alt=" " width="720" height="542"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Original image by Jerry Shao, inspired by Role of LLM agents at a glance — Source: &lt;a href="https://media.licdn.com/dms/image/D4E22AQE9ZyDxYRUB5w/feedshare-shrink_800/0/1695238313231?e=2147483647&amp;amp;v=beta&amp;amp;t=vHEk2w3EQKVvSIXpxddnbT3qG_pl1unG-cywZV3oKFI" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Agents can be used for different purposes and in different areas, for example, mathematical problem solving, retrieval-augmented chat, personal assistants, etc. A data agent is typically designed for an extractive goal by directly interacting with the data itself. By helping with assistive reasoning tasks, general application performance can improve greatly and responses more accurately.&lt;/p&gt;

&lt;p&gt;Below is the general architecture of a data agent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwzzftro8rmxmtk261kcf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwzzftro8rmxmtk261kcf.png" alt=" " width="800" height="541"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Original image by Jerry Shao, inspired by Role of LLM agents at a glance — Source: &lt;a href="https://media.licdn.com/dms/image/D4E22AQE9ZyDxYRUB5w/feedshare-shrink_800/0/1695238313231?e=2147483647&amp;amp;v=beta&amp;amp;t=vHEk2w3EQKVvSIXpxddnbT3qG_pl1unG-cywZV3oKFI" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the agent will take instructions from the LLM, and depending on the design it will interface with the user or LLM through a set of APIs or other agents. It then breaks down large tasks into smaller ones through planning, with some reflection and refinement capabilities. Combined with memory, the agent will retain and recall information over long context windows through the use of vector store and retrieval methods. Agents can also call external APIs to fill in missing information from alternate data sources, which is extremely useful.&lt;/p&gt;
&lt;h2&gt;
  
  
  Production Issues in RAG Development
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;There already exist plenty of demos, POCs, and tutorials describing how to build a simple data agent, but when we turn to production usage, we still face several challenges.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Data quality and integrity
&lt;/h3&gt;

&lt;p&gt;Regardless of which LLM you use, data quality and integrity will directly affect the accuracy of the answers. The quality of metadata for structured data will directly result in the accuracy of generated SQL statements, which can have ill-intended effects. Regardless of your chunking strategy, poor source data and documents will pollute the quality of your vector embeddings and result in poor retrieval results that can be nonsensical or hallucinatory. The saying “garbage in, garbage out” is more important than ever before in the age of generative AI.&lt;/p&gt;
&lt;h3&gt;
  
  
  Retrieve information from a wide range of sources
&lt;/h3&gt;

&lt;p&gt;In any organization or a company, data will likely be ingested from a wide range of sources. On top of a given variety of formats and storage solutions, data may also need to traverse from one data center/region into cross-regional, cross-cloud distributions. If we cannot successfully connect and retrieve data from the entire organization’s wide range of sources efficiently, we open ourselves to a huge disadvantage by missing key data and relationships, making it hard to implement a knowledge graph or map out similarities for our LLM to provide accurate answers from. In the meantime, the traditional way of ETL to centralize the data will also lower the effectiveness of the answers, as usually you will need T+1 to get data prepared.&lt;/p&gt;
&lt;h3&gt;
  
  
  Data privacy, security, and compliance
&lt;/h3&gt;

&lt;p&gt;Data privacy, security, and compliance are paramount when building any production-level data system, including data agents and APIs. This problem becomes more challenging when implementing LLMs because of their tendency to be incredibly high dimensional and complex at scale and thus trace their outputs from the source. Troubleshooting such systems, especially when making many calls to external tools and APIs, is very hard to do- let alone while retaining privacy and security. It is important to design our data infrastructure and end-to-end systems to have high visibility, observability, measurability, and robustness in a continuous way.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Apache Gravitino (incubating)?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/apache/gravitino" rel="noopener noreferrer"&gt;Apache (incubating) Gravitino&lt;/a&gt; is a high-performance, geo-distributed, and federated metadata lake. By using a technical data catalog and metadata lake, you can manage access and perform data governance for all your data sources (including filestores, relational databases, and event streams) while safely using multiple engines like Spark, Trino, or Flink on multiple formats on different cloud providers. This is very useful for us to plug into our data architecture when trying to get LlamaIndex up and running quickly on top of numerous data sources at the same time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqgij4iovx4700e3ra87.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqgij4iovx4700e3ra87.png" alt=" " width="720" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Apache (incubating) Gravitino’s Architecture at A Glance&lt;/small&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  With Gravitino, you can achieve:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Single Source of Truth for multi-regional data with geo-distributed architecture support.&lt;/li&gt;
&lt;li&gt;Unified Data and AI asset management for both users and engines.&lt;/li&gt;
&lt;li&gt;Security in one place, centralizing the security for different sources.&lt;/li&gt;
&lt;li&gt;Built-in data management and data access management.&lt;/li&gt;
&lt;li&gt;An AI-ready and low cost metadata fabric that standardizes across all your data stores.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more details about Gravitino, please refer to our blogpost &lt;a href="https://datastrato.ai/blog/gravitino-unified-metadata-lake/" rel="noopener noreferrer"&gt;Gravitino — the unified metadata lake.&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Without Gravitino, a typical agentic RAG system would look like this:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2bopsg80w8w07y9i742.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2bopsg80w8w07y9i742.png" alt=" " width="720" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Image by Jerry Shao, inspired by LlamaIndex flow — Source: &lt;a href="https://www.llamaindex.ai/" rel="noopener noreferrer"&gt;LlamaIndex&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Users would need to use different readers to connect to various sources one by one, the difficulties will be multiplied when data is distributed across clouds with varying security policies.&lt;/p&gt;
&lt;h3&gt;
  
  
  With Gravitino, the new architecture is streamlined:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk899cbn3lonvc7m87zb9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk899cbn3lonvc7m87zb9.png" alt=" " width="720" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Image by Jerry Shao, inspired by LlamaIndex flow — Source: LlamaIndex&lt;/small&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Using Gravitino and LlamaIndex to build a Universal Data Agent
&lt;/h2&gt;

&lt;p&gt;Now, let’s show how you can build a data agent in 15 minutes. This data agent will have several advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No data movement: data will stay where it is, and there’s no need to preprocess or aggregate data together.&lt;/li&gt;
&lt;li&gt;Obtain answers both from structured and unstructured data.&lt;/li&gt;
&lt;li&gt;Natural language interface. Using natural language to ask the data questions, which will automatically decompose into subqueries and generate SQL as required.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Environment Setup
&lt;/h2&gt;

&lt;p&gt;Below we have abstracted out the code you will need to reproduce this on your own. If you are interested in running this step by step with us, we have a prepared setup that can be run locally. Keep in mind, to run this demo you will need an &lt;a href="https://openai.com/index/openai-api/" rel="noopener noreferrer"&gt;OpenAI API key&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To learn more about the playground, see here: &lt;a href="https://github.com/apache/gravitino-playground" rel="noopener noreferrer"&gt;Apache Gravitino Demo Playground&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone git@github.com:apache/gravitino-playground.git
cd gravitino-playground
./launch-playground.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From there, you will need to navigate to the Jupyter Notebook through the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the Jupyter Notebook in the browser at &lt;a href="http://localhost:8888" rel="noopener noreferrer"&gt;http://localhost:8888/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Open the &lt;code&gt;gravitino_llamaIndex_demo.ipynb&lt;/code&gt; notebook&lt;/li&gt;
&lt;li&gt;Start the notebook and run the cells&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The overall architecture of the demo that is included in the local playground looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl880opvh5knbdzmlniq5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl880opvh5knbdzmlniq5.png" alt=" " width="720" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Manage datasets using Gravitino
&lt;/h2&gt;

&lt;p&gt;First, we’ll need to set up our first catalog and connect it to our filesets. In our case, the data source is Hadoop. We’ll then need to define the schemas and provide the storage location.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;demo_catalog = None
try:
    demo_catalog = gravitino_client.load_catalog(name=catalog_name)
except Exception as e:
    demo_catalog = gravitino_client.create_catalog(name=catalog_name,
                                               catalog_type=Catalog.Type.FILESET,
                                               comment="demo",
                                               provider="hadoop",
                                               properties={})

# Create schema and fileset
schema_countries = None
try:
    schema_countries = demo_catalog.as_schemas().load_schema(ident=schema_ident)
except Exception as e:
    schema_countries = demo_catalog.as_schemas().create_schema(ident=schema_ident,
                                                           comment="countries",
                                                           properties={})

fileset_cities = None
try:
    fileset_cities = demo_catalog.as_fileset_catalog().load_fileset(ident=fileset_ident)
except Exception as e:
    fileset_cities = demo_catalog.as_fileset_catalog().create_fileset(ident=fileset_ident,
                                                                      fileset_type=Fileset.Type.EXTERNAL,
                                                                      comment="cities",
                                                                      storage_location="/tmp/gravitino/data/pdfs",
                                                                      properties={})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Build a Gravitino structured data reader
&lt;/h2&gt;

&lt;p&gt;Once our data sources are connected, we’ll need to query it somehow. We’ve decided to use Trino, connected via sqlalchemy in this case to help us out. You could also use PySpark, however if that is what your team already uses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from sqlalchemy import create_engine
from trino.sqlalchemy import URL
from sqlalchemy.sql.expression import select, text

trino_engine = create_engine('trino://admin@trino:8080/catalog_mysql/demo_llamaindex')

connection = trino_engine.connect();

with trino_engine.connect() as connection:
    cursor = connection.exec_driver_sql("SELECT * FROM catalog_mysql.demo_llamaindex.city_stats")
    print(cursor.fetchall())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Build a Gravitino unstructured data reader
&lt;/h2&gt;

&lt;p&gt;Once our basic data infrastructure has been set up, we can now directly read it into LlamaIndex. Gravitino will use a virtual file system to serve the data as a directory that LlamaIndex can take as input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from llama_index.core import SimpleDirectoryReader
from gravitino import gvfs

fs = gvfs.GravitinoVirtualFileSystem(
    server_uri=gravitino_url,
    metalake_name=metalake_name
    )

fileset_virtual_location = "fileset/catalog_fileset/countries/cities"

reader = SimpleDirectoryReader(
    input_dir=fileset_virtual_location,
    fs=fs,
    recursive=True)
wiki_docs = reader.load_data()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Build SQL metadata index from the structured data connection
&lt;/h2&gt;

&lt;p&gt;Once built, we can now begin to build our index and vector stores from the metadata alone.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from llama_index.core import SQLDatabase
sql_database = SQLDatabase(trino_engine, include_tables=["city_stats"])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Build vector index from unstructured data
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from llama_index.core import VectorStoreIndex
from llama_index.core import Settings
from llama_index.llms.openai import OpenAI

# Insert documents into vector index
# Each document has metadata of the city attached

vector_indices = {}
vector_query_engines = {}

for city, wiki_doc in zip(cities, wiki_docs):
   vector_index = VectorStoreIndex.from_documents([wiki_doc])

   query_engine = vector_index.as_query_engine(
       similarity_top_k=2, llm=OpenAI(model="gpt-3.5-turbo")
   )

   vector_indices[city] = vector_index
   vector_query_engines[city] = query_engine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Define query engines and ask the questions
&lt;/h2&gt;

&lt;p&gt;To make this a fully functioning chat application, we will need to be able to provide a text to SQL interface to pull it all together. In this case we will use LlamaIndex’s native functions to directly interface with the index we defined in the previous steps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from llama_index.core.query_engine import NLSQLTableQueryEngine
from llama_index.core.query_engine import SQLJoinQueryEngine

# Define the NL to SQL engine
sql_query_engine = NLSQLTableQueryEngine(
   sql_database=sql_database,
   tables=["city_stats"],
)


# Define the vector query engines for each city
from llama_index.core.tools import QueryEngineTool
from llama_index.core.tools import ToolMetadata
from llama_index.core.query_engine import SubQuestionQueryEngine


query_engine_tools = []
for city in cities:
   query_engine = vector_query_engines[city]


   query_engine_tool = QueryEngineTool(
       query_engine=query_engine,
       metadata=ToolMetadata(
           name=city, description=f"Provides information about {city}"
       ),
   )
   query_engine_tools.append(query_engine_tool)


s_engine = SubQuestionQueryEngine.from_defaults(
   query_engine_tools=query_engine_tools, llm=OpenAI(model="gpt-3.5-turbo")
)


# Convert engines to tools and combine them together
sql_tool = QueryEngineTool.from_defaults(
   query_engine=sql_query_engine,
   description=(
       "Useful for translating a natural language query into a SQL query over"
       " a table containing: city_stats, containing the population/country of"
       " each city"
   ),
)
s_engine_tool = QueryEngineTool.from_defaults(
   query_engine=s_engine,
   description=(
       f"Useful for answering semantic questions about different cities"
   ),
)

query_engine = SQLJoinQueryEngine(
   sql_tool, s_engine_tool, llm=OpenAI(model="gpt-4")
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Issue query
response = query_engine.query(
   "Tell me about the arts and culture of the city with the highest"
   " population"
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final answer combines from two parts:&lt;/p&gt;

&lt;p&gt;One is the answer from SQL engine, the data agent generates a SQL statement “&lt;code&gt;SELECT city_name, population, country FROM city_stats ORDER BY population DESC LIMIT 1&lt;/code&gt;” from natural language and gets an answer from the structured data that Tokyo has the highest population.&lt;/p&gt;

&lt;p&gt;Based on the first answer, the data agent then generates three sub questions “&lt;strong&gt;&lt;em&gt;Can you provide more details about the museums, theaters, and performance venues in Tokyo?&lt;/em&gt;&lt;/strong&gt;” regarding art and culture in Tokyo.&lt;/p&gt;

&lt;p&gt;The final answer combines the two parts and is shown below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Final response: The city with the highest population is Tokyo, Japan. Tokyo is known for its vibrant arts and culture scene, with a mix of traditional and modern influences. From ancient temples and traditional tea ceremonies to cutting-edge technology and contemporary art galleries, Tokyo offers a diverse range of cultural experiences for visitors and residents alike. The city is also home to numerous museums, theaters, and performance venues showcasing the rich history and creativity of Japan. Unfortunately, I cannot provide more details about the museums, theaters, and performance venues in Tokyo based on the context information provided.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So what’s next?
&lt;/h2&gt;

&lt;p&gt;The demo here shows how to use Gravitino for data ingestion and LlamaIndex for efficient data retrieval. With Gravitino’s production-ready features, it is easy for users to build a universal data agent. We’re continually improving Gravitino to make it a key component to building a data agent that meets enterprise-grade standards.&lt;/p&gt;

&lt;p&gt;Ready to take your data agent to the next level? Dive into the &lt;a href="https://datastrato.ai/docs/0.5.1/" rel="noopener noreferrer"&gt;guides&lt;/a&gt; and join our &lt;a href="https://join.slack.com/t/the-asf/shared_invite/zt-2l5oovqck-S8XeAdPXjEohmpBy3Ig_Lw" rel="noopener noreferrer"&gt;ASF Community Slack Channel&lt;/a&gt; for support.&lt;/p&gt;

&lt;p&gt;Huge thanks to co-writer &lt;a href="https://www.linkedin.com/in/jerry-saisai-shao-944052a6" rel="noopener noreferrer"&gt;Jerry Shao&lt;/a&gt; for collaborating with me on this.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>datascience</category>
      <category>dataengineering</category>
      <category>generativeaitools</category>
    </item>
    <item>
      <title>Gravitino 0.5.0: Expanding the horizon to Apache Spark, non-tabular data, and more!</title>
      <dc:creator>Alex Yan</dc:creator>
      <pubDate>Wed, 13 Aug 2025 18:52:49 +0000</pubDate>
      <link>https://dev.to/datastrato/gravitino-050-expanding-the-horizon-to-apache-spark-non-tabular-data-and-more-4han</link>
      <guid>https://dev.to/datastrato/gravitino-050-expanding-the-horizon-to-apache-spark-non-tabular-data-and-more-4han</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvfk20kgmdklw8hnkjrw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvfk20kgmdklw8hnkjrw.png" alt="gravitino-0.5.0" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our community is always looking to build new features and enhancements to meet the ever changing needs of today’s data and AI ecosystem. As such, we are glad to announce the release of Gravitino 0.5.0, which features Spark engine support, non-tabular data management, messaging data support, and a brand new Python Client. Make sure to keep reading to learn what we’ve done and check out some usage examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core features and enhancements
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Apache Spark connector
&lt;/h3&gt;

&lt;p&gt;With our new Spark connector support, we’ll allow seamless integration with one of the most widely used data processing frameworks. Users can now read and write metadata directly from Gravitino, making the management of large-scale data processing pipelines more convenient and unified. If you’re already a heavy Spark user, this will feel natural to plug into your stack compared to before, where we mainly supported Trino. You can refer to the &lt;a href="https://datastrato.ai/docs/0.5.0/spark-connector/spark-connector" rel="noopener noreferrer"&gt;Spark connector&lt;/a&gt; to get started and see the specs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Support for non-tabular data management
&lt;/h2&gt;

&lt;p&gt;When we group files together as collections as a means of organizing data, we are essentially using “Filesets”. Compared to relational data models like databases, and tables, filesets are used to manage non-tabular data that often does not fit neatly into traditional row-and-column structures of tabular data. Examples of this are unstructured data types like images, documents, audio and video files.&lt;/p&gt;

&lt;p&gt;Filesets are useful because they provide a level of abstraction over the storage systems, making it possible to leverage metadata to manage the files, much like a traditional database would do with records in a table. This abstraction brings possibilities like life cycle management, security permissions, and other metadata-level management such as schema or partition information to non-tabular data.&lt;/p&gt;

&lt;p&gt;Many modern data infrastructures leverage these formats for data processing, especially with the surge of AI and ML. Their models and data management systems will usually need to use both tabular and non-tabular data, so managing both with a single application can save a lot of headaches for engineers. These difficulties become harder at scale when it comes to data operations, enforcing policies, and dealing with complex storage architectures.&lt;/p&gt;

&lt;p&gt;Now that Gravitino supports Fileset features, managing non-tabular data on storage such as HDFS, S3, and other Hadoop-compatible systems is simpler and more integrated. This means you can manage permissions, track usage, and oversee the end-to-end lifecycle of all your data, no matter where the data physically resides. (&lt;a href="https://github.com/datastrato/gravitino/issues/1241" rel="noopener noreferrer"&gt;Issue #1241&lt;/a&gt;, refer to Fileset catalog for more details).&lt;/p&gt;

&lt;p&gt;Here is a brief example of how to use Fileset in Gravitino.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shell
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
-H "Content-Type: application/json" -d '{
  "name": "local_fileset",
  "comment": "This is an local fileset",
  "type": "MANAGED",
  "storageLocation": "file:/tmp/root/schema/local_fileset",
  "properties": {}
}' http://localhost:8090/api/metalakes/metalake/catalogs/fileset_catalog_1/schemas/schema4/filesets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Java
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GravitinoClient gravitinoClient = GravitinoClient
    .builder("http://127.0.0.1:8090")
    .withMetalake("metalake")
    .build();

Catalog catalog = gravitinoClient.loadCatalog(NameIdentifier.of("metalake", "catalog"));
FilesetCatalog filesetCatalog = catalog.asFilesetCatalog();

Map&amp;lt;String, String&amp;gt; propertiesMap = ImmutableMap.&amp;lt;String, String&amp;gt;builder()
        .build();

filesetCatalog.createFileset(
  NameIdentifier.of("metalake", "fileset_catalog_1", "schema4", "local_fileset"),
  "This is an local fileset",
  Fileset.Type.MANAGED,
  "file:/tmp/root/schema/local_fileset",
  propertiesMap,
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgxx3li3pfnpzc11n8zg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgxx3li3pfnpzc11n8zg.png" alt=" " width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After creating a Fileset catalog, we can use &lt;a href="https://datastrato.ai/docs/0.5.0/how-to-use-gvfs#introduction" rel="noopener noreferrer"&gt;Gravitino Virtual Filesystem&lt;/a&gt; to manage the data using Fileset virtual path:&lt;/p&gt;

&lt;h3&gt;
  
  
  Java
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Configuration conf = new Configuration();
conf.set("fs.AbstractFileSystem.gvfs.impl","com.datastrato.gravitino.filesystem.hadoop.Gvfs");
conf.set("fs.gvfs.impl","com.datastrato.gravitino.filesystem.hadoop.GravitinoVirtualFileSystem");
conf.set("fs.gravitino.server.uri","http://localhost:8090");
conf.set("fs.gravitino.client.metalake","metalake");
Path filesetPath = new Path("gvfs://fileset/fileset_catalog/test_schema/test_fileset_1");
FileSystem fs = filesetPath.getFileSystem(conf);
fs.getFileStatus(filesetPath);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Spark
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.apache.spark.sql.SparkSession

val spark = SparkSession.builder()
  .appName("DataFrame Example")
  .getOrCreate()

// Assuming the file format is text, we use `text` method to read as a DataFrame
val df = spark.read.text("gvfs://fileset/test_catalog/test_schema/test_fileset_1")

// Show the contents of the DataFrame using `show`
// Setting truncate to false to show the entire content of the row if it is too long
df.show(truncate = false)

// Alternatively, to print the DataFrame contents to the console in a plain format like `foreach(println)`:
df.collect().foreach(println)

// Stop the SparkSession
spark.stop()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Further details can be found in &lt;a href="https://datastrato.ai/docs/0.5.0/hadoop-catalog" rel="noopener noreferrer"&gt;hadoop-catalog&lt;/a&gt; and &lt;a href="https://datastrato.ai/docs/0.5.0/how-to-use-gvfs#introduction" rel="noopener noreferrer"&gt;Gravitino Virtual Filesystem&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Messaging data support
&lt;/h3&gt;

&lt;p&gt;Along with the previously mentioned unstructured data,real-time data analytics and processing has now become commonplace in many modern data systems. To facilitate the management of these systems, Gravitino now supports messaging-type data, including Apache Kafka and Kafka-compatible messaging systems. Users can now seamlessly manage their messaging data alongside their other data sources in a unified way using Gravitino. (&lt;a href="https://github.com/datastrato/gravitino/issues/2369" rel="noopener noreferrer"&gt;Issue #2369&lt;/a&gt;, further information can be found at kafka-catalog).&lt;/p&gt;

&lt;p&gt;The following is an example of how to create a Kafka catalog, more can be found in &lt;a href="https://datastrato.ai/docs/0.5.0/kafka-catalog" rel="noopener noreferrer"&gt;Kafka catalog&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shell
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
-H "Content-Type: application/json" -d '{
  "name": "catalog",
  "type": "MESSAGING",
  "comment": "comment of kafka catalog",
  "provider": "kafka",
  "properties": {
  "bootstrap.servers": "localhost:9092",
  }
}' http://localhost:8090/api/metalakes/metalake/catalogs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Java
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GravitinoClient gravitinoClient = GravitinoClient
.builder("http://127.0.0.1:8090")
.withMetalake("metalake")
.build();

Map&amp;lt;String, String&amp;gt; properties = ImmutableMap.&amp;lt;String, String&amp;gt;builder()
// You should replace the following with your own Kafka bootstrap servers that Gravitino can connect to.
.put("bootstrap.servers", "localhost:9092")
.build();


Catalog catalog = gravitinoClient.createCatalog(
NameIdentifier.of("metalake", "catalog"),
Type.MESSAGING,
"kafka", // provider, Gravitino only supports "kafka" for now.
"This is a Kafka catalog",
properties);
// ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Python client support
&lt;/h3&gt;

&lt;p&gt;Python is the #1 most popular AI/ML programming language, hosting some of the most popular machine learning frameworks such as PyTorch, Tensorflow, and Ray. Like a lot of other core infrastructure tools, Gravitino was originally written in Java but now has added a Python client so that users can use our data management features directly from their Python IDE of choice, like Jupyter-notebook. This allows data engineers and machine learning scientists to consume the metadata in Gravitino natively using Python. Note that currently only Fileset type catalogs are supported through the Python client. (&lt;a href="https://github.com/datastrato/gravitino/issues/2229" rel="noopener noreferrer"&gt;Issue #2229&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The following code is a simple example of how to use the Python client to connect with Gravitino.&lt;/p&gt;

&lt;p&gt;Python&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider: str = "hadoop"

// Related NameIdentifer
schema_ident: NameIdentifier = NameIdentifier.of_schema(metalake_name, catalog_name, schema_name)
fileset_ident: NameIdentifier = NameIdentifier.of_fileset(metalake_name, catalog_name, schema_name, fileset_name)

// Init Gravitino client
gravitino_client = GravitinoClient(uri="http://localhost:8090", metalake_name=metalake_name)

// Create catalog
catalog = gravitino_client.create_catalog(
    ident=catalog_ident,
    type=Catalog.Type.FILESET,
    provider=provider,
    comment="catalog comment",
    properties={}
)

// Create schema
catalog.as_schemas().create_schema(ident=schema_ident, comment="schema comment", properties={})

// Create a fileset
fileset = catalog.as_fileset_catalog().create_fileset(ident=fileset_ident,type=Fileset.Type.MANAGED,comment="comment of fileset",storage_location="file:/tmp/root/schema/local_file",properties={})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Apache Doris support
&lt;/h3&gt;

&lt;p&gt;Tagging onto our Real-Time Analytics support, we are now also supporting &lt;a href="https://doris.apache.org/" rel="noopener noreferrer"&gt;Apache Doris&lt;/a&gt; in this release. Doris is a high-performance, real-time analytical data warehouse that is known for its speed and ease of use. By adding a Doris catalog, engineers implementing Gravitino will now have more flexibility in their cataloging options for their analytical workloads. (&lt;a href="https://github.com/datastrato/gravitino/issues/1339" rel="noopener noreferrer"&gt;Issue #1339&lt;/a&gt;, visit jdbc-doris-catalog for specifics). Related user documents can be found &lt;a href="https://datastrato.ai/docs/0.5.0/jdbc-doris-catalog" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Empowering operations with event listener system
&lt;/h3&gt;

&lt;p&gt;To complement our efforts in enabling real-time, dynamic data infrastructures, Gravitino’s 0.5.0 release now also includes a new Event Listener System for applications to plug into. This new system allows users to track and handle all operational events through use of a hook mechanism for custom events, enhancing capabilities in auditing, real-time monitoring, observability, and integration with other applications. (&lt;a href="https://github.com/datastrato/gravitino/issues/2233" rel="noopener noreferrer"&gt;Issue #2233&lt;/a&gt;, detailed at event-listener-configuration). You can refer to the &lt;a href="https://datastrato.ai/docs/0.5.0/gravitino-server-config#event-listener-configuration" rel="noopener noreferrer"&gt;event listener system&lt;/a&gt; for more information.&lt;/p&gt;

&lt;h3&gt;
  
  
  JDBC storage backend
&lt;/h3&gt;

&lt;p&gt;Diversifying its storage options, Gravitino 0.5.0 now supports JDBC backends other than KV storage. This allows the use of popular databases like MySQL or PostgreSQL as the entity store. (&lt;a href="https://github.com/datastrato/gravitino/issues/1811" rel="noopener noreferrer"&gt;Issue #1811&lt;/a&gt;, check out storage-configuration for further insights). Users only need to replace the following configurations in the configuration file to use the JDBC storage backend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Yaml
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gravitino.entity.store = relational
gravitino.entity.store.relational = JDBCBackend
gravitino.entity.store.relational.jdbcUrl = jdbc:mysql://localhost:3306/mydb
gravitino.entity.store.relational.jdbcDriver = com.mysql.cj.jdbc.Driver
gravitino.entity.store.relational.jdbcUser = user
gravitino.entity.store.relational.jdbcPassword = password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Bug fixes and optimizations
&lt;/h3&gt;

&lt;p&gt;Gravitino 0.5.0 also contains many bug fixes and optimizations that enhance overall system stability and performance. These improvements address issues that have been identified by the community through issues and direct feedbacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overall
&lt;/h2&gt;

&lt;p&gt;We show appreciation to the Gravitino community for their continued support and valuable contributions, including feedback and testing. Thanks to the vocal feedback of our users that we are able to innovate and build, so cheers to all those reading this!&lt;/p&gt;

&lt;p&gt;To explore Gravitino 0.5.0 release in full, please check &lt;a href="https://datastrato.ai/docs/0.5.0/" rel="noopener noreferrer"&gt;the documentation&lt;/a&gt; and &lt;a href="https://github.com/datastrato/gravitino/releases/tag/v0.5.0" rel="noopener noreferrer"&gt;release notes&lt;/a&gt;. Your feedback is invaluable to the community and the project.&lt;/p&gt;

&lt;p&gt;Enjoy the Data and AI journey with Gravitino 0.5.0!&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;br&gt;
Apache®, &lt;a href="http://doris.apache.org/" rel="noopener noreferrer"&gt;Apache Doris™&lt;/a&gt;, &lt;a href="http://doris.apache.org/" rel="noopener noreferrer"&gt;Doris™&lt;/a&gt;, &lt;a href="http://hadoop.apache.org/" rel="noopener noreferrer"&gt;Apache Hadoop®&lt;/a&gt;, &lt;a href="http://hadoop.apache.org/" rel="noopener noreferrer"&gt;Hadoop®&lt;/a&gt;, &lt;a href="http://kafka.apache.org/" rel="noopener noreferrer"&gt;Apache Kafka®&lt;/a&gt;, &lt;a href="http://kafka.apache.org/" rel="noopener noreferrer"&gt;Kafka®&lt;/a&gt;, &lt;a href="http://spark.apache.org/" rel="noopener noreferrer"&gt;Apache Spark&lt;/a&gt;, &lt;a href="http://spark.apache.org/" rel="noopener noreferrer"&gt;Spark™&lt;/a&gt;, are either registered trademarks or trademarks of the &lt;a href="https://www.apache.org/" rel="noopener noreferrer"&gt;Apache Software Foundation&lt;/a&gt; in the United States and/or other countries. Java and MySQL are registered trademarks of Oracle and/or its affiliates. Python is a registered trademark of the Python Software Foundation. PostgreSQL is a registered trademark of the PostgreSQL Community Association of Canada.&lt;br&gt;
&lt;/small&gt;&lt;/p&gt;

</description>
      <category>gravatino</category>
      <category>spark</category>
      <category>nontabulardata</category>
      <category>messagingcatalog</category>
    </item>
    <item>
      <title>How to Implement a REST Catalog for Apache Iceberg</title>
      <dc:creator>Alex Yan</dc:creator>
      <pubDate>Mon, 11 Aug 2025 16:29:01 +0000</pubDate>
      <link>https://dev.to/datastrato/how-to-implement-a-rest-catalog-for-apache-iceberg-1end</link>
      <guid>https://dev.to/datastrato/how-to-implement-a-rest-catalog-for-apache-iceberg-1end</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ifeq2laid1m14hvq1p5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ifeq2laid1m14hvq1p5.png" alt="Blue Yellow Futuristic Virtual Technology Blog Banner" width="627" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Data Catalogs can be extremely useful for understanding your data at a glance. By making your data catalogs available in a REST API format it becomes widely available for applications and users to pull from, but more importantly, you can also use it to manage your data catalog by plugging it into other frameworks. Today we’ll review how to use a REST Catalog for Apache Iceberg.&lt;/p&gt;

&lt;p&gt;Since the current &lt;a href="https://iceberg.apache.org/releases/" rel="noopener noreferrer"&gt;Apache Iceberg version (1.5.1)&lt;/a&gt; does not natively support a REST Catalog, we will use &lt;a href="https://github.com/datastrato/gravitino" rel="noopener noreferrer"&gt;Gravitino&lt;/a&gt;, an open-source metadata lake and data catalog. It provides a standard REST catalog for Apache Iceberg. Throughout this process, you can also refer to Gravitino’s &lt;a href="https://datastrato.ai/docs/0.5.0" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;. They’ve also released some blog posts that are helpful for today, such as &lt;a href="https://datastrato.ai/blog/gravitino-unified-metadata-lake" rel="noopener noreferrer"&gt;“Gravitino: the unified metadata lake”&lt;/a&gt;, &lt;a href="https://datastrato.ai/blog/i/blog/gravitino-iceberg-rest-catalog-service" rel="noopener noreferrer"&gt;“Gravitino: Next-Gen REST Catalog for Iceberg, and Why You Need It”&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Today however, we will go over how to leverage their Iceberg REST Catalog service instead of building it from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Getting the Gravitino package
&lt;/h2&gt;

&lt;p&gt;You can either download the latest version binary package from the Gravitino Github &lt;a href="https://github.com/datastrato/gravitino/releases/download/v0.5.0/gravitino-0.5.0-bin.tar.gz" rel="noopener noreferrer"&gt;releases&lt;/a&gt;, or use the following code to checkout and build from source locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone git@github.com:datastrato/gravitino.git

// You will see some output here of git retrieving and downloading the repo locally

cd gravitino
./gradlew clean assembleDistribution -x test

// Build the package, this may take a minute and check the output that it built successfully

ls distribution/gravitino-0.5.0-bin.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To do the initial installation, you will need to first clone the repository using git and then build the package using &lt;a href="https://docs.gradle.org/current/userguide/userguide.html" rel="noopener noreferrer"&gt;Gradle&lt;/a&gt;, a popular JVM build tool. Although everything you need is in the repository, you will need to make sure you have a Java version supported (e.g. JDK 8, 11, or 17). If you would rather build Gravitino from source code, please refer to the &lt;a href="https://datastrato.ai/docs/0.5.0/how-to-build" rel="noopener noreferrer"&gt;build doc&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;After building, decompress the package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd distribution

tar xfz gravitino-0.5.0-bin.tar.gz
cd gravitino-0.5.0-bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Launching the Iceberg REST catalog
./bin/gravitino.sh start
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Log dir doesn't exist, create /Users/user/Downloads/gravitino/distribution/gravitino-0.5.0-bin/logs
Gravitino Server start success!
Gravitino Server is running[PID:38047]
// Check server process started, will see the GravitinoServer process
jps | grep GravitinoServer
// Check interface works as expected, like `{"defaults":{},"overrides":{}}`
curl http://127.0.0.1:9001/iceberg/v1/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running the Gravitino script will then start the Gravitino server. If there are no errors returned you can assume the Iceberg REST catalog service is started and listening on local port 9001. If you want to, you could add more configurations in &lt;code&gt;conf/gravitino.conf&lt;/code&gt;. There are two locations for logging you can check: &lt;code&gt;logs/gravitino-server.log&lt;/code&gt; and &lt;code&gt;logs/gravitino-server.out&lt;/code&gt;. Below are some critical configuration items listed, but you can also refer to the &lt;a href="https://datastrato.ai/docs/0.5.0/iceberg-rest-service/ho" rel="noopener noreferrer"&gt;Iceberg REST catalog service document&lt;/a&gt; for details.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Configuration item&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;gravitino.auxService.names&lt;/td&gt;
&lt;td&gt;Must specify &lt;code&gt;iceberg-rest&lt;/code&gt; to start Iceberg REST service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gravitino.auxService.iceberg-rest.catalog-backend&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;memory&lt;/code&gt; is the default mainly used to test, could use &lt;code&gt;hive&lt;/code&gt; or &lt;code&gt;jdbc&lt;/code&gt; for production.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  3. Using the Iceberg REST catalog
&lt;/h2&gt;

&lt;p&gt;Using Spark as an example, we can configure the Spark catalog options to use the Gravitino Iceberg REST catalog with the name &lt;code&gt;“rest”&lt;/code&gt;. This then allows us to directly query the Iceberg Catalog using SparkSQL - the same can be done with Trino, for instance.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run spark-sql shell using the following cmd and set the following configurations. Please note in the case below, we are using Spark version 3.4, Scala version 2.12 and Iceberg version 1.3.1. You may need to adjust the jar file (provided by Iceberg project) according to the actual version in your environment.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./bin/spark-sql -v \
--packages org.apache.iceberg:iceberg-spark-runtime-3.4_2.12:1.3.1 \
--conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
--conf spark.sql.catalog.rest=org.apache.iceberg.spark.SparkCatalog  \
--conf spark.sql.catalog.rest.type=rest  \
--conf spark.sql.catalog.rest.uri=http://127.0.0.1:9001/iceberg/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For convenience, you can also place your configuration settings in &lt;code&gt;conf/spark-defaults.conf&lt;/code&gt;. This approach gets rid of specifying configs each time you run Spark and ensures the consistency for your cluster. Here is an example of what this file may look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spark.sql.extensions    org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
spark.sql.catalog.rest         org.apache.iceberg.spark.SparkCatalog
spark.sql.catalog.rest.type    rest
spark.sql.catalog.rest.uri     http://127.0.0.1:9001/iceberg/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exploring your new catalog with Spark SQL&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;USE rest;
CREATE DATABASE IF NOT EXISTS dml;
CREATE TABLE dml.test (id bigint COMMENT 'unique id') using iceberg;
DESCRIBE TABLE EXTENDED dml.test;
INSERT INTO dml.test VALUES (1), (2);
SELECT * FROM dml.test;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, Spark will now default to using the Iceberg REST catalog service. You can also check the Gravitino &lt;a href="https://datastrato.ai/docs/0.5.0/iceberg-rest-service/" rel="noopener noreferrer"&gt;Iceberg REST catalog service document&lt;/a&gt;, or contact the developers on their community &lt;a href="https://join.slack.com/t/datastrato-community/shared_invite/zt-2a8vsjoch-cU_uUwHA_QU6Ab50thoq8w" rel="noopener noreferrer"&gt;Slack channel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Supported versions&lt;br&gt;
We have verified the following versions in our testbed and some community users’ deployment. If you have different versions of compute engines and want to verify the build, please let the developers know by filing an issue on Github or messaging them on &lt;a href="https://join.slack.com/t/datastrato-community/shared_invite/zt-2a8vsjoch-cU_uUwHA_QU6Ab50thoq8w" rel="noopener noreferrer"&gt;slack&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Engine&lt;/th&gt;
&lt;th&gt;Supported versions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Spark&lt;/td&gt;
&lt;td&gt;3.0 and above&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flink&lt;/td&gt;
&lt;td&gt;1.13 and above&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trino&lt;/td&gt;
&lt;td&gt;405 and above&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
    </item>
    <item>
      <title>Community Voices - At Xiaomi, where are we heading with Gravitino</title>
      <dc:creator>Alex Yan</dc:creator>
      <pubDate>Mon, 11 Aug 2025 16:28:53 +0000</pubDate>
      <link>https://dev.to/datastrato/community-voices-at-xiaomi-where-are-we-heading-with-gravitino-18p0</link>
      <guid>https://dev.to/datastrato/community-voices-at-xiaomi-where-are-we-heading-with-gravitino-18p0</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88oy4pmzb7pz7d0zbr12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88oy4pmzb7pz7d0zbr12.png" alt="gravitino-xiaomi&amp;lt;br&amp;gt;
" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Xiaomi Inc. is a consumer electronics and smart manufacturing company with smartphones, smart hardware and electric cars connected by an IoT platform at its core. As of 2023, Xiaomi was ranked among the top 3 in the global smartphone market, according to Canalys, and listed as Fortune Global 500 for the 5th consecutive year.&lt;/p&gt;

&lt;p&gt;The Xiaomi Cloud Computing Platform team is dedicated to providing reliable and secure data computing and processing capabilities for Xiaomi's business. We actively contribute to many open-source projects, covering storage, computing, resource scheduling, message queue, data lake, etc. By leveraging these advanced technologies, our team has achieved significant milestones, including winning the Xiaomi Million-dollar Technology Award Finalist.&lt;/p&gt;

&lt;p&gt;This article focuses on the use of Gravitino in Xiaomi, providing solutions to future work plans and general guidance. There are, as follows, three key points and we look forward to growing our data-driven business with Gravitino.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unifying our metadata&lt;/li&gt;
&lt;li&gt;Integrating data and AI asset management&lt;/li&gt;
&lt;li&gt;Unifying user permission management&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  1. Unify our metadata
&lt;/h2&gt;

&lt;p&gt;With the introduction of multi-regional or multi-cloud deployment, the problem of data silos becomes even more pronounced. It becomes challenging to maintain a unified view of the data across different regions or cloud providers. This is really true for Xiaomi. &lt;a href="https://datastrato.ai/blog/gravitino-unified-metadata-lake" rel="noopener noreferrer"&gt;Gravitino provides a solution to such challenges&lt;/a&gt;, and helps break down the data silos. It aims to solve such problems in data management, governance, and analysis in a multi-cloud architecture.&lt;/p&gt;
&lt;h3&gt;
  
  
  Gravitino's position in Xiaomi's data platform
&lt;/h3&gt;

&lt;p&gt;Gravitino, highlighted in green and yellow in the diagram below, has the following features that we need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unified Metadata Lake&lt;/strong&gt;: As a unified data catalog, it supports multiple data sources, computing engines, and data platforms for data development, management, and governance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time and Consistency&lt;/strong&gt;: Real-time acquisition of metadata to ensure SSOT (Single Source of Truth).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Registration&lt;/strong&gt;: Supports adding/altering the data catalog on the fly, no need to restart the service, which makes maintenance and upgrades much easier than before.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Engines Support&lt;/strong&gt;: not only Data engines, like: Trino, Apache Spark, Apache Flink (WIP), but also AI/ML frameworks, such as Tensorflow (WIP), PyTorch (WIP) and Ray (WIP).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Storage Support&lt;/strong&gt;: Supports both Data and AI domain-specific storages, including HDFS/Hive, Iceberg, RDBMS, as well as NAS/CPFS, JuiceFS, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eco-friendly&lt;/strong&gt;: Supports using external Apache Ranger for permission management, external event bus for audit and notification, and external SchemaRegistry for messaging catalog.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feature is still in active development&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn8n2haejlfwppeomk0wx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn8n2haejlfwppeomk0wx.png" alt=" " width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Unified metadata lake, unified management
&lt;/h3&gt;

&lt;p&gt;As the type of data sources becomes more and more abundant, computing engines like Trino, Spark and Flink need to maintain a long list of the source catalogs for each of them. That introduces a lot of duplicated and complicated maintenance work.&lt;/p&gt;

&lt;p&gt;To build fabric among multiple data sources and computing engines, it is often expected to manage all kinds of data catalogs in one place, and then use a unified service to expose those metadata. Gravitino is extremely useful in this context as it provides a unified metadata lake to standardize the data catalog operations, and unify all metadata management and governance.&lt;/p&gt;
&lt;h3&gt;
  
  
  User Story
&lt;/h3&gt;

&lt;p&gt;Users can use a three-level coordinate: &lt;code&gt;catalog.schema.entity&lt;/code&gt; to describe all the data, and used for data integration, federated queries, etc. What is exciting is that engines no longer need to maintain complex and tedious data catalogs, which simplifies the complexity of &lt;em&gt;&lt;code&gt;O(M*N)&lt;/code&gt;&lt;/em&gt; to &lt;em&gt;&lt;code&gt;O(M+N)&lt;/code&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: M represents the number of engines, N represents the number of data sources.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Furthermore, we can use a simple and unified language to make data integration and federated queries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apache Spark: Writing to Apache Doris from Apache Hive (with Gravitino Spark connector).
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSERT INTO doris_cluster_a.doris_db.doris_table
SELECT
    goods_id,
    goods_name,
    price
FROM
    hive_cluster_a.hive_db.hive_table

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Trino: Making a query between Hive and Apache Iceberg (with Gravitino Trino connector).
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT
    *
FROM
    hive_cluster_b.hive_db.hive_table a
JOIN
    iceberg_cluster_b.iceberg_db.iceberg_table b
ON a.name = b.name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  2. Integrate data and AI asset management
&lt;/h2&gt;

&lt;p&gt;In the realm of big data, we have made significant progress through data lineage, access measurement, and life cycle management. However, in the domain of AI, non-tabular data has always been the most challenging aspect of data management and governance, encompassing HDFS files, NAS files, and other formats.&lt;/p&gt;
&lt;h3&gt;
  
  
  Challenges of AI asset management
&lt;/h3&gt;

&lt;p&gt;In the realm of machine learning, the process of reading and writing files is very flexible. Users can use various formats, such as &lt;em&gt;Thrift-Sequence&lt;/em&gt;, &lt;em&gt;Thrift-Parquet&lt;/em&gt;, &lt;em&gt;Parquet&lt;/em&gt;, &lt;em&gt;TFRecord&lt;/em&gt;, &lt;em&gt;JSON&lt;/em&gt;, &lt;em&gt;text&lt;/em&gt;, and more. Additionally, they can leverage multiple programming languages, including Scala, SQL, Python, and others. To manage our AI assets, we need to take into account these diverse uses and ensure adaptability and compatibility.&lt;/p&gt;

&lt;p&gt;Similar to tabular data management, non-tabular data also needs to adapt to a variety of engines and storages, including frameworks like PyTorch and TensorFlow, as well as various storage interfaces like &lt;em&gt;FileSystem&lt;/em&gt; for file sets, &lt;em&gt;FUSE&lt;/em&gt; for instance disk, &lt;em&gt;CSI&lt;/em&gt; for container storage.&lt;/p&gt;
&lt;h3&gt;
  
  
  Non-tabular data management architecture
&lt;/h3&gt;

&lt;p&gt;We aim to establish AI asset management capabilities by leveraging Gravitino, whose core technologies are outlined in the figure below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Non-tabular data catalog management&lt;/em&gt;&lt;/strong&gt;: Achieving the auditing for AI assets, and the assurance of the specification for file paths;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;File interface support&lt;/em&gt;&lt;/strong&gt;: Ensuring seamless compatibility with various file interfaces:

&lt;ul&gt;
&lt;li&gt;Hadoop File System: Achieving the compatibility with the Hadoop file system through GVFS (Gravitino Virtual File System).&lt;/li&gt;
&lt;li&gt;CSI Driver: Facilitating the reading and writing of files within container storage.&lt;/li&gt;
&lt;li&gt;FUSE Driver: Enabling the reading and writing of files directly on the physical machine disk.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI asset lifecycle management&lt;/strong&gt;: Implementing TTL (Time-To-Live) management for non-tabular data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtb1nnrpuuw5blfev8fb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtb1nnrpuuw5blfev8fb.png" alt=" " width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  User story
&lt;/h3&gt;

&lt;p&gt;We expect that the migration process for users from the original way to the new approach will be straightforward and seamless. In fact, the transition involves just two steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a fileset catalog with the storage location, and configure the TTL (Time-To-Live) on the Gravitino-based data platform.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace the original file path with a new way: &lt;em&gt;&lt;code&gt;gvfs://&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To illustrate, let's consider the example of Spark reading HDFS files as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 1.Structured data - Parquet
val inputPath = "hdfs://cluster_a/database/table/date=20240309"
val df = spark.read.parquet(inputPath).select()...
val outputPath = "hdfs://cluster_a/database/table/date=20240309/hour=00"
df.write().format("parquet").mode(SaveMode.Overwrite).save(outputPath)
// 2.Semi-structured data - Json
inputPath = "hdfs://cluster_a/database/table/date=20240309_${date-7}/xxx.json"
val fileRDD = sc.read.json(inputPath)
// 3.Unstructured data - Text
val inputPath = "hdfs://cluster_a/database/table/date=20240309_12"
val fileRDD = sc.read.text(inputPath)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Leveraging Gravitino, we create a fileset called “myfileset” that is pointing to the origin HDFS, then we can replace the original hdfs://xxx with the new gvfs://fileset/xxx approach, offering users a seamless and intuitive way to upgrade. Users will no longer have to care about the real storage location.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 1.Structured data - Parquet
val inputPath = "gvfs://fileset/myfileset/database/table/date=20240309"
val df = spark.read.parquet(inputPath).select()...
val outputPath = "gvfs://fileset/myfileset/database/table/date=20240309/hour=00"
df.write().format("parquet").mode(SaveMode.Overwrite).save(outputPath)
// 2.Semi-structured data - Json
inputPath = "gvfs://fileset/myfileset/database/table/date=20240309_${date-7}/xxx.json"
val fileRDD = sc.read.json(inputPath)
// 3.Unstructured data - Text
val inputPath = "gvfs://fileset/myfileset/database/table/date=20240309_12")
val fileRDD = sc.read.text(inputPath)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As previously mentioned, file reading and writing exhibit a lot of flexibility, it also adapts to diverse engines. Instead of enumerating individual examples, the overarching principle remains that users should be able to manage and govern non-tabular data with minimal modifications.&lt;/p&gt;

&lt;p&gt;Many challenges within AI asset management require exploration and development work. It includes specifying the depth and date of file paths, facilitating data sharing, exploring non-tabular data reading and writing solutions based on the data lake like Iceberg. Those will be our focus in the near future.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Unify user permission management
&lt;/h2&gt;

&lt;p&gt;Metadata and user permission information are so close to each other, and it is always a good idea to manage them together. The metadata service also needs to integrate user permission-related capabilities to authenticate resource operations. We expect to achieve this in our data platform by leveraging Gravitino.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenges of unified authentication across multi-system
&lt;/h3&gt;

&lt;p&gt;In order to provide users with a seamless data development experience, the data platform often needs to be integrated with various storage and computation systems. However, such integrations often lead to the challenge of managing multiple systems and accounts.&lt;/p&gt;

&lt;p&gt;Users need to authenticate themselves using different accounts in different systems like HDFS (Kerberos), Doris (User/Password), and Talos (AK/SK - Xiaomi IAM account). Such fragmented authentication and authorization processes significantly slow and can even block development.&lt;/p&gt;

&lt;p&gt;To address this issue, a crucial step for a streamlined data development platform is to shield the complexity of different account systems and establish a unified authorization framework to increase the efficiency of data development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unified user permissions based on workspace
&lt;/h3&gt;

&lt;p&gt;Xiaomi's data platform is designed around the concept of Workspace and utilizes the RBAC (Role-Based Access Control) permission model. Gravitino allows us to generate what we call "&lt;em&gt;mini-accounts&lt;/em&gt;" (actual resource accounts, such as &lt;em&gt;HDFS-Kerberos&lt;/em&gt;) within the workspace, effectively shielding users from the complexities of &lt;em&gt;Kerberos&lt;/em&gt;, &lt;em&gt;User/Password&lt;/em&gt;, and &lt;em&gt;IAM/AKSK&lt;/em&gt; accounts.&lt;/p&gt;

&lt;p&gt;Here are the key components of this setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Workspace&lt;/em&gt;&lt;/strong&gt;: Workspaces serve as the smallest operational unit within the data platform, containing all associated resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Role&lt;/em&gt;&lt;/strong&gt;: Identities within the workspace, such as Admin, Developer, and Guest. Each role is granted different permissions for accessing workspace resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Resource&lt;/em&gt;&lt;/strong&gt;: Resources within the workspace, such as &lt;code&gt;catalog.database.table&lt;/code&gt;, are abstracted into three-level coordinates thanks to unified metadata.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Permission&lt;/em&gt;&lt;/strong&gt;: Permissions determine the level of control granted to users for operating resources within the workspace, including admin, write, and read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Token&lt;/em&gt;&lt;/strong&gt;: A unique ID used to identify individuals within the workspace.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Authentication&lt;/em&gt;&lt;/strong&gt;: API operations are authenticated using tokens, while IAM identities are carried through UI operations after login.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Authorization&lt;/em&gt;&lt;/strong&gt;: Authorization is managed through Apache Ranger, granting the necessary permissions to authenticated workspace roles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Mini-account&lt;/em&gt;&lt;/strong&gt;: Each workspace has a dedicated set of proxy accounts to access the resources, such as HDFS (Kerberos) or Apache Doris (User/Password). When the engine accesses the underlying resources, it seamlessly utilizes the corresponding mini-account authentication for each resource. However, the entire process remains transparent to the user, who only needs to focus on managing workspace permissions (which are equivalent to resource permissions by leveraging Gravitino).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  User story
&lt;/h3&gt;

&lt;p&gt;The figure below shows a brief process for users to create and access resources on our data platform:&lt;/p&gt;

&lt;p&gt;All users are only aware of the workspace identity and workspace permissions.&lt;/p&gt;

&lt;p&gt;Upon creating a workspace, a suite of workspace proxy mini-accounts is automatically created. Whenever resources are created or imported within the workspace, the corresponding proxy mini-account is authorized with the necessary resource permissions.&lt;/p&gt;

&lt;p&gt;When a user attempts to read or write to a resource, the system verifies their workspace permissions. If the workspace permission check is successful, the engine utilizes the mini-account to perform the desired read or write operation on the resource.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw97vjw83njrnr7n685cj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw97vjw83njrnr7n685cj.png" alt=" " width="800" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this blog, we showcase three important scenarios at Xiaomi that we’re using Gravitino to accomplish - most of the critical work has been done, the rest are ongoing with good progress. We're confident in the successful landing of all above scenarios in Xiaomi to support our data-driven business in a better way, and we are glad to be part of the Gravitino community to co-create the potential de-facto standard of the unified metadata lake.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Introducing Gravitino 0.4.0</title>
      <dc:creator>Alex Yan</dc:creator>
      <pubDate>Mon, 11 Aug 2025 16:28:45 +0000</pubDate>
      <link>https://dev.to/datastrato/introducing-gravitino-040-3n0n</link>
      <guid>https://dev.to/datastrato/introducing-gravitino-040-3n0n</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsxs5x9fcngko6lz1sag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsxs5x9fcngko6lz1sag.png" alt="Introducing Gravitino 0.4.0" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today, we are pleased to announce the release of Gravitino 0.4.0. This version is a stable release, which includes more than 280 bug fixes as well as a bunch of new features.&lt;/p&gt;

&lt;p&gt;In this blog post, we will walk you through the highlights of Gravitino 0.4.0, giving you a quick overview of features and enhancements. To learn more about the nitty-gritty details, we recommend going through the comprehensive Gravitino 0.4.0 &lt;a href="https://github.com/datastrato/gravitino/releases/tag/v0.4.0" rel="noopener noreferrer"&gt;release notes&lt;/a&gt;, which include a full list of major features and resolved issues across all Gravitino components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Public preview of Gravitino web UI
&lt;/h2&gt;

&lt;p&gt;With the release of Gravitino 0.4.0, we are excited to announce the public preview of Gravitino’s web UI. This greatly improves the user experience of Gravitino.&lt;/p&gt;

&lt;p&gt;Gravitino web UI supports the creation, updating, and deletion of metadata such as metalakes and catalogs. Additionally, it can list and display schemas, tables, columns, and their detailed information. You can access the UI by visiting the URL &lt;code&gt;http://{gravitino-host}:8090&lt;/code&gt; in your browser.&lt;/p&gt;

&lt;p&gt;Here is the screenshot of Gravitino’s UI, you can manage metalakes in the UI as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F297tf0elt96hji4i9otm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F297tf0elt96hji4i9otm.png" alt="metalakes" width="800" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Within each metalake, you can also manage catalogs, the UI will list all the catalogs in a tree structure with schemas and tables under them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fshm94f9aq7m5ot1p58n9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fshm94f9aq7m5ot1p58n9.png" alt="catalogs" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1htdlor8rmsr6e3072uk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1htdlor8rmsr6e3072uk.png" alt="tables" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Unified support of partition management
&lt;/h2&gt;

&lt;p&gt;One of the new features added in Gravitino 0.4.0 is to support unified partition management for tables. With Gravitino, you can create, list, get, and delete partitions from different sources via the REST API and Java API in a unified way.&lt;/p&gt;

&lt;p&gt;Gravitino provides a generic representation of partition definition. It can support Identity Partition (Hive’s partition definition), as well as List Partition and Range Partition supported by other engines.&lt;/p&gt;

&lt;p&gt;Here is a brief example of how to use Gravitino to manage partitions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shell
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
-H "Content-Type: application/json" -d '{
  "partitions": [
    {
      "type": "identity",
      "fieldNames": [
        [
          "dt"
        ],
        [
          "country"
        ]
      ],
      "values": [
        {
          "type": "literal",
          "dataType": "date",
          "value": "2008-08-08"
        },
        {
          "type": "literal",
          "dataType": "string",
          "value": "us"
        }
      ]
    }
  ]
}' http://localhost:8090/api/metalakes/metalake/catalogs/catalog/schemas/schema/tables/table/partitions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Java
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GravitinoClient gravitinoClient = GravitinoClient
    .builder("http://localhost:8090")
    .build();

// Assumes that you have a partitioned table named "metalake.catalog.schema.table".
Partition addedPartition =
    gravitinoClient
        .loadMetalake(NameIdentifier.of("metalake"))
        .loadCatalog(NameIdentifier.of("metalake", "catalog"))
        .asTableCatalog()
        .loadTable(NameIdentifier.of("metalake", "catalog", "schema", "table"))
        .supportPartitions()
        .addPartition(
            Partitions.identity(
              new String[][] {{"dt"}, {"country"}},
              new Literal[] {
              Literals.dateLiteral(LocalDate.parse("2008-08-08")), Literals.stringLiteral("us")},
              Maps.newHashMap()));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more details, you can refer to Gravitino’s &lt;a href="https://datastrato.ai/docs/0.4.0/manage-table-partition-using-gravitino" rel="noopener noreferrer"&gt;partition management documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Support column default values, auto increment, and table indexes
&lt;/h2&gt;

&lt;p&gt;As a unified metadata lake, Gravitino’s goal is to provide a unified representation of different metadata. In version 0.4.0, we have included supporting default values and auto increment in column definitions, as well as indexes in tables.&lt;/p&gt;

&lt;p&gt;Users can now create tables with default values and auto increment specified in column definitions, indexes specified in table definitions.&lt;/p&gt;

&lt;p&gt;Here’s also a brief example of how to use them in table creation:&lt;/p&gt;

&lt;h3&gt;
  
  
  Shell
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
-H "Content-Type: application/json" -d '{
  "name": "table",
  "columns": [
    {
      "name": "id",
      "type": "integer",
      "nullable": true,
      "autoIncrement": true,
      "comment": "Id of the user"
    },
    {
      "name": "name",
      "type": "varchar(1000)",
      "nullable": true,
      "comment": "Name of the user"
    },
    {
      "name": "age",
      "type": "integer",
      "nullable": false,
      "comment": "Age of the user"
      "defaultValue": {
        "type": "literal",
        "dataType": "integer",
        "value": "-1"
      }
    },
    {
      "name": "score",
      "type": "double",
      "nullable": true,
      "comment": "Score of the user"
    }
  ],
  "comment": "A user table with detailed information",
  "indexes": [
    {
      "indexType": "PRIMARY_KEY",
      "name": "PRIMARY",
      "fieldNames": [["id"]]
    },
    {
      "indexType": "UNIQUE_KEY",
      "name": "name_age_score_uk",
      "fieldNames": [["name"],["age"],["score]]
    }
  ]
}' http://localhost:8090/api/metalakes/metalake/catalogs/catalog/schemas/schema/tables
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Java
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tableCatalog.createTable(
    NameIdentifier.of("metalake", "hive_catalog", "schema", "table"),
    new Column[] {
      Column.of("id", Types.IntegerType.get(), "Id of the user", false, true, null),
      Column.of("name", Types.VarCharType.of(1000), "Name of the user", true, false, null),
      Column.of("age", Types.IntergerType.get(), "Age of the user", false, false, Literals.integerLiteral(-1)),
      Column.of("score", Types.DoubleType.get(), "Score of the user", true, false, null)
    },
    "A user table with detailed information",
    tablePropertiesMap,
    Transforms.EMPTY_TRANSFORM,
    Distributions.NONE,
    new SortOrder[0],
    new Index[] {
      Indexes.of(IndexType.PRIMARY_KEY, "PRIMARY", new String[][]{{"id"}}),
      Indexes.of(IndexType.UNIQUE_KEY, "name_age_score_uk", new String[][]{{"name"}, {"age"}, {"score"}})
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more details, you can refer to Gravitino’s &lt;a href="https://datastrato.ai/docs/0.4.0/manage-metadata-using-gravitino#table-column-default-value" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; on how to specify default values auto increment, and indexes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security enhancements
&lt;/h2&gt;

&lt;p&gt;Security is always our top priority at Gravitino. In version 0.3.0, we have implemented OAuth2 authentication support, and in this release, we add additional security features.&lt;/p&gt;

&lt;p&gt;Kerberos is widely supported in the big data field. In response to user demand, we have implemented Kerberos authentication support for client and server communication. With SPNEGO enabled, users can use Kerberos authenticated headers to communicate with the server.&lt;/p&gt;

&lt;p&gt;This version also includes the support of user impersonation, ensuring that each request uses a real user to communicate with the underlying sources. For the Hive catalog, we have added Kerberos support to communicate with the Hive MetaStore, by simply configuring the principal and keytab, Gravitino can now communicate with HMS using Kerberos authentication.&lt;/p&gt;

&lt;p&gt;For more details of how to enable security-related features,see the documentation &lt;a href="https://datastrato.ai/docs/0.4.0/security" rel="noopener noreferrer"&gt;security&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Support completed operator pushdown for Trino connector
&lt;/h2&gt;

&lt;p&gt;In version 0.4.0, we implemented the completed operator pushdown for the Trino connector, which has improved performance. Additionally, we conducted a TPC-H benchmark test, here is the performance comparison between the two versions (lower is better):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flbv0qo10maeusos3pnuu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flbv0qo10maeusos3pnuu.png" alt="TPC-H benchmark" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, for most of the TPC-H queries, the Gravitino 0.4.0 Trino connector gives better results, when compared to the previous version. It gains at most 38% performance boost and on average 7% better performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Java 8, 11, and 17 support
&lt;/h2&gt;

&lt;p&gt;Gravitino can now run on a variety of Java environments, including Java 8, 11, and 17. This enhancement offers increased flexibility and compatibility for users.&lt;/p&gt;

&lt;h2&gt;
  
  
  More than just features in Gravitino 0.4.0
&lt;/h2&gt;

&lt;p&gt;While the spotlight often falls on the new features, the true importance of the project is its focus on usability, stability, and incremental improvements. To that end, Gravitino 0.4.0 has tackled and resolved over 280 issues, thanks to the collaborative efforts of all the contributors. To learn more, read the &lt;a href="https://github.com/datastrato/gravitino/releases/tag/v0.4.0" rel="noopener noreferrer"&gt;release notes&lt;/a&gt; for the full list of improvements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started with Gravitino 0.4.0 today
&lt;/h2&gt;

&lt;p&gt;If you want to experiment with Gravitino 0.4.0, you can simply launch the provided docker playground, see the &lt;a href="https://datastrato.ai/docs/0.4.0/how-to-use-the-playground" rel="noopener noreferrer"&gt;playground documentation&lt;/a&gt;. If you want to install and run from the ground up, also see the documentation on &lt;a href="https://datastrato.ai/docs/0.4.0/how-to-install" rel="noopener noreferrer"&gt;how to install Gravitino&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please let us know if you have any questions, you can contact us via our &lt;a href="https://github.com/datastrato/gravitino" rel="noopener noreferrer"&gt;Github repository&lt;/a&gt;, or join our &lt;a href="https://gravitino.discourse.group/" rel="noopener noreferrer"&gt;Discourse community&lt;/a&gt; and &lt;a href="https://join.slack.com/t/datastrato-community/shared_invite/zt-2a8vsjoch-cU_uUwHA_QU6Ab50thoq8w" rel="noopener noreferrer"&gt;Slack group&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
